WebKit Bugzilla
Attachment 347534 Details for
Bug 188751
: Update some libwebrtc third party libraries as per libwebrtc 984f1a80c0c
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188751-20180820125835.patch (text/plain), 6.70 MB, created by
youenn fablet
on 2018-08-20 12:58:37 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
youenn fablet
Created:
2018-08-20 12:58:37 PDT
Size:
6.70 MB
patch
obsolete
>Subversion Revision: 235086 >diff --git a/Source/ThirdParty/libwebrtc/ChangeLog b/Source/ThirdParty/libwebrtc/ChangeLog >index 8f6aebb7b6a3180594ca725b53c386667e26ab93..30a320b425cbbbb9babca69e9a2885267c4d2e73 100644 >--- a/Source/ThirdParty/libwebrtc/ChangeLog >+++ b/Source/ThirdParty/libwebrtc/ChangeLog >@@ -1,3 +1,16 @@ >+2018-08-20 Youenn Fablet <youenn@apple.com> >+ >+ Update some libwebrtc third party libraries as per libwebrtc 984f1a80c0c >+ https://bugs.webkit.org/show_bug.cgi?id=188751 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ new-refreshed-third-party-libwebrtc >+ >+ * Source/third_party/abseil-cpp: Added. >+ * Source/third_party/libyuv: Refreshed. >+ * Source/third_party/rnnoise: Added. >+ > 2018-08-06 David Kilzer <ddkilzer@apple.com> > > [libwebrtc] SafeSetError() in peerconnection.cc contains use-after-move of webrtc::RTCError variable >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/ABSEIL_ISSUE_TEMPLATE.md b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/ABSEIL_ISSUE_TEMPLATE.md >new file mode 100644 >index 0000000000000000000000000000000000000000..ed5461f166c3f7ae1c177054e1a3b3e3970f3cb4 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/ABSEIL_ISSUE_TEMPLATE.md >@@ -0,0 +1,22 @@ >+Please submit a new Abseil Issue using the template below: >+ >+## [Short title of proposed API change(s)] >+ >+-------------------------------------------------------------------------------- >+-------------------------------------------------------------------------------- >+ >+## Background >+ >+[Provide the background information that is required in order to evaluate the >+proposed API changes. No controversial claims should be made here. If there are >+design constraints that need to be considered, they should be presented here >+**along with justification for those constraints**. Linking to other docs is >+good, but please keep the **pertinent information as self contained** as >+possible in this section.] >+ >+## Proposed API Change (s) >+ >+[Please clearly describe the API change(s) being proposed. If multiple changes, >+please keep them clearly distinguished. When possible, **use example code >+snippets to illustrate before-after API usages**. List pros-n-cons. Highlight >+the main questions that you want to be answered. Given the Abseil project compatibility requirements, describe why the API change is safe.] >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/AUTHORS b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/AUTHORS >new file mode 100644 >index 0000000000000000000000000000000000000000..976d31defc263902a9fe3b54d9ba3cf0d1185447 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/AUTHORS >@@ -0,0 +1,6 @@ >+# This is the list of Abseil authors for copyright purposes. >+# >+# This does not necessarily list everyone who has contributed code, since in >+# some cases, their employer may be the copyright holder. To see the full list >+# of contributors, see the revision history in source control. >+Google Inc. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..253a602e2f16792f1e286a524a1e032d23276df8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/BUILD.gn >@@ -0,0 +1,77 @@ >+# Copyright (c) 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+# Flags specified here must not impact ABI. Code compiled with and without these >+# opts will be linked together, and in some cases headers compiled with and >+# without these options will be part of the same program. >+ >+import("//build/toolchain/toolchain.gni") >+ >+group("default") { >+ deps = [ >+ "absl/types:any", >+ "absl/types:bad_any_cast", >+ "absl/types:span", >+ "absl/types:optional", >+ "absl/types:bad_optional_access", >+ ] >+} >+ >+config("absl_include_config") { >+ include_dirs = [ "." ] >+} >+ >+config("absl_define_config") { >+ defines = [ "ABSL_ALLOCATOR_NOTHROW=1" ] >+} >+ >+config("absl_default_cflags_cc") { >+ cflags_cc = [] >+ if (is_clang) { >+ cflags_cc += [ >+ # TODO(crbug.com/588506): Explicitly enable conversion warnings. >+ "-Wbool-conversion", >+ "-Wconstant-conversion", >+ "-Wenum-conversion", >+ "-Wint-conversion", >+ "-Wliteral-conversion", >+ "-Wnon-literal-null-conversion", >+ "-Wnull-conversion", >+ "-Wobjc-literal-conversion", >+ "-Wno-sign-conversion", >+ "-Wstring-conversion", >+ ] >+ if (!is_nacl && !use_xcode_clang) { >+ cflags_cc += [ "-Wbitfield-enum-conversion" ] >+ } >+ } >+ if (is_win) { >+ cflags_cc += [ >+ "/wd4005", # macro-redefinition >+ "/wd4018", # sign-compare >+ "/wd4068", # unknown pragma >+ "/wd4702", # unreachable code >+ ] >+ } >+} >+ >+config("absl_test_cflags_cc") { >+ cflags_cc = [] >+ if (is_clang || !is_win) { >+ cflags_cc += [ >+ "-Wno-conversion-null", >+ "-Wno-missing-declarations", >+ "-Wno-sign-compare", >+ "-Wno-unused-function", >+ "-Wno-unused-parameter", >+ "-Wno-unused-private-field", >+ ] >+ } >+ if (is_win) { >+ cflags_cc += [ >+ "/wd4018", # signed/unsigned mismatch >+ "/wd4101", # unreferenced local variable >+ ] >+ } >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/AbseilHelpers.cmake b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/AbseilHelpers.cmake >new file mode 100644 >index 0000000000000000000000000000000000000000..e4eafe49e47906515e448a2def59f7629b2ba393 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/AbseilHelpers.cmake >@@ -0,0 +1,170 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+include(CMakeParseArguments) >+ >+# The IDE folder for Abseil that will be used if Abseil is included in a CMake >+# project that sets >+# set_property(GLOBAL PROPERTY USE_FOLDERS ON) >+# For example, Visual Studio supports folders. >+set(ABSL_IDE_FOLDER Abseil) >+ >+# >+# create a library in the absl namespace >+# >+# parameters >+# SOURCES : sources files for the library >+# PUBLIC_LIBRARIES: targets and flags for linking phase >+# PRIVATE_COMPILE_FLAGS: compile flags for the library. Will not be exported. >+# EXPORT_NAME: export name for the absl:: target export >+# TARGET: target name >+# >+# create a target associated to <NAME> >+# libraries are installed under CMAKE_INSTALL_FULL_LIBDIR by default >+# >+function(absl_library) >+ cmake_parse_arguments(ABSL_LIB >+ "DISABLE_INSTALL" # keep that in case we want to support installation one day >+ "TARGET;EXPORT_NAME" >+ "SOURCES;PUBLIC_LIBRARIES;PRIVATE_COMPILE_FLAGS" >+ ${ARGN} >+ ) >+ >+ set(_NAME ${ABSL_LIB_TARGET}) >+ string(TOUPPER ${_NAME} _UPPER_NAME) >+ >+ add_library(${_NAME} STATIC ${ABSL_LIB_SOURCES}) >+ >+ target_compile_options(${_NAME} PRIVATE ${ABSL_COMPILE_CXXFLAGS} ${ABSL_LIB_PRIVATE_COMPILE_FLAGS}) >+ target_link_libraries(${_NAME} PUBLIC ${ABSL_LIB_PUBLIC_LIBRARIES}) >+ target_include_directories(${_NAME} >+ PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} ${ABSL_LIB_PUBLIC_INCLUDE_DIRS} >+ PRIVATE ${ABSL_LIB_PRIVATE_INCLUDE_DIRS} >+ ) >+ # Add all Abseil targets to a a folder in the IDE for organization. >+ set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) >+ >+ if(ABSL_LIB_EXPORT_NAME) >+ add_library(absl::${ABSL_LIB_EXPORT_NAME} ALIAS ${_NAME}) >+ endif() >+endfunction() >+ >+ >+ >+# >+# header only virtual target creation >+# >+function(absl_header_library) >+ cmake_parse_arguments(ABSL_HO_LIB >+ "DISABLE_INSTALL" >+ "EXPORT_NAME;TARGET" >+ "PUBLIC_LIBRARIES;PRIVATE_COMPILE_FLAGS;PUBLIC_INCLUDE_DIRS;PRIVATE_INCLUDE_DIRS" >+ ${ARGN} >+ ) >+ >+ set(_NAME ${ABSL_HO_LIB_TARGET}) >+ >+ set(__dummy_header_only_lib_file "${CMAKE_CURRENT_BINARY_DIR}/${_NAME}_header_only_dummy.cc") >+ >+ if(NOT EXISTS ${__dummy_header_only_lib_file}) >+ file(WRITE ${__dummy_header_only_lib_file} >+ "/* generated file for header-only cmake target */ >+ >+ namespace absl { >+ >+ // single meaningless symbol >+ void ${_NAME}__header_fakesym() {} >+ } // namespace absl >+ " >+ ) >+ endif() >+ >+ >+ add_library(${_NAME} ${__dummy_header_only_lib_file}) >+ target_link_libraries(${_NAME} PUBLIC ${ABSL_HO_LIB_PUBLIC_LIBRARIES}) >+ target_include_directories(${_NAME} >+ PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} ${ABSL_HO_LIB_PUBLIC_INCLUDE_DIRS} >+ PRIVATE ${ABSL_HO_LIB_PRIVATE_INCLUDE_DIRS} >+ ) >+ >+ # Add all Abseil targets to a a folder in the IDE for organization. >+ set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) >+ >+ 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 >+# >+# parameters >+# TARGET: target name prefix >+# SOURCES: sources files for the tests >+# PUBLIC_LIBRARIES: targets and flags for linking phase. >+# PRIVATE_COMPILE_FLAGS: compile flags for the test. Will not be exported. >+# >+# create a target associated to <NAME>_bin >+# >+# all tests will be register for execution with add_test() >+# >+# test compilation and execution is disable when BUILD_TESTING=OFF >+# >+function(absl_test) >+ >+ cmake_parse_arguments(ABSL_TEST >+ "" >+ "TARGET" >+ "SOURCES;PUBLIC_LIBRARIES;PRIVATE_COMPILE_FLAGS;PUBLIC_INCLUDE_DIRS" >+ ${ARGN} >+ ) >+ >+ >+ if(BUILD_TESTING) >+ >+ set(_NAME ${ABSL_TEST_TARGET}) >+ string(TOUPPER ${_NAME} _UPPER_NAME) >+ >+ add_executable(${_NAME}_bin ${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 >+ 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}) >+ >+ add_test(${_NAME} ${_NAME}_bin) >+ endif(BUILD_TESTING) >+ >+endfunction() >+ >+ >+ >+ >+function(check_target my_target) >+ >+ if(NOT TARGET ${my_target}) >+ message(FATAL_ERROR " ABSL: compiling absl requires a ${my_target} CMake target in your project, >+ see CMake/README.md for more details") >+ endif(NOT TARGET ${my_target}) >+ >+endfunction() >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/CMakeLists.txt.in b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/CMakeLists.txt.in >new file mode 100644 >index 0000000000000000000000000000000000000000..d60a33e9ac6a6ddfe0ebd181b33743f95e67b5a5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/CMakeLists.txt.in >@@ -0,0 +1,15 @@ >+cmake_minimum_required(VERSION 2.8.2) >+ >+project(googletest-download NONE) >+ >+include(ExternalProject) >+ExternalProject_Add(googletest >+ GIT_REPOSITORY https://github.com/google/googletest.git >+ GIT_TAG master >+ SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" >+ BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" >+ CONFIGURE_COMMAND "" >+ BUILD_COMMAND "" >+ INSTALL_COMMAND "" >+ TEST_COMMAND "" >+) >\ No newline at end of file >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/DownloadGTest.cmake b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/DownloadGTest.cmake >new file mode 100644 >index 0000000000000000000000000000000000000000..9d4132158b8df3aaf65d442f148521525fb253da >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/DownloadGTest.cmake >@@ -0,0 +1,32 @@ >+# Downloads and unpacks googletest at configure time. Based on the instructions >+# at https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project >+ >+# Download the latest googletest from Github master >+configure_file( >+ ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt.in >+ googletest-download/CMakeLists.txt >+) >+ >+# Configure and build the downloaded googletest source >+execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . >+ RESULT_VARIABLE result >+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download ) >+if(result) >+ message(FATAL_ERROR "CMake step for googletest failed: ${result}") >+endif() >+ >+execute_process(COMMAND ${CMAKE_COMMAND} --build . >+ RESULT_VARIABLE result >+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) >+if(result) >+ message(FATAL_ERROR "Build step for googletest failed: ${result}") >+endif() >+ >+# Prevent overriding the parent project's compiler/linker settings on Windows >+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) >+ >+# Add googletest directly to our build. This defines the gtest and gtest_main >+# targets. >+add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src >+ ${CMAKE_BINARY_DIR}/googletest-build >+ EXCLUDE_FROM_ALL) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/README.md b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/README.md >new file mode 100644 >index 0000000000000000000000000000000000000000..79bbe24d5ad4f40a4391bfab05ab77ca00032e7f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMake/README.md >@@ -0,0 +1,107 @@ >+# Abseil CMake Build Instructions >+ >+Abseil comes with a CMake build script ([CMakeLists.txt](../CMakeLists.txt)) >+that can be used on a wide range of platforms ("C" stands for cross-platform.). >+If you don't have CMake installed already, you can download it for free from >+<http://www.cmake.org/>. >+ >+CMake works by generating native makefiles or build projects that can >+be used in the compiler environment of your choice. >+ >+For API/ABI compatibility reasons, we strongly recommend building Abseil in a >+subdirectory of your project or as an embedded dependency. >+ >+## Incorporating Abseil Into a CMake Project >+ >+The recommendations below are similar to those for using CMake within the >+googletest framework >+(<https://github.com/google/googletest/blob/master/googletest/README.md#incorporating-into-an-existing-cmake-project>) >+ >+### Step-by-Step Instructions >+ >+1. If you want to build the Abseil tests, integrate the Abseil dependency >+[Google Test](https://github.com/google/googletest) into your CMake project. To disable Abseil tests, you have to pass >+`-DBUILD_TESTING=OFF` when configuring your project with CMake. >+ >+2. Download Abseil and copy it into a subdirectory in your CMake project or add >+Abseil as a [git submodule](https://git-scm.com/docs/git-submodule) in your >+CMake project. >+ >+3. You can then use the CMake command >+[`add_subdirectory()`](https://cmake.org/cmake/help/latest/command/add_subdirectory.html) >+to include Abseil directly in your CMake project. >+ >+4. Add the **absl::** target you wish to use to the >+[`target_link_libraries()`](https://cmake.org/cmake/help/latest/command/target_link_libraries.html) >+section of your executable or of your library.<br> >+Here is a short CMakeLists.txt example of a project file using Abseil. >+ >+```cmake >+cmake_minimum_required(VERSION 2.8.12) >+project(my_project) >+ >+set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ ${CMAKE_CXX_FLAGS}") >+ >+if(MSVC) >+ # /wd4005 macro-redefinition >+ # /wd4068 unknown pragma >+ # /wd4244 conversion from 'type1' to 'type2' >+ # /wd4267 conversion from 'size_t' to 'type2' >+ # /wd4800 force value to bool 'true' or 'false' (performance warning) >+ add_compile_options(/wd4005 /wd4068 /wd4244 /wd4267 /wd4800) >+ add_definitions(/DNOMINMAX /DWIN32_LEAN_AND_MEAN=1 /D_CRT_SECURE_NO_WARNINGS) >+endif() >+ >+add_subdirectory(abseil-cpp) >+ >+add_executable(my_exe source.cpp) >+target_link_libraries(my_exe absl::base absl::synchronization absl::strings) >+``` >+ >+### Running Abseil Tests with CMake >+ >+Use the `-DABSL_RUN_TESTS=ON` flag to run Abseil tests. Note that if the `-DBUILD_TESTING=OFF` flag is passed then Abseil tests will not be run. >+ >+You will need to provide Abseil with a Googletest dependency. There are two >+options for how to do this: >+ >+* Use `-DABSL_USE_GOOGLETEST_HEAD`. This will automatically download the latest >+Googletest source into the build directory at configure time. Googletest will >+then be compiled directly alongside Abseil's tests. >+* Manually integrate Googletest with your build. See >+https://github.com/google/googletest/blob/master/googletest/README.md#using-cmake >+for more information on using Googletest in a CMake project. >+ >+For example, to run just the Abseil tests, you could use this script: >+ >+``` >+cd path/to/abseil-cpp >+mkdir build >+cd build >+cmake -DABSL_USE_GOOGLETEST_HEAD=ON -DABSL_RUN_TESTS=ON .. >+make -j >+ctest >+``` >+ >+Currently, we only run our tests with CMake in a Linux environment, but we are >+working on the rest of our supported platforms. See >+https://github.com/abseil/abseil-cpp/projects/1 and >+https://github.com/abseil/abseil-cpp/issues/109 for more information. >+ >+### Available Abseil CMake Public Targets >+ >+Here's a non-exhaustive list of Abseil CMake public targets: >+ >+```cmake >+absl::base >+absl::algorithm >+absl::container >+absl::debugging >+absl::memory >+absl::meta >+absl::numeric >+absl::strings >+absl::synchronization >+absl::time >+absl::utility >+``` >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..89a3386f7e258efc9739b3517566c591f02ade7e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CMakeLists.txt >@@ -0,0 +1,98 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+# 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) >+project(absl) >+ >+list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake) >+ >+include(GNUInstallDirs) >+include(AbseilHelpers) >+ >+ >+# config options >+if (MSVC) >+ # /wd4005 macro-redefinition >+ # /wd4068 unknown pragma >+ # /wd4244 conversion from 'type1' to 'type2' >+ # /wd4267 conversion from 'size_t' to 'type2' >+ # /wd4800 force value to bool 'true' or 'false' (performance warning) >+ add_compile_options(/W3 /WX /wd4005 /wd4068 /wd4244 /wd4267 /wd4800) >+ add_definitions(/DNOMINMAX /DWIN32_LEAN_AND_MEAN=1 /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS) >+else() >+ set(ABSL_STD_CXX_FLAG "-std=c++11" CACHE STRING "c++ std flag (default: c++11)") >+endif() >+ >+ >+ >+## >+## Using absl targets >+## >+## all public absl targets are >+## exported with the absl:: prefix >+## >+## e.g absl::base absl::synchronization absl::strings .... >+## >+## DO NOT rely on the internal targets outside of the prefix >+ >+ >+# include current path >+list(APPEND ABSL_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) >+ >+# -std=X >+set(CMAKE_CXX_FLAGS "${ABSL_STD_CXX_FLAG} ${CMAKE_CXX_FLAGS}") >+ >+# -fexceptions >+set(ABSL_EXCEPTIONS_FLAG "${CMAKE_CXX_EXCEPTIONS}") >+ >+# find dependencies >+## pthread >+find_package(Threads REQUIRED) >+ >+option(ABSL_USE_GOOGLETEST_HEAD >+ "If ON, abseil will download HEAD from googletest at config time." OFF) >+ >+option(ABSL_RUN_TESTS "If ON, Abseil tests will be run." OFF) >+ >+if(${ABSL_RUN_TESTS}) >+ # enable CTest. This will set BUILD_TESTING to ON unless otherwise specified >+ # on the command line >+ include(CTest) >+ enable_testing() >+endif() >+ >+## check targets >+if(BUILD_TESTING) >+ >+ if(${ABSL_USE_GOOGLETEST_HEAD}) >+ include(CMake/DownloadGTest.cmake) >+ endif() >+ >+ check_target(gtest) >+ check_target(gtest_main) >+ check_target(gmock) >+ >+ list(APPEND ABSL_TEST_COMMON_LIBRARIES >+ gtest_main >+ gtest >+ gmock >+ ${CMAKE_THREAD_LIBS_INIT} >+ ) >+endif() >+ >+add_subdirectory(absl) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CONTRIBUTING.md b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CONTRIBUTING.md >new file mode 100644 >index 0000000000000000000000000000000000000000..40351ddcfaa14e0ed253031100a04f9d3323df61 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/CONTRIBUTING.md >@@ -0,0 +1,91 @@ >+# How to Contribute to Abseil >+ >+We'd love to accept your patches and contributions to this project. There are >+just a few small guidelines you need to follow. >+ >+NOTE: If you are new to GitHub, please start by reading [Pull Request >+howto](https://help.github.com/articles/about-pull-requests/) >+ >+## Contributor License Agreement >+ >+Contributions to this project must be accompanied by a Contributor License >+Agreement. You (or your employer) retain the copyright to your contribution, >+this simply gives us permission to use and redistribute your contributions as >+part of the project. Head over to <https://cla.developers.google.com/> to see >+your current agreements on file or to sign a new one. >+ >+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. >+ >+## Coding Style >+ >+To keep the source consistent, readable, diffable and easy to merge, we use a >+fairly rigid coding style, as defined by the >+[google-styleguide](https://github.com/google/styleguide) project. All patches >+will be expected to conform to the style outlined >+[here](https://google.github.io/styleguide/cppguide.html). >+ >+## Guidelines for Pull Requests >+ >+* If you are a Googler, it is preferable to first create an internal CL and >+ have it reviewed and submitted. The code propagation process will deliver >+ the change to GitHub. >+ >+* Create **small PRs** that are narrowly focused on **addressing a single >+ concern**. We often receive PRs that are trying to fix several things at a >+ time, but if only one fix is considered acceptable, nothing gets merged and >+ both author's & review's time is wasted. Create more PRs to address >+ different concerns and everyone will be happy. >+ >+* For speculative changes, consider opening an [Abseil >+ issue](https://github.com/abseil/abseil-cpp/issues) and discussing it first. >+ If you are suggesting a behavioral or API change, consider starting with an >+ [Abseil proposal template](ABSEIL_ISSUE_TEMPLATE.md). >+ >+* Provide a good **PR description** as a record of **what** change is being >+ made and **why** it was made. Link to a GitHub issue if it exists. >+ >+* Don't fix code style and formatting unless you are already changing that >+ line to address an issue. Formatting of modified lines may be done using >+ `git clang-format`. PRs with irrelevant changes won't be merged. If >+ you do want to fix formatting or style, do that in a separate PR. >+ >+* Unless your PR is trivial, you should expect there will be reviewer comments >+ that you'll need to address before merging. We expect you to be reasonably >+ responsive to those comments, otherwise the PR will be closed after 2-3 >+ weeks of inactivity. >+ >+* Maintain **clean commit history** and use **meaningful commit messages**. >+ PRs with messy commit history are difficult to review and won't be merged. >+ Use `rebase -i upstream/master` to curate your commit history and/or to >+ bring in latest changes from master (but avoid rebasing in the middle of a >+ code review). >+ >+* Keep your PR up to date with upstream/master (if there are merge conflicts, >+ we can't really merge your change). >+ >+* **All tests need to be passing** before your change can be merged. We >+ recommend you **run tests locally** (see below) >+ >+* Exceptions to the rules can be made if there's a compelling reason for doing >+ so. That is - the rules are here to serve us, not the other way around, and >+ the rules need to be serving their intended purpose to be valuable. >+ >+* All submissions, including submissions by project members, require review. >+ >+## Running Tests >+ >+Use "bazel test <>" functionality to run the unit tests. >+ >+Prerequisites for building and running tests are listed in >+[README.md](README.md) >+ >+## Abseil Committers >+ >+The current members of the Abseil engineering team are the only committers at >+present. >+ >+## Release Process >+ >+Abseil lives at head, where latest-and-greatest code can be found. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/LICENSE b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/LICENSE >new file mode 100644 >index 0000000000000000000000000000000000000000..fef7d967815b508d2be5bfe3ded6b62ad302e90c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/LICENSE >@@ -0,0 +1,204 @@ >+ >+ Apache License >+ Version 2.0, January 2004 >+ http://www.apache.org/licenses/ >+ >+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION >+ >+ 1. Definitions. >+ >+ "License" shall mean the terms and conditions for use, reproduction, >+ and distribution as defined by Sections 1 through 9 of this document. >+ >+ "Licensor" shall mean the copyright owner or entity authorized by >+ the copyright owner that is granting the License. >+ >+ "Legal Entity" shall mean the union of the acting entity and all >+ other entities that control, are controlled by, or are under common >+ control with that entity. For the purposes of this definition, >+ "control" means (i) the power, direct or indirect, to cause the >+ direction or management of such entity, whether by contract or >+ otherwise, or (ii) ownership of fifty percent (50%) or more of the >+ outstanding shares, or (iii) beneficial ownership of such entity. >+ >+ "You" (or "Your") shall mean an individual or Legal Entity >+ exercising permissions granted by this License. >+ >+ "Source" form shall mean the preferred form for making modifications, >+ including but not limited to software source code, documentation >+ source, and configuration files. >+ >+ "Object" form shall mean any form resulting from mechanical >+ transformation or translation of a Source form, including but >+ not limited to compiled object code, generated documentation, >+ and conversions to other media types. >+ >+ "Work" shall mean the work of authorship, whether in Source or >+ Object form, made available under the License, as indicated by a >+ copyright notice that is included in or attached to the work >+ (an example is provided in the Appendix below). >+ >+ "Derivative Works" shall mean any work, whether in Source or Object >+ form, that is based on (or derived from) the Work and for which the >+ editorial revisions, annotations, elaborations, or other modifications >+ represent, as a whole, an original work of authorship. For the purposes >+ of this License, Derivative Works shall not include works that remain >+ separable from, or merely link (or bind by name) to the interfaces of, >+ the Work and Derivative Works thereof. >+ >+ "Contribution" shall mean any work of authorship, including >+ the original version of the Work and any modifications or additions >+ to that Work or Derivative Works thereof, that is intentionally >+ submitted to Licensor for inclusion in the Work by the copyright owner >+ or by an individual or Legal Entity authorized to submit on behalf of >+ the copyright owner. For the purposes of this definition, "submitted" >+ means any form of electronic, verbal, or written communication sent >+ to the Licensor or its representatives, including but not limited to >+ communication on electronic mailing lists, source code control systems, >+ and issue tracking systems that are managed by, or on behalf of, the >+ Licensor for the purpose of discussing and improving the Work, but >+ excluding communication that is conspicuously marked or otherwise >+ designated in writing by the copyright owner as "Not a Contribution." >+ >+ "Contributor" shall mean Licensor and any individual or Legal Entity >+ on behalf of whom a Contribution has been received by Licensor and >+ subsequently incorporated within the Work. >+ >+ 2. Grant of Copyright License. Subject to the terms and conditions of >+ this License, each Contributor hereby grants to You a perpetual, >+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable >+ copyright license to reproduce, prepare Derivative Works of, >+ publicly display, publicly perform, sublicense, and distribute the >+ Work and such Derivative Works in Source or Object form. >+ >+ 3. Grant of Patent License. Subject to the terms and conditions of >+ this License, each Contributor hereby grants to You a perpetual, >+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable >+ (except as stated in this section) patent license to make, have made, >+ use, offer to sell, sell, import, and otherwise transfer the Work, >+ where such license applies only to those patent claims licensable >+ by such Contributor that are necessarily infringed by their >+ Contribution(s) alone or by combination of their Contribution(s) >+ with the Work to which such Contribution(s) was submitted. If You >+ institute patent litigation against any entity (including a >+ cross-claim or counterclaim in a lawsuit) alleging that the Work >+ or a Contribution incorporated within the Work constitutes direct >+ or contributory patent infringement, then any patent licenses >+ granted to You under this License for that Work shall terminate >+ as of the date such litigation is filed. >+ >+ 4. Redistribution. You may reproduce and distribute copies of the >+ Work or Derivative Works thereof in any medium, with or without >+ modifications, and in Source or Object form, provided that You >+ meet the following conditions: >+ >+ (a) You must give any other recipients of the Work or >+ Derivative Works a copy of this License; and >+ >+ (b) You must cause any modified files to carry prominent notices >+ stating that You changed the files; and >+ >+ (c) You must retain, in the Source form of any Derivative Works >+ that You distribute, all copyright, patent, trademark, and >+ attribution notices from the Source form of the Work, >+ excluding those notices that do not pertain to any part of >+ the Derivative Works; and >+ >+ (d) If the Work includes a "NOTICE" text file as part of its >+ distribution, then any Derivative Works that You distribute must >+ include a readable copy of the attribution notices contained >+ within such NOTICE file, excluding those notices that do not >+ pertain to any part of the Derivative Works, in at least one >+ of the following places: within a NOTICE text file distributed >+ as part of the Derivative Works; within the Source form or >+ documentation, if provided along with the Derivative Works; or, >+ within a display generated by the Derivative Works, if and >+ wherever such third-party notices normally appear. The contents >+ of the NOTICE file are for informational purposes only and >+ do not modify the License. You may add Your own attribution >+ notices within Derivative Works that You distribute, alongside >+ or as an addendum to the NOTICE text from the Work, provided >+ that such additional attribution notices cannot be construed >+ as modifying the License. >+ >+ You may add Your own copyright statement to Your modifications and >+ may provide additional or different license terms and conditions >+ for use, reproduction, or distribution of Your modifications, or >+ for any such Derivative Works as a whole, provided Your use, >+ reproduction, and distribution of the Work otherwise complies with >+ the conditions stated in this License. >+ >+ 5. Submission of Contributions. Unless You explicitly state otherwise, >+ any Contribution intentionally submitted for inclusion in the Work >+ by You to the Licensor shall be under the terms and conditions of >+ this License, without any additional terms or conditions. >+ Notwithstanding the above, nothing herein shall supersede or modify >+ the terms of any separate license agreement you may have executed >+ with Licensor regarding such Contributions. >+ >+ 6. Trademarks. This License does not grant permission to use the trade >+ names, trademarks, service marks, or product names of the Licensor, >+ except as required for reasonable and customary use in describing the >+ origin of the Work and reproducing the content of the NOTICE file. >+ >+ 7. Disclaimer of Warranty. Unless required by applicable law or >+ agreed to in writing, Licensor provides the Work (and each >+ Contributor provides its Contributions) on an "AS IS" BASIS, >+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >+ implied, including, without limitation, any warranties or conditions >+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A >+ PARTICULAR PURPOSE. You are solely responsible for determining the >+ appropriateness of using or redistributing the Work and assume any >+ risks associated with Your exercise of permissions under this License. >+ >+ 8. Limitation of Liability. In no event and under no legal theory, >+ whether in tort (including negligence), contract, or otherwise, >+ unless required by applicable law (such as deliberate and grossly >+ negligent acts) or agreed to in writing, shall any Contributor be >+ liable to You for damages, including any direct, indirect, special, >+ incidental, or consequential damages of any character arising as a >+ result of this License or out of the use or inability to use the >+ Work (including but not limited to damages for loss of goodwill, >+ work stoppage, computer failure or malfunction, or any and all >+ other commercial damages or losses), even if such Contributor >+ has been advised of the possibility of such damages. >+ >+ 9. Accepting Warranty or Additional Liability. While redistributing >+ the Work or Derivative Works thereof, You may choose to offer, >+ and charge a fee for, acceptance of support, warranty, indemnity, >+ or other liability obligations and/or rights consistent with this >+ License. However, in accepting such obligations, You may act only >+ on Your own behalf and on Your sole responsibility, not on behalf >+ of any other Contributor, and only if You agree to indemnify, >+ defend, and hold each Contributor harmless for any liability >+ incurred by, or claims asserted against, such Contributor by reason >+ of your accepting any such warranty or additional liability. >+ >+ END OF TERMS AND CONDITIONS >+ >+ APPENDIX: How to apply the Apache License to your work. >+ >+ To apply the Apache License to your work, attach the following >+ boilerplate notice, with the fields enclosed by brackets "[]" >+ replaced with your own identifying information. (Don't include >+ the brackets!) The text should be enclosed in the appropriate >+ comment syntax for the file format. We also recommend that a >+ file or class name and description of purpose be included on the >+ same "printed page" as the copyright notice for easier >+ identification within third-party archives. >+ >+ Copyright [yyyy] [name of copyright owner] >+ >+ 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. >+ >+ >\ No newline at end of file >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/LTS.md b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/LTS.md >new file mode 100644 >index 0000000000000000000000000000000000000000..385b4f062bf315b4184a7a0db098f3441e7013bf >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/LTS.md >@@ -0,0 +1,13 @@ >+# Long Term Support (LTS) Branches >+ >+This repository contains periodic snapshots of the Abseil codebase that are >+Long Term Support (LTS) branches. An LTS branch allows you to use a known >+version of Abseil without interfering with other projects which may also, in >+turn, use Abseil. (For more information about our releases, see the >+[Abseil Release Management](https://abseil.io/about/releases) guide.) >+ >+## LTS Branches >+ >+The following lists LTS branches and the dates on which they have been released: >+ >+* [LTS Branch June 20, 2018](https://github.com/abseil/abseil-cpp/tree/lts_2018_06_20/) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/OWNERS b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/OWNERS >new file mode 100644 >index 0000000000000000000000000000000000000000..ceca4a8ba2cb16bd8d1d7833bedf78e6f09c93a1 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/OWNERS >@@ -0,0 +1,2 @@ >+mbonadei@chromium.org >+phoglund@chromium.org >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/README.chromium b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/README.chromium >new file mode 100644 >index 0000000000000000000000000000000000000000..91d6d381a47704450b599a009f049c707b1a9232 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/README.chromium >@@ -0,0 +1,34 @@ >+Name: Abseil >+Short Name: absl >+URL: https://github.com/abseil/abseil-cpp >+License: Apache 2.0 >+License File: LICENSE >+Version: 0 >+Revision: bea85b52733022294eef108a2e42d77b616ddca2 >+Security Critical: yes >+ >+Description: >+This directory contains the source code of Abseil for C++. This can be used by >+Chromium's dependencies, but shouldn't be used by Chromium itself. >+See: https://goo.gl/TgnJb8. >+ >+How to update Abseil: >+ >+1. Download the code from the Abseil git repository (see URL). >+ >+2. Copy the content of the Abseil git repo to //third_party/abseil-cpp. >+ >+3. From //third_party/abseil-cpp/ launch ./rename_dynamic_annotations.sh. >+ This script will rewrite dynamic_annotations macros and function inside >+ Abseil in order to avoid ODR violations and macro clashing with Chromium >+ (see: https://github.com/abseil/abseil-cpp/issues/122). >+ >+Local Modifications: >+ >+* absl/copts.bzl has been translated to //third_party/absl-cpp/BUILD.gn. Both >+ files contain lists of compiler flags in order to reduce duplication. >+ >+* All the BUILD.bazel files has been translated to BUILD.gn files. >+ >+* Functions and macros in absl/base/dynamic_annotations.{h,cc} have been renamed >+ to avoid ODR violations (see step 3). >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/README.md b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/README.md >new file mode 100644 >index 0000000000000000000000000000000000000000..8eed5751bf54003681956cd7a4f5b107b15eafd1 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/README.md >@@ -0,0 +1,108 @@ >+# Abseil - C++ Common Libraries >+ >+The repository contains the Abseil C++ library code. Abseil is an open-source >+collection of C++ code (compliant to C++11) designed to augment the C++ >+standard library. >+ >+## Table of Contents >+ >+- [About Abseil](#about) >+- [Quickstart](#quickstart) >+- [Building Abseil](#build) >+- [Codemap](#codemap) >+- [License](#license) >+- [Links](#links) >+ >+<a name="about"></a> >+## About Abseil >+ >+Abseil is an open-source collection of C++ library code designed to augment >+the C++ standard library. The Abseil library code is collected from Google's >+own C++ code base, has been extensively tested and used in production, and >+is the same code we depend on in our daily coding lives. >+ >+In some cases, Abseil provides pieces missing from the C++ standard; in >+others, Abseil provides alternatives to the standard for special needs >+we've found through usage in the Google code base. We denote those cases >+clearly within the library code we provide you. >+ >+Abseil is not meant to be a competitor to the standard library; we've >+just found that many of these utilities serve a purpose within our code >+base, and we now want to provide those resources to the C++ community as >+a whole. >+ >+<a name="quickstart"></a> >+## Quickstart >+ >+If you want to just get started, make sure you at least run through the >+[Abseil Quickstart](https://abseil.io/docs/cpp/quickstart). The Quickstart >+contains information about setting up your development environment, downloading >+the Abseil code, running tests, and getting a simple binary working. >+ >+<a name="build"></a> >+## Building Abseil >+ >+[Bazel](http://bazel.build) is the official build system for Abseil, >+which is supported on most major platforms (Linux, Windows, MacOS, for example) >+and compilers. See the [quickstart](https://abseil.io/docs/cpp/quickstart) for >+more information on building Abseil using the Bazel build system. >+ >+<a name="cmake"></a> >+If you require CMake support, please check the >+[CMake build instructions](CMake/README.md). >+ >+## Codemap >+ >+Abseil contains the following C++ library components: >+ >+* [`base`](absl/base/) Abseil Fundamentals >+ <br /> The `base` library contains initialization code and other code which >+ all other Abseil code depends on. Code within `base` may not depend on any >+ other code (other than the C++ standard library). >+* [`algorithm`](absl/algorithm/) >+ <br /> The `algorithm` library contains additions to the C++ `<algorithm>` >+ library and container-based versions of such algorithms. >+* [`container`](absl/container/) >+ <br /> The `container` library contains additional STL-style containers. >+* [`debugging`](absl/debugging/) >+ <br /> The `debugging` library contains code useful for enabling leak >+ checks. Future updates will add stacktrace and symbolization utilities. >+* [`memory`](absl/memory/) >+ <br /> The `memory` library contains C++11-compatible versions of >+ `std::make_unique()` and related memory management facilities. >+* [`meta`](absl/meta/) >+ <br /> The `meta` library contains C++11-compatible versions of type checks >+ available within C++14 and C++17 versions of the C++ `<type_traits>` library. >+* [`numeric`](absl/numeric/) >+ <br /> The `numeric` library contains C++11-compatible 128-bit integers. >+* [`strings`](absl/strings/) >+ <br /> The `strings` library contains a variety of strings routines and >+ utilities, including a C++11-compatible version of the C++17 >+ `std::string_view` type. >+* [`synchronization`](absl/synchronization/) >+ <br /> The `synchronization` library contains concurrency primitives (Abseil's >+ `absl::Mutex` class, an alternative to `std::mutex`) and a variety of >+ synchronization abstractions. >+* [`time`](absl/time/) >+ <br /> The `time` library contains abstractions for computing with absolute >+ points in time, durations of time, and formatting and parsing time within >+ time zones. >+* [`types`](absl/types/) >+ <br /> The `types` library contains non-container utility types, like a >+ C++11-compatible version of the C++17 `std::optional` type. >+ >+## License >+ >+The Abseil C++ library is licensed under the terms of the Apache >+license. See [LICENSE](LICENSE) for more information. >+ >+## Links >+ >+For more information about Abseil: >+ >+* Consult our [Abseil Introduction](http://abseil.io/about/intro) >+* Read [Why Adopt Abseil](http://abseil.io/about/philosophy) to understand our >+ design philosophy. >+* Peruse our >+ [Abseil Compatibility Guarantees](http://abseil.io/about/compatibility) to >+ understand both what we promise to you, and what we expect of you in return. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/WORKSPACE b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/WORKSPACE >new file mode 100644 >index 0000000000000000000000000000000000000000..e4a911978dc6825695a28413bdfa2355accda27d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/WORKSPACE >@@ -0,0 +1,29 @@ >+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", >+ ], >+ strip_prefix = "bazel-toolchains-287b64e0a211fb7c23b74695f8d5f5205b61f4eb", >+ sha256 = "aca8ac6afd7745027ee4a43032b51a725a61a75a30f02cc58681ee87e4dcdf4b", >+) >+ >+# GoogleTest/GoogleMock framework. Used by most unit-tests. >+http_archive( >+ name = "com_google_googletest", >+ urls = ["https://github.com/google/googletest/archive/b4d4438df9479675a632b2f11125e57133822ece.zip"], # 2018-07-16 >+ strip_prefix = "googletest-b4d4438df9479675a632b2f11125e57133822ece", >+ sha256 = "5aaa5d566517cae711e2a3505ea9a6438be1b37fcaae0ebcb96ccba9aa56f23a", >+) >+ >+# Google benchmark. >+http_archive( >+ name = "com_github_google_benchmark", >+ urls = ["https://github.com/google/benchmark/archive/16703ff83c1ae6d53e5155df3bb3ab0bc96083be.zip"], >+ strip_prefix = "benchmark-16703ff83c1ae6d53e5155df3bb3ab0bc96083be", >+ sha256 = "59f918c8ccd4d74b6ac43484467b500f1d64b40cc1010daa055375b322a43ba3", >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..edd0274c5d837d7dfb717d4e942f59f7e48ed6a5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/BUILD.bazel >@@ -0,0 +1,51 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+package(default_visibility = ["//visibility:public"]) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+load(":compiler_config_setting.bzl", "create_llvm_config") >+ >+create_llvm_config( >+ name = "llvm_compiler", >+ visibility = [":__subpackages__"], >+) >+ >+# following configs are based on mapping defined in: https://git.io/v5Ijz >+config_setting( >+ name = "ios", >+ values = { >+ "cpu": "darwin", >+ }, >+ visibility = [":__subpackages__"], >+) >+ >+config_setting( >+ name = "windows", >+ values = { >+ "cpu": "x64_windows", >+ }, >+ visibility = [":__subpackages__"], >+) >+ >+config_setting( >+ name = "ppc", >+ values = { >+ "cpu": "ppc", >+ }, >+ visibility = [":__subpackages__"], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..689f64e258baac99201cfa7894dbcb80542408df >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/CMakeLists.txt >@@ -0,0 +1,30 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+ >+ >+add_subdirectory(base) >+add_subdirectory(algorithm) >+add_subdirectory(container) >+add_subdirectory(debugging) >+add_subdirectory(memory) >+add_subdirectory(meta) >+add_subdirectory(numeric) >+add_subdirectory(strings) >+add_subdirectory(synchronization) >+add_subdirectory(time) >+add_subdirectory(types) >+add_subdirectory(utility) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..d04dc71206e8d969433f8523beb611f79cb64225 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/BUILD.bazel >@@ -0,0 +1,81 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+) >+ >+package(default_visibility = ["//visibility:public"]) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+cc_library( >+ name = "algorithm", >+ hdrs = ["algorithm.h"], >+ copts = ABSL_DEFAULT_COPTS, >+) >+ >+cc_test( >+ name = "algorithm_test", >+ size = "small", >+ srcs = ["algorithm_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":algorithm", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "algorithm_benchmark", >+ srcs = ["equal_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ deps = [ >+ ":algorithm", >+ "//absl/base:core_headers", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_library( >+ name = "container", >+ hdrs = [ >+ "container.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":algorithm", >+ "//absl/base:core_headers", >+ "//absl/meta:type_traits", >+ ], >+) >+ >+cc_test( >+ name = "container_test", >+ srcs = ["container_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":container", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "//absl/memory", >+ "//absl/types:span", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..37ec665764d49cbb2d1a8bbc5619e059b7c52da3 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/BUILD.gn >@@ -0,0 +1,44 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("algorithm") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "algorithm.h", >+ ] >+} >+ >+source_set("container") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "container.h", >+ ] >+ deps = [ >+ ":algorithm", >+ "../base:core_headers", >+ "../meta:type_traits", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..fdf45c55ed6313e83bb19bfa83a5b473e95ef9b7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt >@@ -0,0 +1,63 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+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 >+ algorithm >+) >+ >+absl_test( >+ TARGET >+ algorithm_test >+ SOURCES >+ ${ALGORITHM_TEST_SRC} >+ PUBLIC_LIBRARIES >+ absl::algorithm >+) >+ >+ >+ >+ >+# test container_test >+set(CONTAINER_TEST_SRC "container_test.cc") >+ >+absl_test( >+ TARGET >+ container_test >+ SOURCES >+ ${CONTAINER_TEST_SRC} >+ PUBLIC_LIBRARIES >+ absl::algorithm >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/algorithm.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/algorithm.h >new file mode 100644 >index 0000000000000000000000000000000000000000..3d6586439fe3bc5111e67b0582511d1c6734fd66 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/algorithm.h >@@ -0,0 +1,150 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: algorithm.h >+// ----------------------------------------------------------------------------- >+// >+// This header file contains Google extensions to the standard <algorithm> C++ >+// header. >+ >+#ifndef ABSL_ALGORITHM_ALGORITHM_H_ >+#define ABSL_ALGORITHM_ALGORITHM_H_ >+ >+#include <algorithm> >+#include <iterator> >+#include <type_traits> >+ >+namespace absl { >+ >+namespace algorithm_internal { >+ >+// Performs comparisons with operator==, similar to C++14's `std::equal_to<>`. >+struct EqualTo { >+ template <typename T, typename U> >+ bool operator()(const T& a, const U& b) const { >+ return a == b; >+ } >+}; >+ >+template <typename InputIter1, typename InputIter2, typename Pred> >+bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2, >+ InputIter2 last2, Pred pred, std::input_iterator_tag, >+ std::input_iterator_tag) { >+ while (true) { >+ if (first1 == last1) return first2 == last2; >+ if (first2 == last2) return false; >+ if (!pred(*first1, *first2)) return false; >+ ++first1; >+ ++first2; >+ } >+} >+ >+template <typename InputIter1, typename InputIter2, typename Pred> >+bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2, >+ InputIter2 last2, Pred&& pred, std::random_access_iterator_tag, >+ std::random_access_iterator_tag) { >+ return (last1 - first1 == last2 - first2) && >+ std::equal(first1, last1, first2, std::forward<Pred>(pred)); >+} >+ >+// When we are using our own internal predicate that just applies operator==, we >+// forward to the non-predicate form of std::equal. This enables an optimization >+// in libstdc++ that can result in std::memcmp being used for integer types. >+template <typename InputIter1, typename InputIter2> >+bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2, >+ InputIter2 last2, algorithm_internal::EqualTo /* unused */, >+ std::random_access_iterator_tag, >+ std::random_access_iterator_tag) { >+ return (last1 - first1 == last2 - first2) && >+ std::equal(first1, last1, first2); >+} >+ >+template <typename It> >+It RotateImpl(It first, It middle, It last, std::true_type) { >+ return std::rotate(first, middle, last); >+} >+ >+template <typename It> >+It RotateImpl(It first, It middle, It last, std::false_type) { >+ std::rotate(first, middle, last); >+ return std::next(first, std::distance(middle, last)); >+} >+ >+} // namespace algorithm_internal >+ >+// Compares the equality of two ranges specified by pairs of iterators, using >+// the given predicate, returning true iff for each corresponding iterator i1 >+// and i2 in the first and second range respectively, pred(*i1, *i2) == true >+// >+// This comparison takes at most min(`last1` - `first1`, `last2` - `first2`) >+// invocations of the predicate. Additionally, if InputIter1 and InputIter2 are >+// both random-access iterators, and `last1` - `first1` != `last2` - `first2`, >+// then the predicate is never invoked and the function returns false. >+// >+// This is a C++11-compatible implementation of C++14 `std::equal`. See >+// http://en.cppreference.com/w/cpp/algorithm/equal for more information. >+template <typename InputIter1, typename InputIter2, typename Pred> >+bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, >+ InputIter2 last2, Pred&& pred) { >+ return algorithm_internal::EqualImpl( >+ first1, last1, first2, last2, std::forward<Pred>(pred), >+ typename std::iterator_traits<InputIter1>::iterator_category{}, >+ typename std::iterator_traits<InputIter2>::iterator_category{}); >+} >+ >+// Performs comparison of two ranges specified by pairs of iterators using >+// operator==. >+template <typename InputIter1, typename InputIter2> >+bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, >+ InputIter2 last2) { >+ return absl::equal(first1, last1, first2, last2, >+ algorithm_internal::EqualTo{}); >+} >+ >+// Performs a linear search for `value` using the iterator `first` up to >+// but not including `last`, returning true if [`first`, `last`) contains an >+// element equal to `value`. >+// >+// A linear search is of O(n) complexity which is guaranteed to make at most >+// n = (`last` - `first`) comparisons. A linear search over short containers >+// may be faster than a binary search, even when the container is sorted. >+template <typename InputIterator, typename EqualityComparable> >+bool linear_search(InputIterator first, InputIterator last, >+ const EqualityComparable& value) { >+ return std::find(first, last, value) != last; >+} >+ >+// Performs a left rotation on a range of elements (`first`, `last`) such that >+// `middle` is now the first element. `rotate()` returns an iterator pointing to >+// the first element before rotation. This function is exactly the same as >+// `std::rotate`, but fixes a bug in gcc >+// <= 4.9 where `std::rotate` returns `void` instead of an iterator. >+// >+// The complexity of this algorithm is the same as that of `std::rotate`, but if >+// `ForwardIterator` is not a random-access iterator, then `absl::rotate` >+// performs an additional pass over the range to construct the return value. >+ >+template <typename ForwardIterator> >+ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, >+ ForwardIterator last) { >+ return algorithm_internal::RotateImpl( >+ first, middle, last, >+ std::is_same<decltype(std::rotate(first, middle, last)), >+ ForwardIterator>()); >+} >+ >+} // namespace absl >+ >+#endif // ABSL_ALGORITHM_ALGORITHM_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/algorithm_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/algorithm_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e4322bc4f202e31e8526b21e7d26994de630ea73 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/algorithm_test.cc >@@ -0,0 +1,182 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/algorithm/algorithm.h" >+ >+#include <algorithm> >+#include <list> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+ >+namespace { >+ >+TEST(EqualTest, DefaultComparisonRandomAccess) { >+ std::vector<int> v1{1, 2, 3}; >+ std::vector<int> v2 = v1; >+ std::vector<int> v3 = {1, 2}; >+ std::vector<int> v4 = {1, 2, 4}; >+ >+ EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end())); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end())); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end())); >+} >+ >+TEST(EqualTest, DefaultComparison) { >+ std::list<int> lst1{1, 2, 3}; >+ std::list<int> lst2 = lst1; >+ std::list<int> lst3{1, 2}; >+ std::list<int> lst4{1, 2, 4}; >+ >+ EXPECT_TRUE(absl::equal(lst1.begin(), lst1.end(), lst2.begin(), lst2.end())); >+ EXPECT_FALSE(absl::equal(lst1.begin(), lst1.end(), lst3.begin(), lst3.end())); >+ EXPECT_FALSE(absl::equal(lst1.begin(), lst1.end(), lst4.begin(), lst4.end())); >+} >+ >+TEST(EqualTest, EmptyRange) { >+ std::vector<int> v1{1, 2, 3}; >+ std::vector<int> empty1; >+ std::vector<int> empty2; >+ >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), empty1.begin(), empty1.end())); >+ EXPECT_FALSE(absl::equal(empty1.begin(), empty1.end(), v1.begin(), v1.end())); >+ EXPECT_TRUE( >+ absl::equal(empty1.begin(), empty1.end(), empty2.begin(), empty2.end())); >+} >+ >+TEST(EqualTest, MixedIterTypes) { >+ std::vector<int> v1{1, 2, 3}; >+ std::list<int> lst1{v1.begin(), v1.end()}; >+ std::list<int> lst2{1, 2, 4}; >+ std::list<int> lst3{1, 2}; >+ >+ EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), lst1.begin(), lst1.end())); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), lst2.begin(), lst2.end())); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), lst3.begin(), lst3.end())); >+} >+ >+TEST(EqualTest, MixedValueTypes) { >+ std::vector<int> v1{1, 2, 3}; >+ std::vector<char> v2{1, 2, 3}; >+ std::vector<char> v3{1, 2}; >+ std::vector<char> v4{1, 2, 4}; >+ >+ EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end())); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end())); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end())); >+} >+ >+TEST(EqualTest, WeirdIterators) { >+ std::vector<bool> v1{true, false}; >+ std::vector<bool> v2 = v1; >+ std::vector<bool> v3{true}; >+ std::vector<bool> v4{true, true, true}; >+ >+ EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end())); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end())); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end())); >+} >+ >+TEST(EqualTest, CustomComparison) { >+ int n[] = {1, 2, 3, 4}; >+ std::vector<int*> v1{&n[0], &n[1], &n[2]}; >+ std::vector<int*> v2 = v1; >+ std::vector<int*> v3{&n[0], &n[1], &n[3]}; >+ std::vector<int*> v4{&n[0], &n[1]}; >+ >+ auto eq = [](int* a, int* b) { return *a == *b; }; >+ >+ EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), eq)); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end(), eq)); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end(), eq)); >+} >+ >+TEST(EqualTest, MoveOnlyPredicate) { >+ std::vector<int> v1{1, 2, 3}; >+ std::vector<int> v2{4, 5, 6}; >+ >+ // move-only equality predicate >+ struct Eq { >+ Eq() = default; >+ Eq(Eq &&) = default; >+ Eq(const Eq &) = delete; >+ Eq &operator=(const Eq &) = delete; >+ bool operator()(const int a, const int b) const { return a == b; } >+ }; >+ >+ EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v1.begin(), v1.end(), Eq())); >+ EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), Eq())); >+} >+ >+struct CountingTrivialPred { >+ int* count; >+ bool operator()(int, int) const { >+ ++*count; >+ return true; >+ } >+}; >+ >+TEST(EqualTest, RandomAccessComplexity) { >+ std::vector<int> v1{1, 1, 3}; >+ std::vector<int> v2 = v1; >+ std::vector<int> v3{1, 2}; >+ >+ do { >+ int count = 0; >+ absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), >+ CountingTrivialPred{&count}); >+ EXPECT_LE(count, 3); >+ } while (std::next_permutation(v2.begin(), v2.end())); >+ >+ int count = 0; >+ absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end(), >+ CountingTrivialPred{&count}); >+ EXPECT_EQ(count, 0); >+} >+ >+class LinearSearchTest : public testing::Test { >+ protected: >+ LinearSearchTest() : container_{1, 2, 3} {} >+ >+ static bool Is3(int n) { return n == 3; } >+ static bool Is4(int n) { return n == 4; } >+ >+ std::vector<int> container_; >+}; >+ >+TEST_F(LinearSearchTest, linear_search) { >+ EXPECT_TRUE(absl::linear_search(container_.begin(), container_.end(), 3)); >+ EXPECT_FALSE(absl::linear_search(container_.begin(), container_.end(), 4)); >+} >+ >+TEST_F(LinearSearchTest, linear_searchConst) { >+ const std::vector<int> *const const_container = &container_; >+ EXPECT_TRUE( >+ absl::linear_search(const_container->begin(), const_container->end(), 3)); >+ EXPECT_FALSE( >+ absl::linear_search(const_container->begin(), const_container->end(), 4)); >+} >+ >+TEST(RotateTest, Rotate) { >+ std::vector<int> v{0, 1, 2, 3, 4}; >+ EXPECT_EQ(*absl::rotate(v.begin(), v.begin() + 2, v.end()), 0); >+ EXPECT_THAT(v, testing::ElementsAreArray({2, 3, 4, 0, 1})); >+ >+ std::list<int> l{0, 1, 2, 3, 4}; >+ EXPECT_EQ(*absl::rotate(l.begin(), std::next(l.begin(), 3), l.end()), 0); >+ EXPECT_THAT(l, testing::ElementsAreArray({3, 4, 0, 1, 2})); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/container.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/container.h >new file mode 100644 >index 0000000000000000000000000000000000000000..6af8c09799e56f223ad3eeca246d83ab07063a19 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/container.h >@@ -0,0 +1,1642 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: container.h >+// ----------------------------------------------------------------------------- >+// >+// This header file provides Container-based versions of algorithmic functions >+// within the C++ standard library. The following standard library sets of >+// functions are covered within this file: >+// >+// * Algorithmic <iterator> functions >+// * Algorithmic <numeric> functions >+// * <algorithm> functions >+// >+// The standard library functions operate on iterator ranges; the functions >+// within this API operate on containers, though many return iterator ranges. >+// >+// All functions within this API are named with a `c_` prefix. Calls such as >+// `absl::c_xx(container, ...) are equivalent to std:: functions such as >+// `std::xx(std::begin(cont), std::end(cont), ...)`. Functions that act on >+// iterators but not conceptually on iterator ranges (e.g. `std::iter_swap`) >+// have no equivalent here. >+// >+// For template parameter and variable naming, `C` indicates the container type >+// to which the function is applied, `Pred` indicates the predicate object type >+// to be used by the function and `T` indicates the applicable element type. >+// >+ >+#ifndef ABSL_ALGORITHM_CONTAINER_H_ >+#define ABSL_ALGORITHM_CONTAINER_H_ >+ >+#include <algorithm> >+#include <cassert> >+#include <iterator> >+#include <numeric> >+#include <type_traits> >+#include <utility> >+#include <vector> >+ >+#include "absl/algorithm/algorithm.h" >+#include "absl/base/macros.h" >+#include "absl/meta/type_traits.h" >+ >+namespace absl { >+ >+namespace container_algorithm_internal { >+ >+// NOTE: it is important to defer to ADL lookup for building with C++ modules, >+// especially for headers like <valarray> which are not visible from this file >+// but specialize std::begin and std::end. >+using std::begin; >+using std::end; >+ >+// The type of the iterator given by begin(c) (possibly std::begin(c)). >+// ContainerIter<const vector<T>> gives vector<T>::const_iterator, >+// while ContainerIter<vector<T>> gives vector<T>::iterator. >+template <typename C> >+using ContainerIter = decltype(begin(std::declval<C&>())); >+ >+// An MSVC bug involving template parameter substitution requires us to use >+// decltype() here instead of just std::pair. >+template <typename C1, typename C2> >+using ContainerIterPairType = >+ decltype(std::make_pair(ContainerIter<C1>(), ContainerIter<C2>())); >+ >+template <typename C> >+using ContainerDifferenceType = >+ decltype(std::distance(std::declval<ContainerIter<C>>(), >+ std::declval<ContainerIter<C>>())); >+ >+template <typename C> >+using ContainerPointerType = >+ typename std::iterator_traits<ContainerIter<C>>::pointer; >+ >+// container_algorithm_internal::c_begin and >+// container_algorithm_internal::c_end are abbreviations for proper ADL >+// lookup of std::begin and std::end, i.e. >+// using std::begin; >+// using std::end; >+// std::foo(begin(c), end(c); >+// becomes >+// std::foo(container_algorithm_internal::begin(c), >+// container_algorithm_internal::end(c)); >+// These are meant for internal use only. >+ >+template <typename C> >+ContainerIter<C> c_begin(C& c) { return begin(c); } >+ >+template <typename C> >+ContainerIter<C> c_end(C& c) { return end(c); } >+ >+} // namespace container_algorithm_internal >+ >+// PUBLIC API >+ >+//------------------------------------------------------------------------------ >+// Abseil algorithm.h functions >+//------------------------------------------------------------------------------ >+ >+// c_linear_search() >+// >+// Container-based version of absl::linear_search() for performing a linear >+// search within a container. >+template <typename C, typename EqualityComparable> >+bool c_linear_search(const C& c, EqualityComparable&& value) { >+ return linear_search(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<EqualityComparable>(value)); >+} >+ >+//------------------------------------------------------------------------------ >+// <iterator> algorithms >+//------------------------------------------------------------------------------ >+ >+// c_distance() >+// >+// Container-based version of the <iterator> `std::distance()` function to >+// return the number of elements within a container. >+template <typename C> >+container_algorithm_internal::ContainerDifferenceType<const C> c_distance( >+ const C& c) { >+ return std::distance(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c)); >+} >+ >+//------------------------------------------------------------------------------ >+// <algorithm> Non-modifying sequence operations >+//------------------------------------------------------------------------------ >+ >+// c_all_of() >+// >+// Container-based version of the <algorithm> `std::all_of()` function to >+// test a condition on all elements within a container. >+template <typename C, typename Pred> >+bool c_all_of(const C& c, Pred&& pred) { >+ return std::all_of(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred)); >+} >+ >+// c_any_of() >+// >+// Container-based version of the <algorithm> `std::any_of()` function to >+// test if any element in a container fulfills a condition. >+template <typename C, typename Pred> >+bool c_any_of(const C& c, Pred&& pred) { >+ return std::any_of(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred)); >+} >+ >+// c_none_of() >+// >+// Container-based version of the <algorithm> `std::none_of()` function to >+// test if no elements in a container fulfil a condition. >+template <typename C, typename Pred> >+bool c_none_of(const C& c, Pred&& pred) { >+ return std::none_of(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred)); >+} >+ >+// c_for_each() >+// >+// Container-based version of the <algorithm> `std::for_each()` function to >+// apply a function to a container's elements. >+template <typename C, typename Function> >+decay_t<Function> c_for_each(C&& c, Function&& f) { >+ return std::for_each(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Function>(f)); >+} >+ >+// c_find() >+// >+// Container-based version of the <algorithm> `std::find()` function to find >+// the first element containing the passed value within a container value. >+template <typename C, typename T> >+container_algorithm_internal::ContainerIter<C> c_find(C& c, T&& value) { >+ return std::find(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<T>(value)); >+} >+ >+// c_find_if() >+// >+// Container-based version of the <algorithm> `std::find_if()` function to find >+// the first element in a container matching the given condition. >+template <typename C, typename Pred> >+container_algorithm_internal::ContainerIter<C> c_find_if(C& c, Pred&& pred) { >+ return std::find_if(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred)); >+} >+ >+// c_find_if_not() >+// >+// Container-based version of the <algorithm> `std::find_if_not()` function to >+// find the first element in a container not matching the given condition. >+template <typename C, typename Pred> >+container_algorithm_internal::ContainerIter<C> c_find_if_not(C& c, >+ Pred&& pred) { >+ return std::find_if_not(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred)); >+} >+ >+// c_find_end() >+// >+// Container-based version of the <algorithm> `std::find_end()` function to >+// find the last subsequence within a container. >+template <typename Sequence1, typename Sequence2> >+container_algorithm_internal::ContainerIter<Sequence1> c_find_end( >+ Sequence1& sequence, Sequence2& subsequence) { >+ return std::find_end(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ container_algorithm_internal::c_begin(subsequence), >+ container_algorithm_internal::c_end(subsequence)); >+} >+ >+// Overload of c_find_end() for using a predicate evaluation other than `==` as >+// the function's test condition. >+template <typename Sequence1, typename Sequence2, typename BinaryPredicate> >+container_algorithm_internal::ContainerIter<Sequence1> c_find_end( >+ Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) { >+ return std::find_end(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ container_algorithm_internal::c_begin(subsequence), >+ container_algorithm_internal::c_end(subsequence), >+ std::forward<BinaryPredicate>(pred)); >+} >+ >+// c_find_first_of() >+// >+// Container-based version of the <algorithm> `std::find_first_of()` function to >+// find the first elements in an ordered set within a container. >+template <typename C1, typename C2> >+container_algorithm_internal::ContainerIter<C1> c_find_first_of(C1& container, >+ C2& options) { >+ return std::find_first_of(container_algorithm_internal::c_begin(container), >+ container_algorithm_internal::c_end(container), >+ container_algorithm_internal::c_begin(options), >+ container_algorithm_internal::c_end(options)); >+} >+ >+// Overload of c_find_first_of() for using a predicate evaluation other than >+// `==` as the function's test condition. >+template <typename C1, typename C2, typename BinaryPredicate> >+container_algorithm_internal::ContainerIter<C1> c_find_first_of( >+ C1& container, C2& options, BinaryPredicate&& pred) { >+ return std::find_first_of(container_algorithm_internal::c_begin(container), >+ container_algorithm_internal::c_end(container), >+ container_algorithm_internal::c_begin(options), >+ container_algorithm_internal::c_end(options), >+ std::forward<BinaryPredicate>(pred)); >+} >+ >+// c_adjacent_find() >+// >+// Container-based version of the <algorithm> `std::adjacent_find()` function to >+// find equal adjacent elements within a container. >+template <typename Sequence> >+container_algorithm_internal::ContainerIter<Sequence> c_adjacent_find( >+ Sequence& sequence) { >+ return std::adjacent_find(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_adjacent_find() for using a predicate evaluation other than >+// `==` as the function's test condition. >+template <typename Sequence, typename BinaryPredicate> >+container_algorithm_internal::ContainerIter<Sequence> c_adjacent_find( >+ Sequence& sequence, BinaryPredicate&& pred) { >+ return std::adjacent_find(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<BinaryPredicate>(pred)); >+} >+ >+// c_count() >+// >+// Container-based version of the <algorithm> `std::count()` function to count >+// values that match within a container. >+template <typename C, typename T> >+container_algorithm_internal::ContainerDifferenceType<const C> c_count( >+ const C& c, T&& value) { >+ return std::count(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<T>(value)); >+} >+ >+// c_count_if() >+// >+// Container-based version of the <algorithm> `std::count_if()` function to >+// count values matching a condition within a container. >+template <typename C, typename Pred> >+container_algorithm_internal::ContainerDifferenceType<const C> c_count_if( >+ const C& c, Pred&& pred) { >+ return std::count_if(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred)); >+} >+ >+// c_mismatch() >+// >+// Container-based version of the <algorithm> `std::mismatch()` function to >+// return the first element where two ordered containers differ. >+template <typename C1, typename C2> >+container_algorithm_internal::ContainerIterPairType<C1, C2> >+c_mismatch(C1& c1, C2& c2) { >+ return std::mismatch(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2)); >+} >+ >+// Overload of c_mismatch() for using a predicate evaluation other than `==` as >+// the function's test condition. >+template <typename C1, typename C2, typename BinaryPredicate> >+container_algorithm_internal::ContainerIterPairType<C1, C2> >+c_mismatch(C1& c1, C2& c2, BinaryPredicate&& pred) { >+ return std::mismatch(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ std::forward<BinaryPredicate>(pred)); >+} >+ >+// c_equal() >+// >+// Container-based version of the <algorithm> `std::equal()` function to >+// test whether two containers are equal. >+// >+// NOTE: the semantics of c_equal() are slightly different than those of >+// equal(): while the latter iterates over the second container only up to the >+// size of the first container, c_equal() also checks whether the container >+// sizes are equal. This better matches expectations about c_equal() based on >+// its signature. >+// >+// Example: >+// vector v1 = <1, 2, 3>; >+// vector v2 = <1, 2, 3, 4>; >+// equal(std::begin(v1), std::end(v1), std::begin(v2)) returns true >+// c_equal(v1, v2) returns false >+ >+template <typename C1, typename C2> >+bool c_equal(const C1& c1, const C2& c2) { >+ return ((c1.size() == c2.size()) && >+ std::equal(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2))); >+} >+ >+// Overload of c_equal() for using a predicate evaluation other than `==` as >+// the function's test condition. >+template <typename C1, typename C2, typename BinaryPredicate> >+bool c_equal(const C1& c1, const C2& c2, BinaryPredicate&& pred) { >+ return ((c1.size() == c2.size()) && >+ std::equal(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ std::forward<BinaryPredicate>(pred))); >+} >+ >+// c_is_permutation() >+// >+// Container-based version of the <algorithm> `std::is_permutation()` function >+// to test whether a container is a permutation of another. >+template <typename C1, typename C2> >+bool c_is_permutation(const C1& c1, const C2& c2) { >+ using std::begin; >+ using std::end; >+ return c1.size() == c2.size() && >+ std::is_permutation(begin(c1), end(c1), begin(c2)); >+} >+ >+// Overload of c_is_permutation() for using a predicate evaluation other than >+// `==` as the function's test condition. >+template <typename C1, typename C2, typename BinaryPredicate> >+bool c_is_permutation(const C1& c1, const C2& c2, BinaryPredicate&& pred) { >+ using std::begin; >+ using std::end; >+ return c1.size() == c2.size() && >+ std::is_permutation(begin(c1), end(c1), begin(c2), >+ std::forward<BinaryPredicate>(pred)); >+} >+ >+// c_search() >+// >+// Container-based version of the <algorithm> `std::search()` function to search >+// a container for a subsequence. >+template <typename Sequence1, typename Sequence2> >+container_algorithm_internal::ContainerIter<Sequence1> c_search( >+ Sequence1& sequence, Sequence2& subsequence) { >+ return std::search(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ container_algorithm_internal::c_begin(subsequence), >+ container_algorithm_internal::c_end(subsequence)); >+} >+ >+// Overload of c_search() for using a predicate evaluation other than >+// `==` as the function's test condition. >+template <typename Sequence1, typename Sequence2, typename BinaryPredicate> >+container_algorithm_internal::ContainerIter<Sequence1> c_search( >+ Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) { >+ return std::search(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ container_algorithm_internal::c_begin(subsequence), >+ container_algorithm_internal::c_end(subsequence), >+ std::forward<BinaryPredicate>(pred)); >+} >+ >+// c_search_n() >+// >+// Container-based version of the <algorithm> `std::search_n()` function to >+// search a container for the first sequence of N elements. >+template <typename Sequence, typename Size, typename T> >+container_algorithm_internal::ContainerIter<Sequence> c_search_n( >+ Sequence& sequence, Size count, T&& value) { >+ return std::search_n(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), count, >+ std::forward<T>(value)); >+} >+ >+// Overload of c_search_n() for using a predicate evaluation other than >+// `==` as the function's test condition. >+template <typename Sequence, typename Size, typename T, >+ typename BinaryPredicate> >+container_algorithm_internal::ContainerIter<Sequence> c_search_n( >+ Sequence& sequence, Size count, T&& value, BinaryPredicate&& pred) { >+ return std::search_n(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), count, >+ std::forward<T>(value), >+ std::forward<BinaryPredicate>(pred)); >+} >+ >+//------------------------------------------------------------------------------ >+// <algorithm> Modifying sequence operations >+//------------------------------------------------------------------------------ >+ >+// c_copy() >+// >+// Container-based version of the <algorithm> `std::copy()` function to copy a >+// container's elements into an iterator. >+template <typename InputSequence, typename OutputIterator> >+OutputIterator c_copy(const InputSequence& input, OutputIterator output) { >+ return std::copy(container_algorithm_internal::c_begin(input), >+ container_algorithm_internal::c_end(input), output); >+} >+ >+// c_copy_n() >+// >+// Container-based version of the <algorithm> `std::copy_n()` function to copy a >+// container's first N elements into an iterator. >+template <typename C, typename Size, typename OutputIterator> >+OutputIterator c_copy_n(const C& input, Size n, OutputIterator output) { >+ return std::copy_n(container_algorithm_internal::c_begin(input), n, output); >+} >+ >+// c_copy_if() >+// >+// Container-based version of the <algorithm> `std::copy_if()` function to copy >+// a container's elements satisfying some condition into an iterator. >+template <typename InputSequence, typename OutputIterator, typename Pred> >+OutputIterator c_copy_if(const InputSequence& input, OutputIterator output, >+ Pred&& pred) { >+ return std::copy_if(container_algorithm_internal::c_begin(input), >+ container_algorithm_internal::c_end(input), output, >+ std::forward<Pred>(pred)); >+} >+ >+// c_copy_backward() >+// >+// Container-based version of the <algorithm> `std::copy_backward()` function to >+// copy a container's elements in reverse order into an iterator. >+template <typename C, typename BidirectionalIterator> >+BidirectionalIterator c_copy_backward(const C& src, >+ BidirectionalIterator dest) { >+ return std::copy_backward(container_algorithm_internal::c_begin(src), >+ container_algorithm_internal::c_end(src), dest); >+} >+ >+// c_move() >+// >+// Container-based version of the <algorithm> `std::move()` function to move >+// a container's elements into an iterator. >+template <typename C, typename OutputIterator> >+OutputIterator c_move(C& src, OutputIterator dest) { >+ return std::move(container_algorithm_internal::c_begin(src), >+ container_algorithm_internal::c_end(src), dest); >+} >+ >+// c_swap_ranges() >+// >+// Container-based version of the <algorithm> `std::swap_ranges()` function to >+// swap a container's elements with another container's elements. >+template <typename C1, typename C2> >+container_algorithm_internal::ContainerIter<C2> c_swap_ranges(C1& c1, C2& c2) { >+ return std::swap_ranges(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2)); >+} >+ >+// c_transform() >+// >+// Container-based version of the <algorithm> `std::transform()` function to >+// transform a container's elements using the unary operation, storing the >+// result in an iterator pointing to the last transformed element in the output >+// range. >+template <typename InputSequence, typename OutputIterator, typename UnaryOp> >+OutputIterator c_transform(const InputSequence& input, OutputIterator output, >+ UnaryOp&& unary_op) { >+ return std::transform(container_algorithm_internal::c_begin(input), >+ container_algorithm_internal::c_end(input), output, >+ std::forward<UnaryOp>(unary_op)); >+} >+ >+// Overload of c_transform() for performing a transformation using a binary >+// predicate. >+template <typename InputSequence1, typename InputSequence2, >+ typename OutputIterator, typename BinaryOp> >+OutputIterator c_transform(const InputSequence1& input1, >+ const InputSequence2& input2, OutputIterator output, >+ BinaryOp&& binary_op) { >+ return std::transform(container_algorithm_internal::c_begin(input1), >+ container_algorithm_internal::c_end(input1), >+ container_algorithm_internal::c_begin(input2), output, >+ std::forward<BinaryOp>(binary_op)); >+} >+ >+// c_replace() >+// >+// Container-based version of the <algorithm> `std::replace()` function to >+// replace a container's elements of some value with a new value. The container >+// is modified in place. >+template <typename Sequence, typename T> >+void c_replace(Sequence& sequence, const T& old_value, const T& new_value) { >+ std::replace(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), old_value, >+ new_value); >+} >+ >+// c_replace_if() >+// >+// Container-based version of the <algorithm> `std::replace_if()` function to >+// replace a container's elements of some value with a new value based on some >+// condition. The container is modified in place. >+template <typename C, typename Pred, typename T> >+void c_replace_if(C& c, Pred&& pred, T&& new_value) { >+ std::replace_if(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred), std::forward<T>(new_value)); >+} >+ >+// c_replace_copy() >+// >+// Container-based version of the <algorithm> `std::replace_copy()` function to >+// replace a container's elements of some value with a new value and return the >+// results within an iterator. >+template <typename C, typename OutputIterator, typename T> >+OutputIterator c_replace_copy(const C& c, OutputIterator result, T&& old_value, >+ T&& new_value) { >+ return std::replace_copy(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), result, >+ std::forward<T>(old_value), >+ std::forward<T>(new_value)); >+} >+ >+// c_replace_copy_if() >+// >+// Container-based version of the <algorithm> `std::replace_copy_if()` function >+// to replace a container's elements of some value with a new value based on >+// some condition, and return the results within an iterator. >+template <typename C, typename OutputIterator, typename Pred, typename T> >+OutputIterator c_replace_copy_if(const C& c, OutputIterator result, Pred&& pred, >+ T&& new_value) { >+ return std::replace_copy_if(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), result, >+ std::forward<Pred>(pred), >+ std::forward<T>(new_value)); >+} >+ >+// c_fill() >+// >+// Container-based version of the <algorithm> `std::fill()` function to fill a >+// container with some value. >+template <typename C, typename T> >+void c_fill(C& c, T&& value) { >+ std::fill(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), std::forward<T>(value)); >+} >+ >+// c_fill_n() >+// >+// Container-based version of the <algorithm> `std::fill_n()` function to fill >+// the first N elements in a container with some value. >+template <typename C, typename Size, typename T> >+void c_fill_n(C& c, Size n, T&& value) { >+ std::fill_n(container_algorithm_internal::c_begin(c), n, >+ std::forward<T>(value)); >+} >+ >+// c_generate() >+// >+// Container-based version of the <algorithm> `std::generate()` function to >+// assign a container's elements to the values provided by the given generator. >+template <typename C, typename Generator> >+void c_generate(C& c, Generator&& gen) { >+ std::generate(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Generator>(gen)); >+} >+ >+// c_generate_n() >+// >+// Container-based version of the <algorithm> `std::generate_n()` function to >+// assign a container's first N elements to the values provided by the given >+// generator. >+template <typename C, typename Size, typename Generator> >+container_algorithm_internal::ContainerIter<C> c_generate_n(C& c, Size n, >+ Generator&& gen) { >+ return std::generate_n(container_algorithm_internal::c_begin(c), n, >+ std::forward<Generator>(gen)); >+} >+ >+// Note: `c_xx()` <algorithm> container versions for `remove()`, `remove_if()`, >+// and `unique()` are omitted, because it's not clear whether or not such >+// functions should call erase on their supplied sequences afterwards. Either >+// behavior would be surprising for a different set of users. >+// >+ >+// c_remove_copy() >+// >+// Container-based version of the <algorithm> `std::remove_copy()` function to >+// copy a container's elements while removing any elements matching the given >+// `value`. >+template <typename C, typename OutputIterator, typename T> >+OutputIterator c_remove_copy(const C& c, OutputIterator result, T&& value) { >+ return std::remove_copy(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), result, >+ std::forward<T>(value)); >+} >+ >+// c_remove_copy_if() >+// >+// Container-based version of the <algorithm> `std::remove_copy_if()` function >+// to copy a container's elements while removing any elements matching the given >+// condition. >+template <typename C, typename OutputIterator, typename Pred> >+OutputIterator c_remove_copy_if(const C& c, OutputIterator result, >+ Pred&& pred) { >+ return std::remove_copy_if(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), result, >+ std::forward<Pred>(pred)); >+} >+ >+// c_unique_copy() >+// >+// Container-based version of the <algorithm> `std::unique_copy()` function to >+// copy a container's elements while removing any elements containing duplicate >+// values. >+template <typename C, typename OutputIterator> >+OutputIterator c_unique_copy(const C& c, OutputIterator result) { >+ return std::unique_copy(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), result); >+} >+ >+// Overload of c_unique_copy() for using a predicate evaluation other than >+// `==` for comparing uniqueness of the element values. >+template <typename C, typename OutputIterator, typename BinaryPredicate> >+OutputIterator c_unique_copy(const C& c, OutputIterator result, >+ BinaryPredicate&& pred) { >+ return std::unique_copy(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), result, >+ std::forward<BinaryPredicate>(pred)); >+} >+ >+// c_reverse() >+// >+// Container-based version of the <algorithm> `std::reverse()` function to >+// reverse a container's elements. >+template <typename Sequence> >+void c_reverse(Sequence& sequence) { >+ std::reverse(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// c_reverse_copy() >+// >+// Container-based version of the <algorithm> `std::reverse()` function to >+// reverse a container's elements and write them to an iterator range. >+template <typename C, typename OutputIterator> >+OutputIterator c_reverse_copy(const C& sequence, OutputIterator result) { >+ return std::reverse_copy(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ result); >+} >+ >+// c_rotate() >+// >+// Container-based version of the <algorithm> `std::rotate()` function to >+// shift a container's elements leftward such that the `middle` element becomes >+// the first element in the container. >+template <typename C, >+ typename Iterator = container_algorithm_internal::ContainerIter<C>> >+Iterator c_rotate(C& sequence, Iterator middle) { >+ return absl::rotate(container_algorithm_internal::c_begin(sequence), middle, >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// c_rotate_copy() >+// >+// Container-based version of the <algorithm> `std::rotate_copy()` function to >+// shift a container's elements leftward such that the `middle` element becomes >+// the first element in a new iterator range. >+template <typename C, typename OutputIterator> >+OutputIterator c_rotate_copy( >+ const C& sequence, >+ container_algorithm_internal::ContainerIter<const C> middle, >+ OutputIterator result) { >+ return std::rotate_copy(container_algorithm_internal::c_begin(sequence), >+ middle, container_algorithm_internal::c_end(sequence), >+ result); >+} >+ >+// c_shuffle() >+// >+// Container-based version of the <algorithm> `std::shuffle()` function to >+// randomly shuffle elements within the container using a `gen()` uniform random >+// number generator. >+template <typename RandomAccessContainer, typename UniformRandomBitGenerator> >+void c_shuffle(RandomAccessContainer& c, UniformRandomBitGenerator&& gen) { >+ std::shuffle(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<UniformRandomBitGenerator>(gen)); >+} >+ >+//------------------------------------------------------------------------------ >+// <algorithm> Partition functions >+//------------------------------------------------------------------------------ >+ >+// c_is_partitioned() >+// >+// Container-based version of the <algorithm> `std::is_partitioned()` function >+// to test whether all elements in the container for which `pred` returns `true` >+// precede those for which `pred` is `false`. >+template <typename C, typename Pred> >+bool c_is_partitioned(const C& c, Pred&& pred) { >+ return std::is_partitioned(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred)); >+} >+ >+// c_partition() >+// >+// Container-based version of the <algorithm> `std::partition()` function >+// to rearrange all elements in a container in such a way that all elements for >+// which `pred` returns `true` precede all those for which it returns `false`, >+// returning an iterator to the first element of the second group. >+template <typename C, typename Pred> >+container_algorithm_internal::ContainerIter<C> c_partition(C& c, Pred&& pred) { >+ return std::partition(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred)); >+} >+ >+// c_stable_partition() >+// >+// Container-based version of the <algorithm> `std::stable_partition()` function >+// to rearrange all elements in a container in such a way that all elements for >+// which `pred` returns `true` precede all those for which it returns `false`, >+// preserving the relative ordering between the two groups. The function returns >+// an iterator to the first element of the second group. >+template <typename C, typename Pred> >+container_algorithm_internal::ContainerIter<C> c_stable_partition(C& c, >+ Pred&& pred) { >+ return std::stable_partition(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred)); >+} >+ >+// c_partition_copy() >+// >+// Container-based version of the <algorithm> `std::partition_copy()` function >+// to partition a container's elements and return them into two iterators: one >+// for which `pred` returns `true`, and one for which `pred` returns `false.` >+ >+template <typename C, typename OutputIterator1, typename OutputIterator2, >+ typename Pred> >+std::pair<OutputIterator1, OutputIterator2> c_partition_copy( >+ const C& c, OutputIterator1 out_true, OutputIterator2 out_false, >+ Pred&& pred) { >+ return std::partition_copy(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), out_true, >+ out_false, std::forward<Pred>(pred)); >+} >+ >+// c_partition_point() >+// >+// Container-based version of the <algorithm> `std::partition_point()` function >+// to return the first element of an already partitioned container for which >+// the given `pred` is not `true`. >+template <typename C, typename Pred> >+container_algorithm_internal::ContainerIter<C> c_partition_point(C& c, >+ Pred&& pred) { >+ return std::partition_point(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Pred>(pred)); >+} >+ >+//------------------------------------------------------------------------------ >+// <algorithm> Sorting functions >+//------------------------------------------------------------------------------ >+ >+// c_sort() >+// >+// Container-based version of the <algorithm> `std::sort()` function >+// to sort elements in ascending order of their values. >+template <typename C> >+void c_sort(C& c) { >+ std::sort(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c)); >+} >+ >+// Overload of c_sort() for performing a `comp` comparison other than the >+// default `operator<`. >+template <typename C, typename Compare> >+void c_sort(C& c, Compare&& comp) { >+ std::sort(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Compare>(comp)); >+} >+ >+// c_stable_sort() >+// >+// Container-based version of the <algorithm> `std::stable_sort()` function >+// to sort elements in ascending order of their values, preserving the order >+// of equivalents. >+template <typename C> >+void c_stable_sort(C& c) { >+ std::stable_sort(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c)); >+} >+ >+// Overload of c_stable_sort() for performing a `comp` comparison other than the >+// default `operator<`. >+template <typename C, typename Compare> >+void c_stable_sort(C& c, Compare&& comp) { >+ std::stable_sort(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Compare>(comp)); >+} >+ >+// c_is_sorted() >+// >+// Container-based version of the <algorithm> `std::is_sorted()` function >+// to evaluate whether the given container is sorted in ascending order. >+template <typename C> >+bool c_is_sorted(const C& c) { >+ return std::is_sorted(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c)); >+} >+ >+// c_is_sorted() overload for performing a `comp` comparison other than the >+// default `operator<`. >+template <typename C, typename Compare> >+bool c_is_sorted(const C& c, Compare&& comp) { >+ return std::is_sorted(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Compare>(comp)); >+} >+ >+// c_partial_sort() >+// >+// Container-based version of the <algorithm> `std::partial_sort()` function >+// to rearrange elements within a container such that elements before `middle` >+// are sorted in ascending order. >+template <typename RandomAccessContainer> >+void c_partial_sort( >+ RandomAccessContainer& sequence, >+ container_algorithm_internal::ContainerIter<RandomAccessContainer> middle) { >+ std::partial_sort(container_algorithm_internal::c_begin(sequence), middle, >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_partial_sort() for performing a `comp` comparison other than >+// the default `operator<`. >+template <typename RandomAccessContainer, typename Compare> >+void c_partial_sort( >+ RandomAccessContainer& sequence, >+ container_algorithm_internal::ContainerIter<RandomAccessContainer> middle, >+ Compare&& comp) { >+ std::partial_sort(container_algorithm_internal::c_begin(sequence), middle, >+ container_algorithm_internal::c_end(sequence), >+ std::forward<Compare>(comp)); >+} >+ >+// c_partial_sort_copy() >+// >+// Container-based version of the <algorithm> `std::partial_sort_copy()` >+// function to sort elements within a container such that elements before >+// `middle` are sorted in ascending order, and return the result within an >+// iterator. >+template <typename C, typename RandomAccessContainer> >+container_algorithm_internal::ContainerIter<RandomAccessContainer> >+c_partial_sort_copy(const C& sequence, RandomAccessContainer& result) { >+ return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ container_algorithm_internal::c_begin(result), >+ container_algorithm_internal::c_end(result)); >+} >+ >+// Overload of c_partial_sort_copy() for performing a `comp` comparison other >+// than the default `operator<`. >+template <typename C, typename RandomAccessContainer, typename Compare> >+container_algorithm_internal::ContainerIter<RandomAccessContainer> >+c_partial_sort_copy(const C& sequence, RandomAccessContainer& result, >+ Compare&& comp) { >+ return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ container_algorithm_internal::c_begin(result), >+ container_algorithm_internal::c_end(result), >+ std::forward<Compare>(comp)); >+} >+ >+// c_is_sorted_until() >+// >+// Container-based version of the <algorithm> `std::is_sorted_until()` function >+// to return the first element within a container that is not sorted in >+// ascending order as an iterator. >+template <typename C> >+container_algorithm_internal::ContainerIter<C> c_is_sorted_until(C& c) { >+ return std::is_sorted_until(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c)); >+} >+ >+// Overload of c_is_sorted_until() for performing a `comp` comparison other than >+// the default `operator<`. >+template <typename C, typename Compare> >+container_algorithm_internal::ContainerIter<C> c_is_sorted_until( >+ C& c, Compare&& comp) { >+ return std::is_sorted_until(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Compare>(comp)); >+} >+ >+// c_nth_element() >+// >+// Container-based version of the <algorithm> `std::nth_element()` function >+// to rearrange the elements within a container such that the `nth` element >+// would be in that position in an ordered sequence; other elements may be in >+// any order, except that all preceding `nth` will be less than that element, >+// and all following `nth` will be greater than that element. >+template <typename RandomAccessContainer> >+void c_nth_element( >+ RandomAccessContainer& sequence, >+ container_algorithm_internal::ContainerIter<RandomAccessContainer> nth) { >+ std::nth_element(container_algorithm_internal::c_begin(sequence), nth, >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_nth_element() for performing a `comp` comparison other than >+// the default `operator<`. >+template <typename RandomAccessContainer, typename Compare> >+void c_nth_element( >+ RandomAccessContainer& sequence, >+ container_algorithm_internal::ContainerIter<RandomAccessContainer> nth, >+ Compare&& comp) { >+ std::nth_element(container_algorithm_internal::c_begin(sequence), nth, >+ container_algorithm_internal::c_end(sequence), >+ std::forward<Compare>(comp)); >+} >+ >+//------------------------------------------------------------------------------ >+// <algorithm> Binary Search >+//------------------------------------------------------------------------------ >+ >+// c_lower_bound() >+// >+// Container-based version of the <algorithm> `std::lower_bound()` function >+// to return an iterator pointing to the first element in a sorted container >+// which does not compare less than `value`. >+template <typename Sequence, typename T> >+container_algorithm_internal::ContainerIter<Sequence> c_lower_bound( >+ Sequence& sequence, T&& value) { >+ return std::lower_bound(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(value)); >+} >+ >+// Overload of c_lower_bound() for performing a `comp` comparison other than >+// the default `operator<`. >+template <typename Sequence, typename T, typename Compare> >+container_algorithm_internal::ContainerIter<Sequence> c_lower_bound( >+ Sequence& sequence, T&& value, Compare&& comp) { >+ return std::lower_bound(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(value), std::forward<Compare>(comp)); >+} >+ >+// c_upper_bound() >+// >+// Container-based version of the <algorithm> `std::upper_bound()` function >+// to return an iterator pointing to the first element in a sorted container >+// which is greater than `value`. >+template <typename Sequence, typename T> >+container_algorithm_internal::ContainerIter<Sequence> c_upper_bound( >+ Sequence& sequence, T&& value) { >+ return std::upper_bound(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(value)); >+} >+ >+// Overload of c_upper_bound() for performing a `comp` comparison other than >+// the default `operator<`. >+template <typename Sequence, typename T, typename Compare> >+container_algorithm_internal::ContainerIter<Sequence> c_upper_bound( >+ Sequence& sequence, T&& value, Compare&& comp) { >+ return std::upper_bound(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(value), std::forward<Compare>(comp)); >+} >+ >+// c_equal_range() >+// >+// Container-based version of the <algorithm> `std::equal_range()` function >+// to return an iterator pair pointing to the first and last elements in a >+// sorted container which compare equal to `value`. >+template <typename Sequence, typename T> >+container_algorithm_internal::ContainerIterPairType<Sequence, Sequence> >+c_equal_range(Sequence& sequence, T&& value) { >+ return std::equal_range(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(value)); >+} >+ >+// Overload of c_equal_range() for performing a `comp` comparison other than >+// the default `operator<`. >+template <typename Sequence, typename T, typename Compare> >+container_algorithm_internal::ContainerIterPairType<Sequence, Sequence> >+c_equal_range(Sequence& sequence, T&& value, Compare&& comp) { >+ return std::equal_range(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(value), std::forward<Compare>(comp)); >+} >+ >+// c_binary_search() >+// >+// Container-based version of the <algorithm> `std::binary_search()` function >+// to test if any element in the sorted container contains a value equivalent to >+// 'value'. >+template <typename Sequence, typename T> >+bool c_binary_search(Sequence&& sequence, T&& value) { >+ return std::binary_search(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(value)); >+} >+ >+// Overload of c_binary_search() for performing a `comp` comparison other than >+// the default `operator<`. >+template <typename Sequence, typename T, typename Compare> >+bool c_binary_search(Sequence&& sequence, T&& value, Compare&& comp) { >+ return std::binary_search(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(value), >+ std::forward<Compare>(comp)); >+} >+ >+//------------------------------------------------------------------------------ >+// <algorithm> Merge functions >+//------------------------------------------------------------------------------ >+ >+// c_merge() >+// >+// Container-based version of the <algorithm> `std::merge()` function >+// to merge two sorted containers into a single sorted iterator. >+template <typename C1, typename C2, typename OutputIterator> >+OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result) { >+ return std::merge(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), result); >+} >+ >+// Overload of c_merge() for performing a `comp` comparison other than >+// the default `operator<`. >+template <typename C1, typename C2, typename OutputIterator, typename Compare> >+OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result, >+ Compare&& comp) { >+ return std::merge(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), result, >+ std::forward<Compare>(comp)); >+} >+ >+// c_inplace_merge() >+// >+// Container-based version of the <algorithm> `std::inplace_merge()` function >+// to merge a supplied iterator `middle` into a container. >+template <typename C> >+void c_inplace_merge(C& c, >+ container_algorithm_internal::ContainerIter<C> middle) { >+ std::inplace_merge(container_algorithm_internal::c_begin(c), middle, >+ container_algorithm_internal::c_end(c)); >+} >+ >+// Overload of c_inplace_merge() for performing a merge using a `comp` other >+// than `operator<`. >+template <typename C, typename Compare> >+void c_inplace_merge(C& c, >+ container_algorithm_internal::ContainerIter<C> middle, >+ Compare&& comp) { >+ std::inplace_merge(container_algorithm_internal::c_begin(c), middle, >+ container_algorithm_internal::c_end(c), >+ std::forward<Compare>(comp)); >+} >+ >+// c_includes() >+// >+// Container-based version of the <algorithm> `std::includes()` function >+// to test whether a sorted container `c1` entirely contains another sorted >+// container `c2`. >+template <typename C1, typename C2> >+bool c_includes(const C1& c1, const C2& c2) { >+ return std::includes(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2)); >+} >+ >+// Overload of c_includes() for performing a merge using a `comp` other than >+// `operator<`. >+template <typename C1, typename C2, typename Compare> >+bool c_includes(const C1& c1, const C2& c2, Compare&& comp) { >+ return std::includes(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), >+ std::forward<Compare>(comp)); >+} >+ >+// c_set_union() >+// >+// Container-based version of the <algorithm> `std::set_union()` function >+// to return an iterator containing the union of two containers; duplicate >+// values are not copied into the output. >+template <typename C1, typename C2, typename OutputIterator> >+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), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), output); >+} >+ >+// Overload of c_set_union() for performing a merge using a `comp` other than >+// `operator<`. >+template <typename C1, typename C2, typename OutputIterator, typename Compare> >+OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output, >+ Compare&& comp) { >+ return std::set_union(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), output, >+ std::forward<Compare>(comp)); >+} >+ >+// c_set_intersection() >+// >+// Container-based version of the <algorithm> `std::set_intersection()` function >+// to return an iterator containing the intersection of two containers. >+template <typename C1, typename C2, typename OutputIterator> >+OutputIterator c_set_intersection(const C1& c1, const C2& c2, >+ OutputIterator output) { >+ return std::set_intersection(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), output); >+} >+ >+// Overload of c_set_intersection() for performing a merge using a `comp` other >+// than `operator<`. >+template <typename C1, typename C2, typename OutputIterator, typename Compare> >+OutputIterator c_set_intersection(const C1& c1, const C2& c2, >+ OutputIterator output, Compare&& comp) { >+ return std::set_intersection(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), output, >+ std::forward<Compare>(comp)); >+} >+ >+// c_set_difference() >+// >+// Container-based version of the <algorithm> `std::set_difference()` function >+// to return an iterator containing elements present in the first container but >+// not in the second. >+template <typename C1, typename C2, typename OutputIterator> >+OutputIterator c_set_difference(const C1& c1, const C2& c2, >+ OutputIterator output) { >+ return std::set_difference(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), output); >+} >+ >+// Overload of c_set_difference() for performing a merge using a `comp` other >+// than `operator<`. >+template <typename C1, typename C2, typename OutputIterator, typename Compare> >+OutputIterator c_set_difference(const C1& c1, const C2& c2, >+ OutputIterator output, Compare&& comp) { >+ return std::set_difference(container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), output, >+ std::forward<Compare>(comp)); >+} >+ >+// c_set_symmetric_difference() >+// >+// Container-based version of the <algorithm> `std::set_symmetric_difference()` >+// function to return an iterator containing elements present in either one >+// container or the other, but not both. >+template <typename C1, typename C2, typename OutputIterator> >+OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, >+ OutputIterator output) { >+ return std::set_symmetric_difference( >+ container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), output); >+} >+ >+// Overload of c_set_symmetric_difference() for performing a merge using a >+// `comp` other than `operator<`. >+template <typename C1, typename C2, typename OutputIterator, typename Compare> >+OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, >+ OutputIterator output, >+ Compare&& comp) { >+ return std::set_symmetric_difference( >+ container_algorithm_internal::c_begin(c1), >+ container_algorithm_internal::c_end(c1), >+ container_algorithm_internal::c_begin(c2), >+ container_algorithm_internal::c_end(c2), output, >+ std::forward<Compare>(comp)); >+} >+ >+//------------------------------------------------------------------------------ >+// <algorithm> Heap functions >+//------------------------------------------------------------------------------ >+ >+// c_push_heap() >+// >+// Container-based version of the <algorithm> `std::push_heap()` function >+// to push a value onto a container heap. >+template <typename RandomAccessContainer> >+void c_push_heap(RandomAccessContainer& sequence) { >+ std::push_heap(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_push_heap() for performing a push operation on a heap using a >+// `comp` other than `operator<`. >+template <typename RandomAccessContainer, typename Compare> >+void c_push_heap(RandomAccessContainer& sequence, Compare&& comp) { >+ std::push_heap(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<Compare>(comp)); >+} >+ >+// c_pop_heap() >+// >+// Container-based version of the <algorithm> `std::pop_heap()` function >+// to pop a value from a heap container. >+template <typename RandomAccessContainer> >+void c_pop_heap(RandomAccessContainer& sequence) { >+ std::pop_heap(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_pop_heap() for performing a pop operation on a heap using a >+// `comp` other than `operator<`. >+template <typename RandomAccessContainer, typename Compare> >+void c_pop_heap(RandomAccessContainer& sequence, Compare&& comp) { >+ std::pop_heap(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<Compare>(comp)); >+} >+ >+// c_make_heap() >+// >+// Container-based version of the <algorithm> `std::make_heap()` function >+// to make a container a heap. >+template <typename RandomAccessContainer> >+void c_make_heap(RandomAccessContainer& sequence) { >+ std::make_heap(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_make_heap() for performing heap comparisons using a >+// `comp` other than `operator<` >+template <typename RandomAccessContainer, typename Compare> >+void c_make_heap(RandomAccessContainer& sequence, Compare&& comp) { >+ std::make_heap(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<Compare>(comp)); >+} >+ >+// c_sort_heap() >+// >+// Container-based version of the <algorithm> `std::sort_heap()` function >+// to sort a heap into ascending order (after which it is no longer a heap). >+template <typename RandomAccessContainer> >+void c_sort_heap(RandomAccessContainer& sequence) { >+ std::sort_heap(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_sort_heap() for performing heap comparisons using a >+// `comp` other than `operator<` >+template <typename RandomAccessContainer, typename Compare> >+void c_sort_heap(RandomAccessContainer& sequence, Compare&& comp) { >+ std::sort_heap(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<Compare>(comp)); >+} >+ >+// c_is_heap() >+// >+// Container-based version of the <algorithm> `std::is_heap()` function >+// to check whether the given container is a heap. >+template <typename RandomAccessContainer> >+bool c_is_heap(const RandomAccessContainer& sequence) { >+ return std::is_heap(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_is_heap() for performing heap comparisons using a >+// `comp` other than `operator<` >+template <typename RandomAccessContainer, typename Compare> >+bool c_is_heap(const RandomAccessContainer& sequence, Compare&& comp) { >+ return std::is_heap(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<Compare>(comp)); >+} >+ >+// c_is_heap_until() >+// >+// Container-based version of the <algorithm> `std::is_heap_until()` function >+// to find the first element in a given container which is not in heap order. >+template <typename RandomAccessContainer> >+container_algorithm_internal::ContainerIter<RandomAccessContainer> >+c_is_heap_until(RandomAccessContainer& sequence) { >+ return std::is_heap_until(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_is_heap_until() for performing heap comparisons using a >+// `comp` other than `operator<` >+template <typename RandomAccessContainer, typename Compare> >+container_algorithm_internal::ContainerIter<RandomAccessContainer> >+c_is_heap_until(RandomAccessContainer& sequence, Compare&& comp) { >+ return std::is_heap_until(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<Compare>(comp)); >+} >+ >+//------------------------------------------------------------------------------ >+// <algorithm> Min/max >+//------------------------------------------------------------------------------ >+ >+// c_min_element() >+// >+// Container-based version of the <algorithm> `std::min_element()` function >+// to return an iterator pointing to the element with the smallest value, using >+// `operator<` to make the comparisons. >+template <typename Sequence> >+container_algorithm_internal::ContainerIter<Sequence> c_min_element( >+ Sequence& sequence) { >+ return std::min_element(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_min_element() for performing a `comp` comparison other than >+// `operator<`. >+template <typename Sequence, typename Compare> >+container_algorithm_internal::ContainerIter<Sequence> c_min_element( >+ Sequence& sequence, Compare&& comp) { >+ return std::min_element(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<Compare>(comp)); >+} >+ >+// c_max_element() >+// >+// Container-based version of the <algorithm> `std::max_element()` function >+// to return an iterator pointing to the element with the largest value, using >+// `operator<` to make the comparisons. >+template <typename Sequence> >+container_algorithm_internal::ContainerIter<Sequence> c_max_element( >+ Sequence& sequence) { >+ return std::max_element(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence)); >+} >+ >+// Overload of c_max_element() for performing a `comp` comparison other than >+// `operator<`. >+template <typename Sequence, typename Compare> >+container_algorithm_internal::ContainerIter<Sequence> c_max_element( >+ Sequence& sequence, Compare&& comp) { >+ return std::max_element(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<Compare>(comp)); >+} >+ >+// c_minmax_element() >+// >+// Container-based version of the <algorithm> `std::minmax_element()` function >+// to return a pair of iterators pointing to the elements containing the >+// smallest and largest values, respectively, using `operator<` to make the >+// comparisons. >+template <typename C> >+container_algorithm_internal::ContainerIterPairType<C, C> >+c_minmax_element(C& c) { >+ return std::minmax_element(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c)); >+} >+ >+// Overload of c_minmax_element() for performing `comp` comparisons other than >+// `operator<`. >+template <typename C, typename Compare> >+container_algorithm_internal::ContainerIterPairType<C, C> >+c_minmax_element(C& c, Compare&& comp) { >+ return std::minmax_element(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Compare>(comp)); >+} >+ >+//------------------------------------------------------------------------------ >+// <algorithm> Lexicographical Comparisons >+//------------------------------------------------------------------------------ >+ >+// c_lexicographical_compare() >+// >+// Container-based version of the <algorithm> `std::lexicographical_compare()` >+// function to lexicographically compare (e.g. sort words alphabetically) two >+// container sequences. The comparison is performed using `operator<`. Note >+// that capital letters ("A-Z") have ASCII values less than lowercase letters >+// ("a-z"). >+template <typename Sequence1, typename Sequence2> >+bool c_lexicographical_compare(Sequence1&& sequence1, Sequence2&& sequence2) { >+ return std::lexicographical_compare( >+ container_algorithm_internal::c_begin(sequence1), >+ container_algorithm_internal::c_end(sequence1), >+ container_algorithm_internal::c_begin(sequence2), >+ container_algorithm_internal::c_end(sequence2)); >+} >+ >+// Overload of c_lexicographical_compare() for performing a lexicographical >+// comparison using a `comp` operator instead of `operator<`. >+template <typename Sequence1, typename Sequence2, typename Compare> >+bool c_lexicographical_compare(Sequence1&& sequence1, Sequence2&& sequence2, >+ Compare&& comp) { >+ return std::lexicographical_compare( >+ container_algorithm_internal::c_begin(sequence1), >+ container_algorithm_internal::c_end(sequence1), >+ container_algorithm_internal::c_begin(sequence2), >+ container_algorithm_internal::c_end(sequence2), >+ std::forward<Compare>(comp)); >+} >+ >+// c_next_permutation() >+// >+// Container-based version of the <algorithm> `std::next_permutation()` function >+// to rearrange a container's elements into the next lexicographically greater >+// permutation. >+template <typename C> >+bool c_next_permutation(C& c) { >+ return std::next_permutation(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c)); >+} >+ >+// Overload of c_next_permutation() for performing a lexicographical >+// comparison using a `comp` operator instead of `operator<`. >+template <typename C, typename Compare> >+bool c_next_permutation(C& c, Compare&& comp) { >+ return std::next_permutation(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Compare>(comp)); >+} >+ >+// c_prev_permutation() >+// >+// Container-based version of the <algorithm> `std::prev_permutation()` function >+// to rearrange a container's elements into the next lexicographically lesser >+// permutation. >+template <typename C> >+bool c_prev_permutation(C& c) { >+ return std::prev_permutation(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c)); >+} >+ >+// Overload of c_prev_permutation() for performing a lexicographical >+// comparison using a `comp` operator instead of `operator<`. >+template <typename C, typename Compare> >+bool c_prev_permutation(C& c, Compare&& comp) { >+ return std::prev_permutation(container_algorithm_internal::c_begin(c), >+ container_algorithm_internal::c_end(c), >+ std::forward<Compare>(comp)); >+} >+ >+//------------------------------------------------------------------------------ >+// <numeric> algorithms >+//------------------------------------------------------------------------------ >+ >+// c_iota() >+// >+// Container-based version of the <algorithm> `std::iota()` function >+// to compute successive values of `value`, as if incremented with `++value` >+// after each element is written. and write them to the container. >+template <typename Sequence, typename T> >+void c_iota(Sequence& sequence, T&& value) { >+ std::iota(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(value)); >+} >+// c_accumulate() >+// >+// Container-based version of the <algorithm> `std::accumulate()` function >+// to accumulate the element values of a container to `init` and return that >+// accumulation by value. >+// >+// Note: Due to a language technicality this function has return type >+// absl::decay_t<T>. As a user of this function you can casually read >+// this as "returns T by value" and assume it does the right thing. >+template <typename Sequence, typename T> >+decay_t<T> c_accumulate(const Sequence& sequence, T&& init) { >+ return std::accumulate(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(init)); >+} >+ >+// Overload of c_accumulate() for using a binary operations other than >+// addition for computing the accumulation. >+template <typename Sequence, typename T, typename BinaryOp> >+decay_t<T> c_accumulate(const Sequence& sequence, T&& init, >+ BinaryOp&& binary_op) { >+ return std::accumulate(container_algorithm_internal::c_begin(sequence), >+ container_algorithm_internal::c_end(sequence), >+ std::forward<T>(init), >+ std::forward<BinaryOp>(binary_op)); >+} >+ >+// c_inner_product() >+// >+// Container-based version of the <algorithm> `std::inner_product()` function >+// to compute the cumulative inner product of container element pairs. >+// >+// Note: Due to a language technicality this function has return type >+// absl::decay_t<T>. As a user of this function you can casually read >+// this as "returns T by value" and assume it does the right thing. >+template <typename Sequence1, typename Sequence2, typename T> >+decay_t<T> c_inner_product(const Sequence1& factors1, const Sequence2& factors2, >+ T&& sum) { >+ return std::inner_product(container_algorithm_internal::c_begin(factors1), >+ container_algorithm_internal::c_end(factors1), >+ container_algorithm_internal::c_begin(factors2), >+ std::forward<T>(sum)); >+} >+ >+// Overload of c_inner_product() for using binary operations other than >+// `operator+` (for computing the accumulation) and `operator*` (for computing >+// the product between the two container's element pair). >+template <typename Sequence1, typename Sequence2, typename T, >+ typename BinaryOp1, typename BinaryOp2> >+decay_t<T> c_inner_product(const Sequence1& factors1, const Sequence2& factors2, >+ T&& sum, BinaryOp1&& op1, BinaryOp2&& op2) { >+ return std::inner_product(container_algorithm_internal::c_begin(factors1), >+ container_algorithm_internal::c_end(factors1), >+ container_algorithm_internal::c_begin(factors2), >+ std::forward<T>(sum), std::forward<BinaryOp1>(op1), >+ std::forward<BinaryOp2>(op2)); >+} >+ >+// c_adjacent_difference() >+// >+// Container-based version of the <algorithm> `std::adjacent_difference()` >+// function to compute the difference between each element and the one preceding >+// it and write it to an iterator. >+template <typename InputSequence, typename OutputIt> >+OutputIt c_adjacent_difference(const InputSequence& input, >+ OutputIt output_first) { >+ return std::adjacent_difference(container_algorithm_internal::c_begin(input), >+ container_algorithm_internal::c_end(input), >+ output_first); >+} >+ >+// Overload of c_adjacent_difference() for using a binary operation other than >+// subtraction to compute the adjacent difference. >+template <typename InputSequence, typename OutputIt, typename BinaryOp> >+OutputIt c_adjacent_difference(const InputSequence& input, >+ OutputIt output_first, BinaryOp&& op) { >+ return std::adjacent_difference(container_algorithm_internal::c_begin(input), >+ container_algorithm_internal::c_end(input), >+ output_first, std::forward<BinaryOp>(op)); >+} >+ >+// c_partial_sum() >+// >+// Container-based version of the <algorithm> `std::partial_sum()` function >+// to compute the partial sum of the elements in a sequence and write them >+// to an iterator. The partial sum is the sum of all element values so far in >+// the sequence. >+template <typename InputSequence, typename OutputIt> >+OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first) { >+ return std::partial_sum(container_algorithm_internal::c_begin(input), >+ container_algorithm_internal::c_end(input), >+ output_first); >+} >+ >+// Overload of c_partial_sum() for using a binary operation other than addition >+// to compute the "partial sum". >+template <typename InputSequence, typename OutputIt, typename BinaryOp> >+OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first, >+ BinaryOp&& op) { >+ return std::partial_sum(container_algorithm_internal::c_begin(input), >+ container_algorithm_internal::c_end(input), >+ output_first, std::forward<BinaryOp>(op)); >+} >+ >+} // namespace absl >+ >+#endif // ABSL_ALGORITHM_CONTAINER_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/container_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/container_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..de66f14680f1b8f22d2e965d441a05efc58a6c03 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/container_test.cc >@@ -0,0 +1,997 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/algorithm/container.h" >+ >+#include <functional> >+#include <initializer_list> >+#include <iterator> >+#include <list> >+#include <memory> >+#include <ostream> >+#include <random> >+#include <set> >+#include <unordered_set> >+#include <utility> >+#include <valarray> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/casts.h" >+#include "absl/base/macros.h" >+#include "absl/memory/memory.h" >+#include "absl/types/span.h" >+ >+namespace { >+ >+using ::testing::Each; >+using ::testing::ElementsAre; >+using ::testing::Gt; >+using ::testing::IsNull; >+using ::testing::Lt; >+using ::testing::Pointee; >+using ::testing::Truly; >+using ::testing::UnorderedElementsAre; >+ >+// Most of these tests just check that the code compiles, not that it >+// does the right thing. That's fine since the functions just forward >+// to the STL implementation. >+class NonMutatingTest : public testing::Test { >+ protected: >+ std::unordered_set<int> container_ = {1, 2, 3}; >+ std::list<int> sequence_ = {1, 2, 3}; >+ std::vector<int> vector_ = {1, 2, 3}; >+ int array_[3] = {1, 2, 3}; >+}; >+ >+struct AccumulateCalls { >+ void operator()(int value) { >+ calls.push_back(value); >+ } >+ std::vector<int> calls; >+}; >+ >+bool Predicate(int value) { return value < 3; } >+bool BinPredicate(int v1, int v2) { return v1 < v2; } >+bool Equals(int v1, int v2) { return v1 == v2; } >+bool IsOdd(int x) { return x % 2 != 0; } >+ >+ >+TEST_F(NonMutatingTest, Distance) { >+ EXPECT_EQ(container_.size(), absl::c_distance(container_)); >+ EXPECT_EQ(sequence_.size(), absl::c_distance(sequence_)); >+ EXPECT_EQ(vector_.size(), absl::c_distance(vector_)); >+ EXPECT_EQ(ABSL_ARRAYSIZE(array_), absl::c_distance(array_)); >+ >+ // Works with a temporary argument. >+ EXPECT_EQ(vector_.size(), absl::c_distance(std::vector<int>(vector_))); >+} >+ >+TEST_F(NonMutatingTest, Distance_OverloadedBeginEnd) { >+ // Works with classes which have custom ADL-selected overloads of std::begin >+ // and std::end. >+ std::initializer_list<int> a = {1, 2, 3}; >+ std::valarray<int> b = {1, 2, 3}; >+ EXPECT_EQ(3, absl::c_distance(a)); >+ EXPECT_EQ(3, absl::c_distance(b)); >+ >+ // It is assumed that other c_* functions use the same mechanism for >+ // ADL-selecting begin/end overloads. >+} >+ >+TEST_F(NonMutatingTest, ForEach) { >+ AccumulateCalls c = absl::c_for_each(container_, AccumulateCalls()); >+ // Don't rely on the unordered_set's order. >+ std::sort(c.calls.begin(), c.calls.end()); >+ EXPECT_EQ(vector_, c.calls); >+ >+ // Works with temporary container, too. >+ AccumulateCalls c2 = >+ absl::c_for_each(std::unordered_set<int>(container_), AccumulateCalls()); >+ std::sort(c2.calls.begin(), c2.calls.end()); >+ EXPECT_EQ(vector_, c2.calls); >+} >+ >+TEST_F(NonMutatingTest, FindReturnsCorrectType) { >+ auto it = absl::c_find(container_, 3); >+ EXPECT_EQ(3, *it); >+ absl::c_find(absl::implicit_cast<const std::list<int>&>(sequence_), 3); >+} >+ >+TEST_F(NonMutatingTest, FindIf) { absl::c_find_if(container_, Predicate); } >+ >+TEST_F(NonMutatingTest, FindIfNot) { >+ absl::c_find_if_not(container_, Predicate); >+} >+ >+TEST_F(NonMutatingTest, FindEnd) { >+ absl::c_find_end(sequence_, vector_); >+ absl::c_find_end(vector_, sequence_); >+} >+ >+TEST_F(NonMutatingTest, FindEndWithPredicate) { >+ absl::c_find_end(sequence_, vector_, BinPredicate); >+ absl::c_find_end(vector_, sequence_, BinPredicate); >+} >+ >+TEST_F(NonMutatingTest, FindFirstOf) { >+ absl::c_find_first_of(container_, sequence_); >+ absl::c_find_first_of(sequence_, container_); >+} >+ >+TEST_F(NonMutatingTest, FindFirstOfWithPredicate) { >+ absl::c_find_first_of(container_, sequence_, BinPredicate); >+ absl::c_find_first_of(sequence_, container_, BinPredicate); >+} >+ >+TEST_F(NonMutatingTest, AdjacentFind) { absl::c_adjacent_find(sequence_); } >+ >+TEST_F(NonMutatingTest, AdjacentFindWithPredicate) { >+ absl::c_adjacent_find(sequence_, BinPredicate); >+} >+ >+TEST_F(NonMutatingTest, Count) { EXPECT_EQ(1, absl::c_count(container_, 3)); } >+ >+TEST_F(NonMutatingTest, CountIf) { >+ EXPECT_EQ(2, absl::c_count_if(container_, Predicate)); >+ const std::unordered_set<int>& const_container = container_; >+ EXPECT_EQ(2, absl::c_count_if(const_container, Predicate)); >+} >+ >+TEST_F(NonMutatingTest, Mismatch) { >+ absl::c_mismatch(container_, sequence_); >+ absl::c_mismatch(sequence_, container_); >+} >+ >+TEST_F(NonMutatingTest, MismatchWithPredicate) { >+ absl::c_mismatch(container_, sequence_, BinPredicate); >+ absl::c_mismatch(sequence_, container_, BinPredicate); >+} >+ >+TEST_F(NonMutatingTest, Equal) { >+ EXPECT_TRUE(absl::c_equal(vector_, sequence_)); >+ EXPECT_TRUE(absl::c_equal(sequence_, vector_)); >+ >+ // Test that behavior appropriately differs from that of equal(). >+ std::vector<int> vector_plus = {1, 2, 3}; >+ vector_plus.push_back(4); >+ EXPECT_FALSE(absl::c_equal(vector_plus, sequence_)); >+ EXPECT_FALSE(absl::c_equal(sequence_, vector_plus)); >+} >+ >+TEST_F(NonMutatingTest, EqualWithPredicate) { >+ EXPECT_TRUE(absl::c_equal(vector_, sequence_, Equals)); >+ EXPECT_TRUE(absl::c_equal(sequence_, vector_, Equals)); >+ >+ // Test that behavior appropriately differs from that of equal(). >+ std::vector<int> vector_plus = {1, 2, 3}; >+ vector_plus.push_back(4); >+ EXPECT_FALSE(absl::c_equal(vector_plus, sequence_, Equals)); >+ EXPECT_FALSE(absl::c_equal(sequence_, vector_plus, Equals)); >+} >+ >+TEST_F(NonMutatingTest, IsPermutation) { >+ auto vector_permut_ = vector_; >+ std::next_permutation(vector_permut_.begin(), vector_permut_.end()); >+ EXPECT_TRUE(absl::c_is_permutation(vector_permut_, sequence_)); >+ EXPECT_TRUE(absl::c_is_permutation(sequence_, vector_permut_)); >+ >+ // Test that behavior appropriately differs from that of is_permutation(). >+ std::vector<int> vector_plus = {1, 2, 3}; >+ vector_plus.push_back(4); >+ EXPECT_FALSE(absl::c_is_permutation(vector_plus, sequence_)); >+ EXPECT_FALSE(absl::c_is_permutation(sequence_, vector_plus)); >+} >+ >+TEST_F(NonMutatingTest, IsPermutationWithPredicate) { >+ auto vector_permut_ = vector_; >+ std::next_permutation(vector_permut_.begin(), vector_permut_.end()); >+ EXPECT_TRUE(absl::c_is_permutation(vector_permut_, sequence_, Equals)); >+ EXPECT_TRUE(absl::c_is_permutation(sequence_, vector_permut_, Equals)); >+ >+ // Test that behavior appropriately differs from that of is_permutation(). >+ std::vector<int> vector_plus = {1, 2, 3}; >+ vector_plus.push_back(4); >+ EXPECT_FALSE(absl::c_is_permutation(vector_plus, sequence_, Equals)); >+ EXPECT_FALSE(absl::c_is_permutation(sequence_, vector_plus, Equals)); >+} >+ >+TEST_F(NonMutatingTest, Search) { >+ absl::c_search(sequence_, vector_); >+ absl::c_search(vector_, sequence_); >+ absl::c_search(array_, sequence_); >+} >+ >+TEST_F(NonMutatingTest, SearchWithPredicate) { >+ absl::c_search(sequence_, vector_, BinPredicate); >+ absl::c_search(vector_, sequence_, BinPredicate); >+} >+ >+TEST_F(NonMutatingTest, SearchN) { absl::c_search_n(sequence_, 3, 1); } >+ >+TEST_F(NonMutatingTest, SearchNWithPredicate) { >+ absl::c_search_n(sequence_, 3, 1, BinPredicate); >+} >+ >+TEST_F(NonMutatingTest, LowerBound) { >+ std::list<int>::iterator i = absl::c_lower_bound(sequence_, 3); >+ ASSERT_TRUE(i != sequence_.end()); >+ EXPECT_EQ(2, std::distance(sequence_.begin(), i)); >+ EXPECT_EQ(3, *i); >+} >+ >+TEST_F(NonMutatingTest, LowerBoundWithPredicate) { >+ std::vector<int> v(vector_); >+ std::sort(v.begin(), v.end(), std::greater<int>()); >+ std::vector<int>::iterator i = absl::c_lower_bound(v, 3, std::greater<int>()); >+ EXPECT_TRUE(i == v.begin()); >+ EXPECT_EQ(3, *i); >+} >+ >+TEST_F(NonMutatingTest, UpperBound) { >+ std::list<int>::iterator i = absl::c_upper_bound(sequence_, 1); >+ ASSERT_TRUE(i != sequence_.end()); >+ EXPECT_EQ(1, std::distance(sequence_.begin(), i)); >+ EXPECT_EQ(2, *i); >+} >+ >+TEST_F(NonMutatingTest, UpperBoundWithPredicate) { >+ std::vector<int> v(vector_); >+ std::sort(v.begin(), v.end(), std::greater<int>()); >+ std::vector<int>::iterator i = absl::c_upper_bound(v, 1, std::greater<int>()); >+ EXPECT_EQ(3, i - v.begin()); >+ EXPECT_TRUE(i == v.end()); >+} >+ >+TEST_F(NonMutatingTest, EqualRange) { >+ std::pair<std::list<int>::iterator, std::list<int>::iterator> p = >+ absl::c_equal_range(sequence_, 2); >+ EXPECT_EQ(1, std::distance(sequence_.begin(), p.first)); >+ EXPECT_EQ(2, std::distance(sequence_.begin(), p.second)); >+} >+ >+TEST_F(NonMutatingTest, EqualRangeArray) { >+ auto p = absl::c_equal_range(array_, 2); >+ EXPECT_EQ(1, std::distance(std::begin(array_), p.first)); >+ EXPECT_EQ(2, std::distance(std::begin(array_), p.second)); >+} >+ >+TEST_F(NonMutatingTest, EqualRangeWithPredicate) { >+ std::vector<int> v(vector_); >+ std::sort(v.begin(), v.end(), std::greater<int>()); >+ std::pair<std::vector<int>::iterator, std::vector<int>::iterator> p = >+ absl::c_equal_range(v, 2, std::greater<int>()); >+ EXPECT_EQ(1, std::distance(v.begin(), p.first)); >+ EXPECT_EQ(2, std::distance(v.begin(), p.second)); >+} >+ >+TEST_F(NonMutatingTest, BinarySearch) { >+ EXPECT_TRUE(absl::c_binary_search(vector_, 2)); >+ EXPECT_TRUE(absl::c_binary_search(std::vector<int>(vector_), 2)); >+} >+ >+TEST_F(NonMutatingTest, BinarySearchWithPredicate) { >+ std::vector<int> v(vector_); >+ std::sort(v.begin(), v.end(), std::greater<int>()); >+ EXPECT_TRUE(absl::c_binary_search(v, 2, std::greater<int>())); >+ EXPECT_TRUE( >+ absl::c_binary_search(std::vector<int>(v), 2, std::greater<int>())); >+} >+ >+TEST_F(NonMutatingTest, MinElement) { >+ std::list<int>::iterator i = absl::c_min_element(sequence_); >+ ASSERT_TRUE(i != sequence_.end()); >+ EXPECT_EQ(*i, 1); >+} >+ >+TEST_F(NonMutatingTest, MinElementWithPredicate) { >+ std::list<int>::iterator i = >+ absl::c_min_element(sequence_, std::greater<int>()); >+ ASSERT_TRUE(i != sequence_.end()); >+ EXPECT_EQ(*i, 3); >+} >+ >+TEST_F(NonMutatingTest, MaxElement) { >+ std::list<int>::iterator i = absl::c_max_element(sequence_); >+ ASSERT_TRUE(i != sequence_.end()); >+ EXPECT_EQ(*i, 3); >+} >+ >+TEST_F(NonMutatingTest, MaxElementWithPredicate) { >+ std::list<int>::iterator i = >+ absl::c_max_element(sequence_, std::greater<int>()); >+ ASSERT_TRUE(i != sequence_.end()); >+ EXPECT_EQ(*i, 1); >+} >+ >+TEST_F(NonMutatingTest, LexicographicalCompare) { >+ EXPECT_FALSE(absl::c_lexicographical_compare(sequence_, sequence_)); >+ >+ std::vector<int> v; >+ v.push_back(1); >+ v.push_back(2); >+ v.push_back(4); >+ >+ EXPECT_TRUE(absl::c_lexicographical_compare(sequence_, v)); >+ EXPECT_TRUE(absl::c_lexicographical_compare(std::list<int>(sequence_), v)); >+} >+ >+TEST_F(NonMutatingTest, LexicographicalCopmareWithPredicate) { >+ EXPECT_FALSE(absl::c_lexicographical_compare(sequence_, sequence_, >+ std::greater<int>())); >+ >+ std::vector<int> v; >+ v.push_back(1); >+ v.push_back(2); >+ v.push_back(4); >+ >+ EXPECT_TRUE( >+ absl::c_lexicographical_compare(v, sequence_, std::greater<int>())); >+ EXPECT_TRUE(absl::c_lexicographical_compare( >+ std::vector<int>(v), std::list<int>(sequence_), std::greater<int>())); >+} >+ >+TEST_F(NonMutatingTest, Includes) { >+ std::set<int> s(vector_.begin(), vector_.end()); >+ s.insert(4); >+ EXPECT_TRUE(absl::c_includes(s, vector_)); >+} >+ >+TEST_F(NonMutatingTest, IncludesWithPredicate) { >+ std::vector<int> v = {3, 2, 1}; >+ std::set<int, std::greater<int>> s(v.begin(), v.end()); >+ s.insert(4); >+ EXPECT_TRUE(absl::c_includes(s, v, std::greater<int>())); >+} >+ >+class NumericMutatingTest : public testing::Test { >+ protected: >+ std::list<int> list_ = {1, 2, 3}; >+ std::vector<int> output_; >+}; >+ >+TEST_F(NumericMutatingTest, Iota) { >+ absl::c_iota(list_, 5); >+ std::list<int> expected{5, 6, 7}; >+ EXPECT_EQ(list_, expected); >+} >+ >+TEST_F(NonMutatingTest, Accumulate) { >+ EXPECT_EQ(absl::c_accumulate(sequence_, 4), 1 + 2 + 3 + 4); >+} >+ >+TEST_F(NonMutatingTest, AccumulateWithBinaryOp) { >+ EXPECT_EQ(absl::c_accumulate(sequence_, 4, std::multiplies<int>()), >+ 1 * 2 * 3 * 4); >+} >+ >+TEST_F(NonMutatingTest, AccumulateLvalueInit) { >+ int lvalue = 4; >+ EXPECT_EQ(absl::c_accumulate(sequence_, lvalue), 1 + 2 + 3 + 4); >+} >+ >+TEST_F(NonMutatingTest, AccumulateWithBinaryOpLvalueInit) { >+ int lvalue = 4; >+ EXPECT_EQ(absl::c_accumulate(sequence_, lvalue, std::multiplies<int>()), >+ 1 * 2 * 3 * 4); >+} >+ >+TEST_F(NonMutatingTest, InnerProduct) { >+ EXPECT_EQ(absl::c_inner_product(sequence_, vector_, 1000), >+ 1000 + 1 * 1 + 2 * 2 + 3 * 3); >+} >+ >+TEST_F(NonMutatingTest, InnerProductWithBinaryOps) { >+ EXPECT_EQ(absl::c_inner_product(sequence_, vector_, 10, >+ std::multiplies<int>(), std::plus<int>()), >+ 10 * (1 + 1) * (2 + 2) * (3 + 3)); >+} >+ >+TEST_F(NonMutatingTest, InnerProductLvalueInit) { >+ int lvalue = 1000; >+ EXPECT_EQ(absl::c_inner_product(sequence_, vector_, lvalue), >+ 1000 + 1 * 1 + 2 * 2 + 3 * 3); >+} >+ >+TEST_F(NonMutatingTest, InnerProductWithBinaryOpsLvalueInit) { >+ int lvalue = 10; >+ EXPECT_EQ(absl::c_inner_product(sequence_, vector_, lvalue, >+ std::multiplies<int>(), std::plus<int>()), >+ 10 * (1 + 1) * (2 + 2) * (3 + 3)); >+} >+ >+TEST_F(NumericMutatingTest, AdjacentDifference) { >+ auto last = absl::c_adjacent_difference(list_, std::back_inserter(output_)); >+ *last = 1000; >+ std::vector<int> expected{1, 2 - 1, 3 - 2, 1000}; >+ EXPECT_EQ(output_, expected); >+} >+ >+TEST_F(NumericMutatingTest, AdjacentDifferenceWithBinaryOp) { >+ auto last = absl::c_adjacent_difference(list_, std::back_inserter(output_), >+ std::multiplies<int>()); >+ *last = 1000; >+ std::vector<int> expected{1, 2 * 1, 3 * 2, 1000}; >+ EXPECT_EQ(output_, expected); >+} >+ >+TEST_F(NumericMutatingTest, PartialSum) { >+ auto last = absl::c_partial_sum(list_, std::back_inserter(output_)); >+ *last = 1000; >+ std::vector<int> expected{1, 1 + 2, 1 + 2 + 3, 1000}; >+ EXPECT_EQ(output_, expected); >+} >+ >+TEST_F(NumericMutatingTest, PartialSumWithBinaryOp) { >+ auto last = absl::c_partial_sum(list_, std::back_inserter(output_), >+ std::multiplies<int>()); >+ *last = 1000; >+ std::vector<int> expected{1, 1 * 2, 1 * 2 * 3, 1000}; >+ EXPECT_EQ(output_, expected); >+} >+ >+TEST_F(NonMutatingTest, LinearSearch) { >+ EXPECT_TRUE(absl::c_linear_search(container_, 3)); >+ EXPECT_FALSE(absl::c_linear_search(container_, 4)); >+} >+ >+TEST_F(NonMutatingTest, AllOf) { >+ const std::vector<int>& v = vector_; >+ EXPECT_FALSE(absl::c_all_of(v, [](int x) { return x > 1; })); >+ EXPECT_TRUE(absl::c_all_of(v, [](int x) { return x > 0; })); >+} >+ >+TEST_F(NonMutatingTest, AnyOf) { >+ const std::vector<int>& v = vector_; >+ EXPECT_TRUE(absl::c_any_of(v, [](int x) { return x > 2; })); >+ EXPECT_FALSE(absl::c_any_of(v, [](int x) { return x > 5; })); >+} >+ >+TEST_F(NonMutatingTest, NoneOf) { >+ const std::vector<int>& v = vector_; >+ EXPECT_FALSE(absl::c_none_of(v, [](int x) { return x > 2; })); >+ EXPECT_TRUE(absl::c_none_of(v, [](int x) { return x > 5; })); >+} >+ >+TEST_F(NonMutatingTest, MinMaxElementLess) { >+ std::pair<std::vector<int>::const_iterator, std::vector<int>::const_iterator> >+ p = absl::c_minmax_element(vector_, std::less<int>()); >+ EXPECT_TRUE(p.first == vector_.begin()); >+ EXPECT_TRUE(p.second == vector_.begin() + 2); >+} >+ >+TEST_F(NonMutatingTest, MinMaxElementGreater) { >+ std::pair<std::vector<int>::const_iterator, std::vector<int>::const_iterator> >+ p = absl::c_minmax_element(vector_, std::greater<int>()); >+ EXPECT_TRUE(p.first == vector_.begin() + 2); >+ EXPECT_TRUE(p.second == vector_.begin()); >+} >+ >+TEST_F(NonMutatingTest, MinMaxElementNoPredicate) { >+ std::pair<std::vector<int>::const_iterator, std::vector<int>::const_iterator> >+ p = absl::c_minmax_element(vector_); >+ EXPECT_TRUE(p.first == vector_.begin()); >+ EXPECT_TRUE(p.second == vector_.begin() + 2); >+} >+ >+class SortingTest : public testing::Test { >+ protected: >+ std::list<int> sorted_ = {1, 2, 3, 4}; >+ std::list<int> unsorted_ = {2, 4, 1, 3}; >+ std::list<int> reversed_ = {4, 3, 2, 1}; >+}; >+ >+TEST_F(SortingTest, IsSorted) { >+ EXPECT_TRUE(absl::c_is_sorted(sorted_)); >+ EXPECT_FALSE(absl::c_is_sorted(unsorted_)); >+ EXPECT_FALSE(absl::c_is_sorted(reversed_)); >+} >+ >+TEST_F(SortingTest, IsSortedWithPredicate) { >+ EXPECT_FALSE(absl::c_is_sorted(sorted_, std::greater<int>())); >+ EXPECT_FALSE(absl::c_is_sorted(unsorted_, std::greater<int>())); >+ EXPECT_TRUE(absl::c_is_sorted(reversed_, std::greater<int>())); >+} >+ >+TEST_F(SortingTest, IsSortedUntil) { >+ EXPECT_EQ(1, *absl::c_is_sorted_until(unsorted_)); >+ EXPECT_EQ(4, *absl::c_is_sorted_until(unsorted_, std::greater<int>())); >+} >+ >+TEST_F(SortingTest, NthElement) { >+ std::vector<int> unsorted = {2, 4, 1, 3}; >+ absl::c_nth_element(unsorted, unsorted.begin() + 2); >+ EXPECT_THAT(unsorted, >+ ElementsAre(Lt(3), Lt(3), 3, Gt(3))); >+ absl::c_nth_element(unsorted, unsorted.begin() + 2, std::greater<int>()); >+ EXPECT_THAT(unsorted, >+ ElementsAre(Gt(2), Gt(2), 2, Lt(2))); >+} >+ >+TEST(MutatingTest, IsPartitioned) { >+ EXPECT_TRUE( >+ absl::c_is_partitioned(std::vector<int>{1, 3, 5, 2, 4, 6}, IsOdd)); >+ EXPECT_FALSE( >+ absl::c_is_partitioned(std::vector<int>{1, 2, 3, 4, 5, 6}, IsOdd)); >+ EXPECT_FALSE( >+ absl::c_is_partitioned(std::vector<int>{2, 4, 6, 1, 3, 5}, IsOdd)); >+} >+ >+TEST(MutatingTest, Partition) { >+ std::vector<int> actual = {1, 2, 3, 4, 5}; >+ absl::c_partition(actual, IsOdd); >+ EXPECT_THAT(actual, Truly([](const std::vector<int>& c) { >+ return absl::c_is_partitioned(c, IsOdd); >+ })); >+} >+ >+TEST(MutatingTest, StablePartition) { >+ std::vector<int> actual = {1, 2, 3, 4, 5}; >+ absl::c_stable_partition(actual, IsOdd); >+ EXPECT_THAT(actual, ElementsAre(1, 3, 5, 2, 4)); >+} >+ >+TEST(MutatingTest, PartitionCopy) { >+ const std::vector<int> initial = {1, 2, 3, 4, 5}; >+ std::vector<int> odds, evens; >+ auto ends = absl::c_partition_copy(initial, back_inserter(odds), >+ back_inserter(evens), IsOdd); >+ *ends.first = 7; >+ *ends.second = 6; >+ EXPECT_THAT(odds, ElementsAre(1, 3, 5, 7)); >+ EXPECT_THAT(evens, ElementsAre(2, 4, 6)); >+} >+ >+TEST(MutatingTest, PartitionPoint) { >+ const std::vector<int> initial = {1, 3, 5, 2, 4}; >+ auto middle = absl::c_partition_point(initial, IsOdd); >+ EXPECT_EQ(2, *middle); >+} >+ >+TEST(MutatingTest, CopyMiddle) { >+ const std::vector<int> initial = {4, -1, -2, -3, 5}; >+ const std::list<int> input = {1, 2, 3}; >+ const std::vector<int> expected = {4, 1, 2, 3, 5}; >+ >+ std::list<int> test_list(initial.begin(), initial.end()); >+ absl::c_copy(input, ++test_list.begin()); >+ EXPECT_EQ(std::list<int>(expected.begin(), expected.end()), test_list); >+ >+ std::vector<int> test_vector = initial; >+ absl::c_copy(input, test_vector.begin() + 1); >+ EXPECT_EQ(expected, test_vector); >+} >+ >+TEST(MutatingTest, CopyFrontInserter) { >+ const std::list<int> initial = {4, 5}; >+ const std::list<int> input = {1, 2, 3}; >+ const std::list<int> expected = {3, 2, 1, 4, 5}; >+ >+ std::list<int> test_list = initial; >+ absl::c_copy(input, std::front_inserter(test_list)); >+ EXPECT_EQ(expected, test_list); >+} >+ >+TEST(MutatingTest, CopyBackInserter) { >+ const std::vector<int> initial = {4, 5}; >+ const std::list<int> input = {1, 2, 3}; >+ const std::vector<int> expected = {4, 5, 1, 2, 3}; >+ >+ std::list<int> test_list(initial.begin(), initial.end()); >+ absl::c_copy(input, std::back_inserter(test_list)); >+ EXPECT_EQ(std::list<int>(expected.begin(), expected.end()), test_list); >+ >+ std::vector<int> test_vector = initial; >+ absl::c_copy(input, std::back_inserter(test_vector)); >+ EXPECT_EQ(expected, test_vector); >+} >+ >+TEST(MutatingTest, CopyN) { >+ const std::vector<int> initial = {1, 2, 3, 4, 5}; >+ const std::vector<int> expected = {1, 2}; >+ std::vector<int> actual; >+ absl::c_copy_n(initial, 2, back_inserter(actual)); >+ EXPECT_EQ(expected, actual); >+} >+ >+TEST(MutatingTest, CopyIf) { >+ const std::list<int> input = {1, 2, 3}; >+ std::vector<int> output; >+ absl::c_copy_if(input, std::back_inserter(output), >+ [](int i) { return i != 2; }); >+ EXPECT_THAT(output, ElementsAre(1, 3)); >+} >+ >+TEST(MutatingTest, CopyBackward) { >+ std::vector<int> actual = {1, 2, 3, 4, 5}; >+ std::vector<int> expected = {1, 2, 1, 2, 3}; >+ absl::c_copy_backward(absl::MakeSpan(actual.data(), 3), actual.end()); >+ EXPECT_EQ(expected, actual); >+} >+ >+TEST(MutatingTest, Move) { >+ std::vector<std::unique_ptr<int>> src; >+ src.emplace_back(absl::make_unique<int>(1)); >+ src.emplace_back(absl::make_unique<int>(2)); >+ src.emplace_back(absl::make_unique<int>(3)); >+ src.emplace_back(absl::make_unique<int>(4)); >+ src.emplace_back(absl::make_unique<int>(5)); >+ >+ std::vector<std::unique_ptr<int>> dest = {}; >+ absl::c_move(src, std::back_inserter(dest)); >+ EXPECT_THAT(src, Each(IsNull())); >+ EXPECT_THAT(dest, ElementsAre(Pointee(1), Pointee(2), Pointee(3), Pointee(4), >+ Pointee(5))); >+} >+ >+TEST(MutatingTest, SwapRanges) { >+ std::vector<int> odds = {2, 4, 6}; >+ std::vector<int> evens = {1, 3, 5}; >+ absl::c_swap_ranges(odds, evens); >+ EXPECT_THAT(odds, ElementsAre(1, 3, 5)); >+ EXPECT_THAT(evens, ElementsAre(2, 4, 6)); >+} >+ >+TEST_F(NonMutatingTest, Transform) { >+ std::vector<int> x{0, 2, 4}, y, z; >+ auto end = absl::c_transform(x, back_inserter(y), std::negate<int>()); >+ EXPECT_EQ(std::vector<int>({0, -2, -4}), y); >+ *end = 7; >+ EXPECT_EQ(std::vector<int>({0, -2, -4, 7}), y); >+ >+ y = {1, 3, 0}; >+ end = absl::c_transform(x, y, back_inserter(z), std::plus<int>()); >+ EXPECT_EQ(std::vector<int>({1, 5, 4}), z); >+ *end = 7; >+ EXPECT_EQ(std::vector<int>({1, 5, 4, 7}), z); >+} >+ >+TEST(MutatingTest, Replace) { >+ const std::vector<int> initial = {1, 2, 3, 1, 4, 5}; >+ const std::vector<int> expected = {4, 2, 3, 4, 4, 5}; >+ >+ std::vector<int> test_vector = initial; >+ absl::c_replace(test_vector, 1, 4); >+ EXPECT_EQ(expected, test_vector); >+ >+ std::list<int> test_list(initial.begin(), initial.end()); >+ absl::c_replace(test_list, 1, 4); >+ EXPECT_EQ(std::list<int>(expected.begin(), expected.end()), test_list); >+} >+ >+TEST(MutatingTest, ReplaceIf) { >+ std::vector<int> actual = {1, 2, 3, 4, 5}; >+ const std::vector<int> expected = {0, 2, 0, 4, 0}; >+ >+ absl::c_replace_if(actual, IsOdd, 0); >+ EXPECT_EQ(expected, actual); >+} >+ >+TEST(MutatingTest, ReplaceCopy) { >+ const std::vector<int> initial = {1, 2, 3, 1, 4, 5}; >+ const std::vector<int> expected = {4, 2, 3, 4, 4, 5}; >+ >+ std::vector<int> actual; >+ absl::c_replace_copy(initial, back_inserter(actual), 1, 4); >+ EXPECT_EQ(expected, actual); >+} >+ >+TEST(MutatingTest, Sort) { >+ std::vector<int> test_vector = {2, 3, 1, 4}; >+ absl::c_sort(test_vector); >+ EXPECT_THAT(test_vector, ElementsAre(1, 2, 3, 4)); >+} >+ >+TEST(MutatingTest, SortWithPredicate) { >+ std::vector<int> test_vector = {2, 3, 1, 4}; >+ absl::c_sort(test_vector, std::greater<int>()); >+ EXPECT_THAT(test_vector, ElementsAre(4, 3, 2, 1)); >+} >+ >+// For absl::c_stable_sort tests. Needs an operator< that does not cover all >+// fields so that the test can check the sort preserves order of equal elements. >+struct Element { >+ int key; >+ int value; >+ friend bool operator<(const Element& e1, const Element& e2) { >+ return e1.key < e2.key; >+ } >+ // Make gmock print useful diagnostics. >+ friend std::ostream& operator<<(std::ostream& o, const Element& e) { >+ return o << "{" << e.key << ", " << e.value << "}"; >+ } >+}; >+ >+MATCHER_P2(IsElement, key, value, "") { >+ return arg.key == key && arg.value == value; >+} >+ >+TEST(MutatingTest, StableSort) { >+ std::vector<Element> test_vector = {{1, 1}, {2, 1}, {2, 0}, {1, 0}, {2, 2}}; >+ absl::c_stable_sort(test_vector); >+ EXPECT_THAT( >+ test_vector, >+ ElementsAre(IsElement(1, 1), IsElement(1, 0), IsElement(2, 1), >+ IsElement(2, 0), IsElement(2, 2))); >+} >+ >+TEST(MutatingTest, StableSortWithPredicate) { >+ std::vector<Element> test_vector = {{1, 1}, {2, 1}, {2, 0}, {1, 0}, {2, 2}}; >+ absl::c_stable_sort(test_vector, [](const Element& e1, const Element& e2) { >+ return e2 < e1; >+ }); >+ EXPECT_THAT( >+ test_vector, >+ ElementsAre(IsElement(2, 1), IsElement(2, 0), IsElement(2, 2), >+ IsElement(1, 1), IsElement(1, 0))); >+} >+ >+TEST(MutatingTest, ReplaceCopyIf) { >+ const std::vector<int> initial = {1, 2, 3, 4, 5}; >+ const std::vector<int> expected = {0, 2, 0, 4, 0}; >+ >+ std::vector<int> actual; >+ absl::c_replace_copy_if(initial, back_inserter(actual), IsOdd, 0); >+ EXPECT_EQ(expected, actual); >+} >+ >+TEST(MutatingTest, Fill) { >+ std::vector<int> actual(5); >+ absl::c_fill(actual, 1); >+ EXPECT_THAT(actual, ElementsAre(1, 1, 1, 1, 1)); >+} >+ >+TEST(MutatingTest, FillN) { >+ std::vector<int> actual(5, 0); >+ absl::c_fill_n(actual, 2, 1); >+ EXPECT_THAT(actual, ElementsAre(1, 1, 0, 0, 0)); >+} >+ >+TEST(MutatingTest, Generate) { >+ std::vector<int> actual(5); >+ int x = 0; >+ absl::c_generate(actual, [&x]() { return ++x; }); >+ EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5)); >+} >+ >+TEST(MutatingTest, GenerateN) { >+ std::vector<int> actual(5, 0); >+ int x = 0; >+ absl::c_generate_n(actual, 3, [&x]() { return ++x; }); >+ EXPECT_THAT(actual, ElementsAre(1, 2, 3, 0, 0)); >+} >+ >+TEST(MutatingTest, RemoveCopy) { >+ std::vector<int> actual; >+ absl::c_remove_copy(std::vector<int>{1, 2, 3}, back_inserter(actual), 2); >+ EXPECT_THAT(actual, ElementsAre(1, 3)); >+} >+ >+TEST(MutatingTest, RemoveCopyIf) { >+ std::vector<int> actual; >+ absl::c_remove_copy_if(std::vector<int>{1, 2, 3}, back_inserter(actual), >+ IsOdd); >+ EXPECT_THAT(actual, ElementsAre(2)); >+} >+ >+TEST(MutatingTest, UniqueCopy) { >+ std::vector<int> actual; >+ absl::c_unique_copy(std::vector<int>{1, 2, 2, 2, 3, 3, 2}, >+ back_inserter(actual)); >+ EXPECT_THAT(actual, ElementsAre(1, 2, 3, 2)); >+} >+ >+TEST(MutatingTest, UniqueCopyWithPredicate) { >+ std::vector<int> actual; >+ absl::c_unique_copy(std::vector<int>{1, 2, 3, -1, -2, -3, 1}, >+ back_inserter(actual), >+ [](int x, int y) { return (x < 0) == (y < 0); }); >+ EXPECT_THAT(actual, ElementsAre(1, -1, 1)); >+} >+ >+TEST(MutatingTest, Reverse) { >+ std::vector<int> test_vector = {1, 2, 3, 4}; >+ absl::c_reverse(test_vector); >+ EXPECT_THAT(test_vector, ElementsAre(4, 3, 2, 1)); >+ >+ std::list<int> test_list = {1, 2, 3, 4}; >+ absl::c_reverse(test_list); >+ EXPECT_THAT(test_list, ElementsAre(4, 3, 2, 1)); >+} >+ >+TEST(MutatingTest, ReverseCopy) { >+ std::vector<int> actual; >+ absl::c_reverse_copy(std::vector<int>{1, 2, 3, 4}, back_inserter(actual)); >+ EXPECT_THAT(actual, ElementsAre(4, 3, 2, 1)); >+} >+ >+TEST(MutatingTest, Rotate) { >+ std::vector<int> actual = {1, 2, 3, 4}; >+ auto it = absl::c_rotate(actual, actual.begin() + 2); >+ EXPECT_THAT(actual, testing::ElementsAreArray({3, 4, 1, 2})); >+ EXPECT_EQ(*it, 1); >+} >+ >+TEST(MutatingTest, RotateCopy) { >+ std::vector<int> initial = {1, 2, 3, 4}; >+ std::vector<int> actual; >+ auto end = >+ absl::c_rotate_copy(initial, initial.begin() + 2, back_inserter(actual)); >+ *end = 5; >+ EXPECT_THAT(actual, ElementsAre(3, 4, 1, 2, 5)); >+} >+ >+TEST(MutatingTest, Shuffle) { >+ std::vector<int> actual = {1, 2, 3, 4, 5}; >+ absl::c_shuffle(actual, std::random_device()); >+ EXPECT_THAT(actual, UnorderedElementsAre(1, 2, 3, 4, 5)); >+} >+ >+TEST(MutatingTest, PartialSort) { >+ std::vector<int> sequence{5, 3, 42, 0}; >+ absl::c_partial_sort(sequence, sequence.begin() + 2); >+ EXPECT_THAT(absl::MakeSpan(sequence.data(), 2), ElementsAre(0, 3)); >+ absl::c_partial_sort(sequence, sequence.begin() + 2, std::greater<int>()); >+ EXPECT_THAT(absl::MakeSpan(sequence.data(), 2), ElementsAre(42, 5)); >+} >+ >+TEST(MutatingTest, PartialSortCopy) { >+ const std::vector<int> initial = {5, 3, 42, 0}; >+ std::vector<int> actual(2); >+ absl::c_partial_sort_copy(initial, actual); >+ EXPECT_THAT(actual, ElementsAre(0, 3)); >+ absl::c_partial_sort_copy(initial, actual, std::greater<int>()); >+ EXPECT_THAT(actual, ElementsAre(42, 5)); >+} >+ >+TEST(MutatingTest, Merge) { >+ std::vector<int> actual; >+ absl::c_merge(std::vector<int>{1, 3, 5}, std::vector<int>{2, 4}, >+ back_inserter(actual)); >+ EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5)); >+} >+ >+TEST(MutatingTest, MergeWithComparator) { >+ std::vector<int> actual; >+ absl::c_merge(std::vector<int>{5, 3, 1}, std::vector<int>{4, 2}, >+ back_inserter(actual), std::greater<int>()); >+ EXPECT_THAT(actual, ElementsAre(5, 4, 3, 2, 1)); >+} >+ >+TEST(MutatingTest, InplaceMerge) { >+ std::vector<int> actual = {1, 3, 5, 2, 4}; >+ absl::c_inplace_merge(actual, actual.begin() + 3); >+ EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5)); >+} >+ >+TEST(MutatingTest, InplaceMergeWithComparator) { >+ std::vector<int> actual = {5, 3, 1, 4, 2}; >+ absl::c_inplace_merge(actual, actual.begin() + 3, std::greater<int>()); >+ EXPECT_THAT(actual, ElementsAre(5, 4, 3, 2, 1)); >+} >+ >+class SetOperationsTest : public testing::Test { >+ protected: >+ std::vector<int> a_ = {1, 2, 3}; >+ std::vector<int> b_ = {1, 3, 5}; >+ >+ std::vector<int> a_reversed_ = {3, 2, 1}; >+ std::vector<int> b_reversed_ = {5, 3, 1}; >+}; >+ >+TEST_F(SetOperationsTest, SetUnion) { >+ std::vector<int> actual; >+ absl::c_set_union(a_, b_, back_inserter(actual)); >+ EXPECT_THAT(actual, ElementsAre(1, 2, 3, 5)); >+} >+ >+TEST_F(SetOperationsTest, SetUnionWithComparator) { >+ std::vector<int> actual; >+ absl::c_set_union(a_reversed_, b_reversed_, back_inserter(actual), >+ std::greater<int>()); >+ EXPECT_THAT(actual, ElementsAre(5, 3, 2, 1)); >+} >+ >+TEST_F(SetOperationsTest, SetIntersection) { >+ std::vector<int> actual; >+ absl::c_set_intersection(a_, b_, back_inserter(actual)); >+ EXPECT_THAT(actual, ElementsAre(1, 3)); >+} >+ >+TEST_F(SetOperationsTest, SetIntersectionWithComparator) { >+ std::vector<int> actual; >+ absl::c_set_intersection(a_reversed_, b_reversed_, back_inserter(actual), >+ std::greater<int>()); >+ EXPECT_THAT(actual, ElementsAre(3, 1)); >+} >+ >+TEST_F(SetOperationsTest, SetDifference) { >+ std::vector<int> actual; >+ absl::c_set_difference(a_, b_, back_inserter(actual)); >+ EXPECT_THAT(actual, ElementsAre(2)); >+} >+ >+TEST_F(SetOperationsTest, SetDifferenceWithComparator) { >+ std::vector<int> actual; >+ absl::c_set_difference(a_reversed_, b_reversed_, back_inserter(actual), >+ std::greater<int>()); >+ EXPECT_THAT(actual, ElementsAre(2)); >+} >+ >+TEST_F(SetOperationsTest, SetSymmetricDifference) { >+ std::vector<int> actual; >+ absl::c_set_symmetric_difference(a_, b_, back_inserter(actual)); >+ EXPECT_THAT(actual, ElementsAre(2, 5)); >+} >+ >+TEST_F(SetOperationsTest, SetSymmetricDifferenceWithComparator) { >+ std::vector<int> actual; >+ absl::c_set_symmetric_difference(a_reversed_, b_reversed_, >+ back_inserter(actual), std::greater<int>()); >+ EXPECT_THAT(actual, ElementsAre(5, 2)); >+} >+ >+TEST(HeapOperationsTest, WithoutComparator) { >+ std::vector<int> heap = {1, 2, 3}; >+ EXPECT_FALSE(absl::c_is_heap(heap)); >+ absl::c_make_heap(heap); >+ EXPECT_TRUE(absl::c_is_heap(heap)); >+ heap.push_back(4); >+ EXPECT_EQ(3, absl::c_is_heap_until(heap) - heap.begin()); >+ absl::c_push_heap(heap); >+ EXPECT_EQ(4, heap[0]); >+ absl::c_pop_heap(heap); >+ EXPECT_EQ(4, heap[3]); >+ absl::c_make_heap(heap); >+ absl::c_sort_heap(heap); >+ EXPECT_THAT(heap, ElementsAre(1, 2, 3, 4)); >+ EXPECT_FALSE(absl::c_is_heap(heap)); >+} >+ >+TEST(HeapOperationsTest, WithComparator) { >+ using greater = std::greater<int>; >+ std::vector<int> heap = {3, 2, 1}; >+ EXPECT_FALSE(absl::c_is_heap(heap, greater())); >+ absl::c_make_heap(heap, greater()); >+ EXPECT_TRUE(absl::c_is_heap(heap, greater())); >+ heap.push_back(0); >+ EXPECT_EQ(3, absl::c_is_heap_until(heap, greater()) - heap.begin()); >+ absl::c_push_heap(heap, greater()); >+ EXPECT_EQ(0, heap[0]); >+ absl::c_pop_heap(heap, greater()); >+ EXPECT_EQ(0, heap[3]); >+ absl::c_make_heap(heap, greater()); >+ absl::c_sort_heap(heap, greater()); >+ EXPECT_THAT(heap, ElementsAre(3, 2, 1, 0)); >+ EXPECT_FALSE(absl::c_is_heap(heap, greater())); >+} >+ >+TEST(MutatingTest, PermutationOperations) { >+ std::vector<int> initial = {1, 2, 3, 4}; >+ std::vector<int> permuted = initial; >+ >+ absl::c_next_permutation(permuted); >+ EXPECT_TRUE(absl::c_is_permutation(initial, permuted)); >+ EXPECT_TRUE(absl::c_is_permutation(initial, permuted, std::equal_to<int>())); >+ >+ std::vector<int> permuted2 = initial; >+ absl::c_prev_permutation(permuted2, std::greater<int>()); >+ EXPECT_EQ(permuted, permuted2); >+ >+ absl::c_prev_permutation(permuted); >+ EXPECT_EQ(initial, permuted); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/equal_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/equal_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..19c0780ccd179ce745b5e6821add3da40c582791 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/algorithm/equal_benchmark.cc >@@ -0,0 +1,126 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <cstdint> >+#include <cstring> >+ >+#include "benchmark/benchmark.h" >+#include "absl/algorithm/algorithm.h" >+ >+namespace { >+ >+// The range of sequence sizes to benchmark. >+constexpr int kMinBenchmarkSize = 1024; >+constexpr int kMaxBenchmarkSize = 8 * 1024 * 1024; >+ >+// A user-defined type for use in equality benchmarks. Note that we expect >+// std::memcmp to win for this type: libstdc++'s std::equal only defers to >+// memcmp for integral types. This is because it is not straightforward to >+// guarantee that std::memcmp would produce a result "as-if" compared by >+// operator== for other types (example gotchas: NaN floats, structs with >+// padding). >+struct EightBits { >+ explicit EightBits(int /* unused */) : data(0) {} >+ bool operator==(const EightBits& rhs) const { return data == rhs.data; } >+ uint8_t data; >+}; >+ >+template <typename T> >+void BM_absl_equal_benchmark(benchmark::State& state) { >+ std::vector<T> xs(state.range(0), T(0)); >+ std::vector<T> ys = xs; >+ while (state.KeepRunning()) { >+ const bool same = absl::equal(xs.begin(), xs.end(), ys.begin(), ys.end()); >+ benchmark::DoNotOptimize(same); >+ } >+} >+ >+template <typename T> >+void BM_std_equal_benchmark(benchmark::State& state) { >+ std::vector<T> xs(state.range(0), T(0)); >+ std::vector<T> ys = xs; >+ while (state.KeepRunning()) { >+ const bool same = std::equal(xs.begin(), xs.end(), ys.begin()); >+ benchmark::DoNotOptimize(same); >+ } >+} >+ >+template <typename T> >+void BM_memcmp_benchmark(benchmark::State& state) { >+ std::vector<T> xs(state.range(0), T(0)); >+ std::vector<T> ys = xs; >+ while (state.KeepRunning()) { >+ const bool same = >+ std::memcmp(xs.data(), ys.data(), xs.size() * sizeof(T)) == 0; >+ benchmark::DoNotOptimize(same); >+ } >+} >+ >+// The expectation is that the compiler should be able to elide the equality >+// comparison altogether for sufficiently simple types. >+template <typename T> >+void BM_absl_equal_self_benchmark(benchmark::State& state) { >+ std::vector<T> xs(state.range(0), T(0)); >+ while (state.KeepRunning()) { >+ const bool same = absl::equal(xs.begin(), xs.end(), xs.begin(), xs.end()); >+ benchmark::DoNotOptimize(same); >+ } >+} >+ >+BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint8_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint8_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint8_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint8_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+ >+BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint16_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint16_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint16_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint16_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+ >+BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint32_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint32_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint32_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint32_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+ >+BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint64_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint64_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint64_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint64_t) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+ >+BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, EightBits) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_std_equal_benchmark, EightBits) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_memcmp_benchmark, EightBits) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, EightBits) >+ ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..06d092ebdfa83abf924bb3ee032694259b2e4b2d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/BUILD.bazel >@@ -0,0 +1,423 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+ "ABSL_EXCEPTIONS_FLAG", >+) >+ >+package(default_visibility = ["//visibility:public"]) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+cc_library( >+ name = "spinlock_wait", >+ srcs = [ >+ "internal/spinlock_akaros.inc", >+ "internal/spinlock_posix.inc", >+ "internal/spinlock_wait.cc", >+ "internal/spinlock_win32.inc", >+ ], >+ hdrs = [ >+ "internal/scheduling_mode.h", >+ "internal/spinlock_wait.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ visibility = [ >+ "//absl/base:__pkg__", >+ ], >+ deps = [":core_headers"], >+) >+ >+cc_library( >+ name = "config", >+ hdrs = [ >+ "config.h", >+ "policy_checks.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+) >+ >+cc_library( >+ name = "dynamic_annotations", >+ srcs = ["dynamic_annotations.cc"], >+ hdrs = ["dynamic_annotations.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ defines = ["__CLANG_SUPPORT_DYN_ANNOTATION__"], >+) >+ >+cc_library( >+ name = "core_headers", >+ hdrs = [ >+ "attributes.h", >+ "macros.h", >+ "optimization.h", >+ "port.h", >+ "thread_annotations.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":config", >+ ":dynamic_annotations", >+ ], >+) >+ >+cc_library( >+ name = "malloc_internal", >+ srcs = [ >+ "internal/low_level_alloc.cc", >+ ], >+ hdrs = [ >+ "internal/direct_mmap.h", >+ "internal/low_level_alloc.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ visibility = [ >+ "//absl:__subpackages__", >+ ], >+ deps = [ >+ ":base", >+ ":config", >+ ":core_headers", >+ ":dynamic_annotations", >+ ":spinlock_wait", >+ ], >+) >+ >+cc_library( >+ name = "base_internal", >+ hdrs = [ >+ "internal/hide_ptr.h", >+ "internal/identity.h", >+ "internal/inline_variable.h", >+ "internal/invoke.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ visibility = [ >+ "//absl:__subpackages__", >+ ], >+) >+ >+cc_library( >+ name = "base", >+ srcs = [ >+ "internal/cycleclock.cc", >+ "internal/raw_logging.cc", >+ "internal/spinlock.cc", >+ "internal/sysinfo.cc", >+ "internal/thread_identity.cc", >+ "internal/unscaledcycleclock.cc", >+ ], >+ 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", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":base_internal", >+ ":config", >+ ":core_headers", >+ ":dynamic_annotations", >+ ":spinlock_wait", >+ ], >+) >+ >+cc_test( >+ name = "atomic_hook_test", >+ size = "small", >+ srcs = ["internal/atomic_hook_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":base", >+ ":core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "bit_cast_test", >+ size = "small", >+ srcs = [ >+ "bit_cast_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":base", >+ ":core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_library( >+ name = "throw_delegate", >+ srcs = ["internal/throw_delegate.cc"], >+ hdrs = ["internal/throw_delegate.h"], >+ copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG, >+ visibility = [ >+ "//absl:__subpackages__", >+ ], >+ deps = [ >+ ":base", >+ ":config", >+ ":core_headers", >+ ], >+) >+ >+cc_test( >+ name = "throw_delegate_test", >+ srcs = ["throw_delegate_test.cc"], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":throw_delegate", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_library( >+ name = "exception_testing", >+ testonly = 1, >+ hdrs = ["internal/exception_testing.h"], >+ copts = ABSL_TEST_COPTS, >+ visibility = [ >+ "//absl:__subpackages__", >+ ], >+ deps = [ >+ ":config", >+ "@com_google_googletest//:gtest", >+ ], >+) >+ >+cc_library( >+ name = "pretty_function", >+ hdrs = ["internal/pretty_function.h"], >+ visibility = ["//absl:__subpackages__"], >+) >+ >+cc_library( >+ name = "exception_safety_testing", >+ testonly = 1, >+ srcs = ["internal/exception_safety_testing.cc"], >+ hdrs = ["internal/exception_safety_testing.h"], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":base", >+ ":config", >+ ":pretty_function", >+ "//absl/memory", >+ "//absl/meta:type_traits", >+ "//absl/strings", >+ "//absl/types:optional", >+ "@com_google_googletest//:gtest", >+ ], >+) >+ >+cc_test( >+ name = "exception_safety_testing_test", >+ srcs = ["exception_safety_testing_test.cc"], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":exception_safety_testing", >+ "//absl/memory", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "inline_variable_test", >+ size = "small", >+ srcs = [ >+ "inline_variable_test.cc", >+ "inline_variable_test_a.cc", >+ "inline_variable_test_b.cc", >+ "internal/inline_variable_testing.h", >+ ], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":base_internal", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "invoke_test", >+ size = "small", >+ srcs = ["invoke_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":base_internal", >+ "//absl/memory", >+ "//absl/strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+# Common test library made available for use in non-absl code that overrides >+# AbslInternalSpinLockDelay and AbslInternalSpinLockWake. >+cc_library( >+ name = "spinlock_test_common", >+ testonly = 1, >+ srcs = ["spinlock_test_common.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":base", >+ ":core_headers", >+ ":spinlock_wait", >+ "//absl/synchronization", >+ "@com_google_googletest//:gtest", >+ ], >+ alwayslink = 1, >+) >+ >+cc_test( >+ name = "spinlock_test", >+ size = "medium", >+ srcs = ["spinlock_test_common.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":base", >+ ":core_headers", >+ ":spinlock_wait", >+ "//absl/synchronization", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_library( >+ name = "endian", >+ hdrs = [ >+ "internal/endian.h", >+ "internal/unaligned_access.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":config", >+ ":core_headers", >+ ], >+) >+ >+cc_test( >+ name = "endian_test", >+ srcs = ["internal/endian_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":base", >+ ":config", >+ ":endian", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "config_test", >+ srcs = ["config_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":config", >+ "//absl/synchronization:thread_pool", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "call_once_test", >+ srcs = ["call_once_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":base", >+ ":core_headers", >+ "//absl/synchronization", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "raw_logging_test", >+ srcs = ["raw_logging_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":base", >+ "//absl/strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "sysinfo_test", >+ size = "small", >+ srcs = ["internal/sysinfo_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":base", >+ "//absl/synchronization", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "low_level_alloc_test", >+ size = "small", >+ srcs = ["internal/low_level_alloc_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ linkopts = select({ >+ "//absl:windows": [], >+ "//conditions:default": ["-pthread"], >+ }), >+ tags = ["no_test_ios_x86_64"], >+ deps = [":malloc_internal"], >+) >+ >+cc_test( >+ name = "thread_identity_test", >+ size = "small", >+ srcs = ["internal/thread_identity_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ linkopts = select({ >+ "//absl:windows": [], >+ "//conditions:default": ["-pthread"], >+ }), >+ deps = [ >+ ":base", >+ ":core_headers", >+ "//absl/synchronization", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "thread_identity_benchmark", >+ srcs = ["internal/thread_identity_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":base", >+ "//absl/synchronization", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..a714656462290bcd40cd4999ca1fef20c8637e7d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/BUILD.gn >@@ -0,0 +1,298 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("spinlock_wait") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/spinlock_akaros.inc", >+ "internal/spinlock_posix.inc", >+ "internal/spinlock_wait.cc", >+ "internal/spinlock_win32.inc", >+ ] >+ public = [ >+ "internal/scheduling_mode.h", >+ "internal/spinlock_wait.h", >+ ] >+ deps = [ >+ ":core_headers", >+ ] >+ visibility = [] >+ visibility += [ "../base:*" ] >+} >+ >+source_set("config") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "config.h", >+ "policy_checks.h", >+ ] >+} >+ >+config("clang_support_dynamic_annotations") { >+ cflags_cc = [ "-D__CLANG_SUPPORT_DYN_ANNOTATION__" ] >+} >+ >+source_set("dynamic_annotations") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ >+ ":clang_support_dynamic_annotations", >+ "//third_party/abseil-cpp:absl_include_config", >+ ] >+ sources = [ >+ "dynamic_annotations.cc", >+ ] >+ public = [ >+ "dynamic_annotations.h", >+ ] >+ # Abseil's dynamic annotations are only visible inside Abseil because >+ # their usage is deprecated in Chromium (see README.chromium for more info). >+ visibility = [] >+ visibility = [ "../*" ] >+} >+ >+source_set("core_headers") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "attributes.h", >+ "macros.h", >+ "optimization.h", >+ "port.h", >+ "thread_annotations.h", >+ ] >+ deps = [ >+ ":config", >+ ":dynamic_annotations", >+ ] >+} >+ >+source_set("malloc_internal") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/low_level_alloc.cc", >+ ] >+ public = [ >+ "internal/direct_mmap.h", >+ "internal/low_level_alloc.h", >+ ] >+ deps = [ >+ ":base", >+ ":config", >+ ":core_headers", >+ ":dynamic_annotations", >+ ":spinlock_wait", >+ ] >+ visibility = [] >+ visibility += [ "../*" ] >+} >+ >+source_set("base_internal") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "internal/hide_ptr.h", >+ "internal/identity.h", >+ "internal/inline_variable.h", >+ "internal/invoke.h", >+ ] >+ visibility = [] >+ visibility += [ "../*" ] >+} >+ >+source_set("base") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/cycleclock.cc", >+ "internal/raw_logging.cc", >+ "internal/spinlock.cc", >+ "internal/sysinfo.cc", >+ "internal/thread_identity.cc", >+ "internal/unscaledcycleclock.cc", >+ ] >+ public = [ >+ "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", >+ ] >+ deps = [ >+ ":base_internal", >+ ":config", >+ ":core_headers", >+ ":dynamic_annotations", >+ ":spinlock_wait", >+ ] >+} >+ >+source_set("throw_delegate") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/throw_delegate.cc", >+ ] >+ public = [ >+ "internal/throw_delegate.h", >+ ] >+ deps = [ >+ ":base", >+ ":config", >+ ":core_headers", >+ ] >+ visibility = [] >+ visibility += [ "../*" ] >+} >+ >+source_set("exception_testing") { >+ testonly = true >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_test_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "internal/exception_testing.h", >+ ] >+ deps = [ >+ ":config", >+ ] >+ visibility = [] >+ visibility += [ "../*" ] >+} >+ >+source_set("pretty_function") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "internal/pretty_function.h", >+ ] >+ visibility = [] >+ visibility += [ "../*" ] >+} >+ >+# TODO(mbonadei): This target throws by design. We should probably >+# just remove it. >+# source_set("exception_safety_testing") { >+# testonly = true >+# configs -= [ "//build/config/compiler:chromium_code" ] >+# configs += [ >+# "//build/config/compiler:no_chromium_code", >+# "//third_party/abseil-cpp:absl_test_cflags_cc", >+# ] >+# public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+# sources = [ >+# "internal/exception_safety_testing.cc", >+# ] >+# public = [ >+# "internal/exception_safety_testing.h", >+# ] >+# deps = [ >+# ":base", >+# ":config", >+# ":pretty_function", >+# "../memory", >+# "../meta:type_traits", >+# "../strings", >+# "../types:optional", >+# "//testing/gtest", >+# ] >+# } >+ >+source_set("spinlock_test_common") { >+ testonly = true >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_test_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "spinlock_test_common.cc", >+ ] >+ deps = [ >+ ":base", >+ ":core_headers", >+ ":spinlock_wait", >+ "../synchronization", >+ "//testing/gtest", >+ ] >+} >+ >+source_set("endian") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "internal/endian.h", >+ "internal/unaligned_access.h", >+ ] >+ deps = [ >+ ":config", >+ ":core_headers", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..01d2af085f58e15f3e2639c516cf66d46d121bed >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/CMakeLists.txt >@@ -0,0 +1,386 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+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" >+) >+ >+ >+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_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_library( >+ TARGET >+ absl_base >+ SOURCES >+ ${BASE_SRC} >+ PUBLIC_LIBRARIES >+ absl_dynamic_annotations >+ absl_spinlock_wait >+ EXPORT_NAME >+ base >+) >+ >+# throw delegate library >+set(THROW_DELEGATE_SRC "internal/throw_delegate.cc") >+ >+absl_library( >+ TARGET >+ absl_throw_delegate >+ SOURCES >+ ${THROW_DELEGATE_SRC} >+ PUBLIC_LIBRARIES >+ ${THROW_DELEGATE_PUBLIC_LIBRARIES} >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+ EXPORT_NAME >+ throw_delegate >+) >+ >+if(BUILD_TESTING) >+ # exception-safety testing library >+ set(EXCEPTION_SAFETY_TESTING_SRC >+ "internal/exception_safety_testing.h" >+ "internal/exception_safety_testing.cc" >+ ) >+ set(EXCEPTION_SAFETY_TESTING_PUBLIC_LIBRARIES >+ ${ABSL_TEST_COMMON_LIBRARIES} >+ absl::base >+ absl::memory >+ absl::meta >+ absl::strings >+ absl::optional >+ 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" >+) >+ >+absl_library( >+ TARGET >+ absl_malloc_internal >+ SOURCES >+ ${MALLOC_INTERNAL_SRC} >+ PUBLIC_LIBRARIES >+ absl_dynamic_annotations >+) >+ >+ >+ >+# >+## TESTS >+# >+ >+# call once test >+set(ATOMIC_HOOK_TEST_SRC "internal/atomic_hook_test.cc") >+set(ATOMIC_HOOK_TEST_PUBLIC_LIBRARIES absl::base) >+ >+absl_test( >+ TARGET >+ atomic_hook_test >+ SOURCES >+ ${ATOMIC_HOOK_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${ATOMIC_HOOK_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# call once test >+set(CALL_ONCE_TEST_SRC "call_once_test.cc") >+set(CALL_ONCE_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) >+ >+absl_test( >+ TARGET >+ call_once_test >+ SOURCES >+ ${CALL_ONCE_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${CALL_ONCE_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test bit_cast_test >+set(BIT_CAST_TEST_SRC "bit_cast_test.cc") >+ >+absl_test( >+ TARGET >+ bit_cast_test >+ SOURCES >+ ${BIT_CAST_TEST_SRC} >+) >+ >+ >+# test absl_throw_delegate_test >+set(THROW_DELEGATE_TEST_SRC "throw_delegate_test.cc") >+set(THROW_DELEGATE_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate) >+ >+absl_test( >+ TARGET >+ throw_delegate_test >+ SOURCES >+ ${THROW_DELEGATE_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${THROW_DELEGATE_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test invoke_test >+set(INVOKE_TEST_SRC "invoke_test.cc") >+set(INVOKE_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ invoke_test >+ SOURCES >+ ${INVOKE_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${INVOKE_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test inline_variable_test >+list(APPEND INLINE_VARIABLE_TEST_SRC >+ "internal/inline_variable_testing.h" >+ "inline_variable_test.cc" >+ "inline_variable_test_a.cc" >+ "inline_variable_test_b.cc" >+) >+ >+set(INLINE_VARIABLE_TEST_PUBLIC_LIBRARIES absl::base) >+ >+absl_test( >+ TARGET >+ inline_variable_test >+ SOURCES >+ ${INLINE_VARIABLE_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${INLINE_VARIABLE_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test spinlock_test_common >+set(SPINLOCK_TEST_COMMON_SRC "spinlock_test_common.cc") >+set(SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES absl::base absl::synchronization) >+ >+absl_test( >+ TARGET >+ spinlock_test_common >+ SOURCES >+ ${SPINLOCK_TEST_COMMON_SRC} >+ PUBLIC_LIBRARIES >+ ${SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES} >+) >+ >+ >+# test spinlock_test >+set(SPINLOCK_TEST_SRC "spinlock_test_common.cc") >+set(SPINLOCK_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) >+ >+absl_test( >+ TARGET >+ spinlock_test >+ SOURCES >+ ${SPINLOCK_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${SPINLOCK_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test endian_test >+set(ENDIAN_TEST_SRC "internal/endian_test.cc") >+ >+absl_test( >+ TARGET >+ endian_test >+ SOURCES >+ ${ENDIAN_TEST_SRC} >+) >+ >+ >+# test config_test >+set(CONFIG_TEST_SRC "config_test.cc") >+set(CONFIG_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) >+absl_test( >+ TARGET >+ config_test >+ SOURCES >+ ${CONFIG_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${CONFIG_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test raw_logging_test >+set(RAW_LOGGING_TEST_SRC "raw_logging_test.cc") >+set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base absl::strings) >+ >+absl_test( >+ TARGET >+ raw_logging_test >+ SOURCES >+ ${RAW_LOGGING_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${RAW_LOGGING_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test sysinfo_test >+set(SYSINFO_TEST_SRC "internal/sysinfo_test.cc") >+set(SYSINFO_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) >+ >+absl_test( >+ TARGET >+ sysinfo_test >+ SOURCES >+ ${SYSINFO_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${SYSINFO_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test low_level_alloc_test >+set(LOW_LEVEL_ALLOC_TEST_SRC "internal/low_level_alloc_test.cc") >+set(LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES absl::base) >+ >+absl_test( >+ TARGET >+ low_level_alloc_test >+ SOURCES >+ ${LOW_LEVEL_ALLOC_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test thread_identity_test >+set(THREAD_IDENTITY_TEST_SRC "internal/thread_identity_test.cc") >+set(THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) >+ >+absl_test( >+ TARGET >+ thread_identity_test >+ SOURCES >+ ${THREAD_IDENTITY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES} >+) >+ >+#test exceptions_safety_testing_test >+set(EXCEPTION_SAFETY_TESTING_TEST_SRC "exception_safety_testing_test.cc") >+set(EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES >+ absl::base >+ absl_base_internal_exception_safety_testing >+ absl::memory >+ absl::meta >+ absl::strings >+ absl::optional >+) >+ >+absl_test( >+ TARGET >+ absl_exception_safety_testing_test >+ SOURCES >+ ${EXCEPTION_SAFETY_TESTING_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES} >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/attributes.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/attributes.h >new file mode 100644 >index 0000000000000000000000000000000000000000..b1883b6d752cc15cd76e079240d0857ce18e8d0a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/attributes.h >@@ -0,0 +1,568 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// This header file defines macros for declaring attributes for functions, >+// types, and variables. >+// >+// These macros are used within Abseil and allow the compiler to optimize, where >+// applicable, certain function calls. >+// >+// This file is used for both C and C++! >+// >+// Most macros here are exposing GCC or Clang features, and are stubbed out for >+// other compilers. >+// >+// GCC attributes documentation: >+// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html >+// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Variable-Attributes.html >+// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Type-Attributes.html >+// >+// Most attributes in this file are already supported by GCC 4.7. However, some >+// of them are not supported in older version of Clang. Thus, we check >+// `__has_attribute()` first. If the check fails, we check if we are on GCC and >+// assume the attribute exists on GCC (which is verified on GCC 4.7). >+// >+// ----------------------------------------------------------------------------- >+// Sanitizer Attributes >+// ----------------------------------------------------------------------------- >+// >+// Sanitizer-related attributes are not "defined" in this file (and indeed >+// are not defined as such in any file). To utilize the following >+// sanitizer-related attributes within your builds, define the following macros >+// within your build using a `-D` flag, along with the given value for >+// `-fsanitize`: >+// >+// * `ADDRESS_SANITIZER` + `-fsanitize=address` (Clang, GCC 4.8) >+// * `MEMORY_SANITIZER` + `-fsanitize=memory` (Clang-only) >+// * `THREAD_SANITIZER + `-fsanitize=thread` (Clang, GCC 4.8+) >+// * `UNDEFINED_BEHAVIOR_SANITIZER` + `-fsanitize=undefined` (Clang, GCC 4.9+) >+// * `CONTROL_FLOW_INTEGRITY` + -fsanitize=cfi (Clang-only) >+// >+// Example: >+// >+// // Enable branches in the Abseil code that are tagged for ASan: >+// $ bazel build --copt=-DADDRESS_SANITIZER --copt=-fsanitize=address >+// --linkopt=-fsanitize=address *target* >+// >+// Since these macro names are only supported by GCC and Clang, we only check >+// for `__GNUC__` (GCC or Clang) and the above macros. >+#ifndef ABSL_BASE_ATTRIBUTES_H_ >+#define ABSL_BASE_ATTRIBUTES_H_ >+ >+// ABSL_HAVE_ATTRIBUTE >+// >+// A function-like feature checking macro that is a wrapper around >+// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a >+// nonzero constant integer if the attribute is supported or 0 if not. >+// >+// It evaluates to zero if `__has_attribute` is not defined by the compiler. >+// >+// GCC: https://gcc.gnu.org/gcc-5/changes.html >+// Clang: https://clang.llvm.org/docs/LanguageExtensions.html >+#ifdef __has_attribute >+#define ABSL_HAVE_ATTRIBUTE(x) __has_attribute(x) >+#else >+#define ABSL_HAVE_ATTRIBUTE(x) 0 >+#endif >+ >+// ABSL_HAVE_CPP_ATTRIBUTE >+// >+// A function-like feature checking macro that accepts C++11 style attributes. >+// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 >+// (http://en.cppreference.com/w/cpp/experimental/feature_test). If we don't >+// find `__has_cpp_attribute`, will evaluate to 0. >+#if defined(__cplusplus) && defined(__has_cpp_attribute) >+// NOTE: requiring __cplusplus above should not be necessary, but >+// works around https://bugs.llvm.org/show_bug.cgi?id=23435. >+#define ABSL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) >+#else >+#define ABSL_HAVE_CPP_ATTRIBUTE(x) 0 >+#endif >+ >+// ----------------------------------------------------------------------------- >+// Function Attributes >+// ----------------------------------------------------------------------------- >+// >+// GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html >+// Clang: https://clang.llvm.org/docs/AttributeReference.html >+ >+// ABSL_PRINTF_ATTRIBUTE >+// ABSL_SCANF_ATTRIBUTE >+// >+// Tells the compiler to perform `printf` format std::string checking if the >+// compiler supports it; see the 'format' attribute in >+// <http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html>. >+// >+// Note: As the GCC manual states, "[s]ince non-static C++ methods >+// have an implicit 'this' argument, the arguments of such methods >+// should be counted from two, not one." >+#if ABSL_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) \ >+ __attribute__((__format__(__printf__, string_index, first_to_check))) >+#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) \ >+ __attribute__((__format__(__scanf__, string_index, first_to_check))) >+#else >+#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) >+#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) >+#endif >+ >+// ABSL_ATTRIBUTE_ALWAYS_INLINE >+// ABSL_ATTRIBUTE_NOINLINE >+// >+// Forces functions to either inline or not inline. Introduced in gcc 3.1. >+#if ABSL_HAVE_ATTRIBUTE(always_inline) || \ >+ (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) >+#define ABSL_HAVE_ATTRIBUTE_ALWAYS_INLINE 1 >+#else >+#define ABSL_ATTRIBUTE_ALWAYS_INLINE >+#endif >+ >+#if ABSL_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_ATTRIBUTE_NOINLINE __attribute__((noinline)) >+#define ABSL_HAVE_ATTRIBUTE_NOINLINE 1 >+#else >+#define ABSL_ATTRIBUTE_NOINLINE >+#endif >+ >+// ABSL_ATTRIBUTE_NO_TAIL_CALL >+// >+// Prevents the compiler from optimizing away stack frames for functions which >+// end in a call to another function. >+#if ABSL_HAVE_ATTRIBUTE(disable_tail_calls) >+#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 >+#define ABSL_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls)) >+#elif defined(__GNUC__) && !defined(__clang__) >+#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 >+#define ABSL_ATTRIBUTE_NO_TAIL_CALL \ >+ __attribute__((optimize("no-optimize-sibling-calls"))) >+#else >+#define ABSL_ATTRIBUTE_NO_TAIL_CALL >+#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 0 >+#endif >+ >+// ABSL_ATTRIBUTE_WEAK >+// >+// Tags a function as weak for the purposes of compilation and linking. >+#if ABSL_HAVE_ATTRIBUTE(weak) || (defined(__GNUC__) && !defined(__clang__)) >+#undef ABSL_ATTRIBUTE_WEAK >+#define ABSL_ATTRIBUTE_WEAK __attribute__((weak)) >+#define ABSL_HAVE_ATTRIBUTE_WEAK 1 >+#else >+#define ABSL_ATTRIBUTE_WEAK >+#define ABSL_HAVE_ATTRIBUTE_WEAK 0 >+#endif >+ >+// ABSL_ATTRIBUTE_NONNULL >+// >+// Tells the compiler either (a) that a particular function parameter >+// should be a non-null pointer, or (b) that all pointer arguments should >+// be non-null. >+// >+// Note: As the GCC manual states, "[s]ince non-static C++ methods >+// have an implicit 'this' argument, the arguments of such methods >+// should be counted from two, not one." >+// >+// Args are indexed starting at 1. >+// >+// For non-static class member functions, the implicit `this` argument >+// is arg 1, and the first explicit argument is arg 2. For static class member >+// functions, there is no implicit `this`, and the first explicit argument is >+// arg 1. >+// >+// Example: >+// >+// /* arg_a cannot be null, but arg_b can */ >+// void Function(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(1); >+// >+// class C { >+// /* arg_a cannot be null, but arg_b can */ >+// void Method(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(2); >+// >+// /* arg_a cannot be null, but arg_b can */ >+// static void StaticMethod(void* arg_a, void* arg_b) >+// ABSL_ATTRIBUTE_NONNULL(1); >+// }; >+// >+// If no arguments are provided, then all pointer arguments should be non-null. >+// >+// /* No pointer arguments may be null. */ >+// void Function(void* arg_a, void* arg_b, int arg_c) ABSL_ATTRIBUTE_NONNULL(); >+// >+// NOTE: The GCC nonnull attribute actually accepts a list of arguments, but >+// ABSL_ATTRIBUTE_NONNULL does not. >+#if ABSL_HAVE_ATTRIBUTE(nonnull) || (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index))) >+#else >+#define ABSL_ATTRIBUTE_NONNULL(...) >+#endif >+ >+// ABSL_ATTRIBUTE_NORETURN >+// >+// Tells the compiler that a given function never returns. >+#if ABSL_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_ATTRIBUTE_NORETURN __attribute__((noreturn)) >+#elif defined(_MSC_VER) >+#define ABSL_ATTRIBUTE_NORETURN __declspec(noreturn) >+#else >+#define ABSL_ATTRIBUTE_NORETURN >+#endif >+ >+// ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS >+// >+// Tells the AddressSanitizer (or other memory testing tools) to ignore a given >+// function. Useful for cases when a function reads random locations on stack, >+// calls _exit from a cloned subprocess, deliberately accesses buffer >+// out of bounds or does other scary things with memory. >+// NOTE: GCC supports AddressSanitizer(asan) since 4.8. >+// https://gcc.gnu.org/gcc-4.8/changes.html >+#if defined(__GNUC__) && defined(ADDRESS_SANITIZER) >+#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) >+#else >+#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS >+#endif >+ >+// ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY >+// >+// Tells the MemorySanitizer to relax the handling of a given function. All >+// "Use of uninitialized value" warnings from such functions will be suppressed, >+// and all values loaded from memory will be considered fully initialized. >+// This attribute is similar to the ADDRESS_SANITIZER attribute above, but deals >+// with initialized-ness rather than addressability issues. >+// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC. >+#if defined(__GNUC__) && defined(MEMORY_SANITIZER) >+#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) >+#else >+#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY >+#endif >+ >+// ABSL_ATTRIBUTE_NO_SANITIZE_THREAD >+// >+// Tells the ThreadSanitizer to not instrument a given function. >+// NOTE: GCC supports ThreadSanitizer(tsan) since 4.8. >+// https://gcc.gnu.org/gcc-4.8/changes.html >+#if defined(__GNUC__) && defined(THREAD_SANITIZER) >+#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) >+#else >+#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD >+#endif >+ >+// ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED >+// >+// Tells the UndefinedSanitizer to ignore a given function. Useful for cases >+// where certain behavior (eg. division by zero) is being used intentionally. >+// NOTE: GCC supports UndefinedBehaviorSanitizer(ubsan) since 4.9. >+// https://gcc.gnu.org/gcc-4.9/changes.html >+#if defined(__GNUC__) && \ >+ (defined(UNDEFINED_BEHAVIOR_SANITIZER) || defined(ADDRESS_SANITIZER)) >+#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ >+ __attribute__((no_sanitize("undefined"))) >+#else >+#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED >+#endif >+ >+// ABSL_ATTRIBUTE_NO_SANITIZE_CFI >+// >+// Tells the ControlFlowIntegrity sanitizer to not instrument a given function. >+// See https://clang.llvm.org/docs/ControlFlowIntegrity.html for details. >+#if defined(__GNUC__) && defined(CONTROL_FLOW_INTEGRITY) >+#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi"))) >+#else >+#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI >+#endif >+ >+// ABSL_ATTRIBUTE_RETURNS_NONNULL >+// >+// Tells the compiler that a particular function never returns a null pointer. >+#if ABSL_HAVE_ATTRIBUTE(returns_nonnull) || \ >+ (defined(__GNUC__) && \ >+ (__GNUC__ > 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) && \ >+ !defined(__clang__)) >+#define ABSL_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) >+#else >+#define ABSL_ATTRIBUTE_RETURNS_NONNULL >+#endif >+ >+// ABSL_HAVE_ATTRIBUTE_SECTION >+// >+// Indicates whether labeled sections are supported. 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__) >+#define ABSL_HAVE_ATTRIBUTE_SECTION 1 >+ >+// ABSL_ATTRIBUTE_SECTION >+// >+// Tells the compiler/linker to put a given function into a section and define >+// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. >+// This functionality is supported by GNU linker. Any function annotated with >+// `ABSL_ATTRIBUTE_SECTION` must not be inlined, or it will be placed into >+// whatever section its caller is placed into. >+// >+#ifndef ABSL_ATTRIBUTE_SECTION >+#define ABSL_ATTRIBUTE_SECTION(name) \ >+ __attribute__((section(#name))) __attribute__((noinline)) >+#endif >+ >+ >+// ABSL_ATTRIBUTE_SECTION_VARIABLE >+// >+// Tells the compiler/linker to put a given variable into a section and define >+// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. >+// This functionality is supported by GNU linker. >+#ifndef ABSL_ATTRIBUTE_SECTION_VARIABLE >+#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name))) >+#endif >+ >+// ABSL_DECLARE_ATTRIBUTE_SECTION_VARS >+// >+// A weak section declaration to be used as a global declaration >+// for ABSL_ATTRIBUTE_SECTION_START|STOP(name) to compile and link >+// even without functions with ABSL_ATTRIBUTE_SECTION(name). >+// ABSL_DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's >+// a no-op on ELF but not on Mach-O. >+// >+#ifndef ABSL_DECLARE_ATTRIBUTE_SECTION_VARS >+#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) \ >+ extern char __start_##name[] ABSL_ATTRIBUTE_WEAK; \ >+ extern char __stop_##name[] ABSL_ATTRIBUTE_WEAK >+#endif >+#ifndef ABSL_DEFINE_ATTRIBUTE_SECTION_VARS >+#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name) >+#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) >+#endif >+ >+// ABSL_ATTRIBUTE_SECTION_START >+// >+// Returns `void*` pointers to start/end of a section of code with >+// functions having ABSL_ATTRIBUTE_SECTION(name). >+// Returns 0 if no such functions exist. >+// One must ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and >+// link. >+// >+#define ABSL_ATTRIBUTE_SECTION_START(name) \ >+ (reinterpret_cast<void *>(__start_##name)) >+#define ABSL_ATTRIBUTE_SECTION_STOP(name) \ >+ (reinterpret_cast<void *>(__stop_##name)) >+ >+#else // !ABSL_HAVE_ATTRIBUTE_SECTION >+ >+#define ABSL_HAVE_ATTRIBUTE_SECTION 0 >+ >+// provide dummy definitions >+#define ABSL_ATTRIBUTE_SECTION(name) >+#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) >+#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name) >+#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) >+#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) >+#define ABSL_ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void *>(0)) >+#define ABSL_ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void *>(0)) >+ >+#endif // ABSL_ATTRIBUTE_SECTION >+ >+// ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC >+// >+// Support for aligning the stack on 32-bit x86. >+#if ABSL_HAVE_ATTRIBUTE(force_align_arg_pointer) || \ >+ (defined(__GNUC__) && !defined(__clang__)) >+#if defined(__i386__) >+#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC \ >+ __attribute__((force_align_arg_pointer)) >+#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) >+#elif defined(__x86_64__) >+#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (1) >+#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC >+#else // !__i386__ && !__x86_64 >+#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) >+#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC >+#endif // __i386__ >+#else >+#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC >+#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) >+#endif >+ >+// 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: >+// >+// Example: >+// >+// ABSL_MUST_USE_RESULT Sprocket* AllocateSprocket(); >+// >+// 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. >+// >+// 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. >+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 >+// >+// Note: past advice was to place the macro after the argument list. >+#if ABSL_HAVE_ATTRIBUTE(nodiscard) >+#define ABSL_MUST_USE_RESULT [[nodiscard]] >+#elif defined(__clang__) && ABSL_HAVE_ATTRIBUTE(warn_unused_result) >+#define ABSL_MUST_USE_RESULT __attribute__((warn_unused_result)) >+#else >+#define ABSL_MUST_USE_RESULT >+#endif >+ >+// ABSL_ATTRIBUTE_HOT, ABSL_ATTRIBUTE_COLD >+// >+// Tells GCC that a function is hot or cold. GCC can use this information to >+// improve static analysis, i.e. a conditional branch to a cold function >+// is likely to be not-taken. >+// This annotation is used for function declarations. >+// >+// Example: >+// >+// int foo() ABSL_ATTRIBUTE_HOT; >+#if ABSL_HAVE_ATTRIBUTE(hot) || (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_ATTRIBUTE_HOT __attribute__((hot)) >+#else >+#define ABSL_ATTRIBUTE_HOT >+#endif >+ >+#if ABSL_HAVE_ATTRIBUTE(cold) || (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_ATTRIBUTE_COLD __attribute__((cold)) >+#else >+#define ABSL_ATTRIBUTE_COLD >+#endif >+ >+// ABSL_XRAY_ALWAYS_INSTRUMENT, ABSL_XRAY_NEVER_INSTRUMENT, ABSL_XRAY_LOG_ARGS >+// >+// We define the ABSL_XRAY_ALWAYS_INSTRUMENT and ABSL_XRAY_NEVER_INSTRUMENT >+// macro used as an attribute to mark functions that must always or never be >+// instrumented by XRay. Currently, this is only supported in Clang/LLVM. >+// >+// For reference on the LLVM XRay instrumentation, see >+// http://llvm.org/docs/XRay.html. >+// >+// A function with the XRAY_ALWAYS_INSTRUMENT macro attribute in its declaration >+// will always get the XRay instrumentation sleds. These sleds may introduce >+// some binary size and runtime overhead and must be used sparingly. >+// >+// These attributes only take effect when the following conditions are met: >+// >+// * The file/target is built in at least C++11 mode, with a Clang compiler >+// that supports XRay attributes. >+// * The file/target is built with the -fxray-instrument flag set for the >+// Clang/LLVM compiler. >+// * The function is defined in the translation unit (the compiler honors the >+// attribute in either the definition or the declaration, and must match). >+// >+// There are cases when, even when building with XRay instrumentation, users >+// might want to control specifically which functions are instrumented for a >+// particular build using special-case lists provided to the compiler. These >+// special case lists are provided to Clang via the >+// -fxray-always-instrument=... and -fxray-never-instrument=... flags. The >+// attributes in source take precedence over these special-case lists. >+// >+// To disable the XRay attributes at build-time, users may define >+// ABSL_NO_XRAY_ATTRIBUTES. Do NOT define ABSL_NO_XRAY_ATTRIBUTES on specific >+// packages/targets, as this may lead to conflicting definitions of functions at >+// link-time. >+// >+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_always_instrument) && \ >+ !defined(ABSL_NO_XRAY_ATTRIBUTES) >+#define ABSL_XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]] >+#define ABSL_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]] >+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_log_args) >+#define ABSL_XRAY_LOG_ARGS(N) \ >+ [[clang::xray_always_instrument, clang::xray_log_args(N)]] >+#else >+#define ABSL_XRAY_LOG_ARGS(N) [[clang::xray_always_instrument]] >+#endif >+#else >+#define ABSL_XRAY_ALWAYS_INSTRUMENT >+#define ABSL_XRAY_NEVER_INSTRUMENT >+#define ABSL_XRAY_LOG_ARGS(N) >+#endif >+ >+// ----------------------------------------------------------------------------- >+// Variable Attributes >+// ----------------------------------------------------------------------------- >+ >+// ABSL_ATTRIBUTE_UNUSED >+// >+// Prevents the compiler from complaining about or optimizing away variables >+// that appear unused. >+#if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) >+#undef ABSL_ATTRIBUTE_UNUSED >+#define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__)) >+#else >+#define ABSL_ATTRIBUTE_UNUSED >+#endif >+ >+// ABSL_ATTRIBUTE_INITIAL_EXEC >+// >+// Tells the compiler to use "initial-exec" mode for a thread-local variable. >+// See http://people.redhat.com/drepper/tls.pdf for the gory details. >+#if ABSL_HAVE_ATTRIBUTE(tls_model) || (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec"))) >+#else >+#define ABSL_ATTRIBUTE_INITIAL_EXEC >+#endif >+ >+// ABSL_ATTRIBUTE_PACKED >+// >+// Prevents the compiler from padding a structure to natural alignment >+#if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) >+#else >+#define ABSL_ATTRIBUTE_PACKED >+#endif >+ >+// ABSL_ATTRIBUTE_FUNC_ALIGN >+// >+// Tells the compiler to align the function start at least to certain >+// alignment boundary >+#if ABSL_HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__((aligned(bytes))) >+#else >+#define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes) >+#endif >+ >+// ABSL_CONST_INIT >+// >+// A variable declaration annotated with the `ABSL_CONST_INIT` attribute will >+// not compile (on supported platforms) unless the variable has a constant >+// initializer. This is useful for variables with static and thread storage >+// duration, because it guarantees that they will not suffer from the so-called >+// "static init order fiasco". Prefer to put this attribute on the most visible >+// declaration of the variable, if there's more than one, because code that >+// accesses the variable can then use the attribute for optimization. >+// >+// Example: >+// >+// class MyClass { >+// public: >+// ABSL_CONST_INIT static MyType my_var; >+// }; >+// >+// MyType MyClass::my_var = MakeMyType(...); >+// >+// Note that this attribute is redundant if the variable is declared constexpr. >+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) >+// NOLINTNEXTLINE(whitespace/braces) >+#define ABSL_CONST_INIT [[clang::require_constant_initialization]] >+#else >+#define ABSL_CONST_INIT >+#endif // ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) >+ >+#endif // ABSL_BASE_ATTRIBUTES_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/bit_cast_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/bit_cast_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..8cd878d756e3d87c2c182f4a2ac22bb0e46f9e26 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/bit_cast_test.cc >@@ -0,0 +1,107 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Unit test for bit_cast template. >+ >+#include <cstdint> >+#include <cstring> >+ >+#include "gtest/gtest.h" >+#include "absl/base/casts.h" >+#include "absl/base/macros.h" >+ >+namespace absl { >+namespace { >+ >+template <int N> >+struct marshall { char buf[N]; }; >+ >+template <typename T> >+void TestMarshall(const T values[], int num_values) { >+ for (int i = 0; i < num_values; ++i) { >+ T t0 = values[i]; >+ marshall<sizeof(T)> m0 = absl::bit_cast<marshall<sizeof(T)> >(t0); >+ T t1 = absl::bit_cast<T>(m0); >+ marshall<sizeof(T)> m1 = absl::bit_cast<marshall<sizeof(T)> >(t1); >+ ASSERT_EQ(0, memcmp(&t0, &t1, sizeof(T))); >+ ASSERT_EQ(0, memcmp(&m0, &m1, sizeof(T))); >+ } >+} >+ >+// Convert back and forth to an integral type. The C++ standard does >+// not guarantee this will work, but we test that this works on all the >+// platforms we support. >+// >+// Likewise, we below make assumptions about sizeof(float) and >+// sizeof(double) which the standard does not guarantee, but which hold on the >+// platforms we support. >+ >+template <typename T, typename I> >+void TestIntegral(const T values[], int num_values) { >+ for (int i = 0; i < num_values; ++i) { >+ T t0 = values[i]; >+ I i0 = absl::bit_cast<I>(t0); >+ T t1 = absl::bit_cast<T>(i0); >+ I i1 = absl::bit_cast<I>(t1); >+ ASSERT_EQ(0, memcmp(&t0, &t1, sizeof(T))); >+ ASSERT_EQ(i0, i1); >+ } >+} >+ >+TEST(BitCast, Bool) { >+ static const bool bool_list[] = { false, true }; >+ TestMarshall<bool>(bool_list, ABSL_ARRAYSIZE(bool_list)); >+} >+ >+TEST(BitCast, Int32) { >+ static const int32_t int_list[] = >+ { 0, 1, 100, 2147483647, -1, -100, -2147483647, -2147483647-1 }; >+ TestMarshall<int32_t>(int_list, ABSL_ARRAYSIZE(int_list)); >+} >+ >+TEST(BitCast, Int64) { >+ static const int64_t int64_list[] = >+ { 0, 1, 1LL << 40, -1, -(1LL<<40) }; >+ TestMarshall<int64_t>(int64_list, ABSL_ARRAYSIZE(int64_list)); >+} >+ >+TEST(BitCast, Uint64) { >+ static const uint64_t uint64_list[] = >+ { 0, 1, 1LLU << 40, 1LLU << 63 }; >+ TestMarshall<uint64_t>(uint64_list, ABSL_ARRAYSIZE(uint64_list)); >+} >+ >+TEST(BitCast, Float) { >+ static const float float_list[] = >+ { 0.0f, 1.0f, -1.0f, 10.0f, -10.0f, >+ 1e10f, 1e20f, 1e-10f, 1e-20f, >+ 2.71828f, 3.14159f }; >+ TestMarshall<float>(float_list, ABSL_ARRAYSIZE(float_list)); >+ TestIntegral<float, int>(float_list, ABSL_ARRAYSIZE(float_list)); >+ TestIntegral<float, unsigned>(float_list, ABSL_ARRAYSIZE(float_list)); >+} >+ >+TEST(BitCast, Double) { >+ static const double double_list[] = >+ { 0.0, 1.0, -1.0, 10.0, -10.0, >+ 1e10, 1e100, 1e-10, 1e-100, >+ 2.718281828459045, >+ 3.141592653589793238462643383279502884197169399375105820974944 }; >+ TestMarshall<double>(double_list, ABSL_ARRAYSIZE(double_list)); >+ TestIntegral<double, int64_t>(double_list, ABSL_ARRAYSIZE(double_list)); >+ TestIntegral<double, uint64_t>(double_list, ABSL_ARRAYSIZE(double_list)); >+} >+ >+} // namespace >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/call_once.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/call_once.h >new file mode 100644 >index 0000000000000000000000000000000000000000..532ee2e38bb5201e8e55cf7d834a64ab4d1bd1cf >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/call_once.h >@@ -0,0 +1,216 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: call_once.h >+// ----------------------------------------------------------------------------- >+// >+// This header file provides an Abseil version of `std::call_once` for invoking >+// a given function at most once, across all threads. This Abseil version is >+// faster than the C++11 version and incorporates the C++17 argument-passing >+// fix, so that (for example) non-const references may be passed to the invoked >+// function. >+ >+#ifndef ABSL_BASE_CALL_ONCE_H_ >+#define ABSL_BASE_CALL_ONCE_H_ >+ >+#include <algorithm> >+#include <atomic> >+#include <cstdint> >+#include <type_traits> >+ >+#include "absl/base/internal/invoke.h" >+#include "absl/base/internal/low_level_scheduling.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/scheduling_mode.h" >+#include "absl/base/internal/spinlock_wait.h" >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+ >+namespace absl { >+ >+class once_flag; >+ >+namespace base_internal { >+std::atomic<uint32_t>* ControlWord(absl::once_flag* flag); >+} // namespace base_internal >+ >+// call_once() >+// >+// For all invocations using a given `once_flag`, invokes a given `fn` exactly >+// once across all threads. The first call to `call_once()` with a particular >+// `once_flag` argument (that does not throw an exception) will run the >+// specified function with the provided `args`; other calls with the same >+// `once_flag` argument will not run the function, but will wait >+// for the provided function to finish running (if it is still running). >+// >+// This mechanism provides a safe, simple, and fast mechanism for one-time >+// initialization in a multi-threaded process. >+// >+// Example: >+// >+// class MyInitClass { >+// public: >+// ... >+// mutable absl::once_flag once_; >+// >+// MyInitClass* init() const { >+// absl::call_once(once_, &MyInitClass::Init, this); >+// return ptr_; >+// } >+// >+template <typename Callable, typename... Args> >+void call_once(absl::once_flag& flag, Callable&& fn, Args&&... args); >+ >+// once_flag >+// >+// Objects of this type are used to distinguish calls to `call_once()` and >+// ensure the provided function is only invoked once across all threads. This >+// type is not copyable or movable. However, it has a `constexpr` >+// constructor, and is safe to use as a namespace-scoped global variable. >+class once_flag { >+ public: >+ constexpr once_flag() : control_(0) {} >+ once_flag(const once_flag&) = delete; >+ once_flag& operator=(const once_flag&) = delete; >+ >+ private: >+ friend std::atomic<uint32_t>* base_internal::ControlWord(once_flag* flag); >+ std::atomic<uint32_t> control_; >+}; >+ >+//------------------------------------------------------------------------------ >+// End of public interfaces. >+// Implementation details follow. >+//------------------------------------------------------------------------------ >+ >+namespace base_internal { >+ >+// Like call_once, but uses KERNEL_ONLY scheduling. Intended to be used to >+// initialize entities used by the scheduler implementation. >+template <typename Callable, typename... Args> >+void LowLevelCallOnce(absl::once_flag* flag, Callable&& fn, Args&&... args); >+ >+// Disables scheduling while on stack when scheduling mode is non-cooperative. >+// No effect for cooperative scheduling modes. >+class SchedulingHelper { >+ public: >+ explicit SchedulingHelper(base_internal::SchedulingMode mode) : mode_(mode) { >+ if (mode_ == base_internal::SCHEDULE_KERNEL_ONLY) { >+ guard_result_ = base_internal::SchedulingGuard::DisableRescheduling(); >+ } >+ } >+ >+ ~SchedulingHelper() { >+ if (mode_ == base_internal::SCHEDULE_KERNEL_ONLY) { >+ base_internal::SchedulingGuard::EnableRescheduling(guard_result_); >+ } >+ } >+ >+ private: >+ base_internal::SchedulingMode mode_; >+ bool guard_result_; >+}; >+ >+// Bit patterns for call_once state machine values. Internal implementation >+// detail, not for use by clients. >+// >+// The bit patterns are arbitrarily chosen from unlikely values, to aid in >+// debugging. However, kOnceInit must be 0, so that a zero-initialized >+// once_flag will be valid for immediate use. >+enum { >+ kOnceInit = 0, >+ kOnceRunning = 0x65C2937B, >+ kOnceWaiter = 0x05A308D2, >+ // A very small constant is chosen for kOnceDone so that it fit in a single >+ // compare with immediate instruction for most common ISAs. This is verified >+ // for x86, POWER and ARM. >+ kOnceDone = 221, // Random Number >+}; >+ >+template <typename Callable, typename... Args> >+void CallOnceImpl(std::atomic<uint32_t>* control, >+ base_internal::SchedulingMode scheduling_mode, Callable&& fn, >+ Args&&... args) { >+#ifndef NDEBUG >+ { >+ uint32_t old_control = control->load(std::memory_order_acquire); >+ if (old_control != kOnceInit && >+ old_control != kOnceRunning && >+ old_control != kOnceWaiter && >+ old_control != kOnceDone) { >+ ABSL_RAW_LOG( >+ FATAL, >+ "Unexpected value for control word: %lx. Either the control word " >+ "has non-static storage duration (where GoogleOnceDynamic might " >+ "be appropriate), or there's been a memory corruption.", >+ static_cast<unsigned long>(old_control)); // NOLINT >+ } >+ } >+#endif // NDEBUG >+ static const base_internal::SpinLockWaitTransition trans[] = { >+ {kOnceInit, kOnceRunning, true}, >+ {kOnceRunning, kOnceWaiter, false}, >+ {kOnceDone, kOnceDone, true}}; >+ >+ // Must do this before potentially modifying control word's state. >+ base_internal::SchedulingHelper maybe_disable_scheduling(scheduling_mode); >+ // Short circuit the simplest case to avoid procedure call overhead. >+ uint32_t old_control = kOnceInit; >+ if (control->compare_exchange_strong(old_control, kOnceRunning, >+ std::memory_order_acquire, >+ std::memory_order_relaxed) || >+ base_internal::SpinLockWait(control, ABSL_ARRAYSIZE(trans), trans, >+ scheduling_mode) == kOnceInit) { >+ base_internal::Invoke(std::forward<Callable>(fn), >+ std::forward<Args>(args)...); >+ old_control = control->load(std::memory_order_relaxed); >+ control->store(base_internal::kOnceDone, std::memory_order_release); >+ if (old_control == base_internal::kOnceWaiter) { >+ base_internal::SpinLockWake(control, true); >+ } >+ } // else *control is already kOnceDone >+} >+ >+inline std::atomic<uint32_t>* ControlWord(once_flag* flag) { >+ return &flag->control_; >+} >+ >+template <typename Callable, typename... Args> >+void LowLevelCallOnce(absl::once_flag* flag, Callable&& fn, Args&&... args) { >+ std::atomic<uint32_t>* once = base_internal::ControlWord(flag); >+ uint32_t s = once->load(std::memory_order_acquire); >+ if (ABSL_PREDICT_FALSE(s != base_internal::kOnceDone)) { >+ base_internal::CallOnceImpl(once, base_internal::SCHEDULE_KERNEL_ONLY, >+ std::forward<Callable>(fn), >+ std::forward<Args>(args)...); >+ } >+} >+ >+} // namespace base_internal >+ >+template <typename Callable, typename... Args> >+void call_once(absl::once_flag& flag, Callable&& fn, Args&&... args) { >+ std::atomic<uint32_t>* once = base_internal::ControlWord(&flag); >+ uint32_t s = once->load(std::memory_order_acquire); >+ if (ABSL_PREDICT_FALSE(s != base_internal::kOnceDone)) { >+ base_internal::CallOnceImpl( >+ once, base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL, >+ std::forward<Callable>(fn), std::forward<Args>(args)...); >+ } >+} >+ >+} // namespace absl >+ >+#endif // ABSL_BASE_CALL_ONCE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/call_once_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/call_once_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..cd58ee19f08e6c51a2b5867fda8521bda8cbe306 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/call_once_test.cc >@@ -0,0 +1,102 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/call_once.h" >+ >+#include <thread> >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/base/thread_annotations.h" >+#include "absl/synchronization/mutex.h" >+ >+namespace absl { >+namespace { >+ >+absl::once_flag once; >+Mutex counters_mu; >+ >+int running_thread_count GUARDED_BY(counters_mu) = 0; >+int call_once_invoke_count GUARDED_BY(counters_mu) = 0; >+int call_once_finished_count GUARDED_BY(counters_mu) = 0; >+int call_once_return_count GUARDED_BY(counters_mu) = 0; >+bool done_blocking GUARDED_BY(counters_mu) = false; >+ >+// Function to be called from absl::call_once. Waits for a notification. >+void WaitAndIncrement() { >+ counters_mu.Lock(); >+ ++call_once_invoke_count; >+ counters_mu.Unlock(); >+ >+ counters_mu.LockWhen(Condition(&done_blocking)); >+ ++call_once_finished_count; >+ counters_mu.Unlock(); >+} >+ >+void ThreadBody() { >+ counters_mu.Lock(); >+ ++running_thread_count; >+ counters_mu.Unlock(); >+ >+ absl::call_once(once, WaitAndIncrement); >+ >+ counters_mu.Lock(); >+ ++call_once_return_count; >+ counters_mu.Unlock(); >+} >+ >+// Returns true if all threads are set up for the test. >+bool ThreadsAreSetup(void*) EXCLUSIVE_LOCKS_REQUIRED(counters_mu) { >+ // All ten threads must be running, and WaitAndIncrement should be blocked. >+ return running_thread_count == 10 && call_once_invoke_count == 1; >+} >+ >+TEST(CallOnceTest, ExecutionCount) { >+ std::vector<std::thread> threads; >+ >+ // Start 10 threads all calling call_once on the same once_flag. >+ for (int i = 0; i < 10; ++i) { >+ threads.emplace_back(ThreadBody); >+ } >+ >+ >+ // Wait until all ten threads have started, and WaitAndIncrement has been >+ // invoked. >+ counters_mu.LockWhen(Condition(ThreadsAreSetup, nullptr)); >+ >+ // WaitAndIncrement should have been invoked by exactly one call_once() >+ // instance. That thread should be blocking on a notification, and all other >+ // call_once instances should be blocking as well. >+ EXPECT_EQ(call_once_invoke_count, 1); >+ EXPECT_EQ(call_once_finished_count, 0); >+ EXPECT_EQ(call_once_return_count, 0); >+ >+ // Allow WaitAndIncrement to finish executing. Once it does, the other >+ // call_once waiters will be unblocked. >+ done_blocking = true; >+ counters_mu.Unlock(); >+ >+ for (std::thread& thread : threads) { >+ thread.join(); >+ } >+ >+ counters_mu.Lock(); >+ EXPECT_EQ(call_once_invoke_count, 1); >+ EXPECT_EQ(call_once_finished_count, 1); >+ EXPECT_EQ(call_once_return_count, 10); >+ counters_mu.Unlock(); >+} >+ >+} // namespace >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/casts.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/casts.h >new file mode 100644 >index 0000000000000000000000000000000000000000..20fd34da70105d6fc7df55988c89b6ece4b7e33e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/casts.h >@@ -0,0 +1,189 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: casts.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines casting templates to fit use cases not covered by >+// the standard casts provided in the C++ standard. As with all cast operations, >+// use these with caution and only if alternatives do not exist. >+ >+#ifndef ABSL_BASE_CASTS_H_ >+#define ABSL_BASE_CASTS_H_ >+ >+#include <cstring> >+#include <memory> >+#include <type_traits> >+ >+#include "absl/base/internal/identity.h" >+#include "absl/base/macros.h" >+ >+namespace absl { >+ >+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 <class T> >+struct is_trivially_copyable >+ : std::integral_constant< >+ bool, std::is_destructible<T>::value&& __has_trivial_destructor(T) && >+ __has_trivial_copy(T) && __has_trivial_assign(T)> {}; >+ >+template <class Dest, class Source> >+struct is_bitcastable >+ : std::integral_constant<bool, >+ sizeof(Dest) == sizeof(Source) && >+ is_trivially_copyable<Source>::value && >+ is_trivially_copyable<Dest>::value && >+ std::is_default_constructible<Dest>::value> {}; >+ >+} // namespace internal_casts >+ >+// implicit_cast() >+// >+// Performs an implicit conversion between types following the language >+// rules for implicit conversion; if an implicit conversion is otherwise >+// allowed by the language in the given context, this function performs such an >+// implicit conversion. >+// >+// Example: >+// >+// // If the context allows implicit conversion: >+// From from; >+// To to = from; >+// >+// // Such code can be replaced by: >+// implicit_cast<To>(from); >+// >+// An `implicit_cast()` may also be used to annotate numeric type conversions >+// that, although safe, may produce compiler warnings (such as `long` to `int`). >+// Additionally, an `implicit_cast()` is also useful within return statements to >+// indicate a specific implicit conversion is being undertaken. >+// >+// Example: >+// >+// return implicit_cast<double>(size_in_bytes) / capacity_; >+// >+// Annotating code with `implicit_cast()` allows you to explicitly select >+// particular overloads and template instantiations, while providing a safer >+// cast than `reinterpret_cast()` or `static_cast()`. >+// >+// Additionally, an `implicit_cast()` can be used to allow upcasting within a >+// type hierarchy where incorrect use of `static_cast()` could accidentally >+// allow downcasting. >+// >+// Finally, an `implicit_cast()` can be used to perform implicit conversions >+// from unrelated types that otherwise couldn't be implicitly cast directly; >+// C++ will normally only implicitly cast "one step" in such conversions. >+// >+// That is, if C is a type which can be implicitly converted to B, with B being >+// a type that can be implicitly converted to A, an `implicit_cast()` can be >+// used to convert C to B (which the compiler can then implicitly convert to A >+// using language rules). >+// >+// Example: >+// >+// // Assume an object C is convertible to B, which is implicitly convertible >+// // to A >+// A a = implicit_cast<B>(C); >+// >+// Such implicit cast chaining may be useful within template logic. >+template <typename To> >+inline To implicit_cast(typename absl::internal::identity_t<To> to) { >+ return to; >+} >+ >+// bit_cast() >+// >+// Performs a bitwise cast on a type without changing the underlying bit >+// representation of that type's value. The two types must be of the same size >+// and both types must be trivially copyable. As with most casts, use with >+// caution. A `bit_cast()` might be needed when you need to temporarily treat a >+// type as some other type, such as in the following cases: >+// >+// * Serialization (casting temporarily to `char *` for those purposes is >+// always allowed by the C++ standard) >+// * Managing the individual bits of a type within mathematical operations >+// that are not normally accessible through that type >+// * Casting non-pointer types to pointer types (casting the other way is >+// allowed by `reinterpret_cast()` but round-trips cannot occur the other >+// way). >+// >+// Example: >+// >+// float f = 3.14159265358979; >+// int i = bit_cast<int32_t>(f); >+// // i = 0x40490fdb >+// >+// Casting non-pointer types to pointer types and then dereferencing them >+// traditionally produces undefined behavior. >+// >+// Example: >+// >+// // WRONG >+// float f = 3.14159265358979; // WRONG >+// int i = * reinterpret_cast<int*>(&f); // WRONG >+// >+// The address-casting method produces undefined behavior according to the ISO >+// C++ specification section [basic.lval]. Roughly, this section says: if an >+// object in memory has one type, and a program accesses it with a different >+// type, the result is undefined behavior for most values of "different type". >+// >+// Such casting results in type punning: holding an object in memory of one type >+// 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. >+// >+// 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<internal_casts::is_bitcastable<Dest, Source>::value, >+ int>::type = 0> >+inline Dest bit_cast(const Source& source) { >+ Dest dest; >+ memcpy(static_cast<void*>(std::addressof(dest)), >+ static_cast<const void*>(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<Dest, Source>::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."); >+ >+ Dest dest; >+ memcpy(&dest, &source, sizeof(dest)); >+ return dest; >+} >+ >+} // namespace absl >+ >+#endif // ABSL_BASE_CASTS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/config.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/config.h >new file mode 100644 >index 0000000000000000000000000000000000000000..6890e313bf27af7e5e8a5c051325013e27215a0e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/config.h >@@ -0,0 +1,427 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: config.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines a set of macros for checking the presence of >+// important compiler and platform features. Such macros can be used to >+// produce portable code by parameterizing compilation based on the presence or >+// lack of a given feature. >+// >+// We define a "feature" as some interface we wish to program to: for example, >+// a library function or system call. A value of `1` indicates support for >+// that feature; any other value indicates the feature support is undefined. >+// >+// Example: >+// >+// Suppose a programmer wants to write a program that uses the 'mmap()' system >+// call. The Abseil macro for that feature (`ABSL_HAVE_MMAP`) allows you to >+// selectively include the `mmap.h` header and bracket code using that feature >+// in the macro: >+// >+// #include "absl/base/config.h" >+// >+// #ifdef ABSL_HAVE_MMAP >+// #include "sys/mman.h" >+// #endif //ABSL_HAVE_MMAP >+// >+// ... >+// #ifdef ABSL_HAVE_MMAP >+// void *ptr = mmap(...); >+// ... >+// #endif // ABSL_HAVE_MMAP >+ >+#ifndef ABSL_BASE_CONFIG_H_ >+#define ABSL_BASE_CONFIG_H_ >+ >+// Included for the __GLIBC__ macro (or similar macros on other systems). >+#include <limits.h> >+ >+#ifdef __cplusplus >+// Included for __GLIBCXX__, _LIBCPP_VERSION >+#include <cstddef> >+#endif // __cplusplus >+ >+#if defined(__APPLE__) >+// Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED, >+// __IPHONE_8_0. >+#include <Availability.h> >+#include <TargetConditionals.h> >+#endif >+ >+#include "absl/base/policy_checks.h" >+ >+// ----------------------------------------------------------------------------- >+// Compiler Feature Checks >+// ----------------------------------------------------------------------------- >+ >+// ABSL_HAVE_BUILTIN() >+// >+// Checks whether the compiler supports a Clang Feature Checking Macro, and if >+// so, checks whether it supports the provided builtin function "x" where x >+// is one of the functions noted in >+// https://clang.llvm.org/docs/LanguageExtensions.html >+// >+// Note: Use this macro to avoid an extra level of #ifdef __has_builtin check. >+// http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html >+#ifdef __has_builtin >+#define ABSL_HAVE_BUILTIN(x) __has_builtin(x) >+#else >+#define ABSL_HAVE_BUILTIN(x) 0 >+#endif >+ >+// ABSL_HAVE_TLS is defined to 1 when __thread should be supported. >+// We assume __thread is supported on Linux when compiled with Clang or compiled >+// against libstdc++ with _GLIBCXX_HAVE_TLS defined. >+#ifdef ABSL_HAVE_TLS >+#error ABSL_HAVE_TLS cannot be directly set >+#elif defined(__linux__) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS)) >+#define ABSL_HAVE_TLS 1 >+#endif >+ >+// ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE >+// >+// Checks whether `std::is_trivially_destructible<T>` is supported. >+// >+// Notes: All supported compilers using libc++ support this feature, as does >+// gcc >= 4.8.1 using libstdc++, and Visual Studio. >+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE >+#error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set >+#elif defined(_LIBCPP_VERSION) || \ >+ (!defined(__clang__) && defined(__GNUC__) && defined(__GLIBCXX__) && \ >+ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \ >+ defined(_MSC_VER) >+#define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1 >+#endif >+ >+// ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE >+// >+// Checks whether `std::is_trivially_default_constructible<T>` and >+// `std::is_trivially_copy_constructible<T>` are supported. >+ >+// ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE >+// >+// Checks whether `std::is_trivially_copy_assignable<T>` is supported. >+ >+// Notes: Clang with libc++ supports these features, as does gcc >= 5.1 with >+// either libc++ or libstdc++, and Visual Studio. >+#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) >+#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set >+#elif defined(ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE) >+#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set >+#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ >+ (!defined(__clang__) && defined(__GNUC__) && \ >+ (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)) && \ >+ (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \ >+ defined(_MSC_VER) >+#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 >+#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 >+#endif >+ >+// ABSL_HAVE_THREAD_LOCAL >+// >+// Checks whether C++11's `thread_local` storage duration specifier is >+// supported. >+#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 >+// `defined(__APPLE__)` check. >+#if __has_feature(cxx_thread_local) >+#define ABSL_HAVE_THREAD_LOCAL 1 >+#endif >+#else // !defined(__APPLE__) >+#define ABSL_HAVE_THREAD_LOCAL 1 >+#endif >+ >+// There are platforms for which TLS should not be used even though the compiler >+// makes it seem like it's supported (Android NDK < r12b for example). >+// This is primarily because of linker problems and toolchain misconfiguration: >+// Abseil does not intend to support this indefinitely. Currently, the newest >+// toolchain that we intend to support that requires this behavior is the >+// r11 NDK - allowing for a 5 year support window on that means this option >+// is likely to be removed around June of 2021. >+// TLS isn't supported until NDK r12b per >+// https://developer.android.com/ndk/downloads/revision_history.html >+// Since NDK r16, `__NDK_MAJOR__` and `__NDK_MINOR__` are defined in >+// <android/ndk-version.h>. For NDK < r16, users should define these macros, >+// e.g. `-D__NDK_MAJOR__=11 -D__NKD_MINOR__=0` for NDK r11. >+#if defined(__ANDROID__) && defined(__clang__) >+#if __has_include(<android/ndk-version.h>) >+#include <android/ndk-version.h> >+#endif // __has_include(<android/ndk-version.h>) >+#if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \ >+ defined(__NDK_MINOR__) && \ >+ ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1))) >+#undef ABSL_HAVE_TLS >+#undef ABSL_HAVE_THREAD_LOCAL >+#endif >+#endif // defined(__ANDROID__) && defined(__clang__) >+ >+// ABSL_HAVE_INTRINSIC_INT128 >+// >+// Checks whether the __int128 compiler extension for a 128-bit integral type is >+// supported. >+// >+// Note: __SIZEOF_INT128__ is defined by Clang and GCC when __int128 is >+// supported, but we avoid using it in certain cases: >+// * On Clang: >+// * Building using Clang for Windows, where the Clang runtime library has >+// 128-bit support only on LP64 architectures, but Windows is LLP64. >+// * Building for aarch64, where __int128 exists but has exhibits a sporadic >+// compiler crashing bug. >+// * On Nvidia's nvcc: >+// * nvcc also defines __GNUC__ and __SIZEOF_INT128__, but not all versions >+// actually support __int128. >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+#error ABSL_HAVE_INTRINSIC_INT128 cannot be directly set >+#elif defined(__SIZEOF_INT128__) >+#if (defined(__clang__) && !defined(_WIN32) && !defined(__aarch64__)) || \ >+ (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \ >+ (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__)) >+#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 >+// 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 >+#define ABSL_HAVE_INTRINSIC_INT128 1 >+#endif // __CUDACC_VER__ >= 70000 >+#endif // defined(__CUDACC__) >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ >+// ABSL_HAVE_EXCEPTIONS >+// >+// Checks whether the compiler both supports and enables exceptions. Many >+// compilers support a "no exceptions" mode that disables exceptions. >+// >+// Generally, when ABSL_HAVE_EXCEPTIONS is not defined: >+// >+// * Code using `throw` and `try` may not compile. >+// * The `noexcept` specifier will still compile and behave as normal. >+// * The `noexcept` operator may still return `false`. >+// >+// For further details, consult the compiler's documentation. >+#ifdef ABSL_HAVE_EXCEPTIONS >+#error ABSL_HAVE_EXCEPTIONS cannot be directly set. >+ >+#elif defined(__clang__) >+// TODO(calabrese) >+// Switch to using __cpp_exceptions when we no longer support versions < 3.6. >+// For details on this check, see: >+// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro >+#if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) >+#define ABSL_HAVE_EXCEPTIONS 1 >+#endif // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) >+ >+// Handle remaining special cases and default to exceptions being supported. >+#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ >+ !(defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__cpp_exceptions)) && \ >+ !(defined(_MSC_VER) && !defined(_CPPUNWIND)) >+#define ABSL_HAVE_EXCEPTIONS 1 >+#endif >+ >+// ----------------------------------------------------------------------------- >+// Platform Feature Checks >+// ----------------------------------------------------------------------------- >+ >+// Currently supported operating systems and associated preprocessor >+// symbols: >+// >+// Linux and Linux-derived __linux__ >+// Android __ANDROID__ (implies __linux__) >+// Linux (non-Android) __linux__ && !__ANDROID__ >+// Darwin (Mac OS X and iOS) __APPLE__ >+// Akaros (http://akaros.org) __ros__ >+// Windows _WIN32 >+// NaCL __native_client__ >+// AsmJS __asmjs__ >+// WebAssembly __wasm__ >+// Fuchsia __Fuchsia__ >+// >+// Note that since Android defines both __ANDROID__ and __linux__, one >+// may probe for either Linux or Android by simply testing for __linux__. >+ >+// ABSL_HAVE_MMAP >+// >+// Checks whether the platform has an mmap(2) implementation as defined in >+// POSIX.1-2001. >+#ifdef ABSL_HAVE_MMAP >+#error ABSL_HAVE_MMAP cannot be directly set >+#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ >+ defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \ >+ defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) >+#define ABSL_HAVE_MMAP 1 >+#endif >+ >+// ABSL_HAVE_PTHREAD_GETSCHEDPARAM >+// >+// Checks whether the platform implements the pthread_(get|set)schedparam(3) >+// functions as defined in POSIX.1-2001. >+#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM >+#error ABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set >+#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ >+ defined(__ros__) >+#define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1 >+#endif >+ >+// ABSL_HAVE_SCHED_YIELD >+// >+// Checks whether the platform implements sched_yield(2) as defined in >+// POSIX.1-2001. >+#ifdef ABSL_HAVE_SCHED_YIELD >+#error ABSL_HAVE_SCHED_YIELD cannot be directly set >+#elif defined(__linux__) || defined(__ros__) || defined(__native_client__) >+#define ABSL_HAVE_SCHED_YIELD 1 >+#endif >+ >+// ABSL_HAVE_SEMAPHORE_H >+// >+// Checks whether the platform supports the <semaphore.h> header and sem_open(3) >+// family of functions as standardized in POSIX.1-2001. >+// >+// Note: While Apple provides <semaphore.h> for both iOS and macOS, it is >+// explicitly deprecated and will cause build failures if enabled for those >+// platforms. We side-step the issue by not defining it here for Apple >+// platforms. >+#ifdef ABSL_HAVE_SEMAPHORE_H >+#error ABSL_HAVE_SEMAPHORE_H cannot be directly set >+#elif defined(__linux__) || defined(__ros__) >+#define ABSL_HAVE_SEMAPHORE_H 1 >+#endif >+ >+// ABSL_HAVE_ALARM >+// >+// Checks whether the platform supports the <signal.h> header and alarm(2) >+// function as standardized in POSIX.1-2001. >+#ifdef ABSL_HAVE_ALARM >+#error ABSL_HAVE_ALARM cannot be directly set >+#elif defined(__GOOGLE_GRTE_VERSION__) >+// feature tests for Google's GRTE >+#define ABSL_HAVE_ALARM 1 >+#elif defined(__GLIBC__) >+// feature test for glibc >+#define ABSL_HAVE_ALARM 1 >+#elif defined(_MSC_VER) >+// feature tests for Microsoft's library >+#elif defined(__native_client__) >+#else >+// other standard libraries >+#define ABSL_HAVE_ALARM 1 >+#endif >+ >+// ABSL_IS_LITTLE_ENDIAN >+// ABSL_IS_BIG_ENDIAN >+// >+// Checks the endianness of the platform. >+// >+// Notes: uses the built in endian macros provided by GCC (since 4.6) and >+// Clang (since 3.2); see >+// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html. >+// Otherwise, if _WIN32, assume little endian. Otherwise, bail with an error. >+#if defined(ABSL_IS_BIG_ENDIAN) >+#error "ABSL_IS_BIG_ENDIAN cannot be directly set." >+#endif >+#if defined(ABSL_IS_LITTLE_ENDIAN) >+#error "ABSL_IS_LITTLE_ENDIAN cannot be directly set." >+#endif >+ >+#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ >+ __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) >+#define ABSL_IS_LITTLE_ENDIAN 1 >+#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ >+ __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ >+#define ABSL_IS_BIG_ENDIAN 1 >+#elif defined(_WIN32) >+#define ABSL_IS_LITTLE_ENDIAN 1 >+#else >+#error "absl endian detection needs to be set up for your compiler" >+#endif >+ >+// ABSL_HAVE_STD_ANY >+// >+// Checks whether C++17 std::any is available by checking whether <any> exists. >+#ifdef ABSL_HAVE_STD_ANY >+#error "ABSL_HAVE_STD_ANY cannot be directly set." >+#endif >+ >+#ifdef __has_include >+#if __has_include(<any>) && __cplusplus >= 201703L >+#define ABSL_HAVE_STD_ANY 1 >+#endif >+#endif >+ >+// ABSL_HAVE_STD_OPTIONAL >+// >+// Checks whether C++17 std::optional is available. >+#ifdef ABSL_HAVE_STD_OPTIONAL >+#error "ABSL_HAVE_STD_OPTIONAL cannot be directly set." >+#endif >+ >+#ifdef __has_include >+#if __has_include(<optional>) && __cplusplus >= 201703L >+#define ABSL_HAVE_STD_OPTIONAL 1 >+#endif >+#endif >+ >+// ABSL_HAVE_STD_VARIANT >+// >+// Checks whether C++17 std::variant is available. >+#ifdef ABSL_HAVE_STD_VARIANT >+#error "ABSL_HAVE_STD_VARIANT cannot be directly set." >+#endif >+ >+#ifdef __has_include >+#if __has_include(<variant>) && __cplusplus >= 201703L >+#define ABSL_HAVE_STD_VARIANT 1 >+#endif >+#endif >+ >+// ABSL_HAVE_STD_STRING_VIEW >+// >+// Checks whether C++17 std::string_view is available. >+#ifdef ABSL_HAVE_STD_STRING_VIEW >+#error "ABSL_HAVE_STD_STRING_VIEW cannot be directly set." >+#endif >+ >+#ifdef __has_include >+#if __has_include(<string_view>) && __cplusplus >= 201703L >+#define ABSL_HAVE_STD_STRING_VIEW 1 >+#endif >+#endif >+ >+// For MSVC, `__has_include` is supported in VS 2017 15.3, which is later than >+// the support for <optional>, <any>, <string_view>, <variant>. So we use >+// _MSC_VER to check whether we have VS 2017 RTM (when <optional>, <any>, >+// <string_view>, <variant> 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`. >+#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 >+#endif >+ >+#endif // ABSL_BASE_CONFIG_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/config_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/config_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..c839712a537e4169ca0165ff9f9d30b17e821e28 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/config_test.cc >@@ -0,0 +1,60 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/config.h" >+ >+#include <cstdint> >+ >+#include "gtest/gtest.h" >+#include "absl/synchronization/internal/thread_pool.h" >+ >+namespace { >+ >+TEST(ConfigTest, Endianness) { >+ union { >+ uint32_t value; >+ uint8_t data[sizeof(uint32_t)]; >+ } number; >+ number.data[0] = 0x00; >+ number.data[1] = 0x01; >+ number.data[2] = 0x02; >+ number.data[3] = 0x03; >+#if defined(ABSL_IS_LITTLE_ENDIAN) && defined(ABSL_IS_BIG_ENDIAN) >+#error Both ABSL_IS_LITTLE_ENDIAN and ABSL_IS_BIG_ENDIAN are defined >+#elif defined(ABSL_IS_LITTLE_ENDIAN) >+ EXPECT_EQ(UINT32_C(0x03020100), number.value); >+#elif defined(ABSL_IS_BIG_ENDIAN) >+ EXPECT_EQ(UINT32_C(0x00010203), number.value); >+#else >+#error Unknown endianness >+#endif >+} >+ >+#if defined(ABSL_HAVE_THREAD_LOCAL) >+TEST(ConfigTest, ThreadLocal) { >+ static thread_local int mine_mine_mine = 16; >+ EXPECT_EQ(16, mine_mine_mine); >+ { >+ absl::synchronization_internal::ThreadPool pool(1); >+ pool.Schedule([&] { >+ EXPECT_EQ(16, mine_mine_mine); >+ mine_mine_mine = 32; >+ EXPECT_EQ(32, mine_mine_mine); >+ }); >+ } >+ EXPECT_EQ(16, mine_mine_mine); >+} >+#endif >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/dynamic_annotations.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/dynamic_annotations.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..b97fa3a8b4a9bc8e67ed3726d45241bde5da12eb >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/dynamic_annotations.cc >@@ -0,0 +1,129 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <stdlib.h> >+#include <string.h> >+ >+#include "absl/base/dynamic_annotations.h" >+ >+#ifndef __has_feature >+#define __has_feature(x) 0 >+#endif >+ >+/* Compiler-based ThreadSanitizer defines >+ ABSL_DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL = 1 >+ and provides its own definitions of the functions. */ >+ >+#ifndef ABSL_DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL >+# define ABSL_DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL 0 >+#endif >+ >+/* Each function is empty and called (via a macro) only in debug mode. >+ The arguments are captured by dynamic tools at runtime. */ >+ >+#if ABSL_DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 && !defined(__native_client__) >+ >+#if __has_feature(memory_sanitizer) >+#include <sanitizer/msan_interface.h> >+#endif >+ >+#ifdef __cplusplus >+extern "C" { >+#endif >+ >+void AbslAnnotateRWLockCreate(const char *, int, >+ const volatile void *){} >+void AbslAnnotateRWLockDestroy(const char *, int, >+ const volatile void *){} >+void AbslAnnotateRWLockAcquired(const char *, int, >+ const volatile void *, long){} >+void AbslAnnotateRWLockReleased(const char *, int, >+ const volatile void *, long){} >+void AbslAnnotateBenignRace(const char *, int, >+ const volatile void *, >+ const char *){} >+void AbslAnnotateBenignRaceSized(const char *, int, >+ const volatile void *, >+ size_t, >+ const char *) {} >+void AbslAnnotateThreadName(const char *, int, >+ const char *){} >+void AbslAnnotateIgnoreReadsBegin(const char *, int){} >+void AbslAnnotateIgnoreReadsEnd(const char *, int){} >+void AbslAnnotateIgnoreWritesBegin(const char *, int){} >+void AbslAnnotateIgnoreWritesEnd(const char *, int){} >+void AbslAnnotateEnableRaceDetection(const char *, int, int){} >+void AbslAnnotateMemoryIsInitialized(const char *, int, >+ const volatile void *mem, size_t size) { >+#if __has_feature(memory_sanitizer) >+ __msan_unpoison(mem, size); >+#else >+ (void)mem; >+ (void)size; >+#endif >+} >+ >+void AbslAnnotateMemoryIsUninitialized(const char *, int, >+ const volatile void *mem, size_t size) { >+#if __has_feature(memory_sanitizer) >+ __msan_allocated_memory(mem, size); >+#else >+ (void)mem; >+ (void)size; >+#endif >+} >+ >+static int AbslGetRunningOnValgrind(void) { >+#ifdef RUNNING_ON_VALGRIND >+ if (RUNNING_ON_VALGRIND) return 1; >+#endif >+ char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND"); >+ if (running_on_valgrind_str) { >+ return strcmp(running_on_valgrind_str, "0") != 0; >+ } >+ return 0; >+} >+ >+/* See the comments in dynamic_annotations.h */ >+int AbslRunningOnValgrind(void) { >+ static volatile int running_on_valgrind = -1; >+ int local_running_on_valgrind = running_on_valgrind; >+ /* C doesn't have thread-safe initialization of statics, and we >+ don't want to depend on pthread_once here, so hack it. */ >+ ABSL_ANNOTATE_BENIGN_RACE(&running_on_valgrind, "safe hack"); >+ if (local_running_on_valgrind == -1) >+ running_on_valgrind = local_running_on_valgrind = AbslGetRunningOnValgrind(); >+ return local_running_on_valgrind; >+} >+ >+/* See the comments in dynamic_annotations.h */ >+double AbslValgrindSlowdown(void) { >+ /* Same initialization hack as in AbslRunningOnValgrind(). */ >+ static volatile double slowdown = 0.0; >+ double local_slowdown = slowdown; >+ ABSL_ANNOTATE_BENIGN_RACE(&slowdown, "safe hack"); >+ if (AbslRunningOnValgrind() == 0) { >+ return 1.0; >+ } >+ if (local_slowdown == 0.0) { >+ char *env = getenv("VALGRIND_SLOWDOWN"); >+ slowdown = local_slowdown = env ? atof(env) : 50.0; >+ } >+ return local_slowdown; >+} >+ >+#ifdef __cplusplus >+} // extern "C" >+#endif >+#endif /* ABSL_DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 */ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/dynamic_annotations.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/dynamic_annotations.h >new file mode 100644 >index 0000000000000000000000000000000000000000..88048b0fbb1f4f792b0a74e465d9910e7804f58f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/dynamic_annotations.h >@@ -0,0 +1,388 @@ >+/* >+ * Copyright 2017 The Abseil Authors. >+ * >+ * Licensed under the Apache License, Version 2.0 (the "License"); >+ * you may not use this file except in compliance with the License. >+ * You may obtain a copy of the License at >+ * >+ * http://www.apache.org/licenses/LICENSE-2.0 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+/* This file defines dynamic annotations for use with dynamic analysis >+ tool such as valgrind, PIN, etc. >+ >+ Dynamic annotation is a source code annotation that affects >+ the generated code (that is, the annotation is not a comment). >+ Each such annotation is attached to a particular >+ instruction and/or to a particular object (address) in the program. >+ >+ The annotations that should be used by users are macros in all upper-case >+ (e.g., ABSL_ANNOTATE_THREAD_NAME). >+ >+ Actual implementation of these macros may differ depending on the >+ dynamic analysis tool being used. >+ >+ This file supports the following configurations: >+ - Dynamic Annotations enabled (with static thread-safety warnings disabled). >+ In this case, macros expand to functions implemented by Thread Sanitizer, >+ when building with TSan. When not provided an external implementation, >+ dynamic_annotations.cc provides no-op implementations. >+ >+ - Static Clang thread-safety warnings enabled. >+ When building with a Clang compiler that supports thread-safety warnings, >+ a subset of annotations can be statically-checked at compile-time. We >+ expand these macros to static-inline functions that can be analyzed for >+ thread-safety, but afterwards elided when building the final binary. >+ >+ - All annotations are disabled. >+ If neither Dynamic Annotations nor Clang thread-safety warnings are >+ enabled, then all annotation-macros expand to empty. */ >+ >+#ifndef ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ >+#define ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ >+ >+#ifndef ABSL_DYNAMIC_ANNOTATIONS_ENABLED >+# define ABSL_DYNAMIC_ANNOTATIONS_ENABLED 0 >+#endif >+ >+#if ABSL_DYNAMIC_ANNOTATIONS_ENABLED != 0 >+ >+ /* ------------------------------------------------------------- >+ Annotations that suppress errors. It is usually better to express the >+ program's synchronization using the other annotations, but these can >+ be used when all else fails. */ >+ >+ /* Report that we may have a benign race at "pointer", with size >+ "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the >+ point where "pointer" has been allocated, preferably close to the point >+ where the race happens. See also ABSL_ANNOTATE_BENIGN_RACE_STATIC. */ >+ #define ABSL_ANNOTATE_BENIGN_RACE(pointer, description) \ >+ AbslAnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ >+ sizeof(*(pointer)), description) >+ >+ /* Same as ABSL_ANNOTATE_BENIGN_RACE(address, description), but applies to >+ the memory range [address, address+size). */ >+ #define ABSL_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ >+ AbslAnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) >+ >+ /* Enable (enable!=0) or disable (enable==0) race detection for all threads. >+ This annotation could be useful if you want to skip expensive race analysis >+ during some period of program execution, e.g. during initialization. */ >+ #define ABSL_ANNOTATE_ENABLE_RACE_DETECTION(enable) \ >+ AbslAnnotateEnableRaceDetection(__FILE__, __LINE__, enable) >+ >+ /* ------------------------------------------------------------- >+ Annotations useful for debugging. */ >+ >+ /* Report the current thread name to a race detector. */ >+ #define ABSL_ANNOTATE_THREAD_NAME(name) \ >+ AbslAnnotateThreadName(__FILE__, __LINE__, name) >+ >+ /* ------------------------------------------------------------- >+ Annotations useful when implementing locks. They are not >+ normally needed by modules that merely use locks. >+ The "lock" argument is a pointer to the lock object. */ >+ >+ /* Report that a lock has been created at address "lock". */ >+ #define ABSL_ANNOTATE_RWLOCK_CREATE(lock) \ >+ AbslAnnotateRWLockCreate(__FILE__, __LINE__, lock) >+ >+ /* Report that a linker initialized lock has been created at address "lock". >+ */ >+#ifdef THREAD_SANITIZER >+ #define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ >+ AbslAnnotateRWLockCreateStatic(__FILE__, __LINE__, lock) >+#else >+ #define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) ABSL_ANNOTATE_RWLOCK_CREATE(lock) >+#endif >+ >+ /* Report that the lock at address "lock" is about to be destroyed. */ >+ #define ABSL_ANNOTATE_RWLOCK_DESTROY(lock) \ >+ AbslAnnotateRWLockDestroy(__FILE__, __LINE__, lock) >+ >+ /* Report that the lock at address "lock" has been acquired. >+ is_w=1 for writer lock, is_w=0 for reader lock. */ >+ #define ABSL_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ >+ AbslAnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) >+ >+ /* Report that the lock at address "lock" is about to be released. */ >+ #define ABSL_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ >+ AbslAnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) >+ >+#else /* ABSL_DYNAMIC_ANNOTATIONS_ENABLED == 0 */ >+ >+ #define ABSL_ANNOTATE_RWLOCK_CREATE(lock) /* empty */ >+ #define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) /* empty */ >+ #define ABSL_ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ >+ #define ABSL_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ >+ #define ABSL_ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ >+ #define ABSL_ANNOTATE_BENIGN_RACE(address, description) /* empty */ >+ #define ABSL_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ >+ #define ABSL_ANNOTATE_THREAD_NAME(name) /* empty */ >+ #define ABSL_ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ >+ >+#endif /* ABSL_DYNAMIC_ANNOTATIONS_ENABLED */ >+ >+/* These annotations are also made available to LLVM's Memory Sanitizer */ >+#if ABSL_DYNAMIC_ANNOTATIONS_ENABLED == 1 || defined(MEMORY_SANITIZER) >+ #define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ >+ AbslAnnotateMemoryIsInitialized(__FILE__, __LINE__, address, size) >+ >+ #define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ >+ AbslAnnotateMemoryIsUninitialized(__FILE__, __LINE__, address, size) >+#else >+ #define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) /* empty */ >+ #define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) /* empty */ >+#endif /* ABSL_DYNAMIC_ANNOTATIONS_ENABLED || MEMORY_SANITIZER */ >+/* TODO(delesley) -- Replace __CLANG_SUPPORT_DYN_ANNOTATION__ with the >+ appropriate feature ID. */ >+#if defined(__clang__) && (!defined(SWIG)) \ >+ && defined(__CLANG_SUPPORT_DYN_ANNOTATION__) >+ >+ #if ABSL_DYNAMIC_ANNOTATIONS_ENABLED == 0 >+ #define ABSL_ANNOTALYSIS_ENABLED >+ #endif >+ >+ /* When running in opt-mode, GCC will issue a warning, if these attributes are >+ compiled. Only include them when compiling using Clang. */ >+ #define ABSL_ATTRIBUTE_IGNORE_READS_BEGIN \ >+ __attribute((exclusive_lock_function("*"))) >+ #define ABSL_ATTRIBUTE_IGNORE_READS_END \ >+ __attribute((unlock_function("*"))) >+#else >+ #define ABSL_ATTRIBUTE_IGNORE_READS_BEGIN /* empty */ >+ #define ABSL_ATTRIBUTE_IGNORE_READS_END /* empty */ >+#endif /* defined(__clang__) && ... */ >+ >+#if (ABSL_DYNAMIC_ANNOTATIONS_ENABLED != 0) || defined(ABSL_ANNOTALYSIS_ENABLED) >+ #define ABSL_ANNOTATIONS_ENABLED >+#endif >+ >+#if (ABSL_DYNAMIC_ANNOTATIONS_ENABLED != 0) >+ >+ /* Request the analysis tool to ignore all reads in the current thread >+ until ABSL_ANNOTATE_IGNORE_READS_END is called. >+ Useful to ignore intentional racey reads, while still checking >+ other reads and all writes. >+ See also ABSL_ANNOTATE_UNPROTECTED_READ. */ >+ #define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ >+ AbslAnnotateIgnoreReadsBegin(__FILE__, __LINE__) >+ >+ /* Stop ignoring reads. */ >+ #define ABSL_ANNOTATE_IGNORE_READS_END() \ >+ AbslAnnotateIgnoreReadsEnd(__FILE__, __LINE__) >+ >+ /* Similar to ABSL_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. */ >+ #define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN() \ >+ AbslAnnotateIgnoreWritesBegin(__FILE__, __LINE__) >+ >+ /* Stop ignoring writes. */ >+ #define ABSL_ANNOTATE_IGNORE_WRITES_END() \ >+ AbslAnnotateIgnoreWritesEnd(__FILE__, __LINE__) >+ >+/* Clang provides limited support for static thread-safety analysis >+ through a feature called Annotalysis. We configure macro-definitions >+ according to whether Annotalysis support is available. */ >+#elif defined(ABSL_ANNOTALYSIS_ENABLED) >+ >+ #define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ >+ AbslStaticAnnotateIgnoreReadsBegin(__FILE__, __LINE__) >+ >+ #define ABSL_ANNOTATE_IGNORE_READS_END() \ >+ AbslStaticAnnotateIgnoreReadsEnd(__FILE__, __LINE__) >+ >+ #define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN() \ >+ AbslStaticAnnotateIgnoreWritesBegin(__FILE__, __LINE__) >+ >+ #define ABSL_ANNOTATE_IGNORE_WRITES_END() \ >+ AbslStaticAnnotateIgnoreWritesEnd(__FILE__, __LINE__) >+ >+#else >+ #define ABSL_ANNOTATE_IGNORE_READS_BEGIN() /* empty */ >+ #define ABSL_ANNOTATE_IGNORE_READS_END() /* empty */ >+ #define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ >+ #define ABSL_ANNOTATE_IGNORE_WRITES_END() /* empty */ >+#endif >+ >+/* Implement the ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more >+ primitive annotations defined above. */ >+#if defined(ABSL_ANNOTATIONS_ENABLED) >+ >+ /* Start ignoring all memory accesses (both reads and writes). */ >+ #define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ >+ do { \ >+ ABSL_ANNOTATE_IGNORE_READS_BEGIN(); \ >+ ABSL_ANNOTATE_IGNORE_WRITES_BEGIN(); \ >+ }while (0) >+ >+ /* Stop ignoring both reads and writes. */ >+ #define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END() \ >+ do { \ >+ ABSL_ANNOTATE_IGNORE_WRITES_END(); \ >+ ABSL_ANNOTATE_IGNORE_READS_END(); \ >+ }while (0) >+ >+#else >+ #define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ >+ #define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ >+#endif >+ >+/* Use the macros above rather than using these functions directly. */ >+#include <stddef.h> >+#ifdef __cplusplus >+extern "C" { >+#endif >+void AbslAnnotateRWLockCreate(const char *file, int line, >+ const volatile void *lock); >+void AbslAnnotateRWLockCreateStatic(const char *file, int line, >+ const volatile void *lock); >+void AbslAnnotateRWLockDestroy(const char *file, int line, >+ const volatile void *lock); >+void AbslAnnotateRWLockAcquired(const char *file, int line, >+ const volatile void *lock, long is_w); /* NOLINT */ >+void AbslAnnotateRWLockReleased(const char *file, int line, >+ const volatile void *lock, long is_w); /* NOLINT */ >+void AbslAnnotateBenignRace(const char *file, int line, >+ const volatile void *address, >+ const char *description); >+void AbslAnnotateBenignRaceSized(const char *file, int line, >+ const volatile void *address, >+ size_t size, >+ const char *description); >+void AbslAnnotateThreadName(const char *file, int line, >+ const char *name); >+void AbslAnnotateEnableRaceDetection(const char *file, int line, int enable); >+void AbslAnnotateMemoryIsInitialized(const char *file, int line, >+ const volatile void *mem, size_t size); >+void AbslAnnotateMemoryIsUninitialized(const char *file, int line, >+ const volatile void *mem, size_t size); >+ >+/* Annotations expand to these functions, when Dynamic Annotations are enabled. >+ These functions are either implemented as no-op calls, if no Sanitizer is >+ attached, or provided with externally-linked implementations by a library >+ like ThreadSanitizer. */ >+void AbslAnnotateIgnoreReadsBegin(const char *file, int line) >+ ABSL_ATTRIBUTE_IGNORE_READS_BEGIN; >+void AbslAnnotateIgnoreReadsEnd(const char *file, int line) >+ ABSL_ATTRIBUTE_IGNORE_READS_END; >+void AbslAnnotateIgnoreWritesBegin(const char *file, int line); >+void AbslAnnotateIgnoreWritesEnd(const char *file, int line); >+ >+#if defined(ABSL_ANNOTALYSIS_ENABLED) >+/* When Annotalysis is enabled without Dynamic Annotations, the use of >+ static-inline functions allows the annotations to be read at compile-time, >+ while still letting the compiler elide the functions from the final build. >+ >+ TODO(delesley) -- The exclusive lock here ignores writes as well, but >+ allows IGNORE_READS_AND_WRITES to work properly. */ >+#pragma GCC diagnostic push >+#pragma GCC diagnostic ignored "-Wunused-function" >+static inline void AbslStaticAnnotateIgnoreReadsBegin(const char *file, int line) >+ ABSL_ATTRIBUTE_IGNORE_READS_BEGIN { (void)file; (void)line; } >+static inline void AbslStaticAnnotateIgnoreReadsEnd(const char *file, int line) >+ ABSL_ATTRIBUTE_IGNORE_READS_END { (void)file; (void)line; } >+static inline void AbslStaticAnnotateIgnoreWritesBegin( >+ const char *file, int line) { (void)file; (void)line; } >+static inline void AbslStaticAnnotateIgnoreWritesEnd( >+ const char *file, int line) { (void)file; (void)line; } >+#pragma GCC diagnostic pop >+#endif >+ >+/* Return non-zero value if running under valgrind. >+ >+ If "valgrind.h" is included into dynamic_annotations.cc, >+ the regular valgrind mechanism will be used. >+ See http://valgrind.org/docs/manual/manual-core-adv.html about >+ RUNNING_ON_VALGRIND and other valgrind "client requests". >+ The file "valgrind.h" may be obtained by doing >+ svn co svn://svn.valgrind.org/valgrind/trunk/include >+ >+ If for some reason you can't use "valgrind.h" or want to fake valgrind, >+ there are two ways to make this function return non-zero: >+ - Use environment variable: export RUNNING_ON_VALGRIND=1 >+ - Make your tool intercept the function AbslRunningOnValgrind() and >+ change its return value. >+ */ >+int AbslRunningOnValgrind(void); >+ >+/* AbslValgrindSlowdown returns: >+ * 1.0, if (AbslRunningOnValgrind() == 0) >+ * 50.0, if (AbslRunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL) >+ * atof(getenv("VALGRIND_SLOWDOWN")) otherwise >+ This function can be used to scale timeout values: >+ EXAMPLE: >+ for (;;) { >+ DoExpensiveBackgroundTask(); >+ SleepForSeconds(5 * AbslValgrindSlowdown()); >+ } >+ */ >+double AbslValgrindSlowdown(void); >+ >+#ifdef __cplusplus >+} >+#endif >+ >+/* ABSL_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. >+ >+ Instead of doing >+ ABSL_ANNOTATE_IGNORE_READS_BEGIN(); >+ ... = x; >+ ABSL_ANNOTATE_IGNORE_READS_END(); >+ one can use >+ ... = ABSL_ANNOTATE_UNPROTECTED_READ(x); */ >+#if defined(__cplusplus) && defined(ABSL_ANNOTATIONS_ENABLED) >+template <typename T> >+inline T ABSL_ANNOTATE_UNPROTECTED_READ(const volatile T &x) { /* NOLINT */ >+ ABSL_ANNOTATE_IGNORE_READS_BEGIN(); >+ T res = x; >+ ABSL_ANNOTATE_IGNORE_READS_END(); >+ return res; >+ } >+#else >+ #define ABSL_ANNOTATE_UNPROTECTED_READ(x) (x) >+#endif >+ >+#if ABSL_DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) >+ /* Apply ABSL_ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ >+ #define ABSL_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ >+ namespace { \ >+ class static_var ## _annotator { \ >+ public: \ >+ static_var ## _annotator() { \ >+ ABSL_ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ >+ sizeof(static_var), \ >+ # static_var ": " description); \ >+ } \ >+ }; \ >+ static static_var ## _annotator the ## static_var ## _annotator;\ >+ } // namespace >+#else /* ABSL_DYNAMIC_ANNOTATIONS_ENABLED == 0 */ >+ #define ABSL_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ >+#endif /* ABSL_DYNAMIC_ANNOTATIONS_ENABLED */ >+ >+#ifdef ADDRESS_SANITIZER >+/* Describe the current state of a contiguous container such as e.g. >+ * std::vector or std::string. For more details see >+ * sanitizer/common_interface_defs.h, which is provided by the compiler. */ >+#include <sanitizer/common_interface_defs.h> >+#define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \ >+ __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid) >+#define ABSL_ADDRESS_SANITIZER_REDZONE(name) \ >+ struct { char x[8] __attribute__ ((aligned (8))); } name >+#else >+#define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) >+#define ABSL_ADDRESS_SANITIZER_REDZONE(name) >+#endif // ADDRESS_SANITIZER >+ >+/* Undefine the macros intended only in this file. */ >+#undef ABSL_ANNOTALYSIS_ENABLED >+#undef ABSL_ANNOTATIONS_ENABLED >+#undef ABSL_ATTRIBUTE_IGNORE_READS_BEGIN >+#undef ABSL_ATTRIBUTE_IGNORE_READS_END >+ >+#endif /* ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ */ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..97c8d6f831894a880a984a1d0e090e04877282ee >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc >@@ -0,0 +1,942 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/exception_safety_testing.h" >+ >+#include <cstddef> >+#include <exception> >+#include <iostream> >+#include <list> >+#include <type_traits> >+#include <vector> >+ >+#include "gtest/gtest-spi.h" >+#include "gtest/gtest.h" >+#include "absl/memory/memory.h" >+ >+namespace testing { >+ >+namespace { >+ >+using ::testing::exceptions_internal::SetCountdown; >+using ::testing::exceptions_internal::TestException; >+using ::testing::exceptions_internal::UnsetCountdown; >+ >+// EXPECT_NO_THROW can't inspect the thrown inspection in general. >+template <typename F> >+void ExpectNoThrow(const F& f) { >+ try { >+ f(); >+ } catch (TestException e) { >+ ADD_FAILURE() << "Unexpected exception thrown from " << e.what(); >+ } >+} >+ >+TEST(ThrowingValueTest, Throws) { >+ SetCountdown(); >+ EXPECT_THROW(ThrowingValue<> bomb, TestException); >+ >+ // It's not guaranteed that every operator only throws *once*. The default >+ // ctor only throws once, though, so use it to make sure we only throw when >+ // the countdown hits 0 >+ SetCountdown(2); >+ ExpectNoThrow([]() { ThrowingValue<> bomb; }); >+ ExpectNoThrow([]() { ThrowingValue<> bomb; }); >+ EXPECT_THROW(ThrowingValue<> bomb, TestException); >+ >+ UnsetCountdown(); >+} >+ >+// Tests that an operation throws when the countdown is at 0, doesn't throw when >+// the countdown doesn't hit 0, and doesn't modify the state of the >+// ThrowingValue if it throws >+template <typename F> >+void TestOp(const F& f) { >+ ExpectNoThrow(f); >+ >+ SetCountdown(); >+ EXPECT_THROW(f(), TestException); >+ UnsetCountdown(); >+} >+ >+TEST(ThrowingValueTest, ThrowingCtors) { >+ ThrowingValue<> bomb; >+ >+ TestOp([]() { ThrowingValue<> bomb(1); }); >+ TestOp([&]() { ThrowingValue<> bomb1 = bomb; }); >+ TestOp([&]() { ThrowingValue<> bomb1 = std::move(bomb); }); >+} >+ >+TEST(ThrowingValueTest, ThrowingAssignment) { >+ ThrowingValue<> bomb, bomb1; >+ >+ TestOp([&]() { bomb = bomb1; }); >+ TestOp([&]() { bomb = std::move(bomb1); }); >+ >+ // Test that when assignment throws, the assignment should fail (lhs != rhs) >+ // and strong guarantee fails (lhs != lhs_copy). >+ { >+ ThrowingValue<> lhs(39), rhs(42); >+ ThrowingValue<> lhs_copy(lhs); >+ SetCountdown(); >+ EXPECT_THROW(lhs = rhs, TestException); >+ UnsetCountdown(); >+ EXPECT_NE(lhs, rhs); >+ EXPECT_NE(lhs_copy, lhs); >+ } >+ { >+ ThrowingValue<> lhs(39), rhs(42); >+ ThrowingValue<> lhs_copy(lhs), rhs_copy(rhs); >+ SetCountdown(); >+ EXPECT_THROW(lhs = std::move(rhs), TestException); >+ UnsetCountdown(); >+ EXPECT_NE(lhs, rhs_copy); >+ EXPECT_NE(lhs_copy, lhs); >+ } >+} >+ >+TEST(ThrowingValueTest, ThrowingComparisons) { >+ ThrowingValue<> bomb1, bomb2; >+ TestOp([&]() { return bomb1 == bomb2; }); >+ TestOp([&]() { return bomb1 != bomb2; }); >+ TestOp([&]() { return bomb1 < bomb2; }); >+ TestOp([&]() { return bomb1 <= bomb2; }); >+ TestOp([&]() { return bomb1 > bomb2; }); >+ TestOp([&]() { return bomb1 >= bomb2; }); >+} >+ >+TEST(ThrowingValueTest, ThrowingArithmeticOps) { >+ ThrowingValue<> bomb1(1), bomb2(2); >+ >+ TestOp([&bomb1]() { +bomb1; }); >+ TestOp([&bomb1]() { -bomb1; }); >+ TestOp([&bomb1]() { ++bomb1; }); >+ TestOp([&bomb1]() { bomb1++; }); >+ TestOp([&bomb1]() { --bomb1; }); >+ TestOp([&bomb1]() { bomb1--; }); >+ >+ TestOp([&]() { bomb1 + bomb2; }); >+ TestOp([&]() { bomb1 - bomb2; }); >+ TestOp([&]() { bomb1* bomb2; }); >+ TestOp([&]() { bomb1 / bomb2; }); >+ TestOp([&]() { bomb1 << 1; }); >+ TestOp([&]() { bomb1 >> 1; }); >+} >+ >+TEST(ThrowingValueTest, ThrowingLogicalOps) { >+ ThrowingValue<> bomb1, bomb2; >+ >+ TestOp([&bomb1]() { !bomb1; }); >+ TestOp([&]() { bomb1&& bomb2; }); >+ TestOp([&]() { bomb1 || bomb2; }); >+} >+ >+TEST(ThrowingValueTest, ThrowingBitwiseOps) { >+ ThrowingValue<> bomb1, bomb2; >+ >+ TestOp([&bomb1]() { ~bomb1; }); >+ TestOp([&]() { bomb1& bomb2; }); >+ TestOp([&]() { bomb1 | bomb2; }); >+ TestOp([&]() { bomb1 ^ bomb2; }); >+} >+ >+TEST(ThrowingValueTest, ThrowingCompoundAssignmentOps) { >+ ThrowingValue<> bomb1(1), bomb2(2); >+ >+ TestOp([&]() { bomb1 += bomb2; }); >+ TestOp([&]() { bomb1 -= bomb2; }); >+ TestOp([&]() { bomb1 *= bomb2; }); >+ TestOp([&]() { bomb1 /= bomb2; }); >+ TestOp([&]() { bomb1 %= bomb2; }); >+ TestOp([&]() { bomb1 &= bomb2; }); >+ TestOp([&]() { bomb1 |= bomb2; }); >+ TestOp([&]() { bomb1 ^= bomb2; }); >+ TestOp([&]() { bomb1 *= bomb2; }); >+} >+ >+TEST(ThrowingValueTest, ThrowingStreamOps) { >+ ThrowingValue<> bomb; >+ >+ TestOp([&]() { >+ std::istringstream stream; >+ stream >> bomb; >+ }); >+ TestOp([&]() { >+ std::stringstream stream; >+ stream << bomb; >+ }); >+} >+ >+// Tests the operator<< of ThrowingValue by forcing ConstructorTracker to emit >+// a nonfatal failure that contains the std::string representation of the Thrower >+TEST(ThrowingValueTest, StreamOpsOutput) { >+ using ::testing::TypeSpec; >+ exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); >+ >+ // Test default spec list (kEverythingThrows) >+ EXPECT_NONFATAL_FAILURE( >+ { >+ using Thrower = ThrowingValue<TypeSpec{}>; >+ auto thrower = Thrower(123); >+ thrower.~Thrower(); >+ }, >+ "ThrowingValue<>(123)"); >+ >+ // Test with one item in spec list (kNoThrowCopy) >+ EXPECT_NONFATAL_FAILURE( >+ { >+ using Thrower = ThrowingValue<TypeSpec::kNoThrowCopy>; >+ auto thrower = Thrower(234); >+ thrower.~Thrower(); >+ }, >+ "ThrowingValue<kNoThrowCopy>(234)"); >+ >+ // Test with multiple items in spec list (kNoThrowMove, kNoThrowNew) >+ EXPECT_NONFATAL_FAILURE( >+ { >+ using Thrower = >+ ThrowingValue<TypeSpec::kNoThrowMove | TypeSpec::kNoThrowNew>; >+ auto thrower = Thrower(345); >+ thrower.~Thrower(); >+ }, >+ "ThrowingValue<kNoThrowMove | kNoThrowNew>(345)"); >+ >+ // Test with all items in spec list (kNoThrowCopy, kNoThrowMove, kNoThrowNew) >+ EXPECT_NONFATAL_FAILURE( >+ { >+ using Thrower = ThrowingValue<static_cast<TypeSpec>(-1)>; >+ auto thrower = Thrower(456); >+ thrower.~Thrower(); >+ }, >+ "ThrowingValue<kNoThrowCopy | kNoThrowMove | kNoThrowNew>(456)"); >+} >+ >+template <typename F> >+void TestAllocatingOp(const F& f) { >+ ExpectNoThrow(f); >+ >+ SetCountdown(); >+ EXPECT_THROW(f(), exceptions_internal::TestBadAllocException); >+ UnsetCountdown(); >+} >+ >+TEST(ThrowingValueTest, ThrowingAllocatingOps) { >+ // make_unique calls unqualified operator new, so these exercise the >+ // ThrowingValue overloads. >+ TestAllocatingOp([]() { return absl::make_unique<ThrowingValue<>>(1); }); >+ TestAllocatingOp([]() { return absl::make_unique<ThrowingValue<>[]>(2); }); >+} >+ >+TEST(ThrowingValueTest, NonThrowingMoveCtor) { >+ ThrowingValue<TypeSpec::kNoThrowMove> nothrow_ctor; >+ >+ SetCountdown(); >+ ExpectNoThrow([¬hrow_ctor]() { >+ ThrowingValue<TypeSpec::kNoThrowMove> nothrow1 = std::move(nothrow_ctor); >+ }); >+ UnsetCountdown(); >+} >+ >+TEST(ThrowingValueTest, NonThrowingMoveAssign) { >+ ThrowingValue<TypeSpec::kNoThrowMove> nothrow_assign1, nothrow_assign2; >+ >+ SetCountdown(); >+ ExpectNoThrow([¬hrow_assign1, ¬hrow_assign2]() { >+ nothrow_assign1 = std::move(nothrow_assign2); >+ }); >+ UnsetCountdown(); >+} >+ >+TEST(ThrowingValueTest, ThrowingCopyCtor) { >+ ThrowingValue<> tv; >+ >+ TestOp([&]() { ThrowingValue<> tv_copy(tv); }); >+} >+ >+TEST(ThrowingValueTest, ThrowingCopyAssign) { >+ ThrowingValue<> tv1, tv2; >+ >+ TestOp([&]() { tv1 = tv2; }); >+} >+ >+TEST(ThrowingValueTest, NonThrowingCopyCtor) { >+ ThrowingValue<TypeSpec::kNoThrowCopy> nothrow_ctor; >+ >+ SetCountdown(); >+ ExpectNoThrow([¬hrow_ctor]() { >+ ThrowingValue<TypeSpec::kNoThrowCopy> nothrow1(nothrow_ctor); >+ }); >+ UnsetCountdown(); >+} >+ >+TEST(ThrowingValueTest, NonThrowingCopyAssign) { >+ ThrowingValue<TypeSpec::kNoThrowCopy> nothrow_assign1, nothrow_assign2; >+ >+ SetCountdown(); >+ ExpectNoThrow([¬hrow_assign1, ¬hrow_assign2]() { >+ nothrow_assign1 = nothrow_assign2; >+ }); >+ UnsetCountdown(); >+} >+ >+TEST(ThrowingValueTest, ThrowingSwap) { >+ ThrowingValue<> bomb1, bomb2; >+ TestOp([&]() { std::swap(bomb1, bomb2); }); >+} >+ >+TEST(ThrowingValueTest, NonThrowingSwap) { >+ ThrowingValue<TypeSpec::kNoThrowMove> bomb1, bomb2; >+ ExpectNoThrow([&]() { std::swap(bomb1, bomb2); }); >+} >+ >+TEST(ThrowingValueTest, NonThrowingAllocation) { >+ ThrowingValue<TypeSpec::kNoThrowNew>* allocated; >+ ThrowingValue<TypeSpec::kNoThrowNew>* array; >+ >+ ExpectNoThrow([&allocated]() { >+ allocated = new ThrowingValue<TypeSpec::kNoThrowNew>(1); >+ delete allocated; >+ }); >+ ExpectNoThrow([&array]() { >+ array = new ThrowingValue<TypeSpec::kNoThrowNew>[2]; >+ delete[] array; >+ }); >+} >+ >+TEST(ThrowingValueTest, NonThrowingDelete) { >+ auto* allocated = new ThrowingValue<>(1); >+ auto* array = new ThrowingValue<>[2]; >+ >+ SetCountdown(); >+ ExpectNoThrow([allocated]() { delete allocated; }); >+ SetCountdown(); >+ ExpectNoThrow([array]() { delete[] array; }); >+ >+ UnsetCountdown(); >+} >+ >+using Storage = >+ absl::aligned_storage_t<sizeof(ThrowingValue<>), alignof(ThrowingValue<>)>; >+ >+TEST(ThrowingValueTest, NonThrowingPlacementDelete) { >+ constexpr int kArrayLen = 2; >+ // We intentionally create extra space to store the tag allocated by placement >+ // new[]. >+ constexpr int kStorageLen = 4; >+ >+ Storage buf; >+ Storage array_buf[kStorageLen]; >+ auto* placed = new (&buf) ThrowingValue<>(1); >+ auto placed_array = new (&array_buf) ThrowingValue<>[kArrayLen]; >+ >+ SetCountdown(); >+ ExpectNoThrow([placed, &buf]() { >+ placed->~ThrowingValue<>(); >+ ThrowingValue<>::operator delete(placed, &buf); >+ }); >+ >+ SetCountdown(); >+ ExpectNoThrow([&, placed_array]() { >+ for (int i = 0; i < kArrayLen; ++i) placed_array[i].~ThrowingValue<>(); >+ ThrowingValue<>::operator delete[](placed_array, &array_buf); >+ }); >+ >+ UnsetCountdown(); >+} >+ >+TEST(ThrowingValueTest, NonThrowingDestructor) { >+ auto* allocated = new ThrowingValue<>(); >+ >+ SetCountdown(); >+ ExpectNoThrow([allocated]() { delete allocated; }); >+ UnsetCountdown(); >+} >+ >+TEST(ThrowingBoolTest, ThrowingBool) { >+ ThrowingBool t = true; >+ >+ // Test that it's contextually convertible to bool >+ if (t) { // NOLINT(whitespace/empty_if_body) >+ } >+ EXPECT_TRUE(t); >+ >+ TestOp([&]() { (void)!t; }); >+} >+ >+TEST(ThrowingAllocatorTest, MemoryManagement) { >+ // Just exercise the memory management capabilities under LSan to make sure we >+ // don't leak. >+ ThrowingAllocator<int> int_alloc; >+ int* ip = int_alloc.allocate(1); >+ int_alloc.deallocate(ip, 1); >+ int* i_array = int_alloc.allocate(2); >+ int_alloc.deallocate(i_array, 2); >+ >+ ThrowingAllocator<ThrowingValue<>> tv_alloc; >+ ThrowingValue<>* ptr = tv_alloc.allocate(1); >+ tv_alloc.deallocate(ptr, 1); >+ ThrowingValue<>* tv_array = tv_alloc.allocate(2); >+ tv_alloc.deallocate(tv_array, 2); >+} >+ >+TEST(ThrowingAllocatorTest, CallsGlobalNew) { >+ ThrowingAllocator<ThrowingValue<>, AllocSpec::kNoThrowAllocate> nothrow_alloc; >+ ThrowingValue<>* ptr; >+ >+ SetCountdown(); >+ // This will only throw if ThrowingValue::new is called. >+ ExpectNoThrow([&]() { ptr = nothrow_alloc.allocate(1); }); >+ nothrow_alloc.deallocate(ptr, 1); >+ >+ UnsetCountdown(); >+} >+ >+TEST(ThrowingAllocatorTest, ThrowingConstructors) { >+ ThrowingAllocator<int> int_alloc; >+ int* ip = nullptr; >+ >+ SetCountdown(); >+ EXPECT_THROW(ip = int_alloc.allocate(1), TestException); >+ ExpectNoThrow([&]() { ip = int_alloc.allocate(1); }); >+ >+ *ip = 1; >+ SetCountdown(); >+ EXPECT_THROW(int_alloc.construct(ip, 2), TestException); >+ EXPECT_EQ(*ip, 1); >+ int_alloc.deallocate(ip, 1); >+ >+ UnsetCountdown(); >+} >+ >+TEST(ThrowingAllocatorTest, NonThrowingConstruction) { >+ { >+ ThrowingAllocator<int, AllocSpec::kNoThrowAllocate> int_alloc; >+ int* ip = nullptr; >+ >+ SetCountdown(); >+ ExpectNoThrow([&]() { ip = int_alloc.allocate(1); }); >+ >+ SetCountdown(); >+ ExpectNoThrow([&]() { int_alloc.construct(ip, 2); }); >+ >+ EXPECT_EQ(*ip, 2); >+ int_alloc.deallocate(ip, 1); >+ >+ UnsetCountdown(); >+ } >+ >+ { >+ ThrowingAllocator<int> int_alloc; >+ int* ip = nullptr; >+ ExpectNoThrow([&]() { ip = int_alloc.allocate(1); }); >+ ExpectNoThrow([&]() { int_alloc.construct(ip, 2); }); >+ EXPECT_EQ(*ip, 2); >+ int_alloc.deallocate(ip, 1); >+ } >+ >+ { >+ ThrowingAllocator<ThrowingValue<>, AllocSpec::kNoThrowAllocate> >+ nothrow_alloc; >+ ThrowingValue<>* ptr; >+ >+ SetCountdown(); >+ ExpectNoThrow([&]() { ptr = nothrow_alloc.allocate(1); }); >+ >+ SetCountdown(); >+ ExpectNoThrow( >+ [&]() { nothrow_alloc.construct(ptr, 2, testing::nothrow_ctor); }); >+ >+ EXPECT_EQ(ptr->Get(), 2); >+ nothrow_alloc.destroy(ptr); >+ nothrow_alloc.deallocate(ptr, 1); >+ >+ UnsetCountdown(); >+ } >+ >+ { >+ ThrowingAllocator<int> a; >+ >+ SetCountdown(); >+ ExpectNoThrow([&]() { ThrowingAllocator<double> a1 = a; }); >+ >+ SetCountdown(); >+ ExpectNoThrow([&]() { ThrowingAllocator<double> a1 = std::move(a); }); >+ >+ UnsetCountdown(); >+ } >+} >+ >+TEST(ThrowingAllocatorTest, ThrowingAllocatorConstruction) { >+ ThrowingAllocator<int> a; >+ TestOp([]() { ThrowingAllocator<int> a; }); >+ TestOp([&]() { a.select_on_container_copy_construction(); }); >+} >+ >+TEST(ThrowingAllocatorTest, State) { >+ ThrowingAllocator<int> a1, a2; >+ EXPECT_NE(a1, a2); >+ >+ auto a3 = a1; >+ EXPECT_EQ(a3, a1); >+ int* ip = a1.allocate(1); >+ EXPECT_EQ(a3, a1); >+ a3.deallocate(ip, 1); >+ EXPECT_EQ(a3, a1); >+} >+ >+TEST(ThrowingAllocatorTest, InVector) { >+ std::vector<ThrowingValue<>, ThrowingAllocator<ThrowingValue<>>> v; >+ for (int i = 0; i < 20; ++i) v.push_back({}); >+ for (int i = 0; i < 20; ++i) v.pop_back(); >+} >+ >+TEST(ThrowingAllocatorTest, InList) { >+ std::list<ThrowingValue<>, ThrowingAllocator<ThrowingValue<>>> l; >+ for (int i = 0; i < 20; ++i) l.push_back({}); >+ for (int i = 0; i < 20; ++i) l.pop_back(); >+ for (int i = 0; i < 20; ++i) l.push_front({}); >+ for (int i = 0; i < 20; ++i) l.pop_front(); >+} >+ >+template <typename TesterInstance, typename = void> >+struct NullaryTestValidator : public std::false_type {}; >+ >+template <typename TesterInstance> >+struct NullaryTestValidator< >+ TesterInstance, >+ absl::void_t<decltype(std::declval<TesterInstance>().Test())>> >+ : public std::true_type {}; >+ >+template <typename TesterInstance> >+bool HasNullaryTest(const TesterInstance&) { >+ return NullaryTestValidator<TesterInstance>::value; >+} >+ >+void DummyOp(void*) {} >+ >+template <typename TesterInstance, typename = void> >+struct UnaryTestValidator : public std::false_type {}; >+ >+template <typename TesterInstance> >+struct UnaryTestValidator< >+ TesterInstance, >+ absl::void_t<decltype(std::declval<TesterInstance>().Test(DummyOp))>> >+ : public std::true_type {}; >+ >+template <typename TesterInstance> >+bool HasUnaryTest(const TesterInstance&) { >+ return UnaryTestValidator<TesterInstance>::value; >+} >+ >+TEST(ExceptionSafetyTesterTest, IncompleteTypesAreNotTestable) { >+ using T = exceptions_internal::UninitializedT; >+ auto op = [](T* t) {}; >+ auto inv = [](T*) { return testing::AssertionSuccess(); }; >+ auto fac = []() { return absl::make_unique<T>(); }; >+ >+ // 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( >+ 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(op) but does not allow for .Test() because it lacks an operation >+ auto without_op = testing::MakeExceptionSafetyTester() >+ .WithInvariants(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 >+ auto without_inv = >+ testing::MakeExceptionSafetyTester().WithOperation(op).WithFactory(fac); >+ EXPECT_FALSE(HasNullaryTest(without_inv)); >+ EXPECT_FALSE(HasUnaryTest(without_inv)); >+} >+ >+struct ExampleStruct {}; >+ >+std::unique_ptr<ExampleStruct> ExampleFunctionFactory() { >+ return absl::make_unique<ExampleStruct>(); >+} >+ >+void ExampleFunctionOperation(ExampleStruct*) {} >+ >+testing::AssertionResult ExampleFunctionInvariant(ExampleStruct*) { >+ return testing::AssertionSuccess(); >+} >+ >+struct { >+ std::unique_ptr<ExampleStruct> operator()() const { >+ return ExampleFunctionFactory(); >+ } >+} example_struct_factory; >+ >+struct { >+ void operator()(ExampleStruct*) const {} >+} example_struct_operation; >+ >+struct { >+ testing::AssertionResult operator()(ExampleStruct* example_struct) const { >+ return ExampleFunctionInvariant(example_struct); >+ } >+} example_struct_invariant; >+ >+auto example_lambda_factory = []() { return ExampleFunctionFactory(); }; >+ >+auto example_lambda_operation = [](ExampleStruct*) {}; >+ >+auto example_lambda_invariant = [](ExampleStruct* example_struct) { >+ return ExampleFunctionInvariant(example_struct); >+}; >+ >+// Testing that function references, pointers, structs with operator() and >+// lambdas can all be used with ExceptionSafetyTester >+TEST(ExceptionSafetyTesterTest, MixedFunctionTypes) { >+ // function reference >+ EXPECT_TRUE(testing::MakeExceptionSafetyTester() >+ .WithFactory(ExampleFunctionFactory) >+ .WithOperation(ExampleFunctionOperation) >+ .WithInvariants(ExampleFunctionInvariant) >+ .Test()); >+ >+ // function pointer >+ EXPECT_TRUE(testing::MakeExceptionSafetyTester() >+ .WithFactory(&ExampleFunctionFactory) >+ .WithOperation(&ExampleFunctionOperation) >+ .WithInvariants(&ExampleFunctionInvariant) >+ .Test()); >+ >+ // struct >+ EXPECT_TRUE(testing::MakeExceptionSafetyTester() >+ .WithFactory(example_struct_factory) >+ .WithOperation(example_struct_operation) >+ .WithInvariants(example_struct_invariant) >+ .Test()); >+ >+ // lambda >+ EXPECT_TRUE(testing::MakeExceptionSafetyTester() >+ .WithFactory(example_lambda_factory) >+ .WithOperation(example_lambda_operation) >+ .WithInvariants(example_lambda_invariant) >+ .Test()); >+} >+ >+struct NonNegative { >+ bool operator==(const NonNegative& other) const { return i == other.i; } >+ int i; >+}; >+ >+testing::AssertionResult CheckNonNegativeInvariants(NonNegative* g) { >+ if (g->i >= 0) { >+ return testing::AssertionSuccess(); >+ } >+ return testing::AssertionFailure() >+ << "i should be non-negative but is " << g->i; >+} >+ >+struct { >+ template <typename T> >+ void operator()(T* t) const { >+ (*t)(); >+ } >+} invoker; >+ >+auto tester = >+ testing::MakeExceptionSafetyTester().WithOperation(invoker).WithInvariants( >+ CheckNonNegativeInvariants); >+auto strong_tester = tester.WithInvariants(testing::strong_guarantee); >+ >+struct FailsBasicGuarantee : public NonNegative { >+ void operator()() { >+ --i; >+ ThrowingValue<> bomb; >+ ++i; >+ } >+}; >+ >+TEST(ExceptionCheckTest, BasicGuaranteeFailure) { >+ EXPECT_FALSE(tester.WithInitialValue(FailsBasicGuarantee{}).Test()); >+} >+ >+struct FollowsBasicGuarantee : public NonNegative { >+ void operator()() { >+ ++i; >+ ThrowingValue<> bomb; >+ } >+}; >+ >+TEST(ExceptionCheckTest, BasicGuarantee) { >+ EXPECT_TRUE(tester.WithInitialValue(FollowsBasicGuarantee{}).Test()); >+} >+ >+TEST(ExceptionCheckTest, StrongGuaranteeFailure) { >+ EXPECT_FALSE(strong_tester.WithInitialValue(FailsBasicGuarantee{}).Test()); >+ EXPECT_FALSE(strong_tester.WithInitialValue(FollowsBasicGuarantee{}).Test()); >+} >+ >+struct BasicGuaranteeWithExtraInvariants : public NonNegative { >+ // After operator(), i is incremented. If operator() throws, i is set to 9999 >+ void operator()() { >+ int old_i = i; >+ i = kExceptionSentinel; >+ ThrowingValue<> bomb; >+ i = ++old_i; >+ } >+ >+ static constexpr int kExceptionSentinel = 9999; >+}; >+constexpr int BasicGuaranteeWithExtraInvariants::kExceptionSentinel; >+ >+TEST(ExceptionCheckTest, BasicGuaranteeWithExtraInvariants) { >+ auto tester_with_val = >+ tester.WithInitialValue(BasicGuaranteeWithExtraInvariants{}); >+ EXPECT_TRUE(tester_with_val.Test()); >+ EXPECT_TRUE( >+ tester_with_val >+ .WithInvariants([](BasicGuaranteeWithExtraInvariants* o) { >+ if (o->i == BasicGuaranteeWithExtraInvariants::kExceptionSentinel) { >+ return testing::AssertionSuccess(); >+ } >+ return testing::AssertionFailure() >+ << "i should be " >+ << BasicGuaranteeWithExtraInvariants::kExceptionSentinel >+ << ", but is " << o->i; >+ }) >+ .Test()); >+} >+ >+struct FollowsStrongGuarantee : public NonNegative { >+ void operator()() { ThrowingValue<> bomb; } >+}; >+ >+TEST(ExceptionCheckTest, StrongGuarantee) { >+ EXPECT_TRUE(tester.WithInitialValue(FollowsStrongGuarantee{}).Test()); >+ EXPECT_TRUE(strong_tester.WithInitialValue(FollowsStrongGuarantee{}).Test()); >+} >+ >+struct HasReset : public NonNegative { >+ void operator()() { >+ i = -1; >+ ThrowingValue<> bomb; >+ i = 1; >+ } >+ >+ void reset() { i = 0; } >+}; >+ >+testing::AssertionResult CheckHasResetInvariants(HasReset* h) { >+ h->reset(); >+ return testing::AssertionResult(h->i == 0); >+} >+ >+TEST(ExceptionCheckTest, ModifyingChecker) { >+ auto set_to_1000 = [](FollowsBasicGuarantee* g) { >+ g->i = 1000; >+ return testing::AssertionSuccess(); >+ }; >+ auto is_1000 = [](FollowsBasicGuarantee* g) { >+ return testing::AssertionResult(g->i == 1000); >+ }; >+ auto increment = [](FollowsStrongGuarantee* g) { >+ ++g->i; >+ return testing::AssertionSuccess(); >+ }; >+ >+ EXPECT_FALSE(tester.WithInitialValue(FollowsBasicGuarantee{}) >+ .WithInvariants(set_to_1000, is_1000) >+ .Test()); >+ EXPECT_TRUE(strong_tester.WithInitialValue(FollowsStrongGuarantee{}) >+ .WithInvariants(increment) >+ .Test()); >+ EXPECT_TRUE(testing::MakeExceptionSafetyTester() >+ .WithInitialValue(HasReset{}) >+ .WithInvariants(CheckHasResetInvariants) >+ .Test(invoker)); >+} >+ >+struct NonCopyable : public NonNegative { >+ NonCopyable(const NonCopyable&) = delete; >+ NonCopyable() : NonNegative{0} {} >+ >+ void operator()() { ThrowingValue<> bomb; } >+}; >+ >+TEST(ExceptionCheckTest, NonCopyable) { >+ auto factory = []() { return absl::make_unique<NonCopyable>(); }; >+ EXPECT_TRUE(tester.WithFactory(factory).Test()); >+ EXPECT_TRUE(strong_tester.WithFactory(factory).Test()); >+} >+ >+struct NonEqualityComparable : public NonNegative { >+ void operator()() { ThrowingValue<> bomb; } >+ >+ void ModifyOnThrow() { >+ ++i; >+ ThrowingValue<> bomb; >+ static_cast<void>(bomb); >+ --i; >+ } >+}; >+ >+TEST(ExceptionCheckTest, NonEqualityComparable) { >+ auto nec_is_strong = [](NonEqualityComparable* nec) { >+ return testing::AssertionResult(nec->i == NonEqualityComparable().i); >+ }; >+ auto strong_nec_tester = tester.WithInitialValue(NonEqualityComparable{}) >+ .WithInvariants(nec_is_strong); >+ >+ EXPECT_TRUE(strong_nec_tester.Test()); >+ EXPECT_FALSE(strong_nec_tester.Test( >+ [](NonEqualityComparable* n) { n->ModifyOnThrow(); })); >+} >+ >+template <typename T> >+struct ExhaustivenessTester { >+ void operator()() { >+ successes |= 1; >+ T b1; >+ static_cast<void>(b1); >+ successes |= (1 << 1); >+ T b2; >+ static_cast<void>(b2); >+ successes |= (1 << 2); >+ T b3; >+ static_cast<void>(b3); >+ successes |= (1 << 3); >+ } >+ >+ bool operator==(const ExhaustivenessTester<ThrowingValue<>>&) const { >+ return true; >+ } >+ >+ static unsigned char successes; >+}; >+ >+struct { >+ template <typename T> >+ testing::AssertionResult operator()(ExhaustivenessTester<T>*) const { >+ return testing::AssertionSuccess(); >+ } >+} CheckExhaustivenessTesterInvariants; >+ >+template <typename T> >+unsigned char ExhaustivenessTester<T>::successes = 0; >+ >+TEST(ExceptionCheckTest, Exhaustiveness) { >+ auto exhaust_tester = testing::MakeExceptionSafetyTester() >+ .WithInvariants(CheckExhaustivenessTesterInvariants) >+ .WithOperation(invoker); >+ >+ EXPECT_TRUE( >+ exhaust_tester.WithInitialValue(ExhaustivenessTester<int>{}).Test()); >+ EXPECT_EQ(ExhaustivenessTester<int>::successes, 0xF); >+ >+ EXPECT_TRUE( >+ exhaust_tester.WithInitialValue(ExhaustivenessTester<ThrowingValue<>>{}) >+ .WithInvariants(testing::strong_guarantee) >+ .Test()); >+ EXPECT_EQ(ExhaustivenessTester<ThrowingValue<>>::successes, 0xF); >+} >+ >+struct LeaksIfCtorThrows : private exceptions_internal::TrackedObject { >+ LeaksIfCtorThrows() : TrackedObject(ABSL_PRETTY_FUNCTION) { >+ ++counter; >+ ThrowingValue<> v; >+ static_cast<void>(v); >+ --counter; >+ } >+ LeaksIfCtorThrows(const LeaksIfCtorThrows&) noexcept >+ : TrackedObject(ABSL_PRETTY_FUNCTION) {} >+ static int counter; >+}; >+int LeaksIfCtorThrows::counter = 0; >+ >+TEST(ExceptionCheckTest, TestLeakyCtor) { >+ testing::TestThrowingCtor<LeaksIfCtorThrows>(); >+ EXPECT_EQ(LeaksIfCtorThrows::counter, 1); >+ LeaksIfCtorThrows::counter = 0; >+} >+ >+struct Tracked : private exceptions_internal::TrackedObject { >+ Tracked() : TrackedObject(ABSL_PRETTY_FUNCTION) {} >+}; >+ >+TEST(ConstructorTrackerTest, CreatedBefore) { >+ Tracked a, b, c; >+ exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); >+} >+ >+TEST(ConstructorTrackerTest, CreatedAfter) { >+ exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); >+ Tracked a, b, c; >+} >+ >+TEST(ConstructorTrackerTest, NotDestroyedAfter) { >+ absl::aligned_storage_t<sizeof(Tracked), alignof(Tracked)> storage; >+ EXPECT_NONFATAL_FAILURE( >+ { >+ exceptions_internal::ConstructorTracker ct( >+ exceptions_internal::countdown); >+ new (&storage) Tracked; >+ }, >+ "not destroyed"); >+} >+ >+TEST(ConstructorTrackerTest, DestroyedTwice) { >+ exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); >+ EXPECT_NONFATAL_FAILURE( >+ { >+ Tracked t; >+ t.~Tracked(); >+ }, >+ "re-destroyed"); >+} >+ >+TEST(ConstructorTrackerTest, ConstructedTwice) { >+ exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); >+ absl::aligned_storage_t<sizeof(Tracked), alignof(Tracked)> storage; >+ EXPECT_NONFATAL_FAILURE( >+ { >+ new (&storage) Tracked; >+ new (&storage) Tracked; >+ reinterpret_cast<Tracked*>(&storage)->~Tracked(); >+ }, >+ "re-constructed"); >+} >+ >+TEST(ThrowingValueTraitsTest, RelationalOperators) { >+ ThrowingValue<> a, b; >+ EXPECT_TRUE((std::is_convertible<decltype(a == b), bool>::value)); >+ EXPECT_TRUE((std::is_convertible<decltype(a != b), bool>::value)); >+ EXPECT_TRUE((std::is_convertible<decltype(a < b), bool>::value)); >+ EXPECT_TRUE((std::is_convertible<decltype(a <= b), bool>::value)); >+ EXPECT_TRUE((std::is_convertible<decltype(a > b), bool>::value)); >+ EXPECT_TRUE((std::is_convertible<decltype(a >= b), bool>::value)); >+} >+ >+TEST(ThrowingAllocatorTraitsTest, Assignablility) { >+ EXPECT_TRUE(std::is_move_assignable<ThrowingAllocator<int>>::value); >+ EXPECT_TRUE(std::is_copy_assignable<ThrowingAllocator<int>>::value); >+ EXPECT_TRUE(std::is_nothrow_move_assignable<ThrowingAllocator<int>>::value); >+ EXPECT_TRUE(std::is_nothrow_copy_assignable<ThrowingAllocator<int>>::value); >+} >+ >+} // namespace >+ >+} // namespace testing >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/inline_variable_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/inline_variable_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..5499189a3da96a33b06b2670a724107c3d673a5f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/inline_variable_test.cc >@@ -0,0 +1,62 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <type_traits> >+ >+#include "absl/base/internal/inline_variable.h" >+#include "absl/base/internal/inline_variable_testing.h" >+ >+#include "gtest/gtest.h" >+ >+namespace absl { >+namespace inline_variable_testing_internal { >+namespace { >+ >+TEST(InlineVariableTest, Constexpr) { >+ static_assert(inline_variable_foo.value == 5, ""); >+ static_assert(other_inline_variable_foo.value == 5, ""); >+ static_assert(inline_variable_int == 5, ""); >+ static_assert(other_inline_variable_int == 5, ""); >+} >+ >+TEST(InlineVariableTest, DefaultConstructedIdentityEquality) { >+ EXPECT_EQ(get_foo_a().value, 5); >+ EXPECT_EQ(get_foo_b().value, 5); >+ EXPECT_EQ(&get_foo_a(), &get_foo_b()); >+} >+ >+TEST(InlineVariableTest, DefaultConstructedIdentityInequality) { >+ EXPECT_NE(&inline_variable_foo, &other_inline_variable_foo); >+} >+ >+TEST(InlineVariableTest, InitializedIdentityEquality) { >+ EXPECT_EQ(get_int_a(), 5); >+ EXPECT_EQ(get_int_b(), 5); >+ EXPECT_EQ(&get_int_a(), &get_int_b()); >+} >+ >+TEST(InlineVariableTest, InitializedIdentityInequality) { >+ EXPECT_NE(&inline_variable_int, &other_inline_variable_int); >+} >+ >+TEST(InlineVariableTest, FunPtrType) { >+ static_assert( >+ std::is_same<void(*)(), >+ std::decay<decltype(inline_variable_fun_ptr)>::type>::value, >+ ""); >+} >+ >+} // namespace >+} // namespace inline_variable_testing_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/inline_variable_test_a.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/inline_variable_test_a.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..a3bf3b68b3cfca4fa0209898c761bc26d788e167 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/inline_variable_test_a.cc >@@ -0,0 +1,25 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/inline_variable_testing.h" >+ >+namespace absl { >+namespace inline_variable_testing_internal { >+ >+const Foo& get_foo_a() { return inline_variable_foo; } >+ >+const int& get_int_a() { return inline_variable_int; } >+ >+} // namespace inline_variable_testing_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/inline_variable_test_b.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/inline_variable_test_b.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..b4b9393a5585cf58e51104d9219a8c99a09b79b5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/inline_variable_test_b.cc >@@ -0,0 +1,25 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/inline_variable_testing.h" >+ >+namespace absl { >+namespace inline_variable_testing_internal { >+ >+const Foo& get_foo_b() { return inline_variable_foo; } >+ >+const int& get_int_b() { return inline_variable_int; } >+ >+} // namespace inline_variable_testing_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/atomic_hook.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/atomic_hook.h >new file mode 100644 >index 0000000000000000000000000000000000000000..b458511b0c734940d1ab181b8212c51be0354d7b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/atomic_hook.h >@@ -0,0 +1,165 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ >+#define ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ >+ >+#include <atomic> >+#include <cassert> >+#include <cstdint> >+#include <utility> >+ >+#ifdef _MSC_FULL_VER >+#define ABSL_HAVE_WORKING_ATOMIC_POINTER 0 >+#else >+#define ABSL_HAVE_WORKING_ATOMIC_POINTER 1 >+#endif >+ >+namespace absl { >+namespace base_internal { >+ >+template <typename T> >+class AtomicHook; >+ >+// AtomicHook is a helper class, templatized on a raw function pointer type, for >+// implementing Abseil customization hooks. It is a callable object that >+// dispatches to the registered hook. >+// >+// A default constructed object performs a no-op (and returns a default >+// constructed object) if no hook has been registered. >+// >+// Hooks can be pre-registered via constant initialization, for example, >+// ABSL_CONST_INIT static AtomicHook<void(*)()> my_hook(DefaultAction); >+// and then changed at runtime via a call to Store(). >+// >+// Reads and writes guarantee memory_order_acquire/memory_order_release >+// semantics. >+template <typename ReturnType, typename... Args> >+class AtomicHook<ReturnType (*)(Args...)> { >+ public: >+ using FnPtr = ReturnType (*)(Args...); >+ >+ // Constructs an object that by default performs a no-op (and >+ // returns a default constructed object) when no hook as been registered. >+ constexpr AtomicHook() : AtomicHook(DummyFunction) {} >+ >+ // Constructs an object that by default dispatches to/returns the >+ // pre-registered default_fn when no hook has been registered at runtime. >+#if ABSL_HAVE_WORKING_ATOMIC_POINTER >+ explicit constexpr AtomicHook(FnPtr default_fn) >+ : hook_(default_fn), default_fn_(default_fn) {} >+#else >+ explicit constexpr AtomicHook(FnPtr default_fn) >+ : hook_(kUninitialized), default_fn_(default_fn) {} >+#endif >+ >+ // Stores the provided function pointer as the value for this hook. >+ // >+ // This is intended to be called once. Multiple calls are legal only if the >+ // same function pointer is provided for each call. The store is implemented >+ // as a memory_order_release operation, and read accesses are implemented as >+ // memory_order_acquire. >+ void Store(FnPtr fn) { >+ bool success = DoStore(fn); >+ static_cast<void>(success); >+ assert(success); >+ } >+ >+ // Invokes the registered callback. If no callback has yet been registered, a >+ // default-constructed object of the appropriate type is returned instead. >+ template <typename... CallArgs> >+ ReturnType operator()(CallArgs&&... args) const { >+ return DoLoad()(std::forward<CallArgs>(args)...); >+ } >+ >+ // Returns the registered callback, or nullptr if none has been registered. >+ // Useful if client code needs to conditionalize behavior based on whether a >+ // callback was registered. >+ // >+ // Note that atomic_hook.Load()() and atomic_hook() have different semantics: >+ // operator()() will perform a no-op if no callback was registered, while >+ // Load()() will dereference a null function pointer. Prefer operator()() to >+ // Load()() unless you must conditionalize behavior on whether a hook was >+ // registered. >+ FnPtr Load() const { >+ FnPtr ptr = DoLoad(); >+ return (ptr == DummyFunction) ? nullptr : ptr; >+ } >+ >+ private: >+ static ReturnType DummyFunction(Args...) { >+ return ReturnType(); >+ } >+ >+ // Current versions of MSVC (as of September 2017) have a broken >+ // implementation of std::atomic<T*>: Its constructor attempts to do the >+ // equivalent of a reinterpret_cast in a constexpr context, which is not >+ // allowed. >+ // >+ // This causes an issue when building with LLVM under Windows. To avoid this, >+ // we use a less-efficient, intptr_t-based implementation on Windows. >+#if ABSL_HAVE_WORKING_ATOMIC_POINTER >+ // Return the stored value, or DummyFunction if no value has been stored. >+ FnPtr DoLoad() const { return hook_.load(std::memory_order_acquire); } >+ >+ // Store the given value. Returns false if a different value was already >+ // stored to this object. >+ bool DoStore(FnPtr fn) { >+ assert(fn); >+ FnPtr expected = default_fn_; >+ const bool store_succeeded = hook_.compare_exchange_strong( >+ expected, fn, std::memory_order_acq_rel, std::memory_order_acquire); >+ const bool same_value_already_stored = (expected == fn); >+ return store_succeeded || same_value_already_stored; >+ } >+ >+ std::atomic<FnPtr> hook_; >+#else // !ABSL_HAVE_WORKING_ATOMIC_POINTER >+ // Use a sentinel value unlikely to be the address of an actual function. >+ static constexpr intptr_t kUninitialized = 0; >+ >+ static_assert(sizeof(intptr_t) >= sizeof(FnPtr), >+ "intptr_t can't contain a function pointer"); >+ >+ FnPtr DoLoad() const { >+ const intptr_t value = hook_.load(std::memory_order_acquire); >+ if (value == kUninitialized) { >+ return default_fn_; >+ } >+ return reinterpret_cast<FnPtr>(value); >+ } >+ >+ bool DoStore(FnPtr fn) { >+ assert(fn); >+ const auto value = reinterpret_cast<intptr_t>(fn); >+ intptr_t expected = kUninitialized; >+ const bool store_succeeded = hook_.compare_exchange_strong( >+ expected, value, std::memory_order_acq_rel, std::memory_order_acquire); >+ const bool same_value_already_stored = (expected == value); >+ return store_succeeded || same_value_already_stored; >+ } >+ >+ std::atomic<intptr_t> hook_; >+#endif >+ >+ const FnPtr default_fn_; >+}; >+ >+#undef ABSL_HAVE_WORKING_ATOMIC_POINTER >+ >+} // namespace base_internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/atomic_hook_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/atomic_hook_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..cf7407573a52b47f326a9ca012e47dedbaf7bad7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/atomic_hook_test.cc >@@ -0,0 +1,70 @@ >+// 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/atomic_hook.h" >+ >+#include "gtest/gtest.h" >+#include "absl/base/attributes.h" >+ >+namespace { >+ >+int value = 0; >+void TestHook(int x) { value = x; } >+ >+TEST(AtomicHookTest, NoDefaultFunction) { >+ ABSL_CONST_INIT static absl::base_internal::AtomicHook<void(*)(int)> hook; >+ value = 0; >+ >+ // Test the default DummyFunction. >+ EXPECT_TRUE(hook.Load() == nullptr); >+ EXPECT_EQ(value, 0); >+ hook(1); >+ EXPECT_EQ(value, 0); >+ >+ // Test a stored hook. >+ hook.Store(TestHook); >+ EXPECT_TRUE(hook.Load() == TestHook); >+ EXPECT_EQ(value, 0); >+ hook(1); >+ EXPECT_EQ(value, 1); >+ >+ // Calling Store() with the same hook should not crash. >+ hook.Store(TestHook); >+ EXPECT_TRUE(hook.Load() == TestHook); >+ EXPECT_EQ(value, 1); >+ hook(2); >+ EXPECT_EQ(value, 2); >+} >+ >+TEST(AtomicHookTest, WithDefaultFunction) { >+ // Set the default value to TestHook at compile-time. >+ ABSL_CONST_INIT static absl::base_internal::AtomicHook<void (*)(int)> hook( >+ TestHook); >+ value = 0; >+ >+ // Test the default value is TestHook. >+ EXPECT_TRUE(hook.Load() == TestHook); >+ EXPECT_EQ(value, 0); >+ hook(1); >+ EXPECT_EQ(value, 1); >+ >+ // Calling Store() with the same hook should not crash. >+ hook.Store(TestHook); >+ EXPECT_TRUE(hook.Load() == TestHook); >+ EXPECT_EQ(value, 1); >+ hook(2); >+ EXPECT_EQ(value, 2); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/cycleclock.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/cycleclock.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..a742df01f94a71cd4cf2a50bd00f16c69a816161 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/cycleclock.cc >@@ -0,0 +1,81 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// The implementation of CycleClock::Frequency. >+// >+// NOTE: only i386 and x86_64 have been well tested. >+// PPC, sparc, alpha, and ia64 are based on >+// http://peter.kuscsik.com/wordpress/?p=14 >+// with modifications by m3b. See also >+// https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.0.1/kernel/cycle.h >+ >+#include "absl/base/internal/cycleclock.h" >+ >+#include <chrono> // NOLINT(build/c++11) >+ >+#include "absl/base/internal/unscaledcycleclock.h" >+ >+namespace absl { >+namespace base_internal { >+ >+#if ABSL_USE_UNSCALED_CYCLECLOCK >+ >+namespace { >+ >+#ifdef NDEBUG >+#ifdef ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY >+// Not debug mode and the UnscaledCycleClock frequency is the CPU >+// frequency. Scale the CycleClock to prevent overflow if someone >+// tries to represent the time as cycles since the Unix epoch. >+static constexpr int32_t kShift = 1; >+#else >+// Not debug mode and the UnscaledCycleClock isn't operating at the >+// raw CPU frequency. There is no need to do any scaling, so don't >+// needlessly sacrifice precision. >+static constexpr int32_t kShift = 0; >+#endif >+#else >+// In debug mode use a different shift to discourage depending on a >+// particular shift value. >+static constexpr int32_t kShift = 2; >+#endif >+ >+static constexpr double kFrequencyScale = 1.0 / (1 << kShift); >+ >+} // namespace >+ >+int64_t CycleClock::Now() { >+ return base_internal::UnscaledCycleClock::Now() >> kShift; >+} >+ >+double CycleClock::Frequency() { >+ return kFrequencyScale * base_internal::UnscaledCycleClock::Frequency(); >+} >+ >+#else >+ >+int64_t CycleClock::Now() { >+ return std::chrono::duration_cast<std::chrono::nanoseconds>( >+ std::chrono::steady_clock::now().time_since_epoch()) >+ .count(); >+} >+ >+double CycleClock::Frequency() { >+ return 1e9; >+} >+ >+#endif >+ >+} // namespace base_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/cycleclock.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/cycleclock.h >new file mode 100644 >index 0000000000000000000000000000000000000000..60e971583c5793c3286779def369420e7e32e1db >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/cycleclock.h >@@ -0,0 +1,77 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+// ----------------------------------------------------------------------------- >+// File: cycleclock.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines a `CycleClock`, which yields the value and frequency >+// of a cycle counter that increments at a rate that is approximately constant. >+// >+// NOTE: >+// >+// The cycle counter frequency is not necessarily related to the core clock >+// frequency and should not be treated as such. That is, `CycleClock` cycles are >+// not necessarily "CPU cycles" and code should not rely on that behavior, even >+// if experimentally observed. >+// >+// >+// An arbitrary offset may have been added to the counter at power on. >+// >+// On some platforms, the rate and offset of the counter may differ >+// slightly when read from different CPUs of a multiprocessor. Usually, >+// we try to ensure that the operating system adjusts values periodically >+// so that values agree approximately. If you need stronger guarantees, >+// consider using alternate interfaces. >+// >+// The CPU is not required to maintain the ordering of a cycle counter read >+// with respect to surrounding instructions. >+ >+#ifndef ABSL_BASE_INTERNAL_CYCLECLOCK_H_ >+#define ABSL_BASE_INTERNAL_CYCLECLOCK_H_ >+ >+#include <cstdint> >+ >+namespace absl { >+namespace base_internal { >+ >+// ----------------------------------------------------------------------------- >+// CycleClock >+// ----------------------------------------------------------------------------- >+class CycleClock { >+ public: >+ // CycleClock::Now() >+ // >+ // Returns the value of a cycle counter that counts at a rate that is >+ // approximately constant. >+ static int64_t Now(); >+ >+ // CycleClock::Frequency() >+ // >+ // Returns the amount by which `CycleClock::Now()` increases per second. Note >+ // that this value may not necessarily match the core CPU clock frequency. >+ static double Frequency(); >+ >+ private: >+ CycleClock() = delete; // no instances >+ CycleClock(const CycleClock&) = delete; >+ CycleClock& operator=(const CycleClock&) = delete; >+}; >+ >+} // namespace base_internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_CYCLECLOCK_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/direct_mmap.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/direct_mmap.h >new file mode 100644 >index 0000000000000000000000000000000000000000..0426e11890b680586012f05633263c09a13a1da2 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/direct_mmap.h >@@ -0,0 +1,153 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Functions for directly invoking mmap() via syscall, avoiding the case where >+// mmap() has been locally overridden. >+ >+#ifndef ABSL_BASE_INTERNAL_DIRECT_MMAP_H_ >+#define ABSL_BASE_INTERNAL_DIRECT_MMAP_H_ >+ >+#include "absl/base/config.h" >+ >+#if ABSL_HAVE_MMAP >+ >+#include <sys/mman.h> >+ >+#ifdef __linux__ >+ >+#include <sys/types.h> >+#ifdef __BIONIC__ >+#include <sys/syscall.h> >+#else >+#include <syscall.h> >+#endif >+ >+#include <linux/unistd.h> >+#include <unistd.h> >+#include <cerrno> >+#include <cstdarg> >+#include <cstdint> >+ >+#ifdef __mips__ >+// Include definitions of the ABI currently in use. >+#ifdef __BIONIC__ >+// Android doesn't have sgidefs.h, but does have asm/sgidefs.h, which has the >+// definitions we need. >+#include <asm/sgidefs.h> >+#else >+#include <sgidefs.h> >+#endif // __BIONIC__ >+#endif // __mips__ >+ >+// SYS_mmap and SYS_munmap are not defined in Android. >+#ifdef __BIONIC__ >+extern "C" void* __mmap2(void*, size_t, int, int, int, size_t); >+#if defined(__NR_mmap) && !defined(SYS_mmap) >+#define SYS_mmap __NR_mmap >+#endif >+#ifndef SYS_munmap >+#define SYS_munmap __NR_munmap >+#endif >+#endif // __BIONIC__ >+ >+namespace absl { >+namespace base_internal { >+ >+// Platform specific logic extracted from >+// https://chromium.googlesource.com/linux-syscall-support/+/master/linux_syscall_support.h >+inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, >+ off64_t offset) noexcept { >+#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ >+ (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ >+ (defined(__PPC__) && !defined(__PPC64__)) || \ >+ (defined(__s390__) && !defined(__s390x__)) >+ // On these architectures, implement mmap with mmap2. >+ static int pagesize = 0; >+ if (pagesize == 0) { >+ pagesize = getpagesize(); >+ } >+ if (offset < 0 || offset % pagesize != 0) { >+ errno = EINVAL; >+ return MAP_FAILED; >+ } >+#ifdef __BIONIC__ >+ // SYS_mmap2 has problems on Android API level <= 16. >+ // Workaround by invoking __mmap2() instead. >+ return __mmap2(start, length, prot, flags, fd, offset / pagesize); >+#else >+ return reinterpret_cast<void*>( >+ syscall(SYS_mmap2, start, length, prot, flags, fd, >+ static_cast<off_t>(offset / pagesize))); >+#endif >+#elif defined(__s390x__) >+ // On s390x, mmap() arguments are passed in memory. >+ unsigned long buf[6] = {reinterpret_cast<unsigned long>(start), // NOLINT >+ static_cast<unsigned long>(length), // NOLINT >+ static_cast<unsigned long>(prot), // NOLINT >+ static_cast<unsigned long>(flags), // NOLINT >+ static_cast<unsigned long>(fd), // NOLINT >+ static_cast<unsigned long>(offset)}; // NOLINT >+ return reinterpret_cast<void*>(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 >+// sign extension. We can't cast pointers directly because those are >+// 32 bits, and gcc will dump ugly warnings about casting from a pointer >+// to an integer of a different size. We also need to make sure __off64_t >+// isn't truncated to 32-bits under x32. >+#define MMAP_SYSCALL_ARG(x) ((uint64_t)(uintptr_t)(x)) >+ return reinterpret_cast<void*>( >+ syscall(SYS_mmap, MMAP_SYSCALL_ARG(start), MMAP_SYSCALL_ARG(length), >+ MMAP_SYSCALL_ARG(prot), MMAP_SYSCALL_ARG(flags), >+ MMAP_SYSCALL_ARG(fd), static_cast<uint64_t>(offset))); >+#undef MMAP_SYSCALL_ARG >+#else // Remaining 64-bit aritectures. >+ static_assert(sizeof(unsigned long) == 8, "Platform is not 64-bit"); >+ return reinterpret_cast<void*>( >+ syscall(SYS_mmap, start, length, prot, flags, fd, offset)); >+#endif >+} >+ >+inline int DirectMunmap(void* start, size_t length) { >+ return static_cast<int>(syscall(SYS_munmap, start, length)); >+} >+ >+} // namespace base_internal >+} // namespace absl >+ >+#else // !__linux__ >+ >+// For non-linux platforms where we have mmap, just dispatch directly to the >+// actual mmap()/munmap() methods. >+ >+namespace absl { >+namespace base_internal { >+ >+inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, >+ off_t offset) { >+ return mmap(start, length, prot, flags, fd, offset); >+} >+ >+inline int DirectMunmap(void* start, size_t length) { >+ return munmap(start, length); >+} >+ >+} // namespace base_internal >+} // namespace absl >+ >+#endif // __linux__ >+ >+#endif // ABSL_HAVE_MMAP >+ >+#endif // ABSL_BASE_INTERNAL_DIRECT_MMAP_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/endian.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/endian.h >new file mode 100644 >index 0000000000000000000000000000000000000000..edc10f10a5aaa3548a3c451bc575e521f122756e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/endian.h >@@ -0,0 +1,269 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_BASE_INTERNAL_ENDIAN_H_ >+#define ABSL_BASE_INTERNAL_ENDIAN_H_ >+ >+// The following guarantees declaration of the byte swap functions >+#ifdef _MSC_VER >+#include <stdlib.h> // NOLINT(build/include) >+#elif defined(__APPLE__) >+// Mac OS X / Darwin features >+#include <libkern/OSByteOrder.h> >+#elif defined(__FreeBSD__) >+#include <sys/endian.h> >+#elif defined(__GLIBC__) >+#include <byteswap.h> // IWYU pragma: export >+#endif >+ >+#include <cstdint> >+#include "absl/base/config.h" >+#include "absl/base/internal/unaligned_access.h" >+#include "absl/base/port.h" >+ >+namespace absl { >+ >+// 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. >+// The 16-bit version is available in Clang and GCC only as of GCC 4.8.0. >+// For simplicity, we enable them all only for GCC 4.8.0 or later. >+#if defined(__clang__) || \ >+ (defined(__GNUC__) && \ >+ ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5)) >+inline uint64_t gbswap_64(uint64_t host_int) { >+ return __builtin_bswap64(host_int); >+} >+inline uint32_t gbswap_32(uint32_t host_int) { >+ return __builtin_bswap32(host_int); >+} >+inline uint16_t gbswap_16(uint16_t host_int) { >+ return __builtin_bswap16(host_int); >+} >+ >+#elif defined(_MSC_VER) >+inline uint64_t gbswap_64(uint64_t host_int) { >+ return _byteswap_uint64(host_int); >+} >+inline uint32_t gbswap_32(uint32_t host_int) { >+ return _byteswap_ulong(host_int); >+} >+inline uint16_t gbswap_16(uint16_t host_int) { >+ return _byteswap_ushort(host_int); >+} >+ >+#elif defined(__APPLE__) >+inline uint64_t gbswap_64(uint64_t host_int) { return OSSwapInt16(host_int); } >+inline uint32_t gbswap_32(uint32_t host_int) { return OSSwapInt32(host_int); } >+inline uint16_t gbswap_16(uint16_t host_int) { return OSSwapInt64(host_int); } >+ >+#else >+inline uint64_t gbswap_64(uint64_t host_int) { >+#if defined(__GNUC__) && defined(__x86_64__) && !defined(__APPLE__) >+ // Adapted from /usr/include/byteswap.h. Not available on Mac. >+ if (__builtin_constant_p(host_int)) { >+ return __bswap_constant_64(host_int); >+ } else { >+ register uint64_t result; >+ __asm__("bswap %0" : "=r"(result) : "0"(host_int)); >+ return result; >+ } >+#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)); >+#endif // bswap_64 >+} >+ >+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)); >+#endif >+} >+ >+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)}; >+#endif >+} >+ >+#endif // intrinics available >+ >+#ifdef ABSL_IS_LITTLE_ENDIAN >+ >+// Definitions for ntohl etc. that don't require us to include >+// netinet/in.h. We wrap gbswap_32 and gbswap_16 in functions rather >+// than just #defining them because in debug mode, gcc doesn't >+// correctly handle the (rather involved) definitions of bswap_32. >+// gcc guarantees that inline functions are as fast as macros, so >+// this isn't a performance hit. >+inline uint16_t ghtons(uint16_t x) { return gbswap_16(x); } >+inline uint32_t ghtonl(uint32_t x) { return gbswap_32(x); } >+inline uint64_t ghtonll(uint64_t x) { return gbswap_64(x); } >+ >+#elif defined ABSL_IS_BIG_ENDIAN >+ >+// These definitions are simpler on big-endian machines >+// These are functions instead of macros to avoid self-assignment warnings >+// on calls such as "i = ghtnol(i);". This also provides type checking. >+inline uint16_t ghtons(uint16_t x) { return x; } >+inline uint32_t ghtonl(uint32_t x) { return x; } >+inline uint64_t ghtonll(uint64_t x) { return x; } >+ >+#else >+#error \ >+ "Unsupported byte order: Either ABSL_IS_BIG_ENDIAN or " \ >+ "ABSL_IS_LITTLE_ENDIAN must be defined" >+#endif // byte order >+ >+inline uint16_t gntohs(uint16_t x) { return ghtons(x); } >+inline uint32_t gntohl(uint32_t x) { return ghtonl(x); } >+inline uint64_t gntohll(uint64_t x) { return ghtonll(x); } >+ >+// Utilities to convert numbers between the current hosts's native byte >+// order and little-endian byte order >+// >+// Load/Store methods are alignment safe >+namespace little_endian { >+// Conversion functions. >+#ifdef ABSL_IS_LITTLE_ENDIAN >+ >+inline uint16_t FromHost16(uint16_t x) { return x; } >+inline uint16_t ToHost16(uint16_t x) { return x; } >+ >+inline uint32_t FromHost32(uint32_t x) { return x; } >+inline uint32_t ToHost32(uint32_t x) { return x; } >+ >+inline uint64_t FromHost64(uint64_t x) { return x; } >+inline uint64_t ToHost64(uint64_t x) { return x; } >+ >+inline constexpr bool IsLittleEndian() { return true; } >+ >+#elif defined ABSL_IS_BIG_ENDIAN >+ >+inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); } >+inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); } >+ >+inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); } >+inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); } >+ >+inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); } >+inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); } >+ >+inline constexpr bool IsLittleEndian() { return false; } >+ >+#endif /* ENDIAN */ >+ >+// Functions to do unaligned loads and stores in little-endian order. >+inline uint16_t Load16(const void *p) { >+ return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p)); >+} >+ >+inline void Store16(void *p, uint16_t v) { >+ ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v)); >+} >+ >+inline uint32_t Load32(const void *p) { >+ return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p)); >+} >+ >+inline void Store32(void *p, uint32_t v) { >+ ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v)); >+} >+ >+inline uint64_t Load64(const void *p) { >+ return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p)); >+} >+ >+inline void Store64(void *p, uint64_t v) { >+ ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v)); >+} >+ >+} // namespace little_endian >+ >+// Utilities to convert numbers between the current hosts's native byte >+// order and big-endian byte order (same as network byte order) >+// >+// Load/Store methods are alignment safe >+namespace big_endian { >+#ifdef ABSL_IS_LITTLE_ENDIAN >+ >+inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); } >+inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); } >+ >+inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); } >+inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); } >+ >+inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); } >+inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); } >+ >+inline constexpr bool IsLittleEndian() { return true; } >+ >+#elif defined ABSL_IS_BIG_ENDIAN >+ >+inline uint16_t FromHost16(uint16_t x) { return x; } >+inline uint16_t ToHost16(uint16_t x) { return x; } >+ >+inline uint32_t FromHost32(uint32_t x) { return x; } >+inline uint32_t ToHost32(uint32_t x) { return x; } >+ >+inline uint64_t FromHost64(uint64_t x) { return x; } >+inline uint64_t ToHost64(uint64_t x) { return x; } >+ >+inline constexpr bool IsLittleEndian() { return false; } >+ >+#endif /* ENDIAN */ >+ >+// Functions to do unaligned loads and stores in big-endian order. >+inline uint16_t Load16(const void *p) { >+ return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p)); >+} >+ >+inline void Store16(void *p, uint16_t v) { >+ ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v)); >+} >+ >+inline uint32_t Load32(const void *p) { >+ return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p)); >+} >+ >+inline void Store32(void *p, uint32_t v) { >+ ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v)); >+} >+ >+inline uint64_t Load64(const void *p) { >+ return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p)); >+} >+ >+inline void Store64(void *p, uint64_t v) { >+ ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v)); >+} >+ >+} // namespace big_endian >+ >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_ENDIAN_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/endian_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/endian_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e27691553bc628caf1ba916a39dc8a3a9f2a881f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/endian_test.cc >@@ -0,0 +1,263 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/endian.h" >+ >+#include <algorithm> >+#include <cstdint> >+#include <limits> >+#include <random> >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/base/config.h" >+ >+namespace absl { >+namespace { >+ >+const uint64_t kInitialNumber{0x0123456789abcdef}; >+const uint64_t k64Value{kInitialNumber}; >+const uint32_t k32Value{0x01234567}; >+const uint16_t k16Value{0x0123}; >+const int kNumValuesToTest = 1000000; >+const int kRandomSeed = 12345; >+ >+#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 uint64_t k64ValueBE{kInitialNumber}; >+const uint32_t k32ValueBE{k32Value}; >+const uint16_t k16ValueBE{k16Value}; >+#elif defined(ABSL_IS_LITTLE_ENDIAN) >+const uint64_t kInitialInNetworkOrder{0xefcdab8967452301}; >+const uint64_t k64ValueLE{kInitialNumber}; >+const uint32_t k32ValueLE{k32Value}; >+const uint16_t k16ValueLE{k16Value}; >+ >+const uint64_t k64ValueBE{0xefcdab8967452301}; >+const uint32_t k32ValueBE{0x67452301}; >+const uint16_t k16ValueBE{0x2301}; >+#endif >+ >+template<typename T> >+std::vector<T> GenerateAllValuesForType() { >+ std::vector<T> result; >+ T next = std::numeric_limits<T>::min(); >+ while (true) { >+ result.push_back(next); >+ if (next == std::numeric_limits<T>::max()) { >+ return result; >+ } >+ ++next; >+ } >+} >+ >+template<typename T> >+std::vector<T> GenerateRandomIntegers(size_t numValuesToTest) { >+ std::vector<T> result; >+ std::mt19937_64 rng(kRandomSeed); >+ for (size_t i = 0; i < numValuesToTest; ++i) { >+ result.push_back(rng()); >+ } >+ return result; >+} >+ >+void ManualByteSwap(char* bytes, int length) { >+ if (length == 1) >+ return; >+ >+ EXPECT_EQ(0, length % 2); >+ for (int i = 0; i < length / 2; ++i) { >+ int j = (length - 1) - i; >+ using std::swap; >+ swap(bytes[i], bytes[j]); >+ } >+} >+ >+template<typename T> >+inline T UnalignedLoad(const char* p) { >+ static_assert( >+ sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, >+ "Unexpected type size"); >+ >+ switch (sizeof(T)) { >+ case 1: return *reinterpret_cast<const T*>(p); >+ case 2: >+ return ABSL_INTERNAL_UNALIGNED_LOAD16(p); >+ case 4: >+ return ABSL_INTERNAL_UNALIGNED_LOAD32(p); >+ case 8: >+ return ABSL_INTERNAL_UNALIGNED_LOAD64(p); >+ default: >+ // Suppresses invalid "not all control paths return a value" on MSVC >+ return {}; >+ } >+} >+ >+template <typename T, typename ByteSwapper> >+static void GBSwapHelper(const std::vector<T>& host_values_to_test, >+ const ByteSwapper& byte_swapper) { >+ // Test byte_swapper against a manual byte swap. >+ for (typename std::vector<T>::const_iterator it = host_values_to_test.begin(); >+ it != host_values_to_test.end(); ++it) { >+ T host_value = *it; >+ >+ char actual_value[sizeof(host_value)]; >+ memcpy(actual_value, &host_value, sizeof(host_value)); >+ byte_swapper(actual_value); >+ >+ char expected_value[sizeof(host_value)]; >+ memcpy(expected_value, &host_value, sizeof(host_value)); >+ ManualByteSwap(expected_value, sizeof(host_value)); >+ >+ ASSERT_EQ(0, memcmp(actual_value, expected_value, sizeof(host_value))) >+ << "Swap output for 0x" << std::hex << host_value << " does not match. " >+ << "Expected: 0x" << UnalignedLoad<T>(expected_value) << "; " >+ << "actual: 0x" << UnalignedLoad<T>(actual_value); >+ } >+} >+ >+void Swap16(char* bytes) { >+ ABSL_INTERNAL_UNALIGNED_STORE16( >+ bytes, gbswap_16(ABSL_INTERNAL_UNALIGNED_LOAD16(bytes))); >+} >+ >+void Swap32(char* bytes) { >+ ABSL_INTERNAL_UNALIGNED_STORE32( >+ bytes, gbswap_32(ABSL_INTERNAL_UNALIGNED_LOAD32(bytes))); >+} >+ >+void Swap64(char* bytes) { >+ ABSL_INTERNAL_UNALIGNED_STORE64( >+ bytes, gbswap_64(ABSL_INTERNAL_UNALIGNED_LOAD64(bytes))); >+} >+ >+TEST(EndianessTest, Uint16) { >+ GBSwapHelper(GenerateAllValuesForType<uint16_t>(), &Swap16); >+} >+ >+TEST(EndianessTest, Uint32) { >+ GBSwapHelper(GenerateRandomIntegers<uint32_t>(kNumValuesToTest), &Swap32); >+} >+ >+TEST(EndianessTest, Uint64) { >+ GBSwapHelper(GenerateRandomIntegers<uint64_t>(kNumValuesToTest), &Swap64); >+} >+ >+TEST(EndianessTest, ghtonll_gntohll) { >+ // Test that absl::ghtonl compiles correctly >+ uint32_t test = 0x01234567; >+ EXPECT_EQ(absl::gntohl(absl::ghtonl(test)), test); >+ >+ uint64_t comp = absl::ghtonll(kInitialNumber); >+ EXPECT_EQ(comp, kInitialInNetworkOrder); >+ comp = absl::gntohll(kInitialInNetworkOrder); >+ EXPECT_EQ(comp, kInitialNumber); >+ >+ // Test that htonll and ntohll are each others' inverse functions on a >+ // somewhat assorted batch of numbers. 37 is chosen to not be anything >+ // particularly nice base 2. >+ uint64_t value = 1; >+ for (int i = 0; i < 100; ++i) { >+ comp = absl::ghtonll(absl::gntohll(value)); >+ EXPECT_EQ(value, comp); >+ comp = absl::gntohll(absl::ghtonll(value)); >+ EXPECT_EQ(value, comp); >+ value *= 37; >+ } >+} >+ >+TEST(EndianessTest, little_endian) { >+ // Check little_endian uint16_t. >+ uint64_t comp = little_endian::FromHost16(k16Value); >+ EXPECT_EQ(comp, k16ValueLE); >+ comp = little_endian::ToHost16(k16ValueLE); >+ EXPECT_EQ(comp, k16Value); >+ >+ // Check little_endian uint32_t. >+ comp = little_endian::FromHost32(k32Value); >+ EXPECT_EQ(comp, k32ValueLE); >+ comp = little_endian::ToHost32(k32ValueLE); >+ EXPECT_EQ(comp, k32Value); >+ >+ // Check little_endian uint64_t. >+ comp = little_endian::FromHost64(k64Value); >+ EXPECT_EQ(comp, k64ValueLE); >+ comp = little_endian::ToHost64(k64ValueLE); >+ EXPECT_EQ(comp, k64Value); >+ >+ // Check little-endian Load and store functions. >+ uint16_t u16Buf; >+ uint32_t u32Buf; >+ uint64_t u64Buf; >+ >+ little_endian::Store16(&u16Buf, k16Value); >+ EXPECT_EQ(u16Buf, k16ValueLE); >+ comp = little_endian::Load16(&u16Buf); >+ EXPECT_EQ(comp, k16Value); >+ >+ little_endian::Store32(&u32Buf, k32Value); >+ EXPECT_EQ(u32Buf, k32ValueLE); >+ comp = little_endian::Load32(&u32Buf); >+ EXPECT_EQ(comp, k32Value); >+ >+ little_endian::Store64(&u64Buf, k64Value); >+ EXPECT_EQ(u64Buf, k64ValueLE); >+ comp = little_endian::Load64(&u64Buf); >+ EXPECT_EQ(comp, k64Value); >+} >+ >+TEST(EndianessTest, big_endian) { >+ // Check big-endian Load and store functions. >+ uint16_t u16Buf; >+ uint32_t u32Buf; >+ uint64_t u64Buf; >+ >+ unsigned char buffer[10]; >+ big_endian::Store16(&u16Buf, k16Value); >+ EXPECT_EQ(u16Buf, k16ValueBE); >+ uint64_t comp = big_endian::Load16(&u16Buf); >+ EXPECT_EQ(comp, k16Value); >+ >+ big_endian::Store32(&u32Buf, k32Value); >+ EXPECT_EQ(u32Buf, k32ValueBE); >+ comp = big_endian::Load32(&u32Buf); >+ EXPECT_EQ(comp, k32Value); >+ >+ big_endian::Store64(&u64Buf, k64Value); >+ EXPECT_EQ(u64Buf, k64ValueBE); >+ comp = big_endian::Load64(&u64Buf); >+ EXPECT_EQ(comp, k64Value); >+ >+ big_endian::Store16(buffer + 1, k16Value); >+ EXPECT_EQ(u16Buf, k16ValueBE); >+ comp = big_endian::Load16(buffer + 1); >+ EXPECT_EQ(comp, k16Value); >+ >+ big_endian::Store32(buffer + 1, k32Value); >+ EXPECT_EQ(u32Buf, k32ValueBE); >+ comp = big_endian::Load32(buffer + 1); >+ EXPECT_EQ(comp, k32Value); >+ >+ big_endian::Store64(buffer + 1, k64Value); >+ EXPECT_EQ(u64Buf, k64ValueBE); >+ comp = big_endian::Load64(buffer + 1); >+ EXPECT_EQ(comp, k64Value); >+} >+ >+} // namespace >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..f1d081f7e50dd66ae93bd3d8612ef21e1f521843 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc >@@ -0,0 +1,71 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/exception_safety_testing.h" >+ >+#include "gtest/gtest.h" >+#include "absl/meta/type_traits.h" >+ >+namespace testing { >+ >+exceptions_internal::NoThrowTag nothrow_ctor; >+ >+exceptions_internal::StrongGuaranteeTagType strong_guarantee; >+ >+namespace exceptions_internal { >+ >+int countdown = -1; >+ >+ConstructorTracker* ConstructorTracker::current_tracker_instance_ = nullptr; >+ >+void MaybeThrow(absl::string_view msg, bool throw_bad_alloc) { >+ if (countdown-- == 0) { >+ if (throw_bad_alloc) throw TestBadAllocException(msg); >+ throw TestException(msg); >+ } >+} >+ >+testing::AssertionResult FailureMessage(const TestException& e, >+ int countdown) noexcept { >+ return testing::AssertionFailure() << "Exception thrown from " << e.what(); >+} >+ >+std::string GetSpecString(TypeSpec spec) { >+ std::string out; >+ absl::string_view sep; >+ const auto append = [&](absl::string_view s) { >+ absl::StrAppend(&out, sep, s); >+ sep = " | "; >+ }; >+ if (static_cast<bool>(TypeSpec::kNoThrowCopy & spec)) { >+ append("kNoThrowCopy"); >+ } >+ if (static_cast<bool>(TypeSpec::kNoThrowMove & spec)) { >+ append("kNoThrowMove"); >+ } >+ if (static_cast<bool>(TypeSpec::kNoThrowNew & spec)) { >+ append("kNoThrowNew"); >+ } >+ return out; >+} >+ >+std::string GetSpecString(AllocSpec spec) { >+ return static_cast<bool>(AllocSpec::kNoThrowAllocate & spec) >+ ? "kNoThrowAllocate" >+ : ""; >+} >+ >+} // namespace exceptions_internal >+ >+} // namespace testing >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8c2f5093fc4da828afa82342be44995d18a3bbe7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h >@@ -0,0 +1,1109 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Utilities for testing exception-safety >+ >+#ifndef ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_ >+#define ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_ >+ >+#include <cstddef> >+#include <cstdint> >+#include <functional> >+#include <initializer_list> >+#include <iosfwd> >+#include <string> >+#include <tuple> >+#include <unordered_map> >+ >+#include "gtest/gtest.h" >+#include "absl/base/config.h" >+#include "absl/base/internal/pretty_function.h" >+#include "absl/memory/memory.h" >+#include "absl/meta/type_traits.h" >+#include "absl/strings/string_view.h" >+#include "absl/strings/substitute.h" >+#include "absl/types/optional.h" >+ >+namespace testing { >+ >+enum class TypeSpec; >+enum class AllocSpec; >+ >+constexpr TypeSpec operator|(TypeSpec a, TypeSpec b) { >+ using T = absl::underlying_type_t<TypeSpec>; >+ return static_cast<TypeSpec>(static_cast<T>(a) | static_cast<T>(b)); >+} >+ >+constexpr TypeSpec operator&(TypeSpec a, TypeSpec b) { >+ using T = absl::underlying_type_t<TypeSpec>; >+ return static_cast<TypeSpec>(static_cast<T>(a) & static_cast<T>(b)); >+} >+ >+constexpr AllocSpec operator|(AllocSpec a, AllocSpec b) { >+ using T = absl::underlying_type_t<AllocSpec>; >+ return static_cast<AllocSpec>(static_cast<T>(a) | static_cast<T>(b)); >+} >+ >+constexpr AllocSpec operator&(AllocSpec a, AllocSpec b) { >+ using T = absl::underlying_type_t<AllocSpec>; >+ return static_cast<AllocSpec>(static_cast<T>(a) & static_cast<T>(b)); >+} >+ >+namespace exceptions_internal { >+ >+std::string GetSpecString(TypeSpec); >+std::string GetSpecString(AllocSpec); >+ >+struct NoThrowTag {}; >+struct StrongGuaranteeTagType {}; >+ >+// A simple exception class. We throw this so that test code can catch >+// exceptions specifically thrown by ThrowingValue. >+class TestException { >+ public: >+ explicit TestException(absl::string_view msg) : msg_(msg) {} >+ virtual ~TestException() {} >+ virtual const char* what() const noexcept { return msg_.c_str(); } >+ >+ private: >+ std::string msg_; >+}; >+ >+// TestBadAllocException exists because allocation functions must throw an >+// exception which can be caught by a handler of std::bad_alloc. We use a child >+// class of std::bad_alloc so we can customise the error message, and also >+// derive from TestException so we don't accidentally end up catching an actual >+// bad_alloc exception in TestExceptionSafety. >+class TestBadAllocException : public std::bad_alloc, public TestException { >+ public: >+ explicit TestBadAllocException(absl::string_view msg) : TestException(msg) {} >+ using TestException::what; >+}; >+ >+extern int countdown; >+ >+// Allows the countdown variable to be set manually (defaulting to the initial >+// value of 0) >+inline void SetCountdown(int i = 0) { countdown = i; } >+// Sets the countdown to the terminal value -1 >+inline void UnsetCountdown() { SetCountdown(-1); } >+ >+void MaybeThrow(absl::string_view msg, bool throw_bad_alloc = false); >+ >+testing::AssertionResult FailureMessage(const TestException& e, >+ int countdown) noexcept; >+ >+struct TrackedAddress { >+ bool is_alive; >+ std::string description; >+}; >+ >+// Inspects the constructions and destructions of anything inheriting from >+// TrackedObject. This allows us to safely "leak" TrackedObjects, as >+// ConstructorTracker will destroy everything left over in its destructor. >+class ConstructorTracker { >+ public: >+ explicit ConstructorTracker(int count) : countdown_(count) { >+ assert(current_tracker_instance_ == nullptr); >+ current_tracker_instance_ = this; >+ } >+ >+ ~ConstructorTracker() { >+ assert(current_tracker_instance_ == this); >+ current_tracker_instance_ = nullptr; >+ >+ for (auto& it : address_map_) { >+ void* address = it.first; >+ TrackedAddress& tracked_address = it.second; >+ if (tracked_address.is_alive) { >+ ADD_FAILURE() << "Object at address " << address >+ << " with countdown of " << countdown_ >+ << " was not destroyed [" << tracked_address.description >+ << "]"; >+ } >+ } >+ } >+ >+ static void ObjectConstructed(void* address, std::string description) { >+ if (!CurrentlyTracking()) return; >+ >+ TrackedAddress& tracked_address = >+ current_tracker_instance_->address_map_[address]; >+ if (tracked_address.is_alive) { >+ ADD_FAILURE() << "Object at address " << address << " with countdown of " >+ << current_tracker_instance_->countdown_ >+ << " was re-constructed. Previously: [" >+ << tracked_address.description << "] Now: [" << description >+ << "]"; >+ } >+ tracked_address = {true, std::move(description)}; >+ } >+ >+ static void ObjectDestructed(void* address) { >+ if (!CurrentlyTracking()) return; >+ >+ auto it = current_tracker_instance_->address_map_.find(address); >+ // Not tracked. Ignore. >+ if (it == current_tracker_instance_->address_map_.end()) return; >+ >+ TrackedAddress& tracked_address = it->second; >+ if (!tracked_address.is_alive) { >+ ADD_FAILURE() << "Object at address " << address << " with countdown of " >+ << current_tracker_instance_->countdown_ >+ << " was re-destroyed or created prior to construction " >+ << "tracking [" << tracked_address.description << "]"; >+ } >+ tracked_address.is_alive = false; >+ } >+ >+ private: >+ static bool CurrentlyTracking() { >+ return current_tracker_instance_ != nullptr; >+ } >+ >+ std::unordered_map<void*, TrackedAddress> address_map_; >+ int countdown_; >+ >+ static ConstructorTracker* current_tracker_instance_; >+}; >+ >+class TrackedObject { >+ public: >+ TrackedObject(const TrackedObject&) = delete; >+ TrackedObject(TrackedObject&&) = delete; >+ >+ protected: >+ explicit TrackedObject(std::string description) { >+ ConstructorTracker::ObjectConstructed(this, std::move(description)); >+ } >+ >+ ~TrackedObject() noexcept { ConstructorTracker::ObjectDestructed(this); } >+}; >+ >+template <typename Factory, typename Operation, typename Invariant> >+absl::optional<testing::AssertionResult> TestSingleInvariantAtCountdownImpl( >+ const Factory& factory, const Operation& operation, int count, >+ const Invariant& invariant) { >+ auto t_ptr = factory(); >+ absl::optional<testing::AssertionResult> current_res; >+ SetCountdown(count); >+ try { >+ operation(t_ptr.get()); >+ } catch (const exceptions_internal::TestException& e) { >+ current_res.emplace(invariant(t_ptr.get())); >+ if (!current_res.value()) { >+ *current_res << e.what() << " failed invariant check"; >+ } >+ } >+ UnsetCountdown(); >+ return current_res; >+} >+ >+template <typename Factory, typename Operation> >+absl::optional<testing::AssertionResult> 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 <typename Factory, typename Operation, typename Invariant> >+int TestSingleInvariantAtCountdown( >+ const Factory& factory, const Operation& operation, int count, >+ const Invariant& invariant, >+ absl::optional<testing::AssertionResult>* 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 <typename Factory, typename Operation, typename... Invariants> >+inline absl::optional<testing::AssertionResult> TestAllInvariantsAtCountdown( >+ const Factory& factory, const Operation& operation, int count, >+ const Invariants&... invariants) { >+ absl::optional<testing::AssertionResult> reduced_res; >+ >+ // Run each checker, short circuiting after the first failure >+ int dummy[] = { >+ 0, (TestSingleInvariantAtCountdown(factory, operation, count, invariants, >+ &reduced_res))...}; >+ static_cast<void>(dummy); >+ return reduced_res; >+} >+ >+} // namespace exceptions_internal >+ >+extern exceptions_internal::NoThrowTag nothrow_ctor; >+ >+extern exceptions_internal::StrongGuaranteeTagType strong_guarantee; >+ >+// A test class which is convertible to bool. The conversion can be >+// instrumented to throw at a controlled time. >+class ThrowingBool { >+ public: >+ ThrowingBool(bool b) noexcept : b_(b) {} // NOLINT(runtime/explicit) >+ operator bool() const { // NOLINT >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return b_; >+ } >+ >+ private: >+ bool b_; >+}; >+ >+/* >+ * Configuration enum for the ThrowingValue type that defines behavior for the >+ * lifetime of the instance. Use testing::nothrow_ctor to prevent the integer >+ * constructor from throwing. >+ * >+ * kEverythingThrows: Every operation can throw an exception >+ * kNoThrowCopy: Copy construction and copy assignment will not throw >+ * kNoThrowMove: Move construction and move assignment will not throw >+ * kNoThrowNew: Overloaded operators new and new[] will not throw >+ */ >+enum class TypeSpec { >+ kEverythingThrows = 0, >+ kNoThrowCopy = 1, >+ kNoThrowMove = 1 << 1, >+ kNoThrowNew = 1 << 2, >+}; >+ >+/* >+ * A testing class instrumented to throw an exception at a controlled time. >+ * >+ * ThrowingValue implements a slightly relaxed version of the Regular concept -- >+ * that is it's a value type with the expected semantics. It also implements >+ * arithmetic operations. It doesn't implement member and pointer operators >+ * like operator-> or operator[]. >+ * >+ * ThrowingValue can be instrumented to have certain operations be noexcept by >+ * using compile-time bitfield template arguments. That is, to make an >+ * ThrowingValue which has noexcept move construction/assignment and noexcept >+ * copy construction/assignment, use the following: >+ * ThrowingValue<testing::kNoThrowMove | testing::kNoThrowCopy> my_thrwr{val}; >+ */ >+template <TypeSpec Spec = TypeSpec::kEverythingThrows> >+class ThrowingValue : private exceptions_internal::TrackedObject { >+ static constexpr bool IsSpecified(TypeSpec spec) { >+ return static_cast<bool>(Spec & spec); >+ } >+ >+ static constexpr int kDefaultValue = 0; >+ static constexpr int kBadValue = 938550620; >+ >+ public: >+ ThrowingValue() : TrackedObject(GetInstanceString(kDefaultValue)) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ = kDefaultValue; >+ } >+ >+ ThrowingValue(const ThrowingValue& other) noexcept( >+ IsSpecified(TypeSpec::kNoThrowCopy)) >+ : TrackedObject(GetInstanceString(other.dummy_)) { >+ if (!IsSpecified(TypeSpec::kNoThrowCopy)) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ } >+ dummy_ = other.dummy_; >+ } >+ >+ ThrowingValue(ThrowingValue&& other) noexcept( >+ IsSpecified(TypeSpec::kNoThrowMove)) >+ : TrackedObject(GetInstanceString(other.dummy_)) { >+ if (!IsSpecified(TypeSpec::kNoThrowMove)) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ } >+ dummy_ = other.dummy_; >+ } >+ >+ explicit ThrowingValue(int i) : TrackedObject(GetInstanceString(i)) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ = i; >+ } >+ >+ ThrowingValue(int i, exceptions_internal::NoThrowTag) noexcept >+ : TrackedObject(GetInstanceString(i)), dummy_(i) {} >+ >+ // absl expects nothrow destructors >+ ~ThrowingValue() noexcept = default; >+ >+ ThrowingValue& operator=(const ThrowingValue& other) noexcept( >+ IsSpecified(TypeSpec::kNoThrowCopy)) { >+ dummy_ = kBadValue; >+ if (!IsSpecified(TypeSpec::kNoThrowCopy)) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ } >+ dummy_ = other.dummy_; >+ return *this; >+ } >+ >+ ThrowingValue& operator=(ThrowingValue&& other) noexcept( >+ IsSpecified(TypeSpec::kNoThrowMove)) { >+ dummy_ = kBadValue; >+ if (!IsSpecified(TypeSpec::kNoThrowMove)) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ } >+ dummy_ = other.dummy_; >+ return *this; >+ } >+ >+ // Arithmetic Operators >+ ThrowingValue operator+(const ThrowingValue& other) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_ + other.dummy_, nothrow_ctor); >+ } >+ >+ ThrowingValue operator+() const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_, nothrow_ctor); >+ } >+ >+ ThrowingValue operator-(const ThrowingValue& other) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_ - other.dummy_, nothrow_ctor); >+ } >+ >+ ThrowingValue operator-() const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(-dummy_, nothrow_ctor); >+ } >+ >+ ThrowingValue& operator++() { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ ++dummy_; >+ return *this; >+ } >+ >+ ThrowingValue operator++(int) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ auto out = ThrowingValue(dummy_, nothrow_ctor); >+ ++dummy_; >+ return out; >+ } >+ >+ ThrowingValue& operator--() { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ --dummy_; >+ return *this; >+ } >+ >+ ThrowingValue operator--(int) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ auto out = ThrowingValue(dummy_, nothrow_ctor); >+ --dummy_; >+ return out; >+ } >+ >+ ThrowingValue operator*(const ThrowingValue& other) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_ * other.dummy_, nothrow_ctor); >+ } >+ >+ ThrowingValue operator/(const ThrowingValue& other) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_ / other.dummy_, nothrow_ctor); >+ } >+ >+ ThrowingValue operator%(const ThrowingValue& other) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_ % other.dummy_, nothrow_ctor); >+ } >+ >+ ThrowingValue operator<<(int shift) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_ << shift, nothrow_ctor); >+ } >+ >+ ThrowingValue operator>>(int shift) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_ >> shift, nothrow_ctor); >+ } >+ >+ // Comparison Operators >+ // NOTE: We use `ThrowingBool` instead of `bool` because most STL >+ // types/containers requires T to be convertible to bool. >+ friend ThrowingBool operator==(const ThrowingValue& a, >+ const ThrowingValue& b) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return a.dummy_ == b.dummy_; >+ } >+ friend ThrowingBool operator!=(const ThrowingValue& a, >+ const ThrowingValue& b) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return a.dummy_ != b.dummy_; >+ } >+ friend ThrowingBool operator<(const ThrowingValue& a, >+ const ThrowingValue& b) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return a.dummy_ < b.dummy_; >+ } >+ friend ThrowingBool operator<=(const ThrowingValue& a, >+ const ThrowingValue& b) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return a.dummy_ <= b.dummy_; >+ } >+ friend ThrowingBool operator>(const ThrowingValue& a, >+ const ThrowingValue& b) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return a.dummy_ > b.dummy_; >+ } >+ friend ThrowingBool operator>=(const ThrowingValue& a, >+ const ThrowingValue& b) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return a.dummy_ >= b.dummy_; >+ } >+ >+ // Logical Operators >+ ThrowingBool operator!() const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return !dummy_; >+ } >+ >+ ThrowingBool operator&&(const ThrowingValue& other) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return dummy_ && other.dummy_; >+ } >+ >+ ThrowingBool operator||(const ThrowingValue& other) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return dummy_ || other.dummy_; >+ } >+ >+ // Bitwise Logical Operators >+ ThrowingValue operator~() const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(~dummy_, nothrow_ctor); >+ } >+ >+ ThrowingValue operator&(const ThrowingValue& other) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_ & other.dummy_, nothrow_ctor); >+ } >+ >+ ThrowingValue operator|(const ThrowingValue& other) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_ | other.dummy_, nothrow_ctor); >+ } >+ >+ ThrowingValue operator^(const ThrowingValue& other) const { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return ThrowingValue(dummy_ ^ other.dummy_, nothrow_ctor); >+ } >+ >+ // Compound Assignment operators >+ ThrowingValue& operator+=(const ThrowingValue& other) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ += other.dummy_; >+ return *this; >+ } >+ >+ ThrowingValue& operator-=(const ThrowingValue& other) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ -= other.dummy_; >+ return *this; >+ } >+ >+ ThrowingValue& operator*=(const ThrowingValue& other) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ *= other.dummy_; >+ return *this; >+ } >+ >+ ThrowingValue& operator/=(const ThrowingValue& other) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ /= other.dummy_; >+ return *this; >+ } >+ >+ ThrowingValue& operator%=(const ThrowingValue& other) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ %= other.dummy_; >+ return *this; >+ } >+ >+ ThrowingValue& operator&=(const ThrowingValue& other) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ &= other.dummy_; >+ return *this; >+ } >+ >+ ThrowingValue& operator|=(const ThrowingValue& other) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ |= other.dummy_; >+ return *this; >+ } >+ >+ ThrowingValue& operator^=(const ThrowingValue& other) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ ^= other.dummy_; >+ return *this; >+ } >+ >+ ThrowingValue& operator<<=(int shift) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ <<= shift; >+ return *this; >+ } >+ >+ ThrowingValue& operator>>=(int shift) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ >>= shift; >+ return *this; >+ } >+ >+ // Pointer operators >+ void operator&() const = delete; // NOLINT(runtime/operator) >+ >+ // Stream operators >+ friend std::ostream& operator<<(std::ostream& os, const ThrowingValue& tv) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return os << GetInstanceString(tv.dummy_); >+ } >+ >+ friend std::istream& operator>>(std::istream& is, const ThrowingValue&) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ return is; >+ } >+ >+ // Memory management operators >+ // Args.. allows us to overload regular and placement new in one shot >+ template <typename... Args> >+ static void* operator new(size_t s, Args&&... args) noexcept( >+ IsSpecified(TypeSpec::kNoThrowNew)) { >+ if (!IsSpecified(TypeSpec::kNoThrowNew)) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); >+ } >+ return ::operator new(s, std::forward<Args>(args)...); >+ } >+ >+ template <typename... Args> >+ static void* operator new[](size_t s, Args&&... args) noexcept( >+ IsSpecified(TypeSpec::kNoThrowNew)) { >+ if (!IsSpecified(TypeSpec::kNoThrowNew)) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); >+ } >+ return ::operator new[](s, std::forward<Args>(args)...); >+ } >+ >+ // Abseil doesn't support throwing overloaded operator delete. These are >+ // provided so a throwing operator-new can clean up after itself. >+ // >+ // We provide both regular and templated operator delete because if only the >+ // templated version is provided as we did with operator new, the compiler has >+ // no way of knowing which overload of operator delete to call. See >+ // http://en.cppreference.com/w/cpp/memory/new/operator_delete and >+ // http://en.cppreference.com/w/cpp/language/delete for the gory details. >+ void operator delete(void* p) noexcept { ::operator delete(p); } >+ >+ template <typename... Args> >+ void operator delete(void* p, Args&&... args) noexcept { >+ ::operator delete(p, std::forward<Args>(args)...); >+ } >+ >+ void operator delete[](void* p) noexcept { return ::operator delete[](p); } >+ >+ template <typename... Args> >+ void operator delete[](void* p, Args&&... args) noexcept { >+ return ::operator delete[](p, std::forward<Args>(args)...); >+ } >+ >+ // Non-standard access to the actual contained value. No need for this to >+ // throw. >+ int& Get() noexcept { return dummy_; } >+ const int& Get() const noexcept { return dummy_; } >+ >+ private: >+ static std::string GetInstanceString(int dummy) { >+ return absl::StrCat("ThrowingValue<", >+ exceptions_internal::GetSpecString(Spec), ">(", dummy, >+ ")"); >+ } >+ >+ int dummy_; >+}; >+// While not having to do with exceptions, explicitly delete comma operator, to >+// make sure we don't use it on user-supplied types. >+template <TypeSpec Spec, typename T> >+void operator,(const ThrowingValue<Spec>&, T&&) = delete; >+template <TypeSpec Spec, typename T> >+void operator,(T&&, const ThrowingValue<Spec>&) = delete; >+ >+/* >+ * Configuration enum for the ThrowingAllocator type that defines behavior for >+ * the lifetime of the instance. >+ * >+ * kEverythingThrows: Calls to the member functions may throw >+ * kNoThrowAllocate: Calls to the member functions will not throw >+ */ >+enum class AllocSpec { >+ kEverythingThrows = 0, >+ kNoThrowAllocate = 1, >+}; >+ >+/* >+ * An allocator type which is instrumented to throw at a controlled time, or not >+ * to throw, using AllocSpec. The supported settings are the default of every >+ * function which is allowed to throw in a conforming allocator possibly >+ * throwing, or nothing throws, in line with the ABSL_ALLOCATOR_THROWS >+ * configuration macro. >+ */ >+template <typename T, AllocSpec Spec = AllocSpec::kEverythingThrows> >+class ThrowingAllocator : private exceptions_internal::TrackedObject { >+ static constexpr bool IsSpecified(AllocSpec spec) { >+ return static_cast<bool>(Spec & spec); >+ } >+ >+ public: >+ using pointer = T*; >+ using const_pointer = const T*; >+ using reference = T&; >+ using const_reference = const T&; >+ using void_pointer = void*; >+ using const_void_pointer = const void*; >+ using value_type = T; >+ using size_type = size_t; >+ using difference_type = ptrdiff_t; >+ >+ using is_nothrow = >+ std::integral_constant<bool, Spec == AllocSpec::kNoThrowAllocate>; >+ using propagate_on_container_copy_assignment = std::true_type; >+ using propagate_on_container_move_assignment = std::true_type; >+ using propagate_on_container_swap = std::true_type; >+ using is_always_equal = std::false_type; >+ >+ ThrowingAllocator() : TrackedObject(GetInstanceString(next_id_)) { >+ exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); >+ dummy_ = std::make_shared<const int>(next_id_++); >+ } >+ >+ template <typename U> >+ ThrowingAllocator(const ThrowingAllocator<U, Spec>& other) noexcept // NOLINT >+ : TrackedObject(GetInstanceString(*other.State())), >+ dummy_(other.State()) {} >+ >+ // According to C++11 standard [17.6.3.5], Table 28, the move/copy ctors of >+ // allocator shall not exit via an exception, thus they are marked noexcept. >+ ThrowingAllocator(const ThrowingAllocator& other) noexcept >+ : TrackedObject(GetInstanceString(*other.State())), >+ dummy_(other.State()) {} >+ >+ template <typename U> >+ ThrowingAllocator(ThrowingAllocator<U, Spec>&& other) noexcept // NOLINT >+ : TrackedObject(GetInstanceString(*other.State())), >+ dummy_(std::move(other.State())) {} >+ >+ ThrowingAllocator(ThrowingAllocator&& other) noexcept >+ : TrackedObject(GetInstanceString(*other.State())), >+ dummy_(std::move(other.State())) {} >+ >+ ~ThrowingAllocator() noexcept = default; >+ >+ ThrowingAllocator& operator=(const ThrowingAllocator& other) noexcept { >+ dummy_ = other.State(); >+ return *this; >+ } >+ >+ template <typename U> >+ ThrowingAllocator& operator=( >+ const ThrowingAllocator<U, Spec>& other) noexcept { >+ dummy_ = other.State(); >+ return *this; >+ } >+ >+ template <typename U> >+ ThrowingAllocator& operator=(ThrowingAllocator<U, Spec>&& other) noexcept { >+ dummy_ = std::move(other.State()); >+ return *this; >+ } >+ >+ template <typename U> >+ struct rebind { >+ using other = ThrowingAllocator<U, Spec>; >+ }; >+ >+ pointer allocate(size_type n) noexcept( >+ IsSpecified(AllocSpec::kNoThrowAllocate)) { >+ ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION); >+ return static_cast<pointer>(::operator new(n * sizeof(T))); >+ } >+ >+ pointer allocate(size_type n, const_void_pointer) noexcept( >+ IsSpecified(AllocSpec::kNoThrowAllocate)) { >+ return allocate(n); >+ } >+ >+ void deallocate(pointer ptr, size_type) noexcept { >+ ReadState(); >+ ::operator delete(static_cast<void*>(ptr)); >+ } >+ >+ template <typename U, typename... Args> >+ void construct(U* ptr, Args&&... args) noexcept( >+ IsSpecified(AllocSpec::kNoThrowAllocate)) { >+ ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION); >+ ::new (static_cast<void*>(ptr)) U(std::forward<Args>(args)...); >+ } >+ >+ template <typename U> >+ void destroy(U* p) noexcept { >+ ReadState(); >+ p->~U(); >+ } >+ >+ size_type max_size() const noexcept { >+ return std::numeric_limits<difference_type>::max() / sizeof(value_type); >+ } >+ >+ ThrowingAllocator select_on_container_copy_construction() noexcept( >+ IsSpecified(AllocSpec::kNoThrowAllocate)) { >+ auto& out = *this; >+ ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION); >+ return out; >+ } >+ >+ template <typename U> >+ bool operator==(const ThrowingAllocator<U, Spec>& other) const noexcept { >+ return dummy_ == other.dummy_; >+ } >+ >+ template <typename U> >+ bool operator!=(const ThrowingAllocator<U, Spec>& other) const noexcept { >+ return dummy_ != other.dummy_; >+ } >+ >+ template <typename, AllocSpec> >+ friend class ThrowingAllocator; >+ >+ private: >+ static std::string GetInstanceString(int dummy) { >+ return absl::StrCat("ThrowingAllocator<", >+ exceptions_internal::GetSpecString(Spec), ">(", dummy, >+ ")"); >+ } >+ >+ const std::shared_ptr<const int>& State() const { return dummy_; } >+ std::shared_ptr<const int>& State() { return dummy_; } >+ >+ void ReadState() { >+ // we know that this will never be true, but the compiler doesn't, so this >+ // should safely force a read of the value. >+ if (*dummy_ < 0) std::abort(); >+ } >+ >+ void ReadStateAndMaybeThrow(absl::string_view msg) const { >+ if (!IsSpecified(AllocSpec::kNoThrowAllocate)) { >+ exceptions_internal::MaybeThrow( >+ absl::Substitute("Allocator id $0 threw from $1", *dummy_, msg)); >+ } >+ } >+ >+ static int next_id_; >+ std::shared_ptr<const int> dummy_; >+}; >+ >+template <typename T, AllocSpec Spec> >+int ThrowingAllocator<T, Spec>::next_id_ = 0; >+ >+// Tests for resource leaks by attempting to construct a T using args repeatedly >+// until successful, using the countdown method. Side effects can then be >+// tested for resource leaks. >+template <typename T, typename... Args> >+void TestThrowingCtor(Args&&... args) { >+ struct Cleanup { >+ ~Cleanup() { exceptions_internal::UnsetCountdown(); } >+ } c; >+ for (int count = 0;; ++count) { >+ exceptions_internal::ConstructorTracker ct(count); >+ exceptions_internal::SetCountdown(count); >+ try { >+ T temp(std::forward<Args>(args)...); >+ static_cast<void>(temp); >+ break; >+ } catch (const exceptions_internal::TestException&) { >+ } >+ } >+} >+ >+// Tests the nothrow guarantee of the provided nullary operation. If the an >+// exception is thrown, the result will be AssertionFailure(). Otherwise, it >+// will be AssertionSuccess(). >+template <typename Operation> >+testing::AssertionResult TestNothrowOp(const Operation& operation) { >+ struct Cleanup { >+ Cleanup() { exceptions_internal::SetCountdown(); } >+ ~Cleanup() { exceptions_internal::UnsetCountdown(); } >+ } c; >+ try { >+ operation(); >+ return testing::AssertionSuccess(); >+ } catch (exceptions_internal::TestException) { >+ return testing::AssertionFailure() >+ << "TestException thrown during call to operation() when nothrow " >+ "guarantee was expected."; >+ } catch (...) { >+ return testing::AssertionFailure() >+ << "Unknown exception thrown during call to operation() when " >+ "nothrow guarantee was expected."; >+ } >+} >+ >+namespace exceptions_internal { >+ >+// Dummy struct for ExceptionSafetyTester<> partial state. >+struct UninitializedT {}; >+ >+template <typename T> >+class DefaultFactory { >+ public: >+ explicit DefaultFactory(const T& t) : t_(t) {} >+ std::unique_ptr<T> operator()() const { return absl::make_unique<T>(t_); } >+ >+ private: >+ T t_; >+}; >+ >+template <size_t LazyInvariantsCount, typename LazyFactory, >+ typename LazyOperation> >+using EnableIfTestable = typename absl::enable_if_t< >+ LazyInvariantsCount != 0 && >+ !std::is_same<LazyFactory, UninitializedT>::value && >+ !std::is_same<LazyOperation, UninitializedT>::value>; >+ >+template <typename Factory = UninitializedT, >+ typename Operation = UninitializedT, typename... Invariants> >+class ExceptionSafetyTester; >+ >+} // namespace exceptions_internal >+ >+exceptions_internal::ExceptionSafetyTester<> MakeExceptionSafetyTester(); >+ >+namespace exceptions_internal { >+ >+/* >+ * Builds a tester object that tests if performing a operation on a T follows >+ * exception safety guarantees. Verification is done via invariant assertion >+ * callbacks applied to T instances post-throw. >+ * >+ * Template parameters for ExceptionSafetyTester: >+ * >+ * - Factory: The factory object (passed in via tester.WithFactory(...) or >+ * tester.WithInitialValue(...)) must be invocable with the signature >+ * `std::unique_ptr<T> operator()() const` where T is the type being tested. >+ * It is used for reliably creating identical T instances to test on. >+ * >+ * - Operation: The operation object (passsed in via tester.WithOperation(...) >+ * or tester.Test(...)) must be invocable with the signature >+ * `void operator()(T*) const` where T is the type being tested. It is used >+ * for performing steps on a T instance that may throw and that need to be >+ * checked for exception safety. Each call to the operation will receive a >+ * 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 >+ * `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 >+ * hold, they must return testing::AssertionFailure. Execution order of >+ * Invariants... 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 <typename Factory, typename Operation, typename... Invariants> >+class ExceptionSafetyTester { >+ 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. >+ * >+ * Preconditions for tester.WithInitialValue(const T& t): >+ * >+ * - The const T& t object must be copy-constructible where T is the type >+ * being tested. For non-copy-constructible objects, use the method >+ * tester.WithFactory(...). >+ */ >+ template <typename T> >+ ExceptionSafetyTester<DefaultFactory<T>, Operation, Invariants...> >+ WithInitialValue(const T& t) const { >+ return WithFactory(DefaultFactory<T>(t)); >+ } >+ >+ /* >+ * Returns a new ExceptionSafetyTester with the provided T factory included. >+ * The existing factory will not be included in the newly-created tester >+ * instance. This method is intended for use with types lacking a copy >+ * constructor. Types that can be copy-constructed should instead use the >+ * method tester.WithInitialValue(...). >+ */ >+ template <typename NewFactory> >+ ExceptionSafetyTester<absl::decay_t<NewFactory>, Operation, Invariants...> >+ WithFactory(const NewFactory& new_factory) const { >+ return {new_factory, operation_, invariants_}; >+ } >+ >+ /* >+ * Returns a new ExceptionSafetyTester with the provided testable operation >+ * included. The existing operation will not be included in the newly created >+ * tester. >+ */ >+ template <typename NewOperation> >+ ExceptionSafetyTester<Factory, absl::decay_t<NewOperation>, Invariants...> >+ WithOperation(const NewOperation& new_operation) const { >+ return {factory_, new_operation, invariants_}; >+ } >+ >+ /* >+ * 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. >+ * >+ * In addition to passing in custom invariant 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 <typename... MoreInvariants> >+ ExceptionSafetyTester<Factory, Operation, Invariants..., >+ absl::decay_t<MoreInvariants>...> >+ WithInvariants(const MoreInvariants&... more_invariants) const { >+ return {factory_, operation_, >+ std::tuple_cat(invariants_, >+ std::tuple<absl::decay_t<MoreInvariants>...>( >+ more_invariants...))}; >+ } >+ >+ /* >+ * 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 >+ * AssertionSuccess, the reduced result is AssertionSuccess. >+ * >+ * The passed-in testable operation will not be saved in a new tester instance >+ * nor will it modify/replace the existing tester instance. This is useful >+ * when each operation being tested is unique and does not need to be reused. >+ * >+ * Preconditions for tester.Test(const NewOperation& new_operation): >+ * >+ * - May only be called after at least one invariant assertion callback and a >+ * factory or initial value have been provided. >+ */ >+ template < >+ typename NewOperation, >+ typename = EnableIfTestable<sizeof...(Invariants), Factory, NewOperation>> >+ testing::AssertionResult Test(const NewOperation& new_operation) const { >+ return TestImpl(new_operation, absl::index_sequence_for<Invariants...>()); >+ } >+ >+ /* >+ * 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 >+ * AssertionSuccess, the reduced result is AssertionSuccess. >+ * >+ * Preconditions for tester.Test(): >+ * >+ * - May only be called after at least one invariant assertion callback, a >+ * factory or initial value and a testable operation have been provided. >+ */ >+ template <typename LazyOperation = Operation, >+ typename = >+ EnableIfTestable<sizeof...(Invariants), Factory, LazyOperation>> >+ testing::AssertionResult Test() const { >+ return TestImpl(operation_, absl::index_sequence_for<Invariants...>()); >+ } >+ >+ private: >+ template <typename, typename, typename...> >+ friend class ExceptionSafetyTester; >+ >+ friend ExceptionSafetyTester<> testing::MakeExceptionSafetyTester(); >+ >+ ExceptionSafetyTester() {} >+ >+ ExceptionSafetyTester(const Factory& f, const Operation& o, >+ const std::tuple<Invariants...>& i) >+ : factory_(f), operation_(o), invariants_(i) {} >+ >+ template <typename SelectedOperation, size_t... Indices> >+ testing::AssertionResult TestImpl(const SelectedOperation& selected_operation, >+ absl::index_sequence<Indices...>) const { >+ // Starting from 0 and counting upwards until one of the exit conditions is >+ // hit... >+ for (int count = 0;; ++count) { >+ exceptions_internal::ConstructorTracker ct(count); >+ >+ // Run the full exception safety test algorithm for the current countdown >+ auto reduced_res = >+ TestAllInvariantsAtCountdown(factory_, selected_operation, count, >+ std::get<Indices>(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. >+ } >+ } >+ >+ Factory factory_; >+ Operation operation_; >+ std::tuple<Invariants...> invariants_; >+}; >+ >+} // 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/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/exception_testing.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/exception_testing.h >new file mode 100644 >index 0000000000000000000000000000000000000000..0cf7918e4c67788971cf94337a279466063c6b3f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/exception_testing.h >@@ -0,0 +1,42 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Testing utilities for ABSL types which throw exceptions. >+ >+#ifndef ABSL_BASE_INTERNAL_EXCEPTION_TESTING_H_ >+#define ABSL_BASE_INTERNAL_EXCEPTION_TESTING_H_ >+ >+#include "gtest/gtest.h" >+#include "absl/base/config.h" >+ >+// ABSL_BASE_INTERNAL_EXPECT_FAIL tests either for a specified thrown exception >+// if exceptions are enabled, or for death with a specified text in the error >+// message >+#ifdef ABSL_HAVE_EXCEPTIONS >+ >+#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \ >+ EXPECT_THROW(expr, exception_t) >+ >+#elif defined(__ANDROID__) >+// Android asserts do not log anywhere that gtest can currently inspect. >+// So we expect exit, but cannot match the message. >+#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \ >+ EXPECT_DEATH(expr, ".*") >+#else >+#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \ >+ EXPECT_DEATH_IF_SUPPORTED(expr, text) >+ >+#endif >+ >+#endif // ABSL_BASE_INTERNAL_EXCEPTION_TESTING_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/hide_ptr.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/hide_ptr.h >new file mode 100644 >index 0000000000000000000000000000000000000000..45cf438912c2714976eba6a7794f55cf2804ae82 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/hide_ptr.h >@@ -0,0 +1,47 @@ >+// 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_HIDE_PTR_H_ >+#define ABSL_BASE_INTERNAL_HIDE_PTR_H_ >+ >+#include <cstdint> >+ >+namespace absl { >+namespace base_internal { >+ >+// Arbitrary value with high bits set. Xor'ing with it is unlikely >+// to map one valid pointer to another valid pointer. >+constexpr uintptr_t HideMask() { >+ return (uintptr_t{0xF03A5F7BU} << (sizeof(uintptr_t) - 4) * 8) | 0xF03A5F7BU; >+} >+ >+// Hide a pointer from the leak checker. For internal use only. >+// Differs from absl::IgnoreLeak(ptr) in that absl::IgnoreLeak(ptr) causes ptr >+// and all objects reachable from ptr to be ignored by the leak checker. >+template <class T> >+inline uintptr_t HidePtr(T* ptr) { >+ return reinterpret_cast<uintptr_t>(ptr) ^ HideMask(); >+} >+ >+// Return a pointer that has been hidden from the leak checker. >+// For internal use only. >+template <class T> >+inline T* UnhidePtr(uintptr_t hidden) { >+ return reinterpret_cast<T*>(hidden ^ HideMask()); >+} >+ >+} // namespace base_internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_HIDE_PTR_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/identity.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/identity.h >new file mode 100644 >index 0000000000000000000000000000000000000000..a1a5d70a84dd34d05ff23f662d50d3c418d6caf9 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/identity.h >@@ -0,0 +1,33 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_BASE_INTERNAL_IDENTITY_H_ >+#define ABSL_BASE_INTERNAL_IDENTITY_H_ >+ >+namespace absl { >+namespace internal { >+ >+template <typename T> >+struct identity { >+ typedef T type; >+}; >+ >+template <typename T> >+using identity_t = typename identity<T>::type; >+ >+} // namespace internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_IDENTITY_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/inline_variable.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/inline_variable.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f7bb8c56525d88e52696050ca142aec651d1b495 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/inline_variable.h >@@ -0,0 +1,107 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ >+#define ABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ >+ >+#include <type_traits> >+ >+#include "absl/base/internal/identity.h" >+ >+// File: >+// This file define a macro that allows the creation of or emulation of C++17 >+// inline variables based on whether or not the feature is supported. >+ >+//////////////////////////////////////////////////////////////////////////////// >+// Macro: ABSL_INTERNAL_INLINE_CONSTEXPR(type, name, init) >+// >+// Description: >+// Expands to the equivalent of an inline constexpr instance of the specified >+// `type` and `name`, initialized to the value `init`. If the compiler being >+// used is detected as supporting actual inline variables as a language >+// feature, then the macro expands to an actual inline variable definition. >+// >+// Requires: >+// `type` is a type that is usable in an extern variable declaration. >+// >+// Requires: `name` is a valid identifier >+// >+// Requires: >+// `init` is an expression that can be used in the following definition: >+// constexpr type name = init; >+// >+// Usage: >+// >+// // Equivalent to: `inline constexpr size_t variant_npos = -1;` >+// ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, -1); >+// >+// Differences in implementation: >+// For a direct, language-level inline variable, decltype(name) will be the >+// type that was specified along with const qualification, whereas for >+// emulated inline variables, decltype(name) may be different (in practice >+// it will likely be a reference type). >+//////////////////////////////////////////////////////////////////////////////// >+ >+#ifdef __cpp_inline_variables >+ >+// Clang's -Wmissing-variable-declarations option erroneously warned that >+// inline constexpr objects need to be pre-declared. This has now been fixed, >+// but we will need to support this workaround for people building with older >+// versions of clang. >+// >+// Bug: https://bugs.llvm.org/show_bug.cgi?id=35862 >+// >+// Note: >+// identity_t is used here so that the const and name are in the >+// appropriate place for pointer types, reference types, function pointer >+// types, etc.. >+#if defined(__clang__) >+#define ABSL_INTERNAL_EXTERN_DECL(type, name) \ >+ extern const ::absl::internal::identity_t<type> name; >+#else // Otherwise, just define the macro to do nothing. >+#define ABSL_INTERNAL_EXTERN_DECL(type, name) >+#endif // defined(__clang__) >+ >+// See above comment at top of file for details. >+#define ABSL_INTERNAL_INLINE_CONSTEXPR(type, name, init) \ >+ ABSL_INTERNAL_EXTERN_DECL(type, name) \ >+ inline constexpr ::absl::internal::identity_t<type> name = init >+ >+#else >+ >+// See above comment at top of file for details. >+// >+// Note: >+// identity_t is used here so that the const and name are in the >+// appropriate place for pointer types, reference types, function pointer >+// types, etc.. >+#define ABSL_INTERNAL_INLINE_CONSTEXPR(var_type, name, init) \ >+ template <class /*AbslInternalDummy*/ = void> \ >+ struct AbslInternalInlineVariableHolder##name { \ >+ static constexpr ::absl::internal::identity_t<var_type> kInstance = init; \ >+ }; \ >+ \ >+ template <class AbslInternalDummy> \ >+ constexpr ::absl::internal::identity_t<var_type> \ >+ AbslInternalInlineVariableHolder##name<AbslInternalDummy>::kInstance; \ >+ \ >+ static constexpr const ::absl::internal::identity_t<var_type>& \ >+ name = /* NOLINT */ \ >+ AbslInternalInlineVariableHolder##name<>::kInstance; \ >+ static_assert(sizeof(void (*)(decltype(name))) != 0, \ >+ "Silence unused variable warnings.") >+ >+#endif // __cpp_inline_variables >+ >+#endif // ABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/inline_variable_testing.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/inline_variable_testing.h >new file mode 100644 >index 0000000000000000000000000000000000000000..a0dd2bb28a402a285a4e6ae5ace0e51dc6bcb4f1 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/inline_variable_testing.h >@@ -0,0 +1,44 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_BASE_INLINE_VARIABLE_TESTING_H_ >+#define ABSL_BASE_INLINE_VARIABLE_TESTING_H_ >+ >+#include "absl/base/internal/inline_variable.h" >+ >+namespace absl { >+namespace inline_variable_testing_internal { >+ >+struct Foo { >+ int value = 5; >+}; >+ >+ABSL_INTERNAL_INLINE_CONSTEXPR(Foo, inline_variable_foo, {}); >+ABSL_INTERNAL_INLINE_CONSTEXPR(Foo, other_inline_variable_foo, {}); >+ >+ABSL_INTERNAL_INLINE_CONSTEXPR(int, inline_variable_int, 5); >+ABSL_INTERNAL_INLINE_CONSTEXPR(int, other_inline_variable_int, 5); >+ >+ABSL_INTERNAL_INLINE_CONSTEXPR(void(*)(), inline_variable_fun_ptr, nullptr); >+ >+const Foo& get_foo_a(); >+const Foo& get_foo_b(); >+ >+const int& get_int_a(); >+const int& get_int_b(); >+ >+} // namespace inline_variable_testing_internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INLINE_VARIABLE_TESTING_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/invoke.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/invoke.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8c3f4f60637ca9d2d4e842620a5642f85336ca98 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/invoke.h >@@ -0,0 +1,188 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// absl::base_internal::Invoke(f, args...) is an implementation of >+// INVOKE(f, args...) from section [func.require] of the C++ standard. >+// >+// [func.require] >+// Define INVOKE (f, t1, t2, ..., tN) as follows: >+// 1. (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T >+// and t1 is an object of type T or a reference to an object of type T or a >+// reference to an object of a type derived from T; >+// 2. ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a >+// class T and t1 is not one of the types described in the previous item; >+// 3. t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is >+// an object of type T or a reference to an object of type T or a reference >+// to an object of a type derived from T; >+// 4. (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 >+// is not one of the types described in the previous item; >+// 5. f(t1, t2, ..., tN) in all other cases. >+// >+// The implementation is SFINAE-friendly: substitution failure within Invoke() >+// isn't an error. >+ >+#ifndef ABSL_BASE_INTERNAL_INVOKE_H_ >+#define ABSL_BASE_INTERNAL_INVOKE_H_ >+ >+#include <algorithm> >+#include <type_traits> >+#include <utility> >+ >+// The following code is internal implementation detail. See the comment at the >+// top of this file for the API documentation. >+ >+namespace absl { >+namespace base_internal { >+ >+// The five classes below each implement one of the clauses from the definition >+// of INVOKE. The inner class template Accept<F, Args...> checks whether the >+// clause is applicable; static function template Invoke(f, args...) does the >+// invocation. >+// >+// By separating the clause selection logic from invocation we make sure that >+// Invoke() does exactly what the standard says. >+ >+template <typename Derived> >+struct StrippedAccept { >+ template <typename... Args> >+ struct Accept : Derived::template AcceptImpl<typename std::remove_cv< >+ typename std::remove_reference<Args>::type>::type...> {}; >+}; >+ >+// (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T >+// and t1 is an object of type T or a reference to an object of type T or a >+// reference to an object of a type derived from T. >+struct MemFunAndRef : StrippedAccept<MemFunAndRef> { >+ template <typename... Args> >+ struct AcceptImpl : std::false_type {}; >+ >+ template <typename R, typename C, typename... Params, typename Obj, >+ typename... Args> >+ struct AcceptImpl<R (C::*)(Params...), Obj, Args...> >+ : std::is_base_of<C, Obj> {}; >+ >+ template <typename R, typename C, typename... Params, typename Obj, >+ typename... Args> >+ struct AcceptImpl<R (C::*)(Params...) const, Obj, Args...> >+ : std::is_base_of<C, Obj> {}; >+ >+ template <typename MemFun, typename Obj, typename... Args> >+ static decltype((std::declval<Obj>().* >+ std::declval<MemFun>())(std::declval<Args>()...)) >+ Invoke(MemFun&& mem_fun, Obj&& obj, Args&&... args) { >+ return (std::forward<Obj>(obj).* >+ std::forward<MemFun>(mem_fun))(std::forward<Args>(args)...); >+ } >+}; >+ >+// ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a >+// class T and t1 is not one of the types described in the previous item. >+struct MemFunAndPtr : StrippedAccept<MemFunAndPtr> { >+ template <typename... Args> >+ struct AcceptImpl : std::false_type {}; >+ >+ template <typename R, typename C, typename... Params, typename Ptr, >+ typename... Args> >+ struct AcceptImpl<R (C::*)(Params...), Ptr, Args...> >+ : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value> {}; >+ >+ template <typename R, typename C, typename... Params, typename Ptr, >+ typename... Args> >+ struct AcceptImpl<R (C::*)(Params...) const, Ptr, Args...> >+ : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value> {}; >+ >+ template <typename MemFun, typename Ptr, typename... Args> >+ static decltype(((*std::declval<Ptr>()).* >+ std::declval<MemFun>())(std::declval<Args>()...)) >+ Invoke(MemFun&& mem_fun, Ptr&& ptr, Args&&... args) { >+ return ((*std::forward<Ptr>(ptr)).* >+ std::forward<MemFun>(mem_fun))(std::forward<Args>(args)...); >+ } >+}; >+ >+// t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is >+// an object of type T or a reference to an object of type T or a reference >+// to an object of a type derived from T. >+struct DataMemAndRef : StrippedAccept<DataMemAndRef> { >+ template <typename... Args> >+ struct AcceptImpl : std::false_type {}; >+ >+ template <typename R, typename C, typename Obj> >+ struct AcceptImpl<R C::*, Obj> : std::is_base_of<C, Obj> {}; >+ >+ template <typename DataMem, typename Ref> >+ static decltype(std::declval<Ref>().*std::declval<DataMem>()) Invoke( >+ DataMem&& data_mem, Ref&& ref) { >+ return std::forward<Ref>(ref).*std::forward<DataMem>(data_mem); >+ } >+}; >+ >+// (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 >+// is not one of the types described in the previous item. >+struct DataMemAndPtr : StrippedAccept<DataMemAndPtr> { >+ template <typename... Args> >+ struct AcceptImpl : std::false_type {}; >+ >+ template <typename R, typename C, typename Ptr> >+ struct AcceptImpl<R C::*, Ptr> >+ : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value> {}; >+ >+ template <typename DataMem, typename Ptr> >+ static decltype((*std::declval<Ptr>()).*std::declval<DataMem>()) Invoke( >+ DataMem&& data_mem, Ptr&& ptr) { >+ return (*std::forward<Ptr>(ptr)).*std::forward<DataMem>(data_mem); >+ } >+}; >+ >+// f(t1, t2, ..., tN) in all other cases. >+struct Callable { >+ // Callable doesn't have Accept because it's the last clause that gets picked >+ // when none of the previous clauses are applicable. >+ template <typename F, typename... Args> >+ static decltype(std::declval<F>()(std::declval<Args>()...)) Invoke( >+ F&& f, Args&&... args) { >+ return std::forward<F>(f)(std::forward<Args>(args)...); >+ } >+}; >+ >+// Resolves to the first matching clause. >+template <typename... Args> >+struct Invoker { >+ typedef typename std::conditional< >+ MemFunAndRef::Accept<Args...>::value, MemFunAndRef, >+ typename std::conditional< >+ MemFunAndPtr::Accept<Args...>::value, MemFunAndPtr, >+ typename std::conditional< >+ DataMemAndRef::Accept<Args...>::value, DataMemAndRef, >+ typename std::conditional<DataMemAndPtr::Accept<Args...>::value, >+ DataMemAndPtr, Callable>::type>::type>:: >+ type>::type type; >+}; >+ >+// The result type of Invoke<F, Args...>. >+template <typename F, typename... Args> >+using InvokeT = decltype(Invoker<F, Args...>::type::Invoke( >+ std::declval<F>(), std::declval<Args>()...)); >+ >+// Invoke(f, args...) is an implementation of INVOKE(f, args...) from section >+// [func.require] of the C++ standard. >+template <typename F, typename... Args> >+InvokeT<F, Args...> Invoke(F&& f, Args&&... args) { >+ return Invoker<F, Args...>::type::Invoke(std::forward<F>(f), >+ std::forward<Args>(args)...); >+} >+} // namespace base_internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_INVOKE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..0626cd5478d97004eb1e9cde215a90e4862d29f1 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc >@@ -0,0 +1,604 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// A low-level allocator that can be used by other low-level >+// modules without introducing dependency cycles. >+// This allocator is slow and wasteful of memory; >+// it should not be used when performance is key. >+ >+#include "absl/base/internal/low_level_alloc.h" >+ >+#include <type_traits> >+ >+#include "absl/base/call_once.h" >+#include "absl/base/config.h" >+#include "absl/base/internal/direct_mmap.h" >+#include "absl/base/internal/scheduling_mode.h" >+#include "absl/base/macros.h" >+#include "absl/base/thread_annotations.h" >+ >+// LowLevelAlloc requires that the platform support low-level >+// allocation of virtual memory. Platforms lacking this cannot use >+// LowLevelAlloc. >+#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING >+ >+#ifndef _WIN32 >+#include <pthread.h> >+#include <signal.h> >+#include <sys/mman.h> >+#include <unistd.h> >+#else >+#include <windows.h> >+#endif >+ >+#include <string.h> >+#include <algorithm> >+#include <atomic> >+#include <cerrno> >+#include <cstddef> >+#include <new> // for placement-new >+ >+#include "absl/base/dynamic_annotations.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/spinlock.h" >+ >+// MAP_ANONYMOUS >+#if defined(__APPLE__) >+// For mmap, Linux defines both MAP_ANONYMOUS and MAP_ANON and says MAP_ANON is >+// deprecated. In Darwin, MAP_ANON is all there is. >+#if !defined MAP_ANONYMOUS >+#define MAP_ANONYMOUS MAP_ANON >+#endif // !MAP_ANONYMOUS >+#endif // __APPLE__ >+ >+namespace absl { >+namespace base_internal { >+ >+// A first-fit allocator with amortized logarithmic free() time. >+ >+// --------------------------------------------------------------------------- >+static const int kMaxLevel = 30; >+ >+namespace { >+// This struct describes one allocated block, or one free block. >+struct AllocList { >+ struct Header { >+ // Size of entire region, including this field. Must be >+ // first. Valid in both allocated and unallocated blocks. >+ uintptr_t size; >+ >+ // kMagicAllocated or kMagicUnallocated xor this. >+ uintptr_t magic; >+ >+ // Pointer to parent arena. >+ LowLevelAlloc::Arena *arena; >+ >+ // Aligns regions to 0 mod 2*sizeof(void*). >+ void *dummy_for_alignment; >+ } header; >+ >+ // Next two fields: in unallocated blocks: freelist skiplist data >+ // in allocated blocks: overlaps with client data >+ >+ // Levels in skiplist used. >+ int levels; >+ >+ // Actually has levels elements. The AllocList node may not have room >+ // for all kMaxLevel entries. See max_fit in LLA_SkiplistLevels(). >+ AllocList *next[kMaxLevel]; >+}; >+} // namespace >+ >+// --------------------------------------------------------------------------- >+// A trivial skiplist implementation. This is used to keep the freelist >+// in address order while taking only logarithmic time per insert and delete. >+ >+// An integer approximation of log2(size/base) >+// Requires size >= base. >+static int IntLog2(size_t size, size_t base) { >+ int result = 0; >+ for (size_t i = size; i > base; i >>= 1) { // i == floor(size/2**result) >+ result++; >+ } >+ // floor(size / 2**result) <= base < floor(size / 2**(result-1)) >+ // => log2(size/(base+1)) <= result < 1+log2(size/base) >+ // => result ~= log2(size/base) >+ return result; >+} >+ >+// Return a random integer n: p(n)=1/(2**n) if 1 <= n; p(n)=0 if n < 1. >+static int Random(uint32_t *state) { >+ uint32_t r = *state; >+ int result = 1; >+ while ((((r = r*1103515245 + 12345) >> 30) & 1) == 0) { >+ result++; >+ } >+ *state = r; >+ return result; >+} >+ >+// Return a number of skiplist levels for a node of size bytes, where >+// base is the minimum node size. Compute level=log2(size / base)+n >+// where n is 1 if random is false and otherwise a random number generated with >+// the standard distribution for a skiplist: See Random() above. >+// Bigger nodes tend to have more skiplist levels due to the log2(size / base) >+// term, so first-fit searches touch fewer nodes. "level" is clipped so >+// level<kMaxLevel and next[level-1] will fit in the node. >+// 0 < LLA_SkiplistLevels(x,y,false) <= LLA_SkiplistLevels(x,y,true) < kMaxLevel >+static int LLA_SkiplistLevels(size_t size, size_t base, uint32_t *random) { >+ // max_fit is the maximum number of levels that will fit in a node for the >+ // given size. We can't return more than max_fit, no matter what the >+ // random number generator says. >+ size_t max_fit = (size - offsetof(AllocList, next)) / sizeof(AllocList *); >+ int level = IntLog2(size, base) + (random != nullptr ? Random(random) : 1); >+ if (static_cast<size_t>(level) > max_fit) level = static_cast<int>(max_fit); >+ if (level > kMaxLevel-1) level = kMaxLevel - 1; >+ ABSL_RAW_CHECK(level >= 1, "block not big enough for even one level"); >+ return level; >+} >+ >+// Return "atleast", the first element of AllocList *head s.t. *atleast >= *e. >+// For 0 <= i < head->levels, set prev[i] to "no_greater", where no_greater >+// points to the last element at level i in the AllocList less than *e, or is >+// head if no such element exists. >+static AllocList *LLA_SkiplistSearch(AllocList *head, >+ AllocList *e, AllocList **prev) { >+ AllocList *p = head; >+ for (int level = head->levels - 1; level >= 0; level--) { >+ for (AllocList *n; (n = p->next[level]) != nullptr && n < e; p = n) { >+ } >+ prev[level] = p; >+ } >+ return (head->levels == 0) ? nullptr : prev[0]->next[0]; >+} >+ >+// Insert element *e into AllocList *head. Set prev[] as LLA_SkiplistSearch. >+// Requires that e->levels be previously set by the caller (using >+// LLA_SkiplistLevels()) >+static void LLA_SkiplistInsert(AllocList *head, AllocList *e, >+ AllocList **prev) { >+ LLA_SkiplistSearch(head, e, prev); >+ for (; head->levels < e->levels; head->levels++) { // extend prev pointers >+ prev[head->levels] = head; // to all *e's levels >+ } >+ for (int i = 0; i != e->levels; i++) { // add element to list >+ e->next[i] = prev[i]->next[i]; >+ prev[i]->next[i] = e; >+ } >+} >+ >+// Remove element *e from AllocList *head. Set prev[] as LLA_SkiplistSearch(). >+// Requires that e->levels be previous set by the caller (using >+// LLA_SkiplistLevels()) >+static void LLA_SkiplistDelete(AllocList *head, AllocList *e, >+ AllocList **prev) { >+ AllocList *found = LLA_SkiplistSearch(head, e, prev); >+ ABSL_RAW_CHECK(e == found, "element not in freelist"); >+ for (int i = 0; i != e->levels && prev[i]->next[i] == e; i++) { >+ prev[i]->next[i] = e->next[i]; >+ } >+ while (head->levels > 0 && head->next[head->levels - 1] == nullptr) { >+ head->levels--; // reduce head->levels if level unused >+ } >+} >+ >+// --------------------------------------------------------------------------- >+// Arena implementation >+ >+// Metadata for an LowLevelAlloc arena instance. >+struct LowLevelAlloc::Arena { >+ // Constructs an arena with the given LowLevelAlloc flags. >+ explicit Arena(uint32_t flags_value); >+ >+ base_internal::SpinLock mu; >+ // Head of free list, sorted by address >+ AllocList freelist GUARDED_BY(mu); >+ // Count of allocated blocks >+ int32_t allocation_count GUARDED_BY(mu); >+ // flags passed to NewArena >+ const uint32_t flags; >+ // Result of getpagesize() >+ const size_t pagesize; >+ // Lowest power of two >= max(16, sizeof(AllocList)) >+ const size_t roundup; >+ // Smallest allocation block size >+ const size_t min_size; >+ // PRNG state >+ uint32_t random GUARDED_BY(mu); >+}; >+ >+namespace { >+using ArenaStorage = std::aligned_storage<sizeof(LowLevelAlloc::Arena), >+ alignof(LowLevelAlloc::Arena)>::type; >+ >+// Static storage space for the lazily-constructed, default global arena >+// instances. We require this space because the whole point of LowLevelAlloc >+// is to avoid relying on malloc/new. >+ArenaStorage default_arena_storage; >+ArenaStorage unhooked_arena_storage; >+#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING >+ArenaStorage unhooked_async_sig_safe_arena_storage; >+#endif >+ >+// We must use LowLevelCallOnce here to construct the global arenas, rather than >+// using function-level statics, to avoid recursively invoking the scheduler. >+absl::once_flag create_globals_once; >+ >+void CreateGlobalArenas() { >+ new (&default_arena_storage) >+ LowLevelAlloc::Arena(LowLevelAlloc::kCallMallocHook); >+ new (&unhooked_arena_storage) LowLevelAlloc::Arena(0); >+#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING >+ new (&unhooked_async_sig_safe_arena_storage) >+ LowLevelAlloc::Arena(LowLevelAlloc::kAsyncSignalSafe); >+#endif >+} >+ >+// Returns a global arena that does not call into hooks. Used by NewArena() >+// when kCallMallocHook is not set. >+LowLevelAlloc::Arena* UnhookedArena() { >+ base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas); >+ return reinterpret_cast<LowLevelAlloc::Arena*>(&unhooked_arena_storage); >+} >+ >+#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING >+// Returns a global arena that is async-signal safe. Used by NewArena() when >+// kAsyncSignalSafe is set. >+LowLevelAlloc::Arena *UnhookedAsyncSigSafeArena() { >+ base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas); >+ return reinterpret_cast<LowLevelAlloc::Arena *>( >+ &unhooked_async_sig_safe_arena_storage); >+} >+#endif >+ >+} // namespace >+ >+// Returns the default arena, as used by LowLevelAlloc::Alloc() and friends. >+LowLevelAlloc::Arena *LowLevelAlloc::DefaultArena() { >+ base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas); >+ return reinterpret_cast<LowLevelAlloc::Arena*>(&default_arena_storage); >+} >+ >+// magic numbers to identify allocated and unallocated blocks >+static const uintptr_t kMagicAllocated = 0x4c833e95U; >+static const uintptr_t kMagicUnallocated = ~kMagicAllocated; >+ >+namespace { >+class SCOPED_LOCKABLE ArenaLock { >+ public: >+ explicit ArenaLock(LowLevelAlloc::Arena *arena) >+ EXCLUSIVE_LOCK_FUNCTION(arena->mu) >+ : arena_(arena) { >+#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING >+ if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) { >+ sigset_t all; >+ sigfillset(&all); >+ mask_valid_ = pthread_sigmask(SIG_BLOCK, &all, &mask_) == 0; >+ } >+#endif >+ arena_->mu.Lock(); >+ } >+ ~ArenaLock() { ABSL_RAW_CHECK(left_, "haven't left Arena region"); } >+ void Leave() UNLOCK_FUNCTION() { >+ arena_->mu.Unlock(); >+#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING >+ if (mask_valid_) { >+ pthread_sigmask(SIG_SETMASK, &mask_, nullptr); >+ } >+#endif >+ left_ = true; >+ } >+ >+ private: >+ bool left_ = false; // whether left region >+#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING >+ bool mask_valid_ = false; >+ sigset_t mask_; // old mask of blocked signals >+#endif >+ LowLevelAlloc::Arena *arena_; >+ ArenaLock(const ArenaLock &) = delete; >+ ArenaLock &operator=(const ArenaLock &) = delete; >+}; >+} // namespace >+ >+// create an appropriate magic number for an object at "ptr" >+// "magic" should be kMagicAllocated or kMagicUnallocated >+inline static uintptr_t Magic(uintptr_t magic, AllocList::Header *ptr) { >+ return magic ^ reinterpret_cast<uintptr_t>(ptr); >+} >+ >+namespace { >+size_t GetPageSize() { >+#ifdef _WIN32 >+ SYSTEM_INFO system_info; >+ GetSystemInfo(&system_info); >+ return std::max(system_info.dwPageSize, system_info.dwAllocationGranularity); >+#else >+ return getpagesize(); >+#endif >+} >+ >+size_t RoundedUpBlockSize() { >+ // Round up block sizes to a power of two close to the header size. >+ size_t roundup = 16; >+ while (roundup < sizeof(AllocList::Header)) { >+ roundup += roundup; >+ } >+ return roundup; >+} >+ >+} // namespace >+ >+LowLevelAlloc::Arena::Arena(uint32_t flags_value) >+ : mu(base_internal::SCHEDULE_KERNEL_ONLY), >+ allocation_count(0), >+ flags(flags_value), >+ pagesize(GetPageSize()), >+ roundup(RoundedUpBlockSize()), >+ min_size(2 * roundup), >+ random(0) { >+ freelist.header.size = 0; >+ freelist.header.magic = >+ Magic(kMagicUnallocated, &freelist.header); >+ freelist.header.arena = this; >+ freelist.levels = 0; >+ memset(freelist.next, 0, sizeof(freelist.next)); >+} >+ >+// L < meta_data_arena->mu >+LowLevelAlloc::Arena *LowLevelAlloc::NewArena(int32_t flags) { >+ Arena *meta_data_arena = DefaultArena(); >+#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING >+ if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) { >+ meta_data_arena = UnhookedAsyncSigSafeArena(); >+ } else // NOLINT(readability/braces) >+#endif >+ if ((flags & LowLevelAlloc::kCallMallocHook) == 0) { >+ meta_data_arena = UnhookedArena(); >+ } >+ Arena *result = >+ new (AllocWithArena(sizeof (*result), meta_data_arena)) Arena(flags); >+ return result; >+} >+ >+// L < arena->mu, L < arena->arena->mu >+bool LowLevelAlloc::DeleteArena(Arena *arena) { >+ ABSL_RAW_CHECK( >+ arena != nullptr && arena != DefaultArena() && arena != UnhookedArena(), >+ "may not delete default arena"); >+ ArenaLock section(arena); >+ if (arena->allocation_count != 0) { >+ section.Leave(); >+ return false; >+ } >+ while (arena->freelist.next[0] != nullptr) { >+ AllocList *region = arena->freelist.next[0]; >+ size_t size = region->header.size; >+ arena->freelist.next[0] = region->next[0]; >+ ABSL_RAW_CHECK( >+ region->header.magic == Magic(kMagicUnallocated, ®ion->header), >+ "bad magic number in DeleteArena()"); >+ ABSL_RAW_CHECK(region->header.arena == arena, >+ "bad arena pointer in DeleteArena()"); >+ ABSL_RAW_CHECK(size % arena->pagesize == 0, >+ "empty arena has non-page-aligned block size"); >+ ABSL_RAW_CHECK(reinterpret_cast<uintptr_t>(region) % arena->pagesize == 0, >+ "empty arena has non-page-aligned block"); >+ int munmap_result; >+#ifdef _WIN32 >+ munmap_result = VirtualFree(region, 0, MEM_RELEASE); >+ ABSL_RAW_CHECK(munmap_result != 0, >+ "LowLevelAlloc::DeleteArena: VitualFree failed"); >+#else >+ if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) { >+ munmap_result = munmap(region, size); >+ } else { >+ munmap_result = base_internal::DirectMunmap(region, size); >+ } >+ if (munmap_result != 0) { >+ ABSL_RAW_LOG(FATAL, "LowLevelAlloc::DeleteArena: munmap failed: %d", >+ errno); >+ } >+#endif >+ } >+ section.Leave(); >+ arena->~Arena(); >+ Free(arena); >+ return true; >+} >+ >+// --------------------------------------------------------------------------- >+ >+// Addition, checking for overflow. The intent is to die if an external client >+// manages to push through a request that would cause arithmetic to fail. >+static inline uintptr_t CheckedAdd(uintptr_t a, uintptr_t b) { >+ uintptr_t sum = a + b; >+ ABSL_RAW_CHECK(sum >= a, "LowLevelAlloc arithmetic overflow"); >+ return sum; >+} >+ >+// Return value rounded up to next multiple of align. >+// align must be a power of two. >+static inline uintptr_t RoundUp(uintptr_t addr, uintptr_t align) { >+ return CheckedAdd(addr, align - 1) & ~(align - 1); >+} >+ >+// Equivalent to "return prev->next[i]" but with sanity checking >+// that the freelist is in the correct order, that it >+// consists of regions marked "unallocated", and that no two regions >+// are adjacent in memory (they should have been coalesced). >+// L < arena->mu >+static AllocList *Next(int i, AllocList *prev, LowLevelAlloc::Arena *arena) { >+ ABSL_RAW_CHECK(i < prev->levels, "too few levels in Next()"); >+ AllocList *next = prev->next[i]; >+ if (next != nullptr) { >+ ABSL_RAW_CHECK( >+ next->header.magic == Magic(kMagicUnallocated, &next->header), >+ "bad magic number in Next()"); >+ ABSL_RAW_CHECK(next->header.arena == arena, "bad arena pointer in Next()"); >+ if (prev != &arena->freelist) { >+ ABSL_RAW_CHECK(prev < next, "unordered freelist"); >+ ABSL_RAW_CHECK(reinterpret_cast<char *>(prev) + prev->header.size < >+ reinterpret_cast<char *>(next), >+ "malformed freelist"); >+ } >+ } >+ return next; >+} >+ >+// Coalesce list item "a" with its successor if they are adjacent. >+static void Coalesce(AllocList *a) { >+ AllocList *n = a->next[0]; >+ if (n != nullptr && reinterpret_cast<char *>(a) + a->header.size == >+ reinterpret_cast<char *>(n)) { >+ LowLevelAlloc::Arena *arena = a->header.arena; >+ a->header.size += n->header.size; >+ n->header.magic = 0; >+ n->header.arena = nullptr; >+ AllocList *prev[kMaxLevel]; >+ LLA_SkiplistDelete(&arena->freelist, n, prev); >+ LLA_SkiplistDelete(&arena->freelist, a, prev); >+ a->levels = LLA_SkiplistLevels(a->header.size, arena->min_size, >+ &arena->random); >+ LLA_SkiplistInsert(&arena->freelist, a, prev); >+ } >+} >+ >+// Adds block at location "v" to the free list >+// L >= arena->mu >+static void AddToFreelist(void *v, LowLevelAlloc::Arena *arena) { >+ AllocList *f = reinterpret_cast<AllocList *>( >+ reinterpret_cast<char *>(v) - sizeof (f->header)); >+ ABSL_RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header), >+ "bad magic number in AddToFreelist()"); >+ ABSL_RAW_CHECK(f->header.arena == arena, >+ "bad arena pointer in AddToFreelist()"); >+ f->levels = LLA_SkiplistLevels(f->header.size, arena->min_size, >+ &arena->random); >+ AllocList *prev[kMaxLevel]; >+ LLA_SkiplistInsert(&arena->freelist, f, prev); >+ f->header.magic = Magic(kMagicUnallocated, &f->header); >+ Coalesce(f); // maybe coalesce with successor >+ Coalesce(prev[0]); // maybe coalesce with predecessor >+} >+ >+// Frees storage allocated by LowLevelAlloc::Alloc(). >+// L < arena->mu >+void LowLevelAlloc::Free(void *v) { >+ if (v != nullptr) { >+ AllocList *f = reinterpret_cast<AllocList *>( >+ reinterpret_cast<char *>(v) - sizeof (f->header)); >+ ABSL_RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header), >+ "bad magic number in Free()"); >+ LowLevelAlloc::Arena *arena = f->header.arena; >+ ArenaLock section(arena); >+ AddToFreelist(v, arena); >+ ABSL_RAW_CHECK(arena->allocation_count > 0, "nothing in arena to free"); >+ arena->allocation_count--; >+ section.Leave(); >+ } >+} >+ >+// allocates and returns a block of size bytes, to be freed with Free() >+// L < arena->mu >+static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) { >+ void *result = nullptr; >+ if (request != 0) { >+ AllocList *s; // will point to region that satisfies request >+ ArenaLock section(arena); >+ // round up with header >+ size_t req_rnd = RoundUp(CheckedAdd(request, sizeof (s->header)), >+ arena->roundup); >+ for (;;) { // loop until we find a suitable region >+ // find the minimum levels that a block of this size must have >+ int i = LLA_SkiplistLevels(req_rnd, arena->min_size, nullptr) - 1; >+ if (i < arena->freelist.levels) { // potential blocks exist >+ AllocList *before = &arena->freelist; // predecessor of s >+ while ((s = Next(i, before, arena)) != nullptr && >+ s->header.size < req_rnd) { >+ before = s; >+ } >+ if (s != nullptr) { // we found a region >+ break; >+ } >+ } >+ // we unlock before mmap() both because mmap() may call a callback hook, >+ // and because it may be slow. >+ arena->mu.Unlock(); >+ // mmap generous 64K chunks to decrease >+ // the chances/impact of fragmentation: >+ size_t new_pages_size = RoundUp(req_rnd, arena->pagesize * 16); >+ void *new_pages; >+#ifdef _WIN32 >+ new_pages = VirtualAlloc(0, new_pages_size, >+ MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); >+ ABSL_RAW_CHECK(new_pages != nullptr, "VirtualAlloc failed"); >+#else >+ 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); >+ } else { >+ new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ, >+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); >+ } >+ if (new_pages == MAP_FAILED) { >+ ABSL_RAW_LOG(FATAL, "mmap error: %d", errno); >+ } >+#endif >+ arena->mu.Lock(); >+ s = reinterpret_cast<AllocList *>(new_pages); >+ s->header.size = new_pages_size; >+ // Pretend the block is allocated; call AddToFreelist() to free it. >+ s->header.magic = Magic(kMagicAllocated, &s->header); >+ s->header.arena = arena; >+ AddToFreelist(&s->levels, arena); // insert new region into free list >+ } >+ AllocList *prev[kMaxLevel]; >+ LLA_SkiplistDelete(&arena->freelist, s, prev); // remove from free list >+ // s points to the first free region that's big enough >+ if (CheckedAdd(req_rnd, arena->min_size) <= s->header.size) { >+ // big enough to split >+ AllocList *n = reinterpret_cast<AllocList *> >+ (req_rnd + reinterpret_cast<char *>(s)); >+ n->header.size = s->header.size - req_rnd; >+ n->header.magic = Magic(kMagicAllocated, &n->header); >+ n->header.arena = arena; >+ s->header.size = req_rnd; >+ AddToFreelist(&n->levels, arena); >+ } >+ s->header.magic = Magic(kMagicAllocated, &s->header); >+ ABSL_RAW_CHECK(s->header.arena == arena, ""); >+ arena->allocation_count++; >+ section.Leave(); >+ result = &s->levels; >+ } >+ ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(result, request); >+ return result; >+} >+ >+void *LowLevelAlloc::Alloc(size_t request) { >+ void *result = DoAllocWithArena(request, DefaultArena()); >+ return result; >+} >+ >+void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) { >+ ABSL_RAW_CHECK(arena != nullptr, "must pass a valid arena"); >+ void *result = DoAllocWithArena(request, arena); >+ return result; >+} >+ >+} // namespace base_internal >+} // namespace absl >+ >+#endif // ABSL_LOW_LEVEL_ALLOC_MISSING >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h >new file mode 100644 >index 0000000000000000000000000000000000000000..3c15605bed3578899389cc4ea296ceb5ba57a15e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h >@@ -0,0 +1,119 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ >+#define ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ >+ >+// A simple thread-safe memory allocator that does not depend on >+// mutexes or thread-specific data. It is intended to be used >+// sparingly, and only when malloc() would introduce an unwanted >+// dependency, such as inside the heap-checker, or the Mutex >+// implementation. >+ >+// IWYU pragma: private, include "base/low_level_alloc.h" >+ >+#include <sys/types.h> >+#include <cstdint> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/config.h" >+ >+// LowLevelAlloc requires that the platform support low-level >+// allocation of virtual memory. Platforms lacking this cannot use >+// LowLevelAlloc. >+#ifdef ABSL_LOW_LEVEL_ALLOC_MISSING >+#error ABSL_LOW_LEVEL_ALLOC_MISSING cannot be directly set >+#elif !defined(ABSL_HAVE_MMAP) && !defined(_WIN32) >+#define ABSL_LOW_LEVEL_ALLOC_MISSING 1 >+#endif >+ >+// Using LowLevelAlloc with kAsyncSignalSafe isn't supported on Windows. >+#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) >+#define ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 1 >+#endif >+ >+#include <cstddef> >+ >+#include "absl/base/port.h" >+ >+namespace absl { >+namespace base_internal { >+ >+class LowLevelAlloc { >+ public: >+ struct Arena; // an arena from which memory may be allocated >+ >+ // Returns a pointer to a block of at least "request" bytes >+ // that have been newly allocated from the specific arena. >+ // for Alloc() call the DefaultArena() is used. >+ // Returns 0 if passed request==0. >+ // Does not return 0 under other circumstances; it crashes if memory >+ // is not available. >+ static void *Alloc(size_t request) ABSL_ATTRIBUTE_SECTION(malloc_hook); >+ static void *AllocWithArena(size_t request, Arena *arena) >+ ABSL_ATTRIBUTE_SECTION(malloc_hook); >+ >+ // Deallocates a region of memory that was previously allocated with >+ // Alloc(). Does nothing if passed 0. "s" must be either 0, >+ // or must have been returned from a call to Alloc() and not yet passed to >+ // Free() since that call to Alloc(). The space is returned to the arena >+ // from which it was allocated. >+ static void Free(void *s) ABSL_ATTRIBUTE_SECTION(malloc_hook); >+ >+ // ABSL_ATTRIBUTE_SECTION(malloc_hook) for Alloc* and Free >+ // are to put all callers of MallocHook::Invoke* in this module >+ // into special section, >+ // so that MallocHook::GetCallerStackTrace can function accurately. >+ >+ // Create a new arena. >+ // The root metadata for the new arena is allocated in the >+ // meta_data_arena; the DefaultArena() can be passed for meta_data_arena. >+ // These values may be ored into flags: >+ enum { >+ // Report calls to Alloc() and Free() via the MallocHook interface. >+ // Set in the DefaultArena. >+ kCallMallocHook = 0x0001, >+ >+#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING >+ // Make calls to Alloc(), Free() be async-signal-safe. Not set in >+ // DefaultArena(). Not supported on all platforms. >+ kAsyncSignalSafe = 0x0002, >+#endif >+ }; >+ // Construct a new arena. The allocation of the underlying metadata honors >+ // the provided flags. For example, the call NewArena(kAsyncSignalSafe) >+ // is itself async-signal-safe, as well as generatating an arena that provides >+ // async-signal-safe Alloc/Free. >+ static Arena *NewArena(int32_t flags); >+ >+ // Destroys an arena allocated by NewArena and returns true, >+ // provided no allocated blocks remain in the arena. >+ // If allocated blocks remain in the arena, does nothing and >+ // returns false. >+ // It is illegal to attempt to destroy the DefaultArena(). >+ static bool DeleteArena(Arena *arena); >+ >+ // The default arena that always exists. >+ static Arena *DefaultArena(); >+ >+ private: >+ LowLevelAlloc(); // no instances >+}; >+ >+} // namespace base_internal >+} // namespace absl >+#endif // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_alloc_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_alloc_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..cf2b363299f4e2279ad51e46ebd080cead2e4545 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_alloc_test.cc >@@ -0,0 +1,157 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/low_level_alloc.h" >+ >+#include <stdint.h> >+#include <stdio.h> >+#include <stdlib.h> >+#include <thread> // NOLINT(build/c++11) >+#include <unordered_map> >+#include <utility> >+ >+namespace absl { >+namespace base_internal { >+namespace { >+ >+// This test doesn't use gtest since it needs to test that everything >+// works before main(). >+#define TEST_ASSERT(x) \ >+ if (!(x)) { \ >+ printf("TEST_ASSERT(%s) FAILED ON LINE %d\n", #x, __LINE__); \ >+ abort(); \ >+ } >+ >+// a block of memory obtained from the allocator >+struct BlockDesc { >+ char *ptr; // pointer to memory >+ int len; // number of bytes >+ int fill; // filled with data starting with this >+}; >+ >+// Check that the pattern placed in the block d >+// by RandomizeBlockDesc is still there. >+static void CheckBlockDesc(const BlockDesc &d) { >+ for (int i = 0; i != d.len; i++) { >+ TEST_ASSERT((d.ptr[i] & 0xff) == ((d.fill + i) & 0xff)); >+ } >+} >+ >+// Fill the block "*d" with a pattern >+// starting with a random byte. >+static void RandomizeBlockDesc(BlockDesc *d) { >+ d->fill = rand() & 0xff; >+ for (int i = 0; i != d->len; i++) { >+ d->ptr[i] = (d->fill + i) & 0xff; >+ } >+} >+ >+// Use to indicate to the malloc hooks that >+// this calls is from LowLevelAlloc. >+static bool using_low_level_alloc = false; >+ >+// n times, toss a coin, and based on the outcome >+// either allocate a new block or deallocate an old block. >+// New blocks are placed in a std::unordered_map with a random key >+// and initialized with RandomizeBlockDesc(). >+// If keys conflict, the older block is freed. >+// Old blocks are always checked with CheckBlockDesc() >+// before being freed. At the end of the run, >+// all remaining allocated blocks are freed. >+// If use_new_arena is true, use a fresh arena, and then delete it. >+// If call_malloc_hook is true and user_arena is true, >+// allocations and deallocations are reported via the MallocHook >+// interface. >+static void Test(bool use_new_arena, bool call_malloc_hook, int n) { >+ typedef std::unordered_map<int, BlockDesc> AllocMap; >+ AllocMap allocated; >+ AllocMap::iterator it; >+ BlockDesc block_desc; >+ int rnd; >+ LowLevelAlloc::Arena *arena = 0; >+ if (use_new_arena) { >+ int32_t flags = call_malloc_hook ? LowLevelAlloc::kCallMallocHook : 0; >+ arena = LowLevelAlloc::NewArena(flags); >+ } >+ for (int i = 0; i != n; i++) { >+ if (i != 0 && i % 10000 == 0) { >+ printf("."); >+ fflush(stdout); >+ } >+ >+ switch (rand() & 1) { // toss a coin >+ case 0: // coin came up heads: add a block >+ using_low_level_alloc = true; >+ block_desc.len = rand() & 0x3fff; >+ block_desc.ptr = >+ reinterpret_cast<char *>( >+ arena == 0 >+ ? LowLevelAlloc::Alloc(block_desc.len) >+ : LowLevelAlloc::AllocWithArena(block_desc.len, arena)); >+ using_low_level_alloc = false; >+ RandomizeBlockDesc(&block_desc); >+ rnd = rand(); >+ it = allocated.find(rnd); >+ if (it != allocated.end()) { >+ CheckBlockDesc(it->second); >+ using_low_level_alloc = true; >+ LowLevelAlloc::Free(it->second.ptr); >+ using_low_level_alloc = false; >+ it->second = block_desc; >+ } else { >+ allocated[rnd] = block_desc; >+ } >+ break; >+ case 1: // coin came up tails: remove a block >+ it = allocated.begin(); >+ if (it != allocated.end()) { >+ CheckBlockDesc(it->second); >+ using_low_level_alloc = true; >+ LowLevelAlloc::Free(it->second.ptr); >+ using_low_level_alloc = false; >+ allocated.erase(it); >+ } >+ break; >+ } >+ } >+ // remove all remaining blocks >+ while ((it = allocated.begin()) != allocated.end()) { >+ CheckBlockDesc(it->second); >+ using_low_level_alloc = true; >+ LowLevelAlloc::Free(it->second.ptr); >+ using_low_level_alloc = false; >+ allocated.erase(it); >+ } >+ if (use_new_arena) { >+ TEST_ASSERT(LowLevelAlloc::DeleteArena(arena)); >+ } >+} >+// LowLevelAlloc is designed to be safe to call before main(). >+static struct BeforeMain { >+ BeforeMain() { >+ Test(false, false, 50000); >+ Test(true, false, 50000); >+ Test(true, true, 50000); >+ } >+} before_main; >+ >+} // namespace >+} // namespace base_internal >+} // namespace absl >+ >+int main(int argc, char *argv[]) { >+ // The actual test runs in the global constructor of `before_main`. >+ printf("PASS\n"); >+ return 0; >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h >new file mode 100644 >index 0000000000000000000000000000000000000000..e716f2b49fa1f9c823928eda9fff8500a973ba19 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h >@@ -0,0 +1,104 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Core interfaces and definitions used by by low-level interfaces such as >+// SpinLock. >+ >+#ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ >+#define ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ >+ >+#include "absl/base/internal/scheduling_mode.h" >+#include "absl/base/macros.h" >+ >+// The following two declarations exist so SchedulingGuard may friend them with >+// the appropriate language linkage. These callbacks allow libc internals, such >+// as function level statics, to schedule cooperatively when locking. >+extern "C" bool __google_disable_rescheduling(void); >+extern "C" void __google_enable_rescheduling(bool disable_result); >+ >+namespace absl { >+namespace base_internal { >+ >+class SchedulingHelper; // To allow use of SchedulingGuard. >+class SpinLock; // To allow use of SchedulingGuard. >+ >+// SchedulingGuard >+// Provides guard semantics that may be used to disable cooperative rescheduling >+// of the calling thread within specific program blocks. This is used to >+// protect resources (e.g. low-level SpinLocks or Domain code) that cooperative >+// scheduling depends on. >+// >+// Domain implementations capable of rescheduling in reaction to involuntary >+// kernel thread actions (e.g blocking due to a pagefault or syscall) must >+// guarantee that an annotated thread is not allowed to (cooperatively) >+// reschedule until the annotated region is complete. >+// >+// It is an error to attempt to use a cooperatively scheduled resource (e.g. >+// Mutex) within a rescheduling-disabled region. >+// >+// All methods are async-signal safe. >+class SchedulingGuard { >+ public: >+ // Returns true iff the calling thread may be cooperatively rescheduled. >+ static bool ReschedulingIsAllowed(); >+ >+ private: >+ // Disable cooperative rescheduling of the calling thread. It may still >+ // initiate scheduling operations (e.g. wake-ups), however, it may not itself >+ // reschedule. Nestable. The returned result is opaque, clients should not >+ // attempt to interpret it. >+ // REQUIRES: Result must be passed to a pairing EnableScheduling(). >+ static bool DisableRescheduling(); >+ >+ // Marks the end of a rescheduling disabled region, previously started by >+ // DisableRescheduling(). >+ // REQUIRES: Pairs with innermost call (and result) of DisableRescheduling(). >+ static void EnableRescheduling(bool disable_result); >+ >+ // A scoped helper for {Disable, Enable}Rescheduling(). >+ // REQUIRES: destructor must run in same thread as constructor. >+ struct ScopedDisable { >+ ScopedDisable() { disabled = SchedulingGuard::DisableRescheduling(); } >+ ~ScopedDisable() { SchedulingGuard::EnableRescheduling(disabled); } >+ >+ bool disabled; >+ }; >+ >+ // Access to SchedulingGuard is explicitly white-listed. >+ friend class SchedulingHelper; >+ friend class SpinLock; >+ >+ SchedulingGuard(const SchedulingGuard&) = delete; >+ SchedulingGuard& operator=(const SchedulingGuard&) = delete; >+}; >+ >+//------------------------------------------------------------------------------ >+// End of public interfaces. >+//------------------------------------------------------------------------------ >+inline bool SchedulingGuard::ReschedulingIsAllowed() { >+ return false; >+} >+ >+inline bool SchedulingGuard::DisableRescheduling() { >+ return false; >+} >+ >+inline void SchedulingGuard::EnableRescheduling(bool /* disable_result */) { >+ return; >+} >+ >+ >+} // namespace base_internal >+} // namespace absl >+#endif // ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/per_thread_tls.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/per_thread_tls.h >new file mode 100644 >index 0000000000000000000000000000000000000000..2428bdc1238edaca3da94388c09d47c089f02dd7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/per_thread_tls.h >@@ -0,0 +1,48 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_ >+#define ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_ >+ >+// This header defines two macros: >+// If the platform supports thread-local storage: >+// ABSL_PER_THREAD_TLS_KEYWORD is the C keyword needed to declare a >+// thread-local variable ABSL_PER_THREAD_TLS is 1 >+// >+// Otherwise: >+// ABSL_PER_THREAD_TLS_KEYWORD is empty >+// ABSL_PER_THREAD_TLS is 0 >+// >+// Microsoft C supports thread-local storage. >+// GCC supports it if the appropriate version of glibc is available, >+// which the programmer can indicate by defining ABSL_HAVE_TLS >+ >+#include "absl/base/port.h" // For ABSL_HAVE_TLS >+ >+#if defined(ABSL_PER_THREAD_TLS) >+#error ABSL_PER_THREAD_TLS cannot be directly set >+#elif defined(ABSL_PER_THREAD_TLS_KEYWORD) >+#error ABSL_PER_THREAD_TLS_KEYWORD cannot be directly set >+#elif defined(ABSL_HAVE_TLS) >+#define ABSL_PER_THREAD_TLS_KEYWORD __thread >+#define ABSL_PER_THREAD_TLS 1 >+#elif defined(_MSC_VER) >+#define ABSL_PER_THREAD_TLS_KEYWORD __declspec(thread) >+#define ABSL_PER_THREAD_TLS 1 >+#else >+#define ABSL_PER_THREAD_TLS_KEYWORD >+#define ABSL_PER_THREAD_TLS 0 >+#endif >+ >+#endif // ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/pretty_function.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/pretty_function.h >new file mode 100644 >index 0000000000000000000000000000000000000000..01b0547bd08a484264b090060f96732fb02daaa1 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/pretty_function.h >@@ -0,0 +1,33 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_BASE_INTERNAL_PRETTY_FUNCTION_H_ >+#define ABSL_BASE_INTERNAL_PRETTY_FUNCTION_H_ >+ >+// ABSL_PRETTY_FUNCTION >+// >+// In C++11, __func__ gives the undecorated name of the current function. That >+// is, "main", not "int main()". Various compilers give extra macros to get the >+// decorated function name, including return type and arguments, to >+// differentiate between overload sets. ABSL_PRETTY_FUNCTION is a portable >+// version of these macros which forwards to the correct macro on each compiler. >+#if defined(_MSC_VER) >+#define ABSL_PRETTY_FUNCTION __FUNCSIG__ >+#elif defined(__GNUC__) >+#define ABSL_PRETTY_FUNCTION __PRETTY_FUNCTION__ >+#else >+#error "Unsupported compiler" >+#endif >+ >+#endif // ABSL_BASE_INTERNAL_PRETTY_FUNCTION_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/raw_logging.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/raw_logging.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..d9485a66cc649272962c3aee2997c073974ebda5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/raw_logging.cc >@@ -0,0 +1,234 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/raw_logging.h" >+ >+#include <stddef.h> >+#include <cstdarg> >+#include <cstdio> >+#include <cstdlib> >+#include <cstring> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/config.h" >+#include "absl/base/internal/atomic_hook.h" >+#include "absl/base/log_severity.h" >+ >+// We know how to perform low-level writes to stderr in POSIX and Windows. For >+// these platforms, we define the token ABSL_LOW_LEVEL_WRITE_SUPPORTED. >+// Much of raw_logging.cc becomes a no-op when we can't output messages, >+// although a FATAL ABSL_RAW_LOG message will still abort the process. >+ >+// ABSL_HAVE_POSIX_WRITE is defined when the platform provides posix write() >+// (as from unistd.h) >+// >+// This preprocessor token is also defined in raw_io.cc. If you need to copy >+// this, consider moving both to config.h instead. >+#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ >+ defined(__Fuchsia__) || defined(__native_client__) >+#include <unistd.h> >+ >+ >+#define ABSL_HAVE_POSIX_WRITE 1 >+#define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1 >+#else >+#undef ABSL_HAVE_POSIX_WRITE >+#endif >+ >+// ABSL_HAVE_SYSCALL_WRITE is defined when the platform provides the syscall >+// syscall(SYS_write, /*int*/ fd, /*char* */ buf, /*size_t*/ len); >+// for low level operations that want to avoid libc. >+#if (defined(__linux__) || defined(__FreeBSD__)) && !defined(__ANDROID__) >+#include <sys/syscall.h> >+#define ABSL_HAVE_SYSCALL_WRITE 1 >+#define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1 >+#else >+#undef ABSL_HAVE_SYSCALL_WRITE >+#endif >+ >+#ifdef _WIN32 >+#include <io.h> >+ >+#define ABSL_HAVE_RAW_IO 1 >+#define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1 >+#else >+#undef ABSL_HAVE_RAW_IO >+#endif >+ >+// TODO(gfalcon): We want raw-logging to work on as many platforms as possible. >+// Explicitly #error out when not ABSL_LOW_LEVEL_WRITE_SUPPORTED, except for a >+// whitelisted set of platforms for which we expect not to be able to raw log. >+ >+ABSL_CONST_INIT static absl::base_internal::AtomicHook< >+ absl::raw_logging_internal::LogPrefixHook> log_prefix_hook; >+ABSL_CONST_INIT static absl::base_internal::AtomicHook< >+ absl::raw_logging_internal::AbortHook> abort_hook; >+ >+#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED >+static const char kTruncated[] = " ... (message truncated)\n"; >+ >+// sprintf the format to the buffer, adjusting *buf and *size to reflect the >+// consumed bytes, and return whether the message fit without truncation. If >+// truncation occurred, if possible leave room in the buffer for the message >+// kTruncated[]. >+inline static bool VADoRawLog(char** buf, int* size, const char* format, >+ va_list ap) ABSL_PRINTF_ATTRIBUTE(3, 0); >+inline static bool VADoRawLog(char** buf, int* size, >+ const char* format, va_list ap) { >+ int n = vsnprintf(*buf, *size, format, ap); >+ bool result = true; >+ if (n < 0 || n > *size) { >+ result = false; >+ if (static_cast<size_t>(*size) > sizeof(kTruncated)) { >+ n = *size - sizeof(kTruncated); // room for truncation message >+ } else { >+ n = 0; // no room for truncation message >+ } >+ } >+ *size -= n; >+ *buf += n; >+ return result; >+} >+#endif // ABSL_LOW_LEVEL_WRITE_SUPPORTED >+ >+static constexpr int kLogBufSize = 3000; >+ >+namespace { >+ >+// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths >+// that invoke malloc() and getenv() that might acquire some locks. >+ >+// Helper for RawLog below. >+// *DoRawLog writes to *buf of *size and move them past the written portion. >+// It returns true iff there was no overflow or error. >+bool DoRawLog(char** buf, int* size, const char* format, ...) >+ ABSL_PRINTF_ATTRIBUTE(3, 4); >+bool DoRawLog(char** buf, int* size, const char* format, ...) { >+ va_list ap; >+ va_start(ap, format); >+ int n = vsnprintf(*buf, *size, format, ap); >+ va_end(ap); >+ if (n < 0 || n > *size) return false; >+ *size -= n; >+ *buf += n; >+ return true; >+} >+ >+void RawLogVA(absl::LogSeverity severity, const char* file, int line, >+ const char* format, va_list ap) ABSL_PRINTF_ATTRIBUTE(4, 0); >+void RawLogVA(absl::LogSeverity severity, const char* file, int line, >+ const char* format, va_list ap) { >+ char buffer[kLogBufSize]; >+ char* buf = buffer; >+ int size = sizeof(buffer); >+#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED >+ bool enabled = true; >+#else >+ bool enabled = false; >+#endif >+ >+#ifdef ABSL_MIN_LOG_LEVEL >+ if (severity < static_cast<absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) && >+ severity < absl::LogSeverity::kFatal) { >+ enabled = false; >+ } >+#endif >+ >+ auto log_prefix_hook_ptr = log_prefix_hook.Load(); >+ if (log_prefix_hook_ptr) { >+ enabled = log_prefix_hook_ptr(severity, file, line, &buf, &size); >+ } else { >+ if (enabled) { >+ DoRawLog(&buf, &size, "[%s : %d] RAW: ", file, line); >+ } >+ } >+ const char* const prefix_end = buf; >+ >+#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED >+ if (enabled) { >+ bool no_chop = VADoRawLog(&buf, &size, format, ap); >+ if (no_chop) { >+ DoRawLog(&buf, &size, "\n"); >+ } else { >+ DoRawLog(&buf, &size, "%s", kTruncated); >+ } >+ absl::raw_logging_internal::SafeWriteToStderr(buffer, strlen(buffer)); >+ } >+#else >+ static_cast<void>(format); >+ static_cast<void>(ap); >+#endif >+ >+ // Abort the process after logging a FATAL message, even if the output itself >+ // was suppressed. >+ if (severity == absl::LogSeverity::kFatal) { >+ abort_hook(file, line, buffer, prefix_end, buffer + kLogBufSize); >+ abort(); >+ } >+} >+ >+} // namespace >+ >+namespace absl { >+namespace raw_logging_internal { >+void SafeWriteToStderr(const char *s, size_t len) { >+#if defined(ABSL_HAVE_SYSCALL_WRITE) >+ syscall(SYS_write, STDERR_FILENO, s, len); >+#elif defined(ABSL_HAVE_POSIX_WRITE) >+ write(STDERR_FILENO, s, len); >+#elif defined(ABSL_HAVE_RAW_IO) >+ _write(/* stderr */ 2, s, len); >+#else >+ // stderr logging unsupported on this platform >+ (void) s; >+ (void) len; >+#endif >+} >+ >+void RawLog(absl::LogSeverity severity, const char* file, int line, >+ const char* format, ...) ABSL_PRINTF_ATTRIBUTE(4, 5); >+void RawLog(absl::LogSeverity severity, const char* file, int line, >+ const char* format, ...) { >+ va_list ap; >+ va_start(ap, format); >+ RawLogVA(severity, file, line, format, ap); >+ 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; >+#else // !ABSL_LOW_LEVEL_WRITE_SUPPORTED >+ return false; >+#endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED >+} >+ >+ABSL_CONST_INIT absl::base_internal::AtomicHook<InternalLogFunction> >+ internal_log_function(DefaultInternalLog); >+ >+void RegisterInternalLogFunction(InternalLogFunction func) { >+ internal_log_function.Store(func); >+} >+ >+} // namespace raw_logging_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/raw_logging.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/raw_logging.h >new file mode 100644 >index 0000000000000000000000000000000000000000..67abfd30798db8fff60b284aa6c92dfe23a45bef >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/raw_logging.h >@@ -0,0 +1,180 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Thread-safe logging routines that do not allocate any memory or >+// acquire any locks, and can therefore be used by low-level memory >+// allocation, synchronization, and signal-handling code. >+ >+#ifndef ABSL_BASE_INTERNAL_RAW_LOGGING_H_ >+#define ABSL_BASE_INTERNAL_RAW_LOGGING_H_ >+ >+#include <string> >+ >+#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" >+ >+// This is similar to LOG(severity) << format..., but >+// * it is to be used ONLY by low-level modules that can't use normal LOG() >+// * it is designed to be a low-level logger that does not allocate any >+// memory and does not need any locks, hence: >+// * it logs straight and ONLY to STDERR w/o buffering >+// * it uses an explicit printf-format and arguments list >+// * it will silently chop off really long message strings >+// Usage example: >+// ABSL_RAW_LOG(ERROR, "Failed foo with %i: %s", status, error); >+// This will print an almost standard log line like this to stderr only: >+// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file >+#define ABSL_RAW_LOG(severity, ...) \ >+ do { \ >+ constexpr const char* absl_raw_logging_internal_basename = \ >+ ::absl::raw_logging_internal::Basename(__FILE__, \ >+ sizeof(__FILE__) - 1); \ >+ ::absl::raw_logging_internal::RawLog(ABSL_RAW_LOGGING_INTERNAL_##severity, \ >+ absl_raw_logging_internal_basename, \ >+ __LINE__, __VA_ARGS__); \ >+ } while (0) >+ >+// Similar to CHECK(condition) << message, but for low-level modules: >+// we use only ABSL_RAW_LOG that does not allocate memory. >+// We do not want to provide args list here to encourage this usage: >+// if (!cond) ABSL_RAW_LOG(FATAL, "foo ...", hard_to_compute_args); >+// so that the args are not computed when not needed. >+#define ABSL_RAW_CHECK(condition, message) \ >+ do { \ >+ if (ABSL_PREDICT_FALSE(!(condition))) { \ >+ ABSL_RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \ >+ } \ >+ } 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 >+#define ABSL_RAW_LOGGING_INTERNAL_FATAL ::absl::LogSeverity::kFatal >+#define ABSL_RAW_LOGGING_INTERNAL_LEVEL(severity) \ >+ ::absl::NormalizeLogSeverity(severity) >+ >+namespace absl { >+namespace raw_logging_internal { >+ >+// Helper function to implement ABSL_RAW_LOG >+// Logs format... at "severity" level, reporting it >+// as called from file:line. >+// This does not allocate memory or acquire locks. >+void RawLog(absl::LogSeverity severity, const char* file, int line, >+ const char* format, ...) ABSL_PRINTF_ATTRIBUTE(4, 5); >+ >+// Writes the provided buffer directly to stderr, in a safe, low-level manner. >+// >+// In POSIX this means calling write(), which is async-signal safe and does >+// not malloc. If the platform supports the SYS_write syscall, we invoke that >+// directly to side-step any libc interception. >+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. >+constexpr const char* Basename(const char* fname, int offset) { >+ return offset == 0 || fname[offset - 1] == '/' || fname[offset - 1] == '\\' >+ ? fname + offset >+ : Basename(fname, offset - 1); >+} >+ >+// For testing only. >+// Returns true if raw logging is fully supported. When it is not >+// fully supported, no messages will be emitted, but a log at FATAL >+// severity will cause an abort. >+// >+// TODO(gfalcon): Come up with a better name for this method. >+bool RawLoggingFullySupported(); >+ >+// Function type for a raw_logging customization hook for suppressing messages >+// by severity, and for writing custom prefixes on non-suppressed messages. >+// >+// The installed hook is called for every raw log invocation. The message will >+// be logged to stderr only if the hook returns true. FATAL errors will cause >+// the process to abort, even if writing to stderr is suppressed. The hook is >+// also provided with an output buffer, where it can write a custom log message >+// prefix. >+// >+// The raw_logging system does not allocate memory or grab locks. User-provided >+// hooks must avoid these operations, and must not throw exceptions. >+// >+// 'severity' is the severity level of the message being written. >+// 'file' and 'line' are the file and line number where the ABSL_RAW_LOG macro >+// was located. >+// 'buffer' and 'buf_size' are pointers to the buffer and buffer size. If the >+// hook writes a prefix, it must increment *buffer and decrement *buf_size >+// accordingly. >+using LogPrefixHook = bool (*)(absl::LogSeverity severity, const char* file, >+ int line, char** buffer, int* buf_size); >+ >+// Function type for a raw_logging customization hook called to abort a process >+// when a FATAL message is logged. If the provided AbortHook() returns, the >+// logging system will call abort(). >+// >+// 'file' and 'line' are the file and line number where the ABSL_RAW_LOG macro >+// was located. >+// The null-terminated logged message lives in the buffer between 'buf_start' >+// and 'buf_end'. 'prefix_end' points to the first non-prefix character of the >+// buffer (as written by the LogPrefixHook.) >+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<InternalLogFunction> internal_log_function; >+ >+void RegisterInternalLogFunction(InternalLogFunction func); >+ >+} // namespace raw_logging_internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_RAW_LOGGING_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/scheduling_mode.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/scheduling_mode.h >new file mode 100644 >index 0000000000000000000000000000000000000000..1b6497ad8757dece8dbcf488e4f918afc5836e04 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/scheduling_mode.h >@@ -0,0 +1,54 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Core interfaces and definitions used by by low-level interfaces such as >+// SpinLock. >+ >+#ifndef ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ >+#define ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ >+ >+namespace absl { >+namespace base_internal { >+ >+// Used to describe how a thread may be scheduled. Typically associated with >+// the declaration of a resource supporting synchronized access. >+// >+// SCHEDULE_COOPERATIVE_AND_KERNEL: >+// Specifies that when waiting, a cooperative thread (e.g. a Fiber) may >+// reschedule (using base::scheduling semantics); allowing other cooperative >+// threads to proceed. >+// >+// SCHEDULE_KERNEL_ONLY: (Also described as "non-cooperative") >+// Specifies that no cooperative scheduling semantics may be used, even if the >+// current thread is itself cooperatively scheduled. This means that >+// cooperative threads will NOT allow other cooperative threads to execute in >+// their place while waiting for a resource of this type. Host operating system >+// semantics (e.g. a futex) may still be used. >+// >+// When optional, clients should strongly prefer SCHEDULE_COOPERATIVE_AND_KERNEL >+// by default. SCHEDULE_KERNEL_ONLY should only be used for resources on which >+// base::scheduling (e.g. the implementation of a Scheduler) may depend. >+// >+// NOTE: Cooperative resources may not be nested below non-cooperative ones. >+// This means that it is invalid to to acquire a SCHEDULE_COOPERATIVE_AND_KERNEL >+// resource if a SCHEDULE_KERNEL_ONLY resource is already held. >+enum SchedulingMode { >+ SCHEDULE_KERNEL_ONLY = 0, // Allow scheduling only the host OS. >+ SCHEDULE_COOPERATIVE_AND_KERNEL, // Also allow cooperative scheduling. >+}; >+ >+} // namespace base_internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..1b97efbccc5870600f3abb8c47d9cc372ebab6ac >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock.cc >@@ -0,0 +1,228 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/spinlock.h" >+ >+#include <algorithm> >+#include <atomic> >+#include <limits> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/internal/atomic_hook.h" >+#include "absl/base/internal/cycleclock.h" >+#include "absl/base/internal/spinlock_wait.h" >+#include "absl/base/internal/sysinfo.h" /* For NumCPUs() */ >+#include "absl/base/call_once.h" >+ >+// Description of lock-word: >+// 31..00: [............................3][2][1][0] >+// >+// [0]: kSpinLockHeld >+// [1]: kSpinLockCooperative >+// [2]: kSpinLockDisabledScheduling >+// [31..3]: ONLY kSpinLockSleeper OR >+// Wait time in cycles >> PROFILE_TIMESTAMP_SHIFT >+// >+// Detailed descriptions: >+// >+// Bit [0]: The lock is considered held iff kSpinLockHeld is set. >+// >+// Bit [1]: Eligible waiters (e.g. Fibers) may co-operatively reschedule when >+// contended iff kSpinLockCooperative is set. >+// >+// Bit [2]: This bit is exclusive from bit [1]. It is used only by a >+// non-cooperative lock. When set, indicates that scheduling was >+// successfully disabled when the lock was acquired. May be unset, >+// even if non-cooperative, if a ThreadIdentity did not yet exist at >+// time of acquisition. >+// >+// Bit [3]: If this is the only upper bit ([31..3]) set then this lock was >+// acquired without contention, however, at least one waiter exists. >+// >+// Otherwise, bits [31..3] represent the time spent by the current lock >+// holder to acquire the lock. There may be outstanding waiter(s). >+ >+namespace absl { >+namespace base_internal { >+ >+ABSL_CONST_INIT static base_internal::AtomicHook<void (*)(const void *lock, >+ int64_t wait_cycles)> >+ submit_profile_data; >+ >+void RegisterSpinLockProfiler(void (*fn)(const void *contendedlock, >+ int64_t wait_cycles)) { >+ submit_profile_data.Store(fn); >+} >+ >+// Uncommon constructors. >+SpinLock::SpinLock(base_internal::SchedulingMode mode) >+ : lockword_(IsCooperative(mode) ? kSpinLockCooperative : 0) { >+ ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static); >+} >+ >+SpinLock::SpinLock(base_internal::LinkerInitialized, >+ base_internal::SchedulingMode mode) { >+ ABSL_TSAN_MUTEX_CREATE(this, 0); >+ if (IsCooperative(mode)) { >+ InitLinkerInitializedAndCooperative(); >+ } >+ // Otherwise, lockword_ is already initialized. >+} >+ >+// Static (linker initialized) spinlocks always start life as functional >+// non-cooperative locks. When their static constructor does run, it will call >+// this initializer to augment the lockword with the cooperative bit. By >+// actually taking the lock when we do this we avoid the need for an atomic >+// operation in the regular unlock path. >+// >+// SlowLock() must be careful to re-test for this bit so that any outstanding >+// waiters may be upgraded to cooperative status. >+void SpinLock::InitLinkerInitializedAndCooperative() { >+ Lock(); >+ lockword_.fetch_or(kSpinLockCooperative, std::memory_order_relaxed); >+ Unlock(); >+} >+ >+// Monitor the lock to see if its value changes within some time period >+// (adaptive_spin_count loop iterations). A timestamp indicating >+// when the thread initially started waiting for the lock is passed in via >+// the initial_wait_timestamp value. The total wait time in cycles for the >+// lock is returned in the wait_cycles parameter. The last value read >+// from the lock is returned from the method. >+uint32_t SpinLock::SpinLoop(int64_t initial_wait_timestamp, >+ uint32_t *wait_cycles) { >+ // We are already in the slow path of SpinLock, initialize the >+ // adaptive_spin_count here. >+ ABSL_CONST_INIT static absl::once_flag init_adaptive_spin_count; >+ ABSL_CONST_INIT static int adaptive_spin_count = 0; >+ base_internal::LowLevelCallOnce(&init_adaptive_spin_count, []() { >+ adaptive_spin_count = base_internal::NumCPUs() > 1 ? 1000 : 1; >+ }); >+ >+ int c = adaptive_spin_count; >+ uint32_t lock_value; >+ do { >+ lock_value = lockword_.load(std::memory_order_relaxed); >+ } while ((lock_value & kSpinLockHeld) != 0 && --c > 0); >+ uint32_t spin_loop_wait_cycles = >+ EncodeWaitCycles(initial_wait_timestamp, CycleClock::Now()); >+ *wait_cycles = spin_loop_wait_cycles; >+ >+ return TryLockInternal(lock_value, spin_loop_wait_cycles); >+} >+ >+void SpinLock::SlowLock() { >+ // 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); >+ >+ 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 >+ // it as having a sleeper. >+ if ((lock_value & kWaitTimeMask) == 0) { >+ // Here, just "mark" that the thread is going to sleep. Don't store the >+ // lock wait time in the lock as that will cause the current lock >+ // owner to think it experienced contention. >+ if (lockword_.compare_exchange_strong( >+ lock_value, lock_value | kSpinLockSleeper, >+ std::memory_order_acquire, std::memory_order_relaxed)) { >+ // Successfully transitioned to kSpinLockSleeper. Pass >+ // kSpinLockSleeper to the SpinLockWait routine to properly indicate >+ // the last lock_value observed. >+ lock_value |= kSpinLockSleeper; >+ } else if ((lock_value & kSpinLockHeld) == 0) { >+ // Lock is free again, so try and acquire it before sleeping. The >+ // new lock state will be the number of cycles this thread waited if >+ // this thread obtains the lock. >+ lock_value = TryLockInternal(lock_value, wait_cycles); >+ continue; // Skip the delay at the end of the loop. >+ } >+ } >+ >+ base_internal::SchedulingMode scheduling_mode; >+ if ((lock_value & kSpinLockCooperative) != 0) { >+ scheduling_mode = base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL; >+ } else { >+ scheduling_mode = base_internal::SCHEDULE_KERNEL_ONLY; >+ } >+ // SpinLockDelay() calls into fiber scheduler, we need to see >+ // synchronization there to avoid false positives. >+ ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0); >+ // Wait for an OS specific delay. >+ base_internal::SpinLockDelay(&lockword_, lock_value, ++lock_wait_call_count, >+ scheduling_mode); >+ 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); >+ } >+} >+ >+void SpinLock::SlowUnlock(uint32_t lock_value) { >+ base_internal::SpinLockWake(&lockword_, >+ false); // wake waiter if necessary >+ >+ // If our acquisition was contended, collect contentionz profile info. We >+ // reserve a unitary wait time to represent that a waiter exists without our >+ // own acquisition having been contended. >+ if ((lock_value & kWaitTimeMask) != kSpinLockSleeper) { >+ const uint64_t wait_cycles = DecodeWaitCycles(lock_value); >+ ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0); >+ submit_profile_data(this, wait_cycles); >+ ABSL_TSAN_MUTEX_POST_DIVERT(this, 0); >+ } >+} >+ >+// We use the upper 29 bits of the lock word to store the time spent waiting to >+// acquire this lock. This is reported by contentionz profiling. Since the >+// lower bits of the cycle counter wrap very quickly on high-frequency >+// processors we divide to reduce the granularity to 2^PROFILE_TIMESTAMP_SHIFT >+// sized units. On a 4Ghz machine this will lose track of wait times greater >+// than (2^29/4 Ghz)*128 =~ 17.2 seconds. Such waits should be extremely rare. >+enum { PROFILE_TIMESTAMP_SHIFT = 7 }; >+enum { LOCKWORD_RESERVED_SHIFT = 3 }; // We currently reserve the lower 3 bits. >+ >+uint32_t SpinLock::EncodeWaitCycles(int64_t wait_start_time, >+ int64_t wait_end_time) { >+ static const int64_t kMaxWaitTime = >+ std::numeric_limits<uint32_t>::max() >> LOCKWORD_RESERVED_SHIFT; >+ int64_t scaled_wait_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<uint32_t>( >+ std::min(scaled_wait_time, kMaxWaitTime) << LOCKWORD_RESERVED_SHIFT); >+ >+ // bump up value if necessary to avoid returning kSpinLockSleeper. >+ const uint32_t after_spinlock_sleeper = >+ kSpinLockSleeper + (1 << LOCKWORD_RESERVED_SHIFT); >+ return clamped == kSpinLockSleeper ? after_spinlock_sleeper : clamped; >+} >+ >+uint64_t SpinLock::DecodeWaitCycles(uint32_t lock_value) { >+ // Cast to uint32_t first to ensure bits [63:32] are cleared. >+ const uint64_t scaled_wait_time = >+ static_cast<uint32_t>(lock_value & kWaitTimeMask); >+ return scaled_wait_time >+ << (PROFILE_TIMESTAMP_SHIFT - LOCKWORD_RESERVED_SHIFT); >+} >+ >+} // namespace base_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock.h >new file mode 100644 >index 0000000000000000000000000000000000000000..212abc669e627363f8a0224ccb77918a69d31194 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock.h >@@ -0,0 +1,239 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+// Most users requiring mutual exclusion should use Mutex. >+// SpinLock is provided for use in three situations: >+// - for use in code that Mutex itself depends on >+// - to get a faster fast-path release under low contention (without an >+// atomic read-modify-write) In return, SpinLock has worse behaviour under >+// contention, which is why Mutex is preferred in most situations. >+// - for async signal safety (see below) >+ >+// SpinLock is async signal safe. If a spinlock is used within a signal >+// handler, all code that acquires the lock must ensure that the signal cannot >+// arrive while they are holding the lock. Typically, this is done by blocking >+// the signal. >+ >+#ifndef ABSL_BASE_INTERNAL_SPINLOCK_H_ >+#define ABSL_BASE_INTERNAL_SPINLOCK_H_ >+ >+#include <stdint.h> >+#include <sys/types.h> >+#include <atomic> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/dynamic_annotations.h" >+#include "absl/base/internal/low_level_scheduling.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/scheduling_mode.h" >+#include "absl/base/internal/tsan_mutex_interface.h" >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+#include "absl/base/thread_annotations.h" >+ >+namespace absl { >+namespace base_internal { >+ >+class LOCKABLE SpinLock { >+ public: >+ SpinLock() : lockword_(kSpinLockCooperative) { >+ ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static); >+ } >+ >+ // Special constructor for use with static SpinLock objects. E.g., >+ // >+ // static SpinLock lock(base_internal::kLinkerInitialized); >+ // >+ // When intialized using this constructor, we depend on the fact >+ // that the linker has already initialized the memory appropriately. >+ // A SpinLock constructed like this can be freely used from global >+ // initializers without worrying about the order in which global >+ // initializers run. >+ explicit SpinLock(base_internal::LinkerInitialized) { >+ // Does nothing; lockword_ is already initialized >+ ABSL_TSAN_MUTEX_CREATE(this, 0); >+ } >+ >+ // Constructors that allow non-cooperative spinlocks to be created for use >+ // inside thread schedulers. Normal clients should not use these. >+ explicit SpinLock(base_internal::SchedulingMode mode); >+ SpinLock(base_internal::LinkerInitialized, >+ base_internal::SchedulingMode mode); >+ >+ ~SpinLock() { ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static); } >+ >+ // Acquire this SpinLock. >+ inline void Lock() EXCLUSIVE_LOCK_FUNCTION() { >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, 0); >+ if (!TryLockImpl()) { >+ SlowLock(); >+ } >+ ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0); >+ } >+ >+ // Try to acquire this SpinLock without blocking and return true if the >+ // acquisition was successful. If the lock was not acquired, false is >+ // returned. If this SpinLock is free at the time of the call, TryLock >+ // will return true with high probability. >+ inline bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock); >+ bool res = TryLockImpl(); >+ ABSL_TSAN_MUTEX_POST_LOCK( >+ this, __tsan_mutex_try_lock | (res ? 0 : __tsan_mutex_try_lock_failed), >+ 0); >+ return res; >+ } >+ >+ // Release this SpinLock, which must be held by the calling thread. >+ 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); >+ >+ if ((lock_value & kSpinLockDisabledScheduling) != 0) { >+ base_internal::SchedulingGuard::EnableRescheduling(true); >+ } >+ if ((lock_value & kWaitTimeMask) != 0) { >+ // Collect contentionz profile info, and speed the wakeup of any waiter. >+ // The wait_cycles value indicates how long this thread spent waiting >+ // for the lock. >+ SlowUnlock(lock_value); >+ } >+ ABSL_TSAN_MUTEX_POST_UNLOCK(this, 0); >+ } >+ >+ // Determine if the lock is held. When the lock is held by the invoking >+ // thread, true will always be returned. Intended to be used as >+ // CHECK(lock.IsHeld()). >+ inline bool IsHeld() const { >+ return (lockword_.load(std::memory_order_relaxed) & kSpinLockHeld) != 0; >+ } >+ >+ protected: >+ // These should not be exported except for testing. >+ >+ // Store number of cycles between wait_start_time and wait_end_time in a >+ // lock value. >+ static uint32_t EncodeWaitCycles(int64_t wait_start_time, >+ int64_t wait_end_time); >+ >+ // Extract number of wait cycles in a lock value. >+ static uint64_t DecodeWaitCycles(uint32_t lock_value); >+ >+ // Provide access to protected method above. Use for testing only. >+ friend struct SpinLockTest; >+ >+ private: >+ // lockword_ is used to store the following: >+ // >+ // bit[0] encodes whether a lock is being held. >+ // bit[1] encodes whether a lock uses cooperative scheduling. >+ // bit[2] encodes whether a lock disables scheduling. >+ // bit[3:31] encodes time a lock spent on waiting as a 29-bit unsigned int. >+ enum { kSpinLockHeld = 1 }; >+ enum { kSpinLockCooperative = 2 }; >+ enum { kSpinLockDisabledScheduling = 4 }; >+ enum { kSpinLockSleeper = 8 }; >+ enum { kWaitTimeMask = // Includes kSpinLockSleeper. >+ ~(kSpinLockHeld | kSpinLockCooperative | kSpinLockDisabledScheduling) }; >+ >+ // Returns true if the provided scheduling mode is cooperative. >+ static constexpr bool IsCooperative( >+ base_internal::SchedulingMode scheduling_mode) { >+ return scheduling_mode == base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL; >+ } >+ >+ uint32_t TryLockInternal(uint32_t lock_value, uint32_t wait_cycles); >+ 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); >+ >+ inline bool TryLockImpl() { >+ uint32_t lock_value = lockword_.load(std::memory_order_relaxed); >+ return (TryLockInternal(lock_value, 0) & kSpinLockHeld) == 0; >+ } >+ >+ std::atomic<uint32_t> lockword_; >+ >+ SpinLock(const SpinLock&) = delete; >+ SpinLock& operator=(const SpinLock&) = delete; >+}; >+ >+// Corresponding locker object that arranges to acquire a spinlock for >+// the duration of a C++ scope. >+class SCOPED_LOCKABLE SpinLockHolder { >+ public: >+ inline explicit SpinLockHolder(SpinLock* l) EXCLUSIVE_LOCK_FUNCTION(l) >+ : lock_(l) { >+ l->Lock(); >+ } >+ inline ~SpinLockHolder() UNLOCK_FUNCTION() { lock_->Unlock(); } >+ >+ SpinLockHolder(const SpinLockHolder&) = delete; >+ SpinLockHolder& operator=(const SpinLockHolder&) = delete; >+ >+ private: >+ SpinLock* lock_; >+}; >+ >+// Register a hook for profiling support. >+// >+// The function pointer registered here will be called whenever a spinlock is >+// contended. The callback is given an opaque handle to the contended spinlock >+// and the number of wait cycles. This is thread-safe, but only a single >+// profiler can be registered. It is an error to call this function multiple >+// times with different arguments. >+void RegisterSpinLockProfiler(void (*fn)(const void* lock, >+ int64_t wait_cycles)); >+ >+//------------------------------------------------------------------------------ >+// Public interface ends here. >+//------------------------------------------------------------------------------ >+ >+// If (result & kSpinLockHeld) == 0, then *this was successfully locked. >+// Otherwise, returns last observed value for lockword_. >+inline uint32_t SpinLock::TryLockInternal(uint32_t lock_value, >+ uint32_t wait_cycles) { >+ if ((lock_value & kSpinLockHeld) != 0) { >+ return lock_value; >+ } >+ >+ uint32_t sched_disabled_bit = 0; >+ if ((lock_value & kSpinLockCooperative) == 0) { >+ // For non-cooperative locks we must make sure we mark ourselves as >+ // non-reschedulable before we attempt to CompareAndSwap. >+ if (base_internal::SchedulingGuard::DisableRescheduling()) { >+ sched_disabled_bit = kSpinLockDisabledScheduling; >+ } >+ } >+ >+ if (lockword_.compare_exchange_strong( >+ lock_value, >+ kSpinLockHeld | lock_value | wait_cycles | sched_disabled_bit, >+ std::memory_order_acquire, std::memory_order_relaxed)) { >+ } else { >+ base_internal::SchedulingGuard::EnableRescheduling(sched_disabled_bit != 0); >+ } >+ >+ return lock_value; >+} >+ >+} // namespace base_internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_SPINLOCK_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_akaros.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_akaros.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..051c8cf87fb6ffb280dcd8bf287b7588091dee30 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_akaros.inc >@@ -0,0 +1,35 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// This file is an Akaros-specific part of spinlock_wait.cc >+ >+#include <atomic> >+ >+#include "absl/base/internal/scheduling_mode.h" >+ >+extern "C" { >+ >+ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( >+ std::atomic<uint32_t>* /* lock_word */, uint32_t /* value */, >+ int /* loop */, absl::base_internal::SchedulingMode /* mode */) { >+ // In Akaros, one must take care not to call anything that could cause a >+ // malloc(), a blocking system call, or a uthread_yield() while holding a >+ // spinlock. Our callers assume will not call into libraries or other >+ // arbitrary code. >+} >+ >+ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake( >+ std::atomic<uint32_t>* /* lock_word */, bool /* all */) {} >+ >+} // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_posix.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_posix.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..0098c1c76016f18538fa6ec82f357c05b4f84934 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_posix.inc >@@ -0,0 +1,46 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// This file is a Posix-specific part of spinlock_wait.cc >+ >+#include <sched.h> >+#include <atomic> >+#include <ctime> >+#include <cerrno> >+ >+#include "absl/base/internal/scheduling_mode.h" >+#include "absl/base/port.h" >+ >+extern "C" { >+ >+ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( >+ std::atomic<uint32_t>* /* lock_word */, uint32_t /* value */, int loop, >+ absl::base_internal::SchedulingMode /* mode */) { >+ int save_errno = errno; >+ if (loop == 0) { >+ } else if (loop == 1) { >+ sched_yield(); >+ } else { >+ struct timespec tm; >+ tm.tv_sec = 0; >+ tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop); >+ nanosleep(&tm, nullptr); >+ } >+ errno = save_errno; >+} >+ >+ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake( >+ std::atomic<uint32_t>* /* lock_word */, bool /* all */) {} >+ >+} // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..9f6e9911e1096b2f187cc6a8430544e9fc166333 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc >@@ -0,0 +1,79 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// The OS-specific header included below must provide two calls: >+// base::subtle::SpinLockDelay() and base::subtle::SpinLockWake(). >+// See spinlock_wait.h for the specs. >+ >+#include <atomic> >+#include <cstdint> >+ >+#include "absl/base/internal/spinlock_wait.h" >+ >+#if defined(_WIN32) >+#include "absl/base/internal/spinlock_win32.inc" >+#elif defined(__akaros__) >+#include "absl/base/internal/spinlock_akaros.inc" >+#else >+#include "absl/base/internal/spinlock_posix.inc" >+#endif >+ >+namespace absl { >+namespace base_internal { >+ >+// See spinlock_wait.h for spec. >+uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n, >+ const SpinLockWaitTransition trans[], >+ base_internal::SchedulingMode scheduling_mode) { >+ for (int loop = 0; ; loop++) { >+ 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 >+ w->compare_exchange_strong(v, trans[i].to, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ if (trans[i].done) return v; >+ } >+ } >+} >+ >+static std::atomic<uint64_t> delay_rand; >+ >+// Return a suggested delay in nanoseconds for iteration number "loop" >+int SpinLockSuggestedDelayNS(int loop) { >+ // Weak pseudo-random number generator to get some spread between threads >+ // when many are spinning. >+ uint64_t r = delay_rand.load(std::memory_order_relaxed); >+ r = 0x5deece66dLL * r + 0xb; // numbers from nrand48() >+ delay_rand.store(r, std::memory_order_relaxed); >+ >+ r <<= 16; // 48-bit random number now in top 48-bits. >+ if (loop < 0 || loop > 32) { // limit loop to 0..32 >+ loop = 32; >+ } >+ // loop>>3 cannot exceed 4 because loop cannot exceed 32. >+ // Select top 20..24 bits of lower 48 bits, >+ // giving approximately 0ms to 16ms. >+ // Mean is exponential in loop for first 32 iterations, then 8ms. >+ // The futex path multiplies this by 16, since we expect explicit wakeups >+ // almost always on that path. >+ return static_cast<int>(r >> (44 - (loop >> 3))); >+} >+ >+} // namespace base_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h >new file mode 100644 >index 0000000000000000000000000000000000000000..5c6cc7fdba4cc3f3b72f50b4c50de9f19a72085d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h >@@ -0,0 +1,91 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_ >+#define ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_ >+ >+// Operations to make atomic transitions on a word, and to allow >+// waiting for those transitions to become possible. >+ >+#include <stdint.h> >+#include <atomic> >+ >+#include "absl/base/internal/scheduling_mode.h" >+ >+namespace absl { >+namespace base_internal { >+ >+// SpinLockWait() waits until it can perform one of several transitions from >+// "from" to "to". It returns when it performs a transition where done==true. >+struct SpinLockWaitTransition { >+ uint32_t from; >+ uint32_t to; >+ bool done; >+}; >+ >+// Wait until *w can transition from trans[i].from to trans[i].to for some i >+// satisfying 0<=i<n && trans[i].done, atomically make the transition, >+// then return the old value of *w. Make any other atomic transitions >+// where !trans[i].done, but continue waiting. >+uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n, >+ const SpinLockWaitTransition trans[], >+ SchedulingMode scheduling_mode); >+ >+// If possible, wake some thread that has called SpinLockDelay(w, ...). If >+// "all" is true, wake all such threads. This call is a hint, and on some >+// systems it may be a no-op; threads calling SpinLockDelay() will always wake >+// eventually even if SpinLockWake() is never called. >+void SpinLockWake(std::atomic<uint32_t> *w, bool all); >+ >+// Wait for an appropriate spin delay on iteration "loop" of a >+// spin loop on location *w, whose previously observed value was "value". >+// SpinLockDelay() may do nothing, may yield the CPU, may sleep a clock tick, >+// or may wait for a delay that can be truncated by a call to SpinLockWake(w). >+// In all cases, it must return in bounded time even if SpinLockWake() is not >+// called. >+void SpinLockDelay(std::atomic<uint32_t> *w, uint32_t value, int loop, >+ base_internal::SchedulingMode scheduling_mode); >+ >+// Helper used by AbslInternalSpinLockDelay. >+// Returns a suggested delay in nanoseconds for iteration number "loop". >+int SpinLockSuggestedDelayNS(int loop); >+ >+} // namespace base_internal >+} // namespace absl >+ >+// In some build configurations we pass --detect-odr-violations to the >+// gold linker. This causes it to flag weak symbol overrides as ODR >+// violations. Because ODR only applies to C++ and not C, >+// --detect-odr-violations ignores symbols not mangled with C++ names. >+// By changing our extension points to be extern "C", we dodge this >+// check. >+extern "C" { >+void AbslInternalSpinLockWake(std::atomic<uint32_t> *w, bool all); >+void AbslInternalSpinLockDelay( >+ std::atomic<uint32_t> *w, uint32_t value, int loop, >+ absl::base_internal::SchedulingMode scheduling_mode); >+} >+ >+inline void absl::base_internal::SpinLockWake(std::atomic<uint32_t> *w, >+ bool all) { >+ AbslInternalSpinLockWake(w, all); >+} >+ >+inline void absl::base_internal::SpinLockDelay( >+ std::atomic<uint32_t> *w, uint32_t value, int loop, >+ absl::base_internal::SchedulingMode scheduling_mode) { >+ AbslInternalSpinLockDelay(w, value, loop, scheduling_mode); >+} >+ >+#endif // ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..32c8fc0bb51d9bdc7e95fcc3f9cddeff0495f024 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc >@@ -0,0 +1,37 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// This file is a Win32-specific part of spinlock_wait.cc >+ >+#include <windows.h> >+#include <atomic> >+#include "absl/base/internal/scheduling_mode.h" >+ >+extern "C" { >+ >+void AbslInternalSpinLockDelay(std::atomic<uint32_t>* /* lock_word */, >+ uint32_t /* value */, int loop, >+ absl::base_internal::SchedulingMode /* mode */) { >+ if (loop == 0) { >+ } else if (loop == 1) { >+ Sleep(0); >+ } else { >+ Sleep(absl::base_internal::SpinLockSuggestedDelayNS(loop) / 1000000); >+ } >+} >+ >+void AbslInternalSpinLockWake(std::atomic<uint32_t>* /* lock_word */, >+ bool /* all */) {} >+ >+} // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/sysinfo.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/sysinfo.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..db41bacc844c63491a80a4071451df740f09f647 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/sysinfo.cc >@@ -0,0 +1,404 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/sysinfo.h" >+ >+#include "absl/base/attributes.h" >+ >+#ifdef _WIN32 >+#include <shlwapi.h> >+#include <windows.h> >+#else >+#include <fcntl.h> >+#include <pthread.h> >+#include <sys/stat.h> >+#include <sys/types.h> >+#include <unistd.h> >+#endif >+ >+#ifdef __linux__ >+#include <sys/syscall.h> >+#endif >+ >+#if defined(__APPLE__) || defined(__FreeBSD__) >+#include <sys/sysctl.h> >+#endif >+ >+#if defined(__myriad2__) >+#include <rtems.h> >+#endif >+ >+#include <string.h> >+#include <cassert> >+#include <cstdint> >+#include <cstdio> >+#include <cstdlib> >+#include <ctime> >+#include <limits> >+#include <thread> // NOLINT(build/c++11) >+#include <utility> >+#include <vector> >+ >+#include "absl/base/call_once.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/spinlock.h" >+#include "absl/base/internal/unscaledcycleclock.h" >+ >+namespace absl { >+namespace base_internal { >+ >+static once_flag init_system_info_once; >+static int num_cpus = 0; >+static double nominal_cpu_frequency = 1.0; // 0.0 might be dangerous. >+ >+static int GetNumCPUs() { >+#if defined(__myriad2__) >+ return 1; >+#else >+ // Other possibilities: >+ // - Read /sys/devices/system/cpu/online and use cpumask_parse() >+ // - sysconf(_SC_NPROCESSORS_ONLN) >+ return std::thread::hardware_concurrency(); >+#endif >+} >+ >+#if defined(_WIN32) >+ >+static double GetNominalCPUFrequency() { >+ DWORD data; >+ DWORD data_size = sizeof(data); >+ #pragma comment(lib, "shlwapi.lib") // For SHGetValue(). >+ if (SUCCEEDED( >+ SHGetValueA(HKEY_LOCAL_MACHINE, >+ "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", >+ "~MHz", nullptr, &data, &data_size))) { >+ return data * 1e6; // Value is MHz. >+ } >+ return 1.0; >+} >+ >+#elif defined(CTL_HW) && defined(HW_CPU_FREQ) >+ >+static double GetNominalCPUFrequency() { >+ unsigned freq; >+ size_t size = sizeof(freq); >+ int mib[2] = {CTL_HW, HW_CPU_FREQ}; >+ if (sysctl(mib, 2, &freq, &size, nullptr, 0) == 0) { >+ return static_cast<double>(freq); >+ } >+ return 1.0; >+} >+ >+#else >+ >+// Helper function for reading a long from a file. Returns true if successful >+// and the memory location pointed to by value is set to the value read. >+static bool ReadLongFromFile(const char *file, long *value) { >+ bool ret = false; >+ int fd = open(file, O_RDONLY); >+ if (fd != -1) { >+ char line[1024]; >+ char *err; >+ memset(line, '\0', sizeof(line)); >+ int len = read(fd, line, sizeof(line) - 1); >+ if (len <= 0) { >+ ret = false; >+ } else { >+ const long temp_value = strtol(line, &err, 10); >+ if (line[0] != '\0' && (*err == '\n' || *err == '\0')) { >+ *value = temp_value; >+ ret = true; >+ } >+ } >+ close(fd); >+ } >+ return ret; >+} >+ >+#if defined(ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY) >+ >+// Reads a monotonic time source and returns a value in >+// nanoseconds. The returned value uses an arbitrary epoch, not the >+// Unix epoch. >+static int64_t ReadMonotonicClockNanos() { >+ struct timespec t; >+#ifdef CLOCK_MONOTONIC_RAW >+ int rc = clock_gettime(CLOCK_MONOTONIC_RAW, &t); >+#else >+ int rc = clock_gettime(CLOCK_MONOTONIC, &t); >+#endif >+ if (rc != 0) { >+ perror("clock_gettime() failed"); >+ abort(); >+ } >+ return int64_t{t.tv_sec} * 1000000000 + t.tv_nsec; >+} >+ >+class UnscaledCycleClockWrapperForInitializeFrequency { >+ public: >+ static int64_t Now() { return base_internal::UnscaledCycleClock::Now(); } >+}; >+ >+struct TimeTscPair { >+ int64_t time; // From ReadMonotonicClockNanos(). >+ int64_t tsc; // From UnscaledCycleClock::Now(). >+}; >+ >+// Returns a pair of values (monotonic kernel time, TSC ticks) that >+// approximately correspond to each other. This is accomplished by >+// doing several reads and picking the reading with the lowest >+// latency. This approach is used to minimize the probability that >+// our thread was preempted between clock reads. >+static TimeTscPair GetTimeTscPair() { >+ int64_t best_latency = std::numeric_limits<int64_t>::max(); >+ TimeTscPair best; >+ for (int i = 0; i < 10; ++i) { >+ int64_t t0 = ReadMonotonicClockNanos(); >+ int64_t tsc = UnscaledCycleClockWrapperForInitializeFrequency::Now(); >+ int64_t t1 = ReadMonotonicClockNanos(); >+ int64_t latency = t1 - t0; >+ if (latency < best_latency) { >+ best_latency = latency; >+ best.time = t0; >+ best.tsc = tsc; >+ } >+ } >+ return best; >+} >+ >+// Measures and returns the TSC frequency by taking a pair of >+// measurements approximately `sleep_nanoseconds` apart. >+static double MeasureTscFrequencyWithSleep(int sleep_nanoseconds) { >+ auto t0 = GetTimeTscPair(); >+ struct timespec ts; >+ ts.tv_sec = 0; >+ ts.tv_nsec = sleep_nanoseconds; >+ while (nanosleep(&ts, &ts) != 0 && errno == EINTR) {} >+ auto t1 = GetTimeTscPair(); >+ double elapsed_ticks = t1.tsc - t0.tsc; >+ double elapsed_time = (t1.time - t0.time) * 1e-9; >+ return elapsed_ticks / elapsed_time; >+} >+ >+// Measures and returns the TSC frequency by calling >+// MeasureTscFrequencyWithSleep(), doubling the sleep interval until the >+// frequency measurement stabilizes. >+static double MeasureTscFrequency() { >+ double last_measurement = -1.0; >+ int sleep_nanoseconds = 1000000; // 1 millisecond. >+ for (int i = 0; i < 8; ++i) { >+ double measurement = MeasureTscFrequencyWithSleep(sleep_nanoseconds); >+ if (measurement * 0.99 < last_measurement && >+ last_measurement < measurement * 1.01) { >+ // Use the current measurement if it is within 1% of the >+ // previous measurement. >+ return measurement; >+ } >+ last_measurement = measurement; >+ sleep_nanoseconds *= 2; >+ } >+ return last_measurement; >+} >+ >+#endif // ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY >+ >+static double GetNominalCPUFrequency() { >+ long freq = 0; >+ >+ // Google's production kernel has a patch to export the TSC >+ // frequency through sysfs. If the kernel is exporting the TSC >+ // frequency use that. There are issues where cpuinfo_max_freq >+ // cannot be relied on because the BIOS may be exporting an invalid >+ // p-state (on x86) or p-states may be used to put the processor in >+ // a new mode (turbo mode). Essentially, those frequencies cannot >+ // always be relied upon. The same reasons apply to /proc/cpuinfo as >+ // well. >+ if (ReadLongFromFile("/sys/devices/system/cpu/cpu0/tsc_freq_khz", &freq)) { >+ return freq * 1e3; // Value is kHz. >+ } >+ >+#if defined(ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY) >+ // On these platforms, the TSC frequency is the nominal CPU >+ // frequency. But without having the kernel export it directly >+ // though /sys/devices/system/cpu/cpu0/tsc_freq_khz, there is no >+ // other way to reliably get the TSC frequency, so we have to >+ // measure it ourselves. Some CPUs abuse cpuinfo_max_freq by >+ // exporting "fake" frequencies for implementing new features. For >+ // example, Intel's turbo mode is enabled by exposing a p-state >+ // value with a higher frequency than that of the real TSC >+ // rate. Because of this, we prefer to measure the TSC rate >+ // ourselves on i386 and x86-64. >+ return MeasureTscFrequency(); >+#else >+ >+ // If CPU scaling is in effect, we want to use the *maximum* >+ // frequency, not whatever CPU speed some random processor happens >+ // to be using now. >+ if (ReadLongFromFile("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", >+ &freq)) { >+ return freq * 1e3; // Value is kHz. >+ } >+ >+ return 1.0; >+#endif // !ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY >+} >+ >+#endif >+ >+// InitializeSystemInfo() may be called before main() and before >+// malloc is properly initialized, therefore this must not allocate >+// memory. >+static void InitializeSystemInfo() { >+ num_cpus = GetNumCPUs(); >+ nominal_cpu_frequency = GetNominalCPUFrequency(); >+} >+ >+int NumCPUs() { >+ base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo); >+ return num_cpus; >+} >+ >+double NominalCPUFrequency() { >+ base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo); >+ return nominal_cpu_frequency; >+} >+ >+#if defined(_WIN32) >+ >+pid_t GetTID() { >+ return GetCurrentThreadId(); >+} >+ >+#elif defined(__linux__) >+ >+#ifndef SYS_gettid >+#define SYS_gettid __NR_gettid >+#endif >+ >+pid_t GetTID() { >+ return syscall(SYS_gettid); >+} >+ >+#elif defined(__akaros__) >+ >+pid_t GetTID() { >+ // Akaros has a concept of "vcore context", which is the state the program >+ // is forced into when we need to make a user-level scheduling decision, or >+ // run a signal handler. This is analogous to the interrupt context that a >+ // CPU might enter if it encounters some kind of exception. >+ // >+ // There is no current thread context in vcore context, but we need to give >+ // a reasonable answer if asked for a thread ID (e.g., in a signal handler). >+ // Thread 0 always exists, so if we are in vcore context, we return that. >+ // >+ // Otherwise, we know (since we are using pthreads) that the uthread struct >+ // current_uthread is pointing to is the first element of a >+ // struct pthread_tcb, so we extract and return the thread ID from that. >+ // >+ // TODO(dcross): Akaros anticipates moving the thread ID to the uthread >+ // structure at some point. We should modify this code to remove the cast >+ // when that happens. >+ if (in_vcore_context()) >+ return 0; >+ return reinterpret_cast<struct pthread_tcb *>(current_uthread)->id; >+} >+ >+#elif defined(__myriad2__) >+ >+pid_t GetTID() { >+ uint32_t tid; >+ rtems_task_ident(RTEMS_SELF, 0, &tid); >+ return tid; >+} >+ >+#else >+ >+// Fallback implementation of GetTID using pthread_getspecific. >+static once_flag tid_once; >+static pthread_key_t tid_key; >+static absl::base_internal::SpinLock tid_lock( >+ absl::base_internal::kLinkerInitialized); >+ >+// We set a bit per thread in this array to indicate that an ID is in >+// use. ID 0 is unused because it is the default value returned by >+// pthread_getspecific(). >+static std::vector<uint32_t>* tid_array GUARDED_BY(tid_lock) = nullptr; >+static constexpr int kBitsPerWord = 32; // tid_array is uint32_t. >+ >+// Returns the TID to tid_array. >+static void FreeTID(void *v) { >+ intptr_t tid = reinterpret_cast<intptr_t>(v); >+ int word = tid / kBitsPerWord; >+ uint32_t mask = ~(1u << (tid % kBitsPerWord)); >+ absl::base_internal::SpinLockHolder lock(&tid_lock); >+ assert(0 <= word && static_cast<size_t>(word) < tid_array->size()); >+ (*tid_array)[word] &= mask; >+} >+ >+static void InitGetTID() { >+ if (pthread_key_create(&tid_key, FreeTID) != 0) { >+ // The logging system calls GetTID() so it can't be used here. >+ perror("pthread_key_create failed"); >+ abort(); >+ } >+ >+ // Initialize tid_array. >+ absl::base_internal::SpinLockHolder lock(&tid_lock); >+ tid_array = new std::vector<uint32_t>(1); >+ (*tid_array)[0] = 1; // ID 0 is never-allocated. >+} >+ >+// Return a per-thread small integer ID from pthread's thread-specific data. >+pid_t GetTID() { >+ absl::call_once(tid_once, InitGetTID); >+ >+ intptr_t tid = reinterpret_cast<intptr_t>(pthread_getspecific(tid_key)); >+ if (tid != 0) { >+ return tid; >+ } >+ >+ int bit; // tid_array[word] = 1u << bit; >+ size_t word; >+ { >+ // Search for the first unused ID. >+ absl::base_internal::SpinLockHolder lock(&tid_lock); >+ // First search for a word in the array that is not all ones. >+ word = 0; >+ while (word < tid_array->size() && ~(*tid_array)[word] == 0) { >+ ++word; >+ } >+ if (word == tid_array->size()) { >+ tid_array->push_back(0); // No space left, add kBitsPerWord more IDs. >+ } >+ // Search for a zero bit in the word. >+ bit = 0; >+ while (bit < kBitsPerWord && (((*tid_array)[word] >> bit) & 1) != 0) { >+ ++bit; >+ } >+ tid = (word * kBitsPerWord) + bit; >+ (*tid_array)[word] |= 1u << bit; // Mark the TID as allocated. >+ } >+ >+ if (pthread_setspecific(tid_key, reinterpret_cast<void *>(tid)) != 0) { >+ perror("pthread_setspecific failed"); >+ abort(); >+ } >+ >+ return static_cast<pid_t>(tid); >+} >+ >+#endif >+ >+} // namespace base_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/sysinfo.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/sysinfo.h >new file mode 100644 >index 0000000000000000000000000000000000000000..5bd1c500bd54cc566655e4eb2205e26656ceb2f2 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/sysinfo.h >@@ -0,0 +1,63 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// This file includes routines to find out characteristics >+// of the machine a program is running on. It is undoubtedly >+// system-dependent. >+ >+// Functions listed here that accept a pid_t as an argument act on the >+// current process if the pid_t argument is 0 >+// All functions here are thread-hostile due to file caching unless >+// commented otherwise. >+ >+#ifndef ABSL_BASE_INTERNAL_SYSINFO_H_ >+#define ABSL_BASE_INTERNAL_SYSINFO_H_ >+ >+#ifndef _WIN32 >+#include <sys/types.h> >+#else >+#include <intsafe.h> >+#endif >+ >+#include "absl/base/port.h" >+ >+namespace absl { >+namespace base_internal { >+ >+// Nominal core processor cycles per second of each processor. This is _not_ >+// necessarily the frequency of the CycleClock counter (see cycleclock.h) >+// Thread-safe. >+double NominalCPUFrequency(); >+ >+// Number of logical processors (hyperthreads) in system. Thread-safe. >+int NumCPUs(); >+ >+// Return the thread id of the current thread, as told by the system. >+// No two currently-live threads implemented by the OS shall have the same ID. >+// Thread ids of exited threads may be reused. Multiple user-level threads >+// may have the same thread ID if multiplexed on the same OS thread. >+// >+// On Linux, you may send a signal to the resulting ID with kill(). However, >+// it is recommended for portability that you use pthread_kill() instead. >+#ifdef _WIN32 >+// On Windows, process id and thread id are of the same type according to >+// the return types of GetProcessId() and GetThreadId() are both DWORD. >+using pid_t = DWORD; >+#endif >+pid_t GetTID(); >+ >+} // namespace base_internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_SYSINFO_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/sysinfo_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/sysinfo_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e0d9aab9bc2dc0d4015ffc62cd1a8e02eeb1e213 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/sysinfo_test.cc >@@ -0,0 +1,98 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/sysinfo.h" >+ >+#ifndef _WIN32 >+#include <sys/types.h> >+#include <unistd.h> >+#endif >+ >+#include <thread> // NOLINT(build/c++11) >+#include <unordered_set> >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/synchronization/barrier.h" >+#include "absl/synchronization/mutex.h" >+ >+namespace absl { >+namespace base_internal { >+namespace { >+ >+TEST(SysinfoTest, NumCPUs) { >+ EXPECT_NE(NumCPUs(), 0) >+ << "NumCPUs() should not have the default value of 0"; >+} >+ >+TEST(SysinfoTest, NominalCPUFrequency) { >+#if !(defined(__aarch64__) && defined(__linux__)) >+ EXPECT_GE(NominalCPUFrequency(), 1000.0) >+ << "NominalCPUFrequency() did not return a reasonable value"; >+#else >+ // TODO(absl-team): Aarch64 cannot read the CPU frequency from sysfs, so we >+ // get back 1.0. Fix once the value is available. >+ EXPECT_EQ(NominalCPUFrequency(), 1.0) >+ << "CPU frequency detection was fixed! Please update unittest."; >+#endif >+} >+ >+TEST(SysinfoTest, GetTID) { >+ EXPECT_EQ(GetTID(), GetTID()); // Basic compile and equality test. >+#ifdef __native_client__ >+ // Native Client has a race condition bug that leads to memory >+ // exaustion when repeatedly creating and joining threads. >+ // https://bugs.chromium.org/p/nativeclient/issues/detail?id=1027 >+ return; >+#endif >+ // Test that TIDs are unique to each thread. >+ // Uses a few loops to exercise implementations that reallocate IDs. >+ for (int i = 0; i < 32; ++i) { >+ constexpr int kNumThreads = 64; >+ Barrier all_threads_done(kNumThreads); >+ std::vector<std::thread> threads; >+ >+ Mutex mutex; >+ std::unordered_set<pid_t> tids; >+ >+ for (int j = 0; j < kNumThreads; ++j) { >+ threads.push_back(std::thread([&]() { >+ pid_t id = GetTID(); >+ { >+ MutexLock lock(&mutex); >+ ASSERT_TRUE(tids.find(id) == tids.end()); >+ tids.insert(id); >+ } >+ // We can't simply join the threads here. The threads need to >+ // be alive otherwise the TID might have been reallocated to >+ // another live thread. >+ all_threads_done.Block(); >+ })); >+ } >+ for (auto& thread : threads) { >+ thread.join(); >+ } >+ } >+} >+ >+#ifdef __linux__ >+TEST(SysinfoTest, LinuxGetTID) { >+ // On Linux, for the main thread, GetTID()==getpid() is guaranteed by the API. >+ EXPECT_EQ(GetTID(), getpid()); >+} >+#endif >+ >+} // namespace >+} // namespace base_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..678e8568d7421e5148e9d19cd56e68084a003705 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity.cc >@@ -0,0 +1,123 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/thread_identity.h" >+ >+#ifndef _WIN32 >+#include <pthread.h> >+#include <signal.h> >+#endif >+ >+#include <atomic> >+#include <cassert> >+#include <memory> >+ >+#include "absl/base/call_once.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/spinlock.h" >+ >+namespace absl { >+namespace base_internal { >+ >+#if ABSL_THREAD_IDENTITY_MODE != ABSL_THREAD_IDENTITY_MODE_USE_CPP11 >+namespace { >+// Used to co-ordinate one-time creation of our pthread_key >+absl::once_flag init_thread_identity_key_once; >+pthread_key_t thread_identity_pthread_key; >+std::atomic<bool> pthread_key_initialized(false); >+ >+void AllocateThreadIdentityKey(ThreadIdentityReclaimerFunction reclaimer) { >+ pthread_key_create(&thread_identity_pthread_key, reclaimer); >+ pthread_key_initialized.store(true, std::memory_order_release); >+} >+} // namespace >+#endif >+ >+#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ >+ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 >+// The actual TLS storage for a thread's currently associated ThreadIdentity. >+// This is referenced by inline accessors in the header. >+// "protected" visibility ensures that if multiple instances of Abseil code >+// exist within a process (via dlopen() or similar), references to >+// thread_identity_ptr from each instance of the code will refer to >+// *different* instances of this ptr. >+#ifdef __GNUC__ >+__attribute__((visibility("protected"))) >+#endif // __GNUC__ >+ ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* thread_identity_ptr; >+#endif // TLS or CPP11 >+ >+void SetCurrentThreadIdentity( >+ ThreadIdentity* identity, ThreadIdentityReclaimerFunction reclaimer) { >+ assert(CurrentThreadIdentityIfPresent() == nullptr); >+ // Associate our destructor. >+ // NOTE: This call to pthread_setspecific is currently the only immovable >+ // barrier to CurrentThreadIdentity() always being async signal safe. >+#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC >+ // NOTE: Not async-safe. But can be open-coded. >+ absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey, >+ reclaimer); >+ // We must mask signals around the call to setspecific as with current glibc, >+ // a concurrent getspecific (needed for GetCurrentThreadIdentityIfPresent()) >+ // may zero our value. >+ // >+ // While not officially async-signal safe, getspecific within a signal handler >+ // is otherwise OK. >+ sigset_t all_signals; >+ sigset_t curr_signals; >+ sigfillset(&all_signals); >+ pthread_sigmask(SIG_SETMASK, &all_signals, &curr_signals); >+ pthread_setspecific(thread_identity_pthread_key, >+ reinterpret_cast<void*>(identity)); >+ pthread_sigmask(SIG_SETMASK, &curr_signals, nullptr); >+#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, >+ reclaimer); >+ pthread_setspecific(thread_identity_pthread_key, >+ reinterpret_cast<void*>(identity)); >+ thread_identity_ptr = identity; >+#elif ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 >+ thread_local std::unique_ptr<ThreadIdentity, ThreadIdentityReclaimerFunction> >+ holder(identity, reclaimer); >+ thread_identity_ptr = identity; >+#else >+#error Unimplemented ABSL_THREAD_IDENTITY_MODE >+#endif >+} >+ >+void ClearCurrentThreadIdentity() { >+#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ >+ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 >+ thread_identity_ptr = nullptr; >+#elif ABSL_THREAD_IDENTITY_MODE == \ >+ ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC >+ // pthread_setspecific expected to clear value on destruction >+ assert(CurrentThreadIdentityIfPresent() == nullptr); >+#endif >+} >+ >+#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC >+ThreadIdentity* CurrentThreadIdentityIfPresent() { >+ bool initialized = pthread_key_initialized.load(std::memory_order_acquire); >+ if (!initialized) { >+ return nullptr; >+ } >+ return reinterpret_cast<ThreadIdentity*>( >+ pthread_getspecific(thread_identity_pthread_key)); >+} >+#endif >+ >+} // namespace base_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity.h >new file mode 100644 >index 0000000000000000000000000000000000000000..a51722f9d828d54965ed9b19993c3c877f44ddbf >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity.h >@@ -0,0 +1,240 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Each active thread has an ThreadIdentity that may represent the thread in >+// various level interfaces. ThreadIdentity objects are never deallocated. >+// When a thread terminates, its ThreadIdentity object may be reused for a >+// thread created later. >+ >+#ifndef ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ >+#define ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ >+ >+#ifndef _WIN32 >+#include <pthread.h> >+// Defines __GOOGLE_GRTE_VERSION__ (via glibc-specific features.h) when >+// supported. >+#include <unistd.h> >+#endif >+ >+#include <atomic> >+#include <cstdint> >+ >+#include "absl/base/internal/per_thread_tls.h" >+ >+namespace absl { >+ >+struct SynchLocksHeld; >+struct SynchWaitParams; >+ >+namespace base_internal { >+ >+class SpinLock; >+struct ThreadIdentity; >+ >+// Used by the implementation of base::Mutex and base::CondVar. >+struct PerThreadSynch { >+ // The internal representation of base::Mutex and base::CondVar rely >+ // on the alignment of PerThreadSynch. Both store the address of the >+ // PerThreadSynch in the high-order bits of their internal state, >+ // which means the low kLowZeroBits of the address of PerThreadSynch >+ // must be zero. >+ static constexpr int kLowZeroBits = 8; >+ static constexpr int kAlignment = 1 << kLowZeroBits; >+ >+ // Returns the associated ThreadIdentity. >+ // This can be implemented as a cast because we guarantee >+ // PerThreadSynch is the first element of ThreadIdentity. >+ ThreadIdentity* thread_identity() { >+ return reinterpret_cast<ThreadIdentity*>(this); >+ } >+ >+ PerThreadSynch *next; // Circular waiter queue; initialized to 0. >+ PerThreadSynch *skip; // If non-zero, all entries in Mutex queue >+ // up to and including "skip" have same >+ // condition as this, and will be woken later >+ bool may_skip; // if false while on mutex queue, a mutex unlocker >+ // is using this PerThreadSynch as a terminator. Its >+ // skip field must not be filled in because the loop >+ // might then skip over the terminator. >+ >+ // The wait parameters of the current wait. waitp is null if the >+ // thread is not waiting. Transitions from null to non-null must >+ // occur before the enqueue commit point (state = kQueued in >+ // Enqueue() and CondVarEnqueue()). Transitions from non-null to >+ // null must occur after the wait is finished (state = kAvailable in >+ // Mutex::Block() and CondVar::WaitCommon()). This field may be >+ // changed only by the thread that describes this PerThreadSynch. A >+ // special case is Fer(), which calls Enqueue() on another thread, >+ // but with an identical SynchWaitParams pointer, thus leaving the >+ // pointer unchanged. >+ SynchWaitParams *waitp; >+ >+ bool suppress_fatal_errors; // If true, try to proceed even in the face of >+ // broken invariants. This is used within fatal >+ // signal handlers to improve the chances of >+ // debug logging information being output >+ // successfully. >+ >+ intptr_t readers; // Number of readers in mutex. >+ int priority; // Priority of thread (updated every so often). >+ >+ // When priority will next be read (cycles). >+ int64_t next_priority_read_cycles; >+ >+ // State values: >+ // kAvailable: This PerThreadSynch is available. >+ // kQueued: This PerThreadSynch is unavailable, it's currently queued on a >+ // Mutex or CondVar waistlist. >+ // >+ // Transitions from kQueued to kAvailable require a release >+ // barrier. This is needed as a waiter may use "state" to >+ // independently observe that it's no longer queued. >+ // >+ // Transitions from kAvailable to kQueued require no barrier, they >+ // are externally ordered by the Mutex. >+ enum State { >+ kAvailable, >+ kQueued >+ }; >+ std::atomic<State> state; >+ >+ bool maybe_unlocking; // Valid at head of Mutex waiter queue; >+ // true if UnlockSlow could be searching >+ // for a waiter to wake. Used for an optimization >+ // in Enqueue(). true is always a valid value. >+ // Can be reset to false when the unlocker or any >+ // writer releases the lock, or a reader fully releases >+ // the lock. It may not be set to false by a reader >+ // that decrements the count to non-zero. >+ // protected by mutex spinlock >+ >+ bool wake; // This thread is to be woken from a Mutex. >+ >+ // If "x" is on a waiter list for a mutex, "x->cond_waiter" is true iff the >+ // waiter is waiting on the mutex as part of a CV Wait or Mutex Await. >+ // >+ // The value of "x->cond_waiter" is meaningless if "x" is not on a >+ // Mutex waiter list. >+ bool cond_waiter; >+ >+ // Locks held; used during deadlock detection. >+ // Allocated in Synch_GetAllLocks() and freed in ReclaimThreadIdentity(). >+ SynchLocksHeld *all_locks; >+}; >+ >+struct ThreadIdentity { >+ // Must be the first member. The Mutex implementation requires that >+ // the PerThreadSynch object associated with each thread is >+ // PerThreadSynch::kAlignment aligned. We provide this alignment on >+ // ThreadIdentity itself. >+ PerThreadSynch per_thread_synch; >+ >+ // Private: Reserved for absl::synchronization_internal::Waiter. >+ struct WaiterState { >+ char data[128]; >+ } waiter_state; >+ >+ // Used by PerThreadSem::{Get,Set}ThreadBlockedCounter(). >+ std::atomic<int>* blocked_count_ptr; >+ >+ // The following variables are mostly read/written just by the >+ // thread itself. The only exception is that these are read by >+ // a ticker thread as a hint. >+ std::atomic<int> ticker; // Tick counter, incremented once per second. >+ std::atomic<int> wait_start; // Ticker value when thread started waiting. >+ std::atomic<bool> is_idle; // Has thread become idle yet? >+ >+ ThreadIdentity* next; >+}; >+ >+// Returns the ThreadIdentity object representing the calling thread; guaranteed >+// to be unique for its lifetime. The returned object will remain valid for the >+// program's lifetime; although it may be re-assigned to a subsequent thread. >+// If one does not exist, return nullptr instead. >+// >+// Does not malloc(*), and is async-signal safe. >+// [*] Technically pthread_setspecific() does malloc on first use; however this >+// is handled internally within tcmalloc's initialization already. >+// >+// New ThreadIdentity objects can be constructed and associated with a thread >+// by calling GetOrCreateCurrentThreadIdentity() in per-thread-sem.h. >+ThreadIdentity* CurrentThreadIdentityIfPresent(); >+ >+using ThreadIdentityReclaimerFunction = void (*)(void*); >+ >+// Sets the current thread identity to the given value. 'reclaimer' is a >+// pointer to the global function for cleaning up instances on thread >+// destruction. >+void SetCurrentThreadIdentity(ThreadIdentity* identity, >+ ThreadIdentityReclaimerFunction reclaimer); >+ >+// Removes the currently associated ThreadIdentity from the running thread. >+// This must be called from inside the ThreadIdentityReclaimerFunction, and only >+// from that function. >+void ClearCurrentThreadIdentity(); >+ >+// May be chosen at compile time via: -DABSL_FORCE_THREAD_IDENTITY_MODE=<mode >+// index> >+#ifdef ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC >+#error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be direcly set >+#else >+#define ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0 >+#endif >+ >+#ifdef ABSL_THREAD_IDENTITY_MODE_USE_TLS >+#error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be direcly set >+#else >+#define ABSL_THREAD_IDENTITY_MODE_USE_TLS 1 >+#endif >+ >+#ifdef ABSL_THREAD_IDENTITY_MODE_USE_CPP11 >+#error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be direcly set >+#else >+#define ABSL_THREAD_IDENTITY_MODE_USE_CPP11 2 >+#endif >+ >+#ifdef ABSL_THREAD_IDENTITY_MODE >+#error ABSL_THREAD_IDENTITY_MODE cannot be direcly set >+#elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE) >+#define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE >+#elif defined(_WIN32) >+#define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11 >+#elif ABSL_PER_THREAD_TLS && defined(__GOOGLE_GRTE_VERSION__) && \ >+ (__GOOGLE_GRTE_VERSION__ >= 20140228L) >+// Support for async-safe TLS was specifically added in GRTEv4. It's not >+// present in the upstream eglibc. >+// Note: Current default for production systems. >+#define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_TLS >+#else >+#define ABSL_THREAD_IDENTITY_MODE \ >+ ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC >+#endif >+ >+#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ >+ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 >+ >+extern ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* thread_identity_ptr; >+ >+inline ThreadIdentity* CurrentThreadIdentityIfPresent() { >+ return thread_identity_ptr; >+} >+ >+#elif ABSL_THREAD_IDENTITY_MODE != \ >+ ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC >+#error Unknown ABSL_THREAD_IDENTITY_MODE >+#endif >+ >+} // namespace base_internal >+} // namespace absl >+#endif // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..242522b4418af000b568b5f8f20fb4757b8e3cc3 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc >@@ -0,0 +1,38 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "benchmark/benchmark.h" >+#include "absl/base/internal/thread_identity.h" >+#include "absl/synchronization/internal/create_thread_identity.h" >+#include "absl/synchronization/internal/per_thread_sem.h" >+ >+namespace { >+ >+void BM_SafeCurrentThreadIdentity(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::synchronization_internal::GetOrCreateCurrentThreadIdentity()); >+ } >+} >+BENCHMARK(BM_SafeCurrentThreadIdentity); >+ >+void BM_UnsafeCurrentThreadIdentity(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::base_internal::CurrentThreadIdentityIfPresent()); >+ } >+} >+BENCHMARK(BM_UnsafeCurrentThreadIdentity); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..ecb8af68982987508817b4dca435c6754be89aa6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/thread_identity_test.cc >@@ -0,0 +1,126 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/thread_identity.h" >+ >+#include <thread> // NOLINT(build/c++11) >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/base/attributes.h" >+#include "absl/base/internal/spinlock.h" >+#include "absl/base/macros.h" >+#include "absl/synchronization/internal/per_thread_sem.h" >+#include "absl/synchronization/mutex.h" >+ >+namespace absl { >+namespace base_internal { >+namespace { >+ >+// protects num_identities_reused >+static absl::base_internal::SpinLock map_lock( >+ absl::base_internal::kLinkerInitialized); >+static int num_identities_reused; >+ >+static const void* const kCheckNoIdentity = reinterpret_cast<void*>(1); >+ >+static void TestThreadIdentityCurrent(const void* assert_no_identity) { >+ ThreadIdentity* identity; >+ >+ // We have to test this conditionally, because if the test framework relies >+ // on Abseil, then some previous action may have already allocated an >+ // identity. >+ if (assert_no_identity == kCheckNoIdentity) { >+ identity = CurrentThreadIdentityIfPresent(); >+ EXPECT_TRUE(identity == nullptr); >+ } >+ >+ identity = synchronization_internal::GetOrCreateCurrentThreadIdentity(); >+ EXPECT_TRUE(identity != nullptr); >+ ThreadIdentity* identity_no_init; >+ identity_no_init = CurrentThreadIdentityIfPresent(); >+ EXPECT_TRUE(identity == identity_no_init); >+ >+ // Check that per_thread_synch is correctly aligned. >+ EXPECT_EQ(0, reinterpret_cast<intptr_t>(&identity->per_thread_synch) % >+ PerThreadSynch::kAlignment); >+ EXPECT_EQ(identity, identity->per_thread_synch.thread_identity()); >+ >+ absl::base_internal::SpinLockHolder l(&map_lock); >+ num_identities_reused++; >+} >+ >+TEST(ThreadIdentityTest, BasicIdentityWorks) { >+ // This tests for the main() thread. >+ TestThreadIdentityCurrent(nullptr); >+} >+ >+TEST(ThreadIdentityTest, BasicIdentityWorksThreaded) { >+ // Now try the same basic test with multiple threads being created and >+ // destroyed. This makes sure that: >+ // - New threads are created without a ThreadIdentity. >+ // - We re-allocate ThreadIdentity objects from the free-list. >+ // - If a thread implementation chooses to recycle threads, that >+ // correct re-initialization occurs. >+ static const int kNumLoops = 3; >+ static const int kNumThreads = 400; >+ for (int iter = 0; iter < kNumLoops; iter++) { >+ std::vector<std::thread> threads; >+ for (int i = 0; i < kNumThreads; ++i) { >+ threads.push_back( >+ std::thread(TestThreadIdentityCurrent, kCheckNoIdentity)); >+ } >+ for (auto& thread : threads) { >+ thread.join(); >+ } >+ } >+ >+ // We should have recycled ThreadIdentity objects above; while (external) >+ // library threads allocating their own identities may preclude some >+ // reuse, we should have sufficient repetitions to exclude this. >+ EXPECT_LT(kNumThreads, num_identities_reused); >+} >+ >+TEST(ThreadIdentityTest, ReusedThreadIdentityMutexTest) { >+ // This test repeatly creates and joins a series of threads, each of >+ // which acquires and releases shared Mutex locks. This verifies >+ // Mutex operations work correctly under a reused >+ // ThreadIdentity. Note that the most likely failure mode of this >+ // test is a crash or deadlock. >+ static const int kNumLoops = 10; >+ static const int kNumThreads = 12; >+ static const int kNumMutexes = 3; >+ static const int kNumLockLoops = 5; >+ >+ Mutex mutexes[kNumMutexes]; >+ for (int iter = 0; iter < kNumLoops; ++iter) { >+ std::vector<std::thread> threads; >+ for (int thread = 0; thread < kNumThreads; ++thread) { >+ threads.push_back(std::thread([&]() { >+ for (int l = 0; l < kNumLockLoops; ++l) { >+ for (int m = 0; m < kNumMutexes; ++m) { >+ MutexLock lock(&mutexes[m]); >+ } >+ } >+ })); >+ } >+ for (auto& thread : threads) { >+ thread.join(); >+ } >+ } >+} >+ >+} // namespace >+} // namespace base_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..46dc573cfa8425f0fa72d563f481dc9093301c3c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc >@@ -0,0 +1,106 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/throw_delegate.h" >+ >+#include <cstdlib> >+#include <functional> >+#include <new> >+#include <stdexcept> >+#include "absl/base/config.h" >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+namespace base_internal { >+ >+namespace { >+template <typename T> >+[[noreturn]] void Throw(const T& error) { >+#ifdef ABSL_HAVE_EXCEPTIONS >+ throw error; >+#else >+ ABSL_RAW_LOG(ERROR, "%s", error.what()); >+ abort(); >+#endif >+} >+} // namespace >+ >+void ThrowStdLogicError(const std::string& what_arg) { >+ Throw(std::logic_error(what_arg)); >+} >+void ThrowStdLogicError(const char* what_arg) { >+ Throw(std::logic_error(what_arg)); >+} >+void ThrowStdInvalidArgument(const std::string& what_arg) { >+ Throw(std::invalid_argument(what_arg)); >+} >+void ThrowStdInvalidArgument(const char* what_arg) { >+ Throw(std::invalid_argument(what_arg)); >+} >+ >+void ThrowStdDomainError(const std::string& what_arg) { >+ Throw(std::domain_error(what_arg)); >+} >+void ThrowStdDomainError(const char* what_arg) { >+ Throw(std::domain_error(what_arg)); >+} >+ >+void ThrowStdLengthError(const std::string& what_arg) { >+ Throw(std::length_error(what_arg)); >+} >+void ThrowStdLengthError(const char* what_arg) { >+ Throw(std::length_error(what_arg)); >+} >+ >+void ThrowStdOutOfRange(const std::string& what_arg) { >+ Throw(std::out_of_range(what_arg)); >+} >+void ThrowStdOutOfRange(const char* what_arg) { >+ Throw(std::out_of_range(what_arg)); >+} >+ >+void ThrowStdRuntimeError(const std::string& what_arg) { >+ Throw(std::runtime_error(what_arg)); >+} >+void ThrowStdRuntimeError(const char* what_arg) { >+ Throw(std::runtime_error(what_arg)); >+} >+ >+void ThrowStdRangeError(const std::string& what_arg) { >+ Throw(std::range_error(what_arg)); >+} >+void ThrowStdRangeError(const char* what_arg) { >+ Throw(std::range_error(what_arg)); >+} >+ >+void ThrowStdOverflowError(const std::string& what_arg) { >+ Throw(std::overflow_error(what_arg)); >+} >+void ThrowStdOverflowError(const char* what_arg) { >+ Throw(std::overflow_error(what_arg)); >+} >+ >+void ThrowStdUnderflowError(const std::string& what_arg) { >+ Throw(std::underflow_error(what_arg)); >+} >+void ThrowStdUnderflowError(const char* what_arg) { >+ Throw(std::underflow_error(what_arg)); >+} >+ >+void ThrowStdBadFunctionCall() { Throw(std::bad_function_call()); } >+ >+void ThrowStdBadAlloc() { Throw(std::bad_alloc()); } >+ >+} // namespace base_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/throw_delegate.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/throw_delegate.h >new file mode 100644 >index 0000000000000000000000000000000000000000..70e2d7709e5b56e02a43d02ce48934693447571a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/throw_delegate.h >@@ -0,0 +1,71 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ >+#define ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ >+ >+#include <string> >+ >+namespace absl { >+namespace base_internal { >+ >+// Helper functions that allow throwing exceptions consistently from anywhere. >+// The main use case is for header-based libraries (eg templates), as they will >+// be built by many different targets with their own compiler options. >+// In particular, this will allow a safe way to throw exceptions even if the >+// caller is compiled with -fno-exceptions. This is intended for implementing >+// things like map<>::at(), which the standard documents as throwing an >+// exception on error. >+// >+// Using other techniques like #if tricks could lead to ODR violations. >+// >+// You shouldn't use it unless you're writing code that you know will be built >+// both with and without exceptions and you need to conform to an interface >+// that uses exceptions. >+ >+[[noreturn]] void ThrowStdLogicError(const std::string& what_arg); >+[[noreturn]] void ThrowStdLogicError(const char* what_arg); >+[[noreturn]] void ThrowStdInvalidArgument(const std::string& what_arg); >+[[noreturn]] void ThrowStdInvalidArgument(const char* what_arg); >+[[noreturn]] void ThrowStdDomainError(const std::string& what_arg); >+[[noreturn]] void ThrowStdDomainError(const char* what_arg); >+[[noreturn]] void ThrowStdLengthError(const std::string& what_arg); >+[[noreturn]] void ThrowStdLengthError(const char* what_arg); >+[[noreturn]] void ThrowStdOutOfRange(const std::string& what_arg); >+[[noreturn]] void ThrowStdOutOfRange(const char* what_arg); >+[[noreturn]] void ThrowStdRuntimeError(const std::string& what_arg); >+[[noreturn]] void ThrowStdRuntimeError(const char* what_arg); >+[[noreturn]] void ThrowStdRangeError(const std::string& what_arg); >+[[noreturn]] void ThrowStdRangeError(const char* what_arg); >+[[noreturn]] void ThrowStdOverflowError(const std::string& what_arg); >+[[noreturn]] void ThrowStdOverflowError(const char* what_arg); >+[[noreturn]] void ThrowStdUnderflowError(const std::string& what_arg); >+[[noreturn]] void ThrowStdUnderflowError(const char* what_arg); >+ >+[[noreturn]] void ThrowStdBadFunctionCall(); >+[[noreturn]] void ThrowStdBadAlloc(); >+ >+// ThrowStdBadArrayNewLength() cannot be consistently supported because >+// std::bad_array_new_length is missing in libstdc++ until 4.9.0. >+// https://gcc.gnu.org/onlinedocs/gcc-4.8.3/libstdc++/api/a01379_source.html >+// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/libstdc++/api/a01327_source.html >+// libcxx (as of 3.2) and msvc (as of 2015) both have it. >+// [[noreturn]] void ThrowStdBadArrayNewLength(); >+ >+} // namespace base_internal >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h >new file mode 100644 >index 0000000000000000000000000000000000000000..6bb4faedb879bb84bbab8b36c67bf5453ac8bfac >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h >@@ -0,0 +1,66 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// This file is intended solely for spinlock.h. >+// It provides ThreadSanitizer annotations for custom mutexes. >+// See <sanitizer/tsan_interface.h> for meaning of these annotations. >+ >+#ifndef ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_ >+#define ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_ >+ >+// ABSL_INTERNAL_HAVE_TSAN_INTERFACE >+// Macro intended only for internal use. >+// >+// Checks whether LLVM Thread Sanitizer interfaces are available. >+// First made available in LLVM 5.0 (Sep 2017). >+#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE >+#error "ABSL_INTERNAL_HAVE_TSAN_INTERFACE cannot be directly set." >+#endif >+ >+#if defined(THREAD_SANITIZER) && defined(__has_include) >+#if __has_include(<sanitizer/tsan_interface.h>) >+#define ABSL_INTERNAL_HAVE_TSAN_INTERFACE 1 >+#endif >+#endif >+ >+#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE >+#include <sanitizer/tsan_interface.h> >+ >+#define ABSL_TSAN_MUTEX_CREATE __tsan_mutex_create >+#define ABSL_TSAN_MUTEX_DESTROY __tsan_mutex_destroy >+#define ABSL_TSAN_MUTEX_PRE_LOCK __tsan_mutex_pre_lock >+#define ABSL_TSAN_MUTEX_POST_LOCK __tsan_mutex_post_lock >+#define ABSL_TSAN_MUTEX_PRE_UNLOCK __tsan_mutex_pre_unlock >+#define ABSL_TSAN_MUTEX_POST_UNLOCK __tsan_mutex_post_unlock >+#define ABSL_TSAN_MUTEX_PRE_SIGNAL __tsan_mutex_pre_signal >+#define ABSL_TSAN_MUTEX_POST_SIGNAL __tsan_mutex_post_signal >+#define ABSL_TSAN_MUTEX_PRE_DIVERT __tsan_mutex_pre_divert >+#define ABSL_TSAN_MUTEX_POST_DIVERT __tsan_mutex_post_divert >+ >+#else >+ >+#define ABSL_TSAN_MUTEX_CREATE(...) >+#define ABSL_TSAN_MUTEX_DESTROY(...) >+#define ABSL_TSAN_MUTEX_PRE_LOCK(...) >+#define ABSL_TSAN_MUTEX_POST_LOCK(...) >+#define ABSL_TSAN_MUTEX_PRE_UNLOCK(...) >+#define ABSL_TSAN_MUTEX_POST_UNLOCK(...) >+#define ABSL_TSAN_MUTEX_PRE_SIGNAL(...) >+#define ABSL_TSAN_MUTEX_POST_SIGNAL(...) >+#define ABSL_TSAN_MUTEX_PRE_DIVERT(...) >+#define ABSL_TSAN_MUTEX_POST_DIVERT(...) >+ >+#endif >+ >+#endif // ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/unaligned_access.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/unaligned_access.h >new file mode 100644 >index 0000000000000000000000000000000000000000..5c7517abd71a6bf5250719d1d58cc7a05a906e1a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/unaligned_access.h >@@ -0,0 +1,297 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ >+#define ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ >+ >+#include <string.h> >+#include <cstdint> >+ >+#include "absl/base/attributes.h" >+ >+// unaligned APIs >+ >+// Portable handling of unaligned loads, stores, and copies. >+// On some platforms, like ARM, the copy functions can be more efficient >+// then a load and a store. >+// >+// It is possible to implement all of these these using constant-length memcpy >+// calls, which is portable and will usually be inlined into simple loads and >+// stores if the architecture supports it. However, such inlining usually >+// happens in a pass that's quite late in compilation, which means the resulting >+// loads and stores cannot participate in many other optimizations, leading to >+// overall worse code. >+ >+// The unaligned API is C++ only. The declarations use C++ features >+// (namespaces, inline) which are absent or incompatible in C. >+#if defined(__cplusplus) >+ >+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) ||\ >+ defined(MEMORY_SANITIZER) >+// Consider we have an unaligned load/store of 4 bytes from address 0x...05. >+// AddressSanitizer will treat it as a 3-byte access to the range 05:07 and >+// will miss a bug if 08 is the first unaddressable byte. >+// ThreadSanitizer will also treat this as a 3-byte access to 05:07 and will >+// miss a race between this access and some other accesses to 08. >+// MemorySanitizer will correctly propagate the shadow on unaligned stores >+// and correctly report bugs on unaligned loads, but it may not properly >+// update and report the origin of the uninitialized memory. >+// For all three tools, replacing an unaligned access with a tool-specific >+// callback solves the problem. >+ >+// Make sure uint16_t/uint32_t/uint64_t are defined. >+#include <stdint.h> >+ >+extern "C" { >+uint16_t __sanitizer_unaligned_load16(const void *p); >+uint32_t __sanitizer_unaligned_load32(const void *p); >+uint64_t __sanitizer_unaligned_load64(const void *p); >+void __sanitizer_unaligned_store16(void *p, uint16_t v); >+void __sanitizer_unaligned_store32(void *p, uint32_t v); >+void __sanitizer_unaligned_store64(void *p, uint64_t v); >+} // extern "C" >+ >+namespace absl { >+ >+inline uint16_t UnalignedLoad16(const void *p) { >+ return __sanitizer_unaligned_load16(p); >+} >+ >+inline uint32_t UnalignedLoad32(const void *p) { >+ return __sanitizer_unaligned_load32(p); >+} >+ >+inline uint64_t UnalignedLoad64(const void *p) { >+ return __sanitizer_unaligned_load64(p); >+} >+ >+inline void UnalignedStore16(void *p, uint16_t v) { >+ __sanitizer_unaligned_store16(p, v); >+} >+ >+inline void UnalignedStore32(void *p, uint32_t v) { >+ __sanitizer_unaligned_store32(p, v); >+} >+ >+inline void UnalignedStore64(void *p, uint64_t v) { >+ __sanitizer_unaligned_store64(p, v); >+} >+ >+} // 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_STORE16(_p, _val) \ >+ (absl::UnalignedStore16(_p, _val)) >+#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ >+ (absl::UnalignedStore32(_p, _val)) >+#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ >+ (absl::UnalignedStore64(_p, _val)) >+ >+#elif defined(UNDEFINED_BEHAVIOR_SANITIZER) >+ >+namespace absl { >+ >+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 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_STORE16(_p, _val) \ >+ (absl::UnalignedStore16(_p, _val)) >+#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ >+ (absl::UnalignedStore32(_p, _val)) >+#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ >+ (absl::UnalignedStore64(_p, _val)) >+ >+#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386) || \ >+ defined(_M_IX86) || defined(__ppc__) || defined(__PPC__) || \ >+ defined(__ppc64__) || defined(__PPC64__) >+ >+// x86 and x86-64 can perform unaligned loads/stores directly; >+// modern PowerPC hardware can also do unaligned integer loads and stores; >+// but note: the FPU still sends unaligned loads and stores to a trap handler! >+ >+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ >+ (*reinterpret_cast<const uint16_t *>(_p)) >+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ >+ (*reinterpret_cast<const uint32_t *>(_p)) >+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ >+ (*reinterpret_cast<const uint64_t *>(_p)) >+ >+#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ >+ (*reinterpret_cast<uint16_t *>(_p) = (_val)) >+#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ >+ (*reinterpret_cast<uint32_t *>(_p) = (_val)) >+#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ >+ (*reinterpret_cast<uint64_t *>(_p) = (_val)) >+ >+#elif defined(__arm__) && \ >+ !defined(__ARM_ARCH_5__) && \ >+ !defined(__ARM_ARCH_5T__) && \ >+ !defined(__ARM_ARCH_5TE__) && \ >+ !defined(__ARM_ARCH_5TEJ__) && \ >+ !defined(__ARM_ARCH_6__) && \ >+ !defined(__ARM_ARCH_6J__) && \ >+ !defined(__ARM_ARCH_6K__) && \ >+ !defined(__ARM_ARCH_6Z__) && \ >+ !defined(__ARM_ARCH_6ZK__) && \ >+ !defined(__ARM_ARCH_6T2__) >+ >+ >+// ARMv7 and newer support native unaligned accesses, but only of 16-bit >+// and 32-bit values (not 64-bit); older versions either raise a fatal signal, >+// do an unaligned read and rotate the words around a bit, or do the reads very >+// slowly (trip through kernel mode). There's no simple #define that says just >+// "ARMv7 or higher", so we have to filter away all ARMv5 and ARMv6 >+// sub-architectures. Newer gcc (>= 4.6) set an __ARM_FEATURE_ALIGNED #define, >+// so in time, maybe we can move on to that. >+// >+// This is a mess, but there's not much we can do about it. >+// >+// To further complicate matters, only LDR instructions (single reads) are >+// allowed to be unaligned, not LDRD (two reads) or LDM (many reads). Unless we >+// explicitly tell the compiler that these accesses can be unaligned, it can and >+// will combine accesses. On armcc, the way to signal this is done by accessing >+// through the type (uint32_t __packed *), but GCC has no such attribute >+// (it ignores __attribute__((packed)) on individual variables). However, >+// we can tell it that a _struct_ is unaligned, which has the same effect, >+// so we do that. >+ >+namespace absl { >+namespace internal { >+ >+struct Unaligned16Struct { >+ uint16_t value; >+ uint8_t dummy; // To make the size non-power-of-two. >+} ABSL_ATTRIBUTE_PACKED; >+ >+struct Unaligned32Struct { >+ uint32_t value; >+ uint8_t dummy; // To make the size non-power-of-two. >+} ABSL_ATTRIBUTE_PACKED; >+ >+} // namespace internal >+} // namespace absl >+ >+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ >+ ((reinterpret_cast<const ::absl::internal::Unaligned16Struct *>(_p))->value) >+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ >+ ((reinterpret_cast<const ::absl::internal::Unaligned32Struct *>(_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)) >+ >+namespace absl { >+ >+inline uint64_t UnalignedLoad64(const void *p) { >+ uint64_t t; >+ memcpy(&t, p, sizeof t); >+ return t; >+} >+ >+inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } >+ >+} // namespace absl >+ >+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p)) >+#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ >+ (absl::UnalignedStore64(_p, _val)) >+ >+#else >+ >+// ABSL_INTERNAL_NEED_ALIGNED_LOADS is defined when the underlying platform >+// doesn't support unaligned access. >+#define ABSL_INTERNAL_NEED_ALIGNED_LOADS >+ >+// These functions are provided for architectures that don't support >+// unaligned loads and stores. >+ >+namespace absl { >+ >+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 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_STORE16(_p, _val) \ >+ (absl::UnalignedStore16(_p, _val)) >+#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ >+ (absl::UnalignedStore32(_p, _val)) >+#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ >+ (absl::UnalignedStore64(_p, _val)) >+ >+#endif >+ >+#endif // defined(__cplusplus), end of unaligned API >+ >+#endif // ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..a12d68bd10af6a2a99826d3fc828bd903d06c412 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc >@@ -0,0 +1,101 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/unscaledcycleclock.h" >+ >+#if ABSL_USE_UNSCALED_CYCLECLOCK >+ >+#if defined(_WIN32) >+#include <intrin.h> >+#endif >+ >+#if defined(__powerpc__) || defined(__ppc__) >+#include <sys/platform/ppc.h> >+#endif >+ >+#include "absl/base/internal/sysinfo.h" >+ >+namespace absl { >+namespace base_internal { >+ >+#if defined(__i386__) >+ >+int64_t UnscaledCycleClock::Now() { >+ int64_t ret; >+ __asm__ volatile("rdtsc" : "=A"(ret)); >+ return ret; >+} >+ >+double UnscaledCycleClock::Frequency() { >+ return base_internal::NominalCPUFrequency(); >+} >+ >+#elif defined(__x86_64__) >+ >+int64_t UnscaledCycleClock::Now() { >+ uint64_t low, high; >+ __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); >+ return (high << 32) | low; >+} >+ >+double UnscaledCycleClock::Frequency() { >+ return base_internal::NominalCPUFrequency(); >+} >+ >+#elif defined(__powerpc__) || defined(__ppc__) >+ >+int64_t UnscaledCycleClock::Now() { >+ return __ppc_get_timebase(); >+} >+ >+double UnscaledCycleClock::Frequency() { >+ return __ppc_get_timebase_freq(); >+} >+ >+#elif defined(__aarch64__) >+ >+// System timer of ARMv8 runs at a different frequency than the CPU's. >+// The frequency is fixed, typically in the range 1-50MHz. It can be >+// read at CNTFRQ special register. We assume the OS has set up >+// the virtual timer properly. >+int64_t UnscaledCycleClock::Now() { >+ int64_t virtual_timer_value; >+ asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value)); >+ return virtual_timer_value; >+} >+ >+double UnscaledCycleClock::Frequency() { >+ uint64_t aarch64_timer_frequency; >+ asm volatile("mrs %0, cntfrq_el0" : "=r"(aarch64_timer_frequency)); >+ return aarch64_timer_frequency; >+} >+ >+#elif defined(_M_IX86) || defined(_M_X64) >+ >+#pragma intrinsic(__rdtsc) >+ >+int64_t UnscaledCycleClock::Now() { >+ return __rdtsc(); >+} >+ >+double UnscaledCycleClock::Frequency() { >+ return base_internal::NominalCPUFrequency(); >+} >+ >+#endif >+ >+} // namespace base_internal >+} // namespace absl >+ >+#endif // ABSL_USE_UNSCALED_CYCLECLOCK >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h >new file mode 100644 >index 0000000000000000000000000000000000000000..049f1cace9811a5cf20570f95953983518e1dd5e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h >@@ -0,0 +1,119 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// UnscaledCycleClock >+// An UnscaledCycleClock yields the value and frequency of a cycle counter >+// that increments at a rate that is approximately constant. >+// This class is for internal / whitelisted use only, you should consider >+// using CycleClock instead. >+// >+// Notes: >+// The cycle counter frequency is not necessarily the core clock frequency. >+// That is, CycleCounter cycles are not necessarily "CPU cycles". >+// >+// An arbitrary offset may have been added to the counter at power on. >+// >+// On some platforms, the rate and offset of the counter may differ >+// slightly when read from different CPUs of a multiprocessor. Usually, >+// we try to ensure that the operating system adjusts values periodically >+// so that values agree approximately. If you need stronger guarantees, >+// consider using alternate interfaces. >+// >+// The CPU is not required to maintain the ordering of a cycle counter read >+// with respect to surrounding instructions. >+ >+#ifndef ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_ >+#define ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_ >+ >+#include <cstdint> >+ >+#if defined(__APPLE__) >+#include <TargetConditionals.h> >+#endif >+ >+#include "absl/base/port.h" >+ >+// The following platforms have an implementation of a hardware counter. >+#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \ >+ defined(__powerpc__) || defined(__ppc__) || \ >+ defined(_M_IX86) || defined(_M_X64) >+#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1 >+#else >+#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 0 >+#endif >+ >+// The following platforms often disable access to the hardware >+// counter (through a sandbox) even if the underlying hardware has a >+// usable counter. The CycleTimer interface also requires a *scaled* >+// CycleClock that runs at atleast 1 MHz. We've found some Android >+// ARM64 devices where this is not the case, so we disable it by >+// default on Android ARM64. >+#if defined(__native_client__) || TARGET_OS_IPHONE || \ >+ (defined(__ANDROID__) && defined(__aarch64__)) >+#define ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT 0 >+#else >+#define ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT 1 >+#endif >+ >+// UnscaledCycleClock is an optional internal feature. >+// Use "#if ABSL_USE_UNSCALED_CYCLECLOCK" to test for its presence. >+// Can be overridden at compile-time via -DABSL_USE_UNSCALED_CYCLECLOCK=0|1 >+#if !defined(ABSL_USE_UNSCALED_CYCLECLOCK) >+#define ABSL_USE_UNSCALED_CYCLECLOCK \ >+ (ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION && \ >+ ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT) >+#endif >+ >+#if ABSL_USE_UNSCALED_CYCLECLOCK >+ >+// This macro can be used to test if UnscaledCycleClock::Frequency() >+// is NominalCPUFrequency() on a particular platform. >+#if (defined(__i386__) || defined(__x86_64__) || \ >+ defined(_M_IX86) || defined(_M_X64)) >+#define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY >+#endif >+namespace absl { >+namespace time_internal { >+class UnscaledCycleClockWrapperForGetCurrentTime; >+} // namespace time_internal >+ >+namespace base_internal { >+class CycleClock; >+class UnscaledCycleClockWrapperForInitializeFrequency; >+ >+class UnscaledCycleClock { >+ private: >+ UnscaledCycleClock() = delete; >+ >+ // Return the value of a cycle counter that counts at a rate that is >+ // approximately constant. >+ static int64_t Now(); >+ >+ // Return the how much UnscaledCycleClock::Now() increases per second. >+ // This is not necessarily the core CPU clock frequency. >+ // It may be the nominal value report by the kernel, rather than a measured >+ // value. >+ static double Frequency(); >+ >+ // Whitelisted friends. >+ friend class base_internal::CycleClock; >+ friend class time_internal::UnscaledCycleClockWrapperForGetCurrentTime; >+ friend class base_internal::UnscaledCycleClockWrapperForInitializeFrequency; >+}; >+ >+} // namespace base_internal >+} // namespace absl >+#endif // ABSL_USE_UNSCALED_CYCLECLOCK >+ >+#endif // ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/invoke_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/invoke_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..466bf114a58dc176e72180911ec9b6b392c288e7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/invoke_test.cc >@@ -0,0 +1,200 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/invoke.h" >+ >+#include <functional> >+#include <memory> >+#include <string> >+#include <utility> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/memory/memory.h" >+#include "absl/strings/str_cat.h" >+ >+namespace absl { >+namespace base_internal { >+namespace { >+ >+int Function(int a, int b) { return a - b; } >+ >+int Sink(std::unique_ptr<int> p) { >+ return *p; >+} >+ >+std::unique_ptr<int> Factory(int n) { >+ return make_unique<int>(n); >+} >+ >+void NoOp() {} >+ >+struct ConstFunctor { >+ int operator()(int a, int b) const { return a - b; } >+}; >+ >+struct MutableFunctor { >+ int operator()(int a, int b) { return a - b; } >+}; >+ >+struct EphemeralFunctor { >+ int operator()(int a, int b) && { return a - b; } >+}; >+ >+struct OverloadedFunctor { >+ template <typename... Args> >+ std::string operator()(const Args&... args) & { >+ return StrCat("&", args...); >+ } >+ template <typename... Args> >+ std::string operator()(const Args&... args) const& { >+ return StrCat("const&", args...); >+ } >+ template <typename... Args> >+ std::string operator()(const Args&... args) && { >+ return StrCat("&&", args...); >+ } >+}; >+ >+struct Class { >+ int Method(int a, int b) { return a - b; } >+ int ConstMethod(int a, int b) const { return a - b; } >+ >+ int member; >+}; >+ >+struct FlipFlop { >+ int ConstMethod() const { return member; } >+ FlipFlop operator*() const { return {-member}; } >+ >+ int member; >+}; >+ >+// CallMaybeWithArg(f) resolves either to Invoke(f) or Invoke(f, 42), depending >+// on which one is valid. >+template <typename F> >+decltype(Invoke(std::declval<const F&>())) CallMaybeWithArg(const F& f) { >+ return Invoke(f); >+} >+ >+template <typename F> >+decltype(Invoke(std::declval<const F&>(), 42)) CallMaybeWithArg(const F& f) { >+ return Invoke(f, 42); >+} >+ >+TEST(InvokeTest, Function) { >+ EXPECT_EQ(1, Invoke(Function, 3, 2)); >+ EXPECT_EQ(1, Invoke(&Function, 3, 2)); >+} >+ >+TEST(InvokeTest, NonCopyableArgument) { >+ EXPECT_EQ(42, Invoke(Sink, make_unique<int>(42))); >+} >+ >+TEST(InvokeTest, NonCopyableResult) { >+ EXPECT_THAT(Invoke(Factory, 42), ::testing::Pointee(42)); >+} >+ >+TEST(InvokeTest, VoidResult) { >+ Invoke(NoOp); >+} >+ >+TEST(InvokeTest, ConstFunctor) { >+ EXPECT_EQ(1, Invoke(ConstFunctor(), 3, 2)); >+} >+ >+TEST(InvokeTest, MutableFunctor) { >+ MutableFunctor f; >+ EXPECT_EQ(1, Invoke(f, 3, 2)); >+ EXPECT_EQ(1, Invoke(MutableFunctor(), 3, 2)); >+} >+ >+TEST(InvokeTest, EphemeralFunctor) { >+ EphemeralFunctor f; >+ EXPECT_EQ(1, Invoke(std::move(f), 3, 2)); >+ EXPECT_EQ(1, Invoke(EphemeralFunctor(), 3, 2)); >+} >+ >+TEST(InvokeTest, OverloadedFunctor) { >+ OverloadedFunctor f; >+ const OverloadedFunctor& cf = f; >+ >+ EXPECT_EQ("&", Invoke(f)); >+ EXPECT_EQ("& 42", Invoke(f, " 42")); >+ >+ EXPECT_EQ("const&", Invoke(cf)); >+ EXPECT_EQ("const& 42", Invoke(cf, " 42")); >+ >+ EXPECT_EQ("&&", Invoke(std::move(f))); >+ EXPECT_EQ("&& 42", Invoke(std::move(f), " 42")); >+} >+ >+TEST(InvokeTest, ReferenceWrapper) { >+ ConstFunctor cf; >+ MutableFunctor mf; >+ EXPECT_EQ(1, Invoke(std::cref(cf), 3, 2)); >+ EXPECT_EQ(1, Invoke(std::ref(cf), 3, 2)); >+ EXPECT_EQ(1, Invoke(std::ref(mf), 3, 2)); >+} >+ >+TEST(InvokeTest, MemberFunction) { >+ std::unique_ptr<Class> p(new Class); >+ std::unique_ptr<const Class> cp(new Class); >+ EXPECT_EQ(1, Invoke(&Class::Method, p, 3, 2)); >+ EXPECT_EQ(1, Invoke(&Class::Method, p.get(), 3, 2)); >+ >+ EXPECT_EQ(1, Invoke(&Class::ConstMethod, p, 3, 2)); >+ EXPECT_EQ(1, Invoke(&Class::ConstMethod, p.get(), 3, 2)); >+ EXPECT_EQ(1, Invoke(&Class::ConstMethod, *p, 3, 2)); >+ >+ EXPECT_EQ(1, Invoke(&Class::ConstMethod, cp, 3, 2)); >+ EXPECT_EQ(1, Invoke(&Class::ConstMethod, cp.get(), 3, 2)); >+ EXPECT_EQ(1, Invoke(&Class::ConstMethod, *cp, 3, 2)); >+ >+ EXPECT_EQ(1, Invoke(&Class::Method, make_unique<Class>(), 3, 2)); >+ EXPECT_EQ(1, Invoke(&Class::ConstMethod, make_unique<Class>(), 3, 2)); >+ EXPECT_EQ(1, Invoke(&Class::ConstMethod, make_unique<const Class>(), 3, 2)); >+} >+ >+TEST(InvokeTest, DataMember) { >+ std::unique_ptr<Class> p(new Class{42}); >+ std::unique_ptr<const Class> cp(new Class{42}); >+ EXPECT_EQ(42, Invoke(&Class::member, p)); >+ EXPECT_EQ(42, Invoke(&Class::member, *p)); >+ EXPECT_EQ(42, Invoke(&Class::member, p.get())); >+ >+ Invoke(&Class::member, p) = 42; >+ Invoke(&Class::member, p.get()) = 42; >+ >+ EXPECT_EQ(42, Invoke(&Class::member, cp)); >+ EXPECT_EQ(42, Invoke(&Class::member, *cp)); >+ EXPECT_EQ(42, Invoke(&Class::member, cp.get())); >+} >+ >+TEST(InvokeTest, FlipFlop) { >+ FlipFlop obj = {42}; >+ // This call could resolve to (obj.*&FlipFlop::ConstMethod)() or >+ // ((*obj).*&FlipFlop::ConstMethod)(). We verify that it's the former. >+ EXPECT_EQ(42, Invoke(&FlipFlop::ConstMethod, obj)); >+ EXPECT_EQ(42, Invoke(&FlipFlop::member, obj)); >+} >+ >+TEST(InvokeTest, SfinaeFriendly) { >+ CallMaybeWithArg(NoOp); >+ EXPECT_THAT(CallMaybeWithArg(Factory), ::testing::Pointee(42)); >+} >+ >+} // namespace >+} // namespace base_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/log_severity.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/log_severity.h >new file mode 100644 >index 0000000000000000000000000000000000000000..e2931c34d1df54a7bbf7ed71de858503362c7337 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/log_severity.h >@@ -0,0 +1,67 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ >+#define ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ >+ >+#include <array> >+ >+#include "absl/base/attributes.h" >+ >+namespace absl { >+ >+// Four severity levels are defined. Logging APIs should terminate the program >+// when a message is logged at severity `kFatal`; the other levels have no >+// special semantics. >+enum class LogSeverity : int { >+ kInfo = 0, >+ kWarning = 1, >+ kError = 2, >+ kFatal = 3, >+}; >+ >+// Returns an iterable of all standard `absl::LogSeverity` values, ordered from >+// least to most severe. >+constexpr std::array<absl::LogSeverity, 4> LogSeverities() { >+ return {{absl::LogSeverity::kInfo, absl::LogSeverity::kWarning, >+ absl::LogSeverity::kError, absl::LogSeverity::kFatal}}; >+} >+ >+// Returns the all-caps std::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 >+ ? "INFO" >+ : s == absl::LogSeverity::kWarning >+ ? "WARNING" >+ : s == absl::LogSeverity::kError >+ ? "ERROR" >+ : s == absl::LogSeverity::kFatal ? "FATAL" : "UNKNOWN"; >+} >+ >+// Values less than `kInfo` normalize to `kInfo`; values greater than `kFatal` >+// normalize to `kError` (**NOT** `kFatal`). >+constexpr absl::LogSeverity NormalizeLogSeverity(absl::LogSeverity s) { >+ return s < absl::LogSeverity::kInfo >+ ? absl::LogSeverity::kInfo >+ : s > absl::LogSeverity::kFatal ? absl::LogSeverity::kError : s; >+} >+constexpr absl::LogSeverity NormalizeLogSeverity(int s) { >+ return NormalizeLogSeverity(static_cast<absl::LogSeverity>(s)); >+} >+ >+} // namespace absl >+ >+#endif // ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/macros.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/macros.h >new file mode 100644 >index 0000000000000000000000000000000000000000..ca3d5edb6536506f68274167e3a313d51cc0e313 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/macros.h >@@ -0,0 +1,202 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: macros.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines the set of language macros used within Abseil code. >+// For the set of macros used to determine supported compilers and platforms, >+// see absl/base/config.h instead. >+// >+// This code is compiled directly on many platforms, including client >+// platforms like Windows, Mac, and embedded systems. Before making >+// any changes here, make sure that you're not breaking any platforms. >+// >+ >+#ifndef ABSL_BASE_MACROS_H_ >+#define ABSL_BASE_MACROS_H_ >+ >+#include <cassert> >+#include <cstddef> >+ >+#include "absl/base/port.h" >+ >+// ABSL_ARRAYSIZE() >+// >+// Returns the number of elements in an array as a compile-time constant, which >+// can be used in defining new arrays. If you use this macro on a pointer by >+// mistake, you will get a compile-time error. >+#define ABSL_ARRAYSIZE(array) \ >+ (sizeof(::absl::macros_internal::ArraySizeHelper(array))) >+ >+namespace absl { >+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 <typename T, size_t N> >+auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N]; >+} // namespace macros_internal >+} // namespace absl >+ >+// kLinkerInitialized >+// >+// An enum used only as a constructor argument to indicate that a variable has >+// static storage duration, and that the constructor should do nothing to its >+// state. Use of this macro indicates to the reader that it is legal to >+// declare a static instance of the class, provided the constructor is given >+// the absl::base_internal::kLinkerInitialized argument. >+// >+// Normally, it is unsafe to declare a static variable that has a constructor or >+// a destructor because invocation order is undefined. However, if the type can >+// be zero-initialized (which the loader does for static variables) into a valid >+// state and the type's destructor does not affect storage, then a constructor >+// for static initialization can be declared. >+// >+// Example: >+// // Declaration >+// explicit MyClass(absl::base_internal:LinkerInitialized x) {} >+// >+// // Invocation >+// static MyClass my_global(absl::base_internal::kLinkerInitialized); >+namespace absl { >+namespace base_internal { >+enum LinkerInitialized { >+ kLinkerInitialized = 0, >+}; >+} // namespace base_internal >+} // namespace absl >+ >+// ABSL_FALLTHROUGH_INTENDED >+// >+// Annotates implicit fall-through between switch labels, allowing a case to >+// indicate intentional fallthrough and turn off warnings about any lack of a >+// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by >+// a semicolon and can be used in most places where `break` can, provided that >+// no statements exist between it and the next switch label. >+// >+// Example: >+// >+// switch (x) { >+// case 40: >+// case 41: >+// if (truth_is_out_there) { >+// ++x; >+// ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations >+// // in comments >+// } else { >+// return x; >+// } >+// case 42: >+// ... >+// >+// Notes: when compiled with clang in C++11 mode, the ABSL_FALLTHROUGH_INTENDED >+// macro is expanded to the [[clang::fallthrough]] attribute, which is analysed >+// when performing switch labels fall-through diagnostic >+// (`-Wimplicit-fallthrough`). See clang documentation on language extensions >+// for details: >+// http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough >+// >+// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro >+// has no effect on diagnostics. In any case this macro has no effect on runtime >+// behavior and performance of code. >+#ifdef ABSL_FALLTHROUGH_INTENDED >+#error "ABSL_FALLTHROUGH_INTENDED should not be defined." >+#endif >+ >+// TODO(zhangxy): Use c++17 standard [[fallthrough]] macro, when supported. >+#if defined(__clang__) && defined(__has_warning) >+#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") >+#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] >+#endif >+#elif defined(__GNUC__) && __GNUC__ >= 7 >+#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] >+#endif >+ >+#ifndef ABSL_FALLTHROUGH_INTENDED >+#define ABSL_FALLTHROUGH_INTENDED \ >+ do { \ >+ } while (0) >+#endif >+ >+// ABSL_DEPRECATED() >+// >+// Marks a deprecated class, struct, enum, function, method and variable >+// declarations. The macro argument is used as a custom diagnostic message (e.g. >+// suggestion of a better alternative). >+// >+// Example: >+// >+// class ABSL_DEPRECATED("Use Bar instead") Foo {...}; >+// ABSL_DEPRECATED("Use Baz instead") void Bar() {...} >+// >+// Every usage of a deprecated entity will trigger a warning when compiled with >+// clang's `-Wdeprecated-declarations` option. This option is turned off by >+// default, but the warnings will be reported by clang-tidy. >+#if defined(__clang__) && __cplusplus >= 201103L >+#define ABSL_DEPRECATED(message) __attribute__((deprecated(message))) >+#endif >+ >+#ifndef ABSL_DEPRECATED >+#define ABSL_DEPRECATED(message) >+#endif >+ >+// ABSL_BAD_CALL_IF() >+// >+// Used on a function overload to trap bad calls: any call that matches the >+// overload will cause a compile-time error. This macro uses a clang-specific >+// "enable_if" attribute, as described at >+// http://clang.llvm.org/docs/AttributeReference.html#enable-if >+// >+// Overloads which use this macro should be bracketed by >+// `#ifdef ABSL_BAD_CALL_IF`. >+// >+// Example: >+// >+// int isdigit(int c); >+// #ifdef ABSL_BAD_CALL_IF >+// int isdigit(int c) >+// ABSL_BAD_CALL_IF(c <= -1 || c > 255, >+// "'c' must have the value of an unsigned char or EOF"); >+// #endif // ABSL_BAD_CALL_IF >+ >+#if defined(__clang__) >+# if __has_attribute(enable_if) >+# define ABSL_BAD_CALL_IF(expr, msg) \ >+ __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg))) >+# endif >+#endif >+ >+// ABSL_ASSERT() >+// >+// In C++11, `assert` can't be used portably within constexpr functions. >+// ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr >+// functions. Example: >+// >+// constexpr double Divide(double a, double b) { >+// return ABSL_ASSERT(b != 0), a / b; >+// } >+// >+// This macro is inspired by >+// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/ >+#if defined(NDEBUG) >+#define ABSL_ASSERT(expr) (false ? (void)(expr) : (void)0) >+#else >+#define ABSL_ASSERT(expr) \ >+ (ABSL_PREDICT_TRUE((expr)) ? (void)0 \ >+ : [] { assert(false && #expr); }()) // NOLINT >+#endif >+ >+#endif // ABSL_BASE_MACROS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/optimization.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/optimization.h >new file mode 100644 >index 0000000000000000000000000000000000000000..2fddfc800c1ddd5ea3776e4892bd2ab40911516c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/optimization.h >@@ -0,0 +1,165 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: optimization.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines portable macros for performance optimization. >+ >+#ifndef ABSL_BASE_OPTIMIZATION_H_ >+#define ABSL_BASE_OPTIMIZATION_H_ >+ >+#include "absl/base/config.h" >+ >+// ABSL_BLOCK_TAIL_CALL_OPTIMIZATION >+// >+// Instructs the compiler to avoid optimizing tail-call recursion. Use of this >+// macro is useful when you wish to preserve the existing function order within >+// a stack trace for logging, debugging, or profiling purposes. >+// >+// Example: >+// >+// int f() { >+// int result = g(); >+// ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); >+// return result; >+// } >+#if defined(__pnacl__) >+#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } >+#elif defined(__clang__) >+// Clang will not tail call given inline volatile assembly. >+#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") >+#elif defined(__GNUC__) >+// GCC will not tail call given inline volatile assembly. >+#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") >+#elif defined(_MSC_VER) >+#include <intrin.h> >+// The __nop() intrinsic blocks the optimisation. >+#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __nop() >+#else >+#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } >+#endif >+ >+// ABSL_CACHELINE_SIZE >+// >+// Explicitly defines the size of the L1 cache for purposes of alignment. >+// Setting the cacheline size allows you to specify that certain objects be >+// aligned on a cacheline boundary with `ABSL_CACHELINE_ALIGNED` declarations. >+// (See below.) >+// >+// NOTE: this macro should be replaced with the following C++17 features, when >+// those are generally available: >+// >+// * `std::hardware_constructive_interference_size` >+// * `std::hardware_destructive_interference_size` >+// >+// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html >+// for more information. >+#if defined(__GNUC__) >+// Cache line alignment >+#if defined(__i386__) || defined(__x86_64__) >+#define ABSL_CACHELINE_SIZE 64 >+#elif defined(__powerpc64__) >+#define ABSL_CACHELINE_SIZE 128 >+#elif defined(__aarch64__) >+// We would need to read special register ctr_el0 to find out L1 dcache size. >+// This value is a good estimate based on a real aarch64 machine. >+#define ABSL_CACHELINE_SIZE 64 >+#elif defined(__arm__) >+// Cache line sizes for ARM: These values are not strictly correct since >+// cache line sizes depend on implementations, not architectures. There >+// are even implementations with cache line sizes configurable at boot >+// time. >+#if defined(__ARM_ARCH_5T__) >+#define ABSL_CACHELINE_SIZE 32 >+#elif defined(__ARM_ARCH_7A__) >+#define ABSL_CACHELINE_SIZE 64 >+#endif >+#endif >+ >+#ifndef ABSL_CACHELINE_SIZE >+// A reasonable default guess. Note that overestimates tend to waste more >+// space, while underestimates tend to waste more time. >+#define ABSL_CACHELINE_SIZE 64 >+#endif >+ >+// ABSL_CACHELINE_ALIGNED >+// >+// Indicates that the declared object be cache aligned using >+// `ABSL_CACHELINE_SIZE` (see above). Cacheline aligning objects allows you to >+// load a set of related objects in the L1 cache for performance improvements. >+// Cacheline aligning objects properly allows constructive memory sharing and >+// prevents destructive (or "false") memory sharing. >+// >+// NOTE: this macro should be replaced with usage of `alignas()` using >+// `std::hardware_constructive_interference_size` and/or >+// `std::hardware_destructive_interference_size` when available within C++17. >+// >+// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html >+// for more information. >+// >+// On some compilers, `ABSL_CACHELINE_ALIGNED` expands to >+// `__attribute__((aligned(ABSL_CACHELINE_SIZE)))`. For compilers where this is >+// not known to work, the macro expands to nothing. >+// >+// No further guarantees are made here. The result of applying the macro >+// to variables and types is always implementation-defined. >+// >+// WARNING: It is easy to use this attribute incorrectly, even to the point >+// of causing bugs that are difficult to diagnose, crash, etc. It does not >+// of itself guarantee that objects are aligned to a cache line. >+// >+// Recommendations: >+// >+// 1) Consult compiler documentation; this comment is not kept in sync as >+// toolchains evolve. >+// 2) Verify your use has the intended effect. This often requires inspecting >+// the generated machine code. >+// 3) Prefer applying this attribute to individual variables. Avoid >+// applying it to types. This tends to localize the effect. >+#define ABSL_CACHELINE_ALIGNED __attribute__((aligned(ABSL_CACHELINE_SIZE))) >+ >+#else // not GCC >+#define ABSL_CACHELINE_SIZE 64 >+#define ABSL_CACHELINE_ALIGNED >+#endif >+ >+// ABSL_PREDICT_TRUE, ABSL_PREDICT_FALSE >+// >+// Enables the compiler to prioritize compilation using static analysis for >+// likely paths within a boolean branch. >+// >+// Example: >+// >+// if (ABSL_PREDICT_TRUE(expression)) { >+// return result; // Faster if more likely >+// } else { >+// return 0; >+// } >+// >+// Compilers can use the information that a certain branch is not likely to be >+// taken (for instance, a CHECK failure) to optimize for the common case in >+// the absence of better information (ie. compiling gcc with `-fprofile-arcs`). >+#if ABSL_HAVE_BUILTIN(__builtin_expect) || \ >+ (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_PREDICT_FALSE(x) (__builtin_expect(x, 0)) >+#define ABSL_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) >+#else >+#define ABSL_PREDICT_FALSE(x) (x) >+#define ABSL_PREDICT_TRUE(x) (x) >+#endif >+ >+#endif // ABSL_BASE_OPTIMIZATION_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/policy_checks.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/policy_checks.h >new file mode 100644 >index 0000000000000000000000000000000000000000..0a07fc035e1526cd916beab6ffc034a9e6706b2f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/policy_checks.h >@@ -0,0 +1,121 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: policy_checks.h >+// ----------------------------------------------------------------------------- >+// >+// This header enforces a minimum set of policies at build time, such as the >+// supported compiler and library versions. Unsupported configurations are >+// reported with `#error`. This enforcement is best effort, so successfully >+// compiling this header does not guarantee a supported configuration. >+ >+#ifndef ABSL_BASE_POLICY_CHECKS_H_ >+#define ABSL_BASE_POLICY_CHECKS_H_ >+ >+// Included for the __GLIBC_PREREQ macro used below. >+#include <limits.h> >+ >+// Included for the _STLPORT_VERSION macro used below. >+#if defined(__cplusplus) >+#include <cstddef> >+#endif >+ >+// ----------------------------------------------------------------------------- >+// Operating System Check >+// ----------------------------------------------------------------------------- >+ >+#if defined(__CYGWIN__) >+#error "Cygwin is not supported." >+#endif >+ >+// ----------------------------------------------------------------------------- >+// Compiler Check >+// ----------------------------------------------------------------------------- >+ >+// We support MSVC++ 14.0 update 2 and later. >+// This minimum will go up. >+#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023918 && !defined(__clang__) >+#error "This package requires Visual Studio 2015 Update 2 or higher." >+#endif >+ >+// We support gcc 4.7 and later. >+// This minimum will go up. >+#if defined(__GNUC__) && !defined(__clang__) >+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) >+#error "This package requires gcc 4.7 or higher." >+#endif >+#endif >+ >+// We support Apple Xcode clang 4.2.1 (version 421.11.65) and later. >+// This corresponds to Apple Xcode version 4.5. >+// This minimum will go up. >+#if defined(__apple_build_version__) && __apple_build_version__ < 4211165 >+#error "This package requires __apple_build_version__ of 4211165 or higher." >+#endif >+ >+// ----------------------------------------------------------------------------- >+// C++ Version Check >+// ----------------------------------------------------------------------------- >+ >+// Enforce C++11 as the minimum. Note that Visual Studio has not >+// advanced __cplusplus despite being good enough for our purposes, so >+// so we exempt it from the check. >+#if defined(__cplusplus) && !defined(_MSC_VER) >+#if __cplusplus < 201103L >+#error "C++ versions less than C++11 are not supported." >+#endif >+#endif >+ >+// ----------------------------------------------------------------------------- >+// Standard Library Check >+// ----------------------------------------------------------------------------- >+ >+// We have chosen glibc 2.12 as the minimum as it was tagged for release >+// in May, 2010 and includes some functionality used in Google software >+// (for instance pthread_setname_np): >+// https://sourceware.org/ml/libc-alpha/2010-05/msg00000.html >+#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) >+#if !__GLIBC_PREREQ(2, 12) >+#error "Minimum required version of glibc is 2.12." >+#endif >+#endif >+ >+#if defined(_STLPORT_VERSION) >+#error "STLPort is not supported." >+#endif >+ >+// ----------------------------------------------------------------------------- >+// `char` Size Check >+// ----------------------------------------------------------------------------- >+ >+// Abseil currently assumes CHAR_BIT == 8. If you would like to use Abseil on a >+// platform where this is not the case, please provide us with the details about >+// your platform so we can consider relaxing this requirement. >+#if CHAR_BIT != 8 >+#error "Abseil assumes CHAR_BIT == 8." >+#endif >+ >+// ----------------------------------------------------------------------------- >+// `int` Size Check >+// ----------------------------------------------------------------------------- >+ >+// Abseil currently assumes that an int is 4 bytes. If you would like to use >+// Abseil on a platform where this is not the case, please provide us with the >+// details about your platform so we can consider relaxing this requirement. >+#if INT_MAX < 2147483647 >+#error "Abseil assumes that int is at least 4 bytes. " >+#endif >+ >+#endif // ABSL_BASE_POLICY_CHECKS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/port.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/port.h >new file mode 100644 >index 0000000000000000000000000000000000000000..1c67257fd8f323eb172ac5ae2cb1b1e41f47d4f8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/port.h >@@ -0,0 +1,26 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// This files is a forwarding header for other headers containing various >+// portability macros and functions. >+// This file is used for both C and C++! >+ >+#ifndef ABSL_BASE_PORT_H_ >+#define ABSL_BASE_PORT_H_ >+ >+#include "absl/base/attributes.h" >+#include "absl/base/config.h" >+#include "absl/base/optimization.h" >+ >+#endif // ABSL_BASE_PORT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/raw_logging_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/raw_logging_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..ebbc5db906727f6cb2c03a63e99a897f5ceb5aa4 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/raw_logging_test.cc >@@ -0,0 +1,79 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// This test serves primarily as a compilation test for base/raw_logging.h. >+// Raw logging testing is covered by logging_unittest.cc, which is not as >+// portable as this test. >+ >+#include "absl/base/internal/raw_logging.h" >+ >+#include <tuple> >+ >+#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); >+} >+ >+TEST(RawLoggingCompilationTest, PassingCheck) { >+ ABSL_RAW_CHECK(true, "RAW CHECK"); >+} >+ >+// 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 >+// 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[] = ""; >+ >+TEST(RawLoggingDeathTest, FailingCheck) { >+ EXPECT_DEATH_IF_SUPPORTED(ABSL_RAW_CHECK(1 == 0, "explanation"), >+ kExpectedDeathOutput); >+} >+ >+TEST(RawLoggingDeathTest, LogFatal) { >+ EXPECT_DEATH_IF_SUPPORTED(ABSL_RAW_LOG(FATAL, "my dog has fleas"), >+ 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/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/spinlock_test_common.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/spinlock_test_common.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..1b508848611e6c1e063c815856a9a78c34fc451e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/spinlock_test_common.cc >@@ -0,0 +1,266 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// A bunch of threads repeatedly hash an array of ints protected by a >+// spinlock. If the spinlock is working properly, all elements of the >+// array should be equal at the end of the test. >+ >+#include <cstdint> >+#include <limits> >+#include <random> >+#include <thread> // NOLINT(build/c++11) >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/base/attributes.h" >+#include "absl/base/internal/low_level_scheduling.h" >+#include "absl/base/internal/scheduling_mode.h" >+#include "absl/base/internal/spinlock.h" >+#include "absl/base/internal/sysinfo.h" >+#include "absl/base/macros.h" >+#include "absl/synchronization/blocking_counter.h" >+#include "absl/synchronization/notification.h" >+ >+constexpr int32_t kNumThreads = 10; >+constexpr int32_t kIters = 1000; >+ >+namespace absl { >+namespace base_internal { >+ >+// This is defined outside of anonymous namespace so that it can be >+// a friend of SpinLock to access protected methods for testing. >+struct SpinLockTest { >+ static uint32_t EncodeWaitCycles(int64_t wait_start_time, >+ int64_t wait_end_time) { >+ return SpinLock::EncodeWaitCycles(wait_start_time, wait_end_time); >+ } >+ static uint64_t DecodeWaitCycles(uint32_t lock_value) { >+ return SpinLock::DecodeWaitCycles(lock_value); >+ } >+}; >+ >+namespace { >+ >+static constexpr int kArrayLength = 10; >+static uint32_t values[kArrayLength]; >+static SpinLock static_spinlock(base_internal::kLinkerInitialized); >+static SpinLock static_cooperative_spinlock( >+ base_internal::kLinkerInitialized, >+ base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL); >+static SpinLock static_noncooperative_spinlock( >+ base_internal::kLinkerInitialized, base_internal::SCHEDULE_KERNEL_ONLY); >+ >+ >+// Simple integer hash function based on the public domain lookup2 hash. >+// http://burtleburtle.net/bob/c/lookup2.c >+static uint32_t Hash32(uint32_t a, uint32_t c) { >+ uint32_t b = 0x9e3779b9UL; // The golden ratio; an arbitrary value. >+ a -= b; a -= c; a ^= (c >> 13); >+ b -= c; b -= a; b ^= (a << 8); >+ c -= a; c -= b; c ^= (b >> 13); >+ a -= b; a -= c; a ^= (c >> 12); >+ b -= c; b -= a; b ^= (a << 16); >+ c -= a; c -= b; c ^= (b >> 5); >+ a -= b; a -= c; a ^= (c >> 3); >+ b -= c; b -= a; b ^= (a << 10); >+ c -= a; c -= b; c ^= (b >> 15); >+ return c; >+} >+ >+static void TestFunction(int thread_salt, SpinLock* spinlock) { >+ for (int i = 0; i < kIters; i++) { >+ SpinLockHolder h(spinlock); >+ for (int j = 0; j < kArrayLength; j++) { >+ const int index = (j + thread_salt) % kArrayLength; >+ values[index] = Hash32(values[index], thread_salt); >+ std::this_thread::yield(); >+ } >+ } >+} >+ >+static void ThreadedTest(SpinLock* spinlock) { >+ std::vector<std::thread> threads; >+ for (int i = 0; i < kNumThreads; ++i) { >+ threads.push_back(std::thread(TestFunction, i, spinlock)); >+ } >+ for (auto& thread : threads) { >+ thread.join(); >+ } >+ >+ SpinLockHolder h(spinlock); >+ for (int i = 1; i < kArrayLength; i++) { >+ EXPECT_EQ(values[0], values[i]); >+ } >+} >+ >+TEST(SpinLock, StackNonCooperativeDisablesScheduling) { >+ SpinLock spinlock(base_internal::SCHEDULE_KERNEL_ONLY); >+ spinlock.Lock(); >+ EXPECT_FALSE(base_internal::SchedulingGuard::ReschedulingIsAllowed()); >+ spinlock.Unlock(); >+} >+ >+TEST(SpinLock, StaticNonCooperativeDisablesScheduling) { >+ static_noncooperative_spinlock.Lock(); >+ EXPECT_FALSE(base_internal::SchedulingGuard::ReschedulingIsAllowed()); >+ static_noncooperative_spinlock.Unlock(); >+} >+ >+TEST(SpinLock, WaitCyclesEncoding) { >+ // These are implementation details not exported by SpinLock. >+ const int kProfileTimestampShift = 7; >+ const int kLockwordReservedShift = 3; >+ const uint32_t kSpinLockSleeper = 8; >+ >+ // We should be able to encode up to (1^kMaxCycleBits - 1) without clamping >+ // but the lower kProfileTimestampShift will be dropped. >+ const int kMaxCyclesShift = >+ 32 - kLockwordReservedShift + kProfileTimestampShift; >+ const uint64_t kMaxCycles = (int64_t{1} << kMaxCyclesShift) - 1; >+ >+ // These bits should be zero after encoding. >+ const uint32_t kLockwordReservedMask = (1 << kLockwordReservedShift) - 1; >+ >+ // These bits are dropped when wait cycles are encoded. >+ const uint64_t kProfileTimestampMask = (1 << kProfileTimestampShift) - 1; >+ >+ // Test a bunch of random values >+ std::default_random_engine generator; >+ // Shift to avoid overflow below. >+ std::uniform_int_distribution<uint64_t> time_distribution( >+ 0, std::numeric_limits<uint64_t>::max() >> 4); >+ std::uniform_int_distribution<uint64_t> cycle_distribution(0, kMaxCycles); >+ >+ for (int i = 0; i < 100; i++) { >+ int64_t start_time = time_distribution(generator); >+ int64_t cycles = cycle_distribution(generator); >+ int64_t end_time = start_time + cycles; >+ uint32_t lock_value = SpinLockTest::EncodeWaitCycles(start_time, end_time); >+ EXPECT_EQ(0, lock_value & kLockwordReservedMask); >+ uint64_t decoded = SpinLockTest::DecodeWaitCycles(lock_value); >+ EXPECT_EQ(0, decoded & kProfileTimestampMask); >+ EXPECT_EQ(cycles & ~kProfileTimestampMask, decoded); >+ } >+ >+ // Test corner cases >+ int64_t start_time = time_distribution(generator); >+ EXPECT_EQ(0, SpinLockTest::EncodeWaitCycles(start_time, start_time)); >+ EXPECT_EQ(0, SpinLockTest::DecodeWaitCycles(0)); >+ EXPECT_EQ(0, SpinLockTest::DecodeWaitCycles(kLockwordReservedMask)); >+ EXPECT_EQ(kMaxCycles & ~kProfileTimestampMask, >+ SpinLockTest::DecodeWaitCycles(~kLockwordReservedMask)); >+ >+ // Check that we cannot produce kSpinLockSleeper during encoding. >+ int64_t sleeper_cycles = >+ kSpinLockSleeper << (kProfileTimestampShift - kLockwordReservedShift); >+ uint32_t sleeper_value = >+ SpinLockTest::EncodeWaitCycles(start_time, start_time + sleeper_cycles); >+ EXPECT_NE(sleeper_value, kSpinLockSleeper); >+ >+ // Test clamping >+ uint32_t max_value = >+ SpinLockTest::EncodeWaitCycles(start_time, start_time + kMaxCycles); >+ uint64_t max_value_decoded = SpinLockTest::DecodeWaitCycles(max_value); >+ uint64_t expected_max_value_decoded = kMaxCycles & ~kProfileTimestampMask; >+ EXPECT_EQ(expected_max_value_decoded, max_value_decoded); >+ >+ const int64_t step = (1 << kProfileTimestampShift); >+ uint32_t after_max_value = >+ SpinLockTest::EncodeWaitCycles(start_time, start_time + kMaxCycles + step); >+ uint64_t after_max_value_decoded = >+ SpinLockTest::DecodeWaitCycles(after_max_value); >+ EXPECT_EQ(expected_max_value_decoded, after_max_value_decoded); >+ >+ uint32_t before_max_value = SpinLockTest::EncodeWaitCycles( >+ start_time, start_time + kMaxCycles - step); >+ uint64_t before_max_value_decoded = >+ SpinLockTest::DecodeWaitCycles(before_max_value); >+ EXPECT_GT(expected_max_value_decoded, before_max_value_decoded); >+} >+TEST(SpinLockWithThreads, StaticSpinLock) { >+ ThreadedTest(&static_spinlock); >+} >+TEST(SpinLockWithThreads, StackSpinLock) { >+ SpinLock spinlock; >+ ThreadedTest(&spinlock); >+} >+ >+TEST(SpinLockWithThreads, StackCooperativeSpinLock) { >+ SpinLock spinlock(base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL); >+ ThreadedTest(&spinlock); >+} >+ >+TEST(SpinLockWithThreads, StackNonCooperativeSpinLock) { >+ SpinLock spinlock(base_internal::SCHEDULE_KERNEL_ONLY); >+ ThreadedTest(&spinlock); >+} >+ >+TEST(SpinLockWithThreads, StaticCooperativeSpinLock) { >+ ThreadedTest(&static_cooperative_spinlock); >+} >+ >+TEST(SpinLockWithThreads, StaticNonCooperativeSpinLock) { >+ ThreadedTest(&static_noncooperative_spinlock); >+} >+ >+TEST(SpinLockWithThreads, DoesNotDeadlock) { >+ struct Helper { >+ static void NotifyThenLock(Notification* locked, SpinLock* spinlock, >+ BlockingCounter* b) { >+ locked->WaitForNotification(); // Wait for LockThenWait() to hold "s". >+ b->DecrementCount(); >+ SpinLockHolder l(spinlock); >+ } >+ >+ static void LockThenWait(Notification* locked, SpinLock* spinlock, >+ BlockingCounter* b) { >+ SpinLockHolder l(spinlock); >+ locked->Notify(); >+ b->Wait(); >+ } >+ >+ static void DeadlockTest(SpinLock* spinlock, int num_spinners) { >+ Notification locked; >+ BlockingCounter counter(num_spinners); >+ std::vector<std::thread> threads; >+ >+ threads.push_back( >+ std::thread(Helper::LockThenWait, &locked, spinlock, &counter)); >+ for (int i = 0; i < num_spinners; ++i) { >+ threads.push_back( >+ std::thread(Helper::NotifyThenLock, &locked, spinlock, &counter)); >+ } >+ >+ for (auto& thread : threads) { >+ thread.join(); >+ } >+ } >+ }; >+ >+ SpinLock stack_cooperative_spinlock( >+ base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL); >+ SpinLock stack_noncooperative_spinlock(base_internal::SCHEDULE_KERNEL_ONLY); >+ Helper::DeadlockTest(&stack_cooperative_spinlock, >+ base_internal::NumCPUs() * 2); >+ Helper::DeadlockTest(&stack_noncooperative_spinlock, >+ base_internal::NumCPUs() * 2); >+ Helper::DeadlockTest(&static_cooperative_spinlock, >+ base_internal::NumCPUs() * 2); >+ Helper::DeadlockTest(&static_noncooperative_spinlock, >+ base_internal::NumCPUs() * 2); >+} >+ >+} // namespace >+} // namespace base_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/thread_annotations.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/thread_annotations.h >new file mode 100644 >index 0000000000000000000000000000000000000000..fbb2797b825f5b25097347b849d2e62344c1ec28 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/thread_annotations.h >@@ -0,0 +1,257 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: thread_annotations.h >+// ----------------------------------------------------------------------------- >+// >+// This header file contains macro definitions for thread safety annotations >+// that allow developers to document the locking policies of multi-threaded >+// code. The annotations can also help program analysis tools to identify >+// potential thread safety issues. >+// >+// >+// These annotations are implemented using compiler attributes. Using the macros >+// defined here instead of raw attributes allow for portability and future >+// compatibility. >+// >+// When referring to mutexes in the arguments of the attributes, you should >+// use variable names or more complex expressions (e.g. my_object->mutex_) >+// 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_ >+#if defined(__clang__) >+#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) >+#else >+#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op >+#endif >+ >+// GUARDED_BY() >+// >+// Documents if a shared field or global variable needs to be protected by a >+// mutex. GUARDED_BY() allows the user to specify a particular mutex that >+// should be held when accessing the annotated variable. >+// >+// Although this annotation (and PT_GUARDED_BY, below) cannot be applied to >+// local variables, a local variable and its associated mutex can often be >+// combined into a small class or struct, thereby allowing the annotation. >+// >+// Example: >+// >+// class Foo { >+// Mutex mu_; >+// int p1_ GUARDED_BY(mu_); >+// ... >+// }; >+#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) >+ >+// PT_GUARDED_BY() >+// >+// Documents if the memory location pointed to by a pointer should be guarded >+// by a mutex when dereferencing the pointer. >+// >+// Example: >+// class Foo { >+// Mutex mu_; >+// int *p1_ PT_GUARDED_BY(mu_); >+// ... >+// }; >+// >+// Note that a pointer variable to a shared memory location could itself be a >+// shared variable. >+// >+// Example: >+// >+// // `q_`, guarded by `mu1_`, points to a shared memory location that is >+// // guarded by `mu2_`: >+// int *q_ GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_); >+#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) >+ >+// ACQUIRED_AFTER() / ACQUIRED_BEFORE() >+// >+// Documents the acquisition order between locks that can be held >+// simultaneously by a thread. For any two locks that need to be annotated >+// to establish an acquisition order, only one of them needs the annotation. >+// (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER >+// and ACQUIRED_BEFORE.) >+// >+// As with GUARDED_BY, this is only applicable to mutexes that are shared >+// fields or global variables. >+// >+// Example: >+// >+// Mutex m1_; >+// Mutex m2_ ACQUIRED_AFTER(m1_); >+#define ACQUIRED_AFTER(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) >+ >+#define ACQUIRED_BEFORE(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) >+ >+// EXCLUSIVE_LOCKS_REQUIRED() / SHARED_LOCKS_REQUIRED() >+// >+// Documents a function that expects a mutex to be held prior to entry. >+// The mutex is expected to be held both on entry to, and exit from, the >+// function. >+// >+// Example: >+// >+// Mutex mu1, mu2; >+// int a GUARDED_BY(mu1); >+// int b GUARDED_BY(mu2); >+// >+// void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... }; >+#define EXCLUSIVE_LOCKS_REQUIRED(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__)) >+ >+#define SHARED_LOCKS_REQUIRED(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__)) >+ >+// LOCKS_EXCLUDED() >+// >+// Documents the locks acquired in the body of the function. These locks >+// cannot be held when calling this function (as Abseil's `Mutex` locks are >+// non-reentrant). >+#define LOCKS_EXCLUDED(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) >+ >+// LOCK_RETURNED() >+// >+// Documents a function that returns a mutex without acquiring it. For example, >+// a public getter method that returns a pointer to a private mutex should >+// be annotated with LOCK_RETURNED. >+#define LOCK_RETURNED(x) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) >+ >+// LOCKABLE >+// >+// Documents if a class/type is a lockable type (such as the `Mutex` class). >+#define LOCKABLE \ >+ THREAD_ANNOTATION_ATTRIBUTE__(lockable) >+ >+// SCOPED_LOCKABLE >+// >+// Documents if a class does RAII locking (such as the `MutexLock` class). >+// The constructor should use `LOCK_FUNCTION()` to specify the mutex that is >+// acquired, and the destructor should use `UNLOCK_FUNCTION()` with no >+// arguments; the analysis will assume that the destructor unlocks whatever the >+// constructor locked. >+#define SCOPED_LOCKABLE \ >+ THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) >+ >+// EXCLUSIVE_LOCK_FUNCTION() >+// >+// Documents functions that acquire a lock in the body of a function, and do >+// not release it. >+#define EXCLUSIVE_LOCK_FUNCTION(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__)) >+ >+// SHARED_LOCK_FUNCTION() >+// >+// Documents functions that acquire a shared (reader) lock in the body of a >+// function, and do not release it. >+#define SHARED_LOCK_FUNCTION(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__)) >+ >+// UNLOCK_FUNCTION() >+// >+// Documents functions that expect a lock to be held on entry to the function, >+// and release it in the body of the function. >+#define UNLOCK_FUNCTION(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__)) >+ >+// EXCLUSIVE_TRYLOCK_FUNCTION() / SHARED_TRYLOCK_FUNCTION() >+// >+// Documents functions that try to acquire a lock, and return success or failure >+// (or a non-boolean value that can be interpreted as a boolean). >+// The first argument should be `true` for functions that return `true` on >+// success, or `false` for functions that return `false` on success. The second >+// argument specifies the mutex that is locked on success. If unspecified, this >+// mutex is assumed to be `this`. >+#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__)) >+ >+#define SHARED_TRYLOCK_FUNCTION(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__)) >+ >+// ASSERT_EXCLUSIVE_LOCK() / ASSERT_SHARED_LOCK() >+// >+// Documents functions that dynamically check to see if a lock is held, and fail >+// if it is not held. >+#define ASSERT_EXCLUSIVE_LOCK(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__)) >+ >+#define ASSERT_SHARED_LOCK(...) \ >+ THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__)) >+ >+// NO_THREAD_SAFETY_ANALYSIS >+// >+// Turns off thread safety checking within the body of a particular function. >+// This annotation is used to mark functions that are known to be correct, but >+// the locking behavior is more complicated than the analyzer can handle. >+#define NO_THREAD_SAFETY_ANALYSIS \ >+ THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) >+ >+//------------------------------------------------------------------------------ >+// Tool-Supplied Annotations >+//------------------------------------------------------------------------------ >+ >+// TS_UNCHECKED should be placed around lock expressions that are not valid >+// C++ syntax, but which are present for documentation purposes. These >+// annotations will be ignored by the analysis. >+#define TS_UNCHECKED(x) "" >+ >+// TS_FIXME is used to mark lock expressions that are not valid C++ syntax. >+// It is used by automated tools to mark and disable invalid expressions. >+// The annotation should either be fixed, or changed to TS_UNCHECKED. >+#define TS_FIXME(x) "" >+ >+// Like NO_THREAD_SAFETY_ANALYSIS, this turns off checking within the body of >+// a particular function. However, this attribute is used to mark functions >+// that are incorrect and need to be fixed. It is used by automated tools to >+// avoid breaking the build when the analysis is updated. >+// Code owners are expected to eventually fix the routine. >+#define NO_THREAD_SAFETY_ANALYSIS_FIXME NO_THREAD_SAFETY_ANALYSIS >+ >+// Similar to NO_THREAD_SAFETY_ANALYSIS_FIXME, this macro marks a GUARDED_BY >+// annotation that needs to be fixed, because it is producing thread safety >+// warning. It disables the GUARDED_BY. >+#define GUARDED_BY_FIXME(x) >+ >+// Disables warnings for a single read operation. This can be used to avoid >+// warnings when it is known that the read is not actually involved in a race, >+// but the compiler cannot confirm that. >+#define TS_UNCHECKED_READ(x) thread_safety_analysis::ts_unchecked_read(x) >+ >+ >+namespace thread_safety_analysis { >+ >+// Takes a reference to a guarded data member, and returns an unguarded >+// reference. >+template <typename T> >+inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS { >+ return v; >+} >+ >+template <typename T> >+inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS { >+ return v; >+} >+ >+} // namespace thread_safety_analysis >+ >+#endif // ABSL_BASE_THREAD_ANNOTATIONS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/throw_delegate_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/throw_delegate_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..0f15df0492b493fffecf4a85daf8290e10192375 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/base/throw_delegate_test.cc >@@ -0,0 +1,94 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/base/internal/throw_delegate.h" >+ >+#include <functional> >+#include <new> >+#include <stdexcept> >+ >+#include "gtest/gtest.h" >+ >+namespace { >+ >+using absl::base_internal::ThrowStdLogicError; >+using absl::base_internal::ThrowStdInvalidArgument; >+using absl::base_internal::ThrowStdDomainError; >+using absl::base_internal::ThrowStdLengthError; >+using absl::base_internal::ThrowStdOutOfRange; >+using absl::base_internal::ThrowStdRuntimeError; >+using absl::base_internal::ThrowStdRangeError; >+using absl::base_internal::ThrowStdOverflowError; >+using absl::base_internal::ThrowStdUnderflowError; >+using absl::base_internal::ThrowStdBadFunctionCall; >+using absl::base_internal::ThrowStdBadAlloc; >+ >+constexpr const char* what_arg = "The quick brown fox jumps over the lazy dog"; >+ >+template <typename E> >+void ExpectThrowChar(void (*f)(const char*)) { >+ try { >+ f(what_arg); >+ FAIL() << "Didn't throw"; >+ } catch (const E& e) { >+ EXPECT_STREQ(e.what(), what_arg); >+ } >+} >+ >+template <typename E> >+void ExpectThrowString(void (*f)(const std::string&)) { >+ try { >+ f(what_arg); >+ FAIL() << "Didn't throw"; >+ } catch (const E& e) { >+ EXPECT_STREQ(e.what(), what_arg); >+ } >+} >+ >+template <typename E> >+void ExpectThrowNoWhat(void (*f)()) { >+ try { >+ f(); >+ FAIL() << "Didn't throw"; >+ } catch (const E& e) { >+ } >+} >+ >+TEST(ThrowHelper, Test) { >+ // Not using EXPECT_THROW because we want to check the .what() message too. >+ ExpectThrowChar<std::logic_error>(ThrowStdLogicError); >+ ExpectThrowChar<std::invalid_argument>(ThrowStdInvalidArgument); >+ ExpectThrowChar<std::domain_error>(ThrowStdDomainError); >+ ExpectThrowChar<std::length_error>(ThrowStdLengthError); >+ ExpectThrowChar<std::out_of_range>(ThrowStdOutOfRange); >+ ExpectThrowChar<std::runtime_error>(ThrowStdRuntimeError); >+ ExpectThrowChar<std::range_error>(ThrowStdRangeError); >+ ExpectThrowChar<std::overflow_error>(ThrowStdOverflowError); >+ ExpectThrowChar<std::underflow_error>(ThrowStdUnderflowError); >+ >+ ExpectThrowString<std::logic_error>(ThrowStdLogicError); >+ ExpectThrowString<std::invalid_argument>(ThrowStdInvalidArgument); >+ ExpectThrowString<std::domain_error>(ThrowStdDomainError); >+ ExpectThrowString<std::length_error>(ThrowStdLengthError); >+ ExpectThrowString<std::out_of_range>(ThrowStdOutOfRange); >+ ExpectThrowString<std::runtime_error>(ThrowStdRuntimeError); >+ ExpectThrowString<std::range_error>(ThrowStdRangeError); >+ ExpectThrowString<std::overflow_error>(ThrowStdOverflowError); >+ ExpectThrowString<std::underflow_error>(ThrowStdUnderflowError); >+ >+ ExpectThrowNoWhat<std::bad_function_call>(ThrowStdBadFunctionCall); >+ ExpectThrowNoWhat<std::bad_alloc>(ThrowStdBadAlloc); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/compiler_config_setting.bzl b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/compiler_config_setting.bzl >new file mode 100644 >index 0000000000000000000000000000000000000000..b77c4f563b95d332c2862657de884db4be7abb4e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/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/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..6d5c958f382ba6397f0b0df1cf996678a7a3c5a6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/BUILD.bazel >@@ -0,0 +1,183 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+ "ABSL_EXCEPTIONS_FLAG", >+) >+ >+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", >+ "//absl/base:throw_delegate", >+ "//absl/memory", >+ ], >+) >+ >+cc_test( >+ name = "fixed_array_test", >+ srcs = ["fixed_array_test.cc"], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":fixed_array", >+ "//absl/base:exception_testing", >+ "//absl/memory", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "fixed_array_test_noexceptions", >+ srcs = ["fixed_array_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":fixed_array", >+ "//absl/base:exception_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, >+ deps = [ >+ ":fixed_array", >+ "//absl/base:exception_safety_testing", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "fixed_array_benchmark", >+ srcs = ["fixed_array_benchmark.cc"], >+ copts = ABSL_TEST_COPTS + ["$(STACK_FRAME_UNLIMITED)"], >+ tags = ["benchmark"], >+ deps = [ >+ ":fixed_array", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_library( >+ name = "inlined_vector", >+ hdrs = ["inlined_vector.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/algorithm", >+ "//absl/base:core_headers", >+ "//absl/base:throw_delegate", >+ "//absl/memory", >+ ], >+) >+ >+cc_test( >+ name = "inlined_vector_test", >+ srcs = ["inlined_vector_test.cc"], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":inlined_vector", >+ ":test_instance_tracker", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "//absl/base:exception_testing", >+ "//absl/memory", >+ "//absl/strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "inlined_vector_test_noexceptions", >+ srcs = ["inlined_vector_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":inlined_vector", >+ ":test_instance_tracker", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "//absl/base:exception_testing", >+ "//absl/memory", >+ "//absl/strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "inlined_vector_benchmark", >+ srcs = ["inlined_vector_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ deps = [ >+ ":inlined_vector", >+ "//absl/base", >+ "//absl/strings", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_library( >+ name = "test_instance_tracker", >+ testonly = 1, >+ srcs = ["internal/test_instance_tracker.cc"], >+ hdrs = ["internal/test_instance_tracker.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ visibility = [ >+ "//absl:__subpackages__", >+ ], >+) >+ >+cc_test( >+ name = "test_instance_tracker_test", >+ srcs = ["internal/test_instance_tracker_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":test_instance_tracker", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..001a2a36d4846d57e851f8143f8aaa5c9915830a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/BUILD.gn >@@ -0,0 +1,86 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("compressed_tuple") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "internal/compressed_tuple.h", >+ ] >+ deps = [ >+ "../utility", >+ ] >+} >+ >+source_set("fixed_array") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "fixed_array.h", >+ ] >+ deps = [ >+ ":compressed_tuple", >+ "../algorithm", >+ "../base:core_headers", >+ "../base:dynamic_annotations", >+ "../base:throw_delegate", >+ "../memory", >+ ] >+} >+ >+source_set("inlined_vector") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "inlined_vector.h", >+ ] >+ deps = [ >+ "../algorithm", >+ "../base:core_headers", >+ "../base:throw_delegate", >+ "../memory", >+ ] >+} >+ >+source_set("test_instance_tracker") { >+ testonly = true >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/test_instance_tracker.cc", >+ ] >+ public = [ >+ "internal/test_instance_tracker.h", >+ ] >+ visibility = [] >+ visibility += [ "../*" ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..123e4c4849aabe2eedea21f05efd2d0263830fb8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/CMakeLists.txt >@@ -0,0 +1,144 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+ >+list(APPEND CONTAINER_PUBLIC_HEADERS >+ "fixed_array.h" >+ "inlined_vector.h" >+) >+ >+ >+list(APPEND CONTAINER_INTERNAL_HEADERS >+ "internal/test_instance_tracker.h" >+) >+ >+ >+absl_header_library( >+ TARGET >+ absl_container >+ EXPORT_NAME >+ container >+) >+ >+ >+# >+## TESTS >+# >+ >+list(APPEND TEST_INSTANCE_TRACKER_LIB_SRC >+ "internal/test_instance_tracker.cc" >+ ${CONTAINER_PUBLIC_HEADERS} >+ ${CONTAINER_INTERNAL_HEADERS} >+) >+ >+ >+absl_library( >+ TARGET >+ test_instance_tracker_lib >+ SOURCES >+ ${TEST_INSTANCE_TRACKER_LIB_SRC} >+ PUBLIC_LIBRARIES >+ absl::container >+) >+ >+ >+ >+# test fixed_array_test >+set(FIXED_ARRAY_TEST_SRC "fixed_array_test.cc") >+set(FIXED_ARRAY_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate test_instance_tracker_lib) >+ >+absl_test( >+ TARGET >+ fixed_array_test >+ SOURCES >+ ${FIXED_ARRAY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${FIXED_ARRAY_TEST_PUBLIC_LIBRARIES} >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+) >+ >+ >+ >+absl_test( >+ TARGET >+ fixed_array_test_noexceptions >+ SOURCES >+ ${FIXED_ARRAY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${FIXED_ARRAY_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test fixed_array_exception_safety_test >+set(FIXED_ARRAY_EXCEPTION_SAFETY_TEST_SRC "fixed_array_exception_safety_test.cc") >+set(FIXED_ARRAY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES >+ absl::container >+ absl_base_internal_exception_safety_testing >+) >+ >+absl_test( >+ TARGET >+ fixed_array_exception_safety_test >+ SOURCES >+ ${FIXED_ARRAY_EXCEPTION_SAFETY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${FIXED_ARRAY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES} >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+) >+ >+ >+# test inlined_vector_test >+set(INLINED_VECTOR_TEST_SRC "inlined_vector_test.cc") >+set(INLINED_VECTOR_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate test_instance_tracker_lib) >+ >+absl_test( >+ TARGET >+ inlined_vector_test >+ SOURCES >+ ${INLINED_VECTOR_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${INLINED_VECTOR_TEST_PUBLIC_LIBRARIES} >+) >+ >+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} >+) >+ >+ >+# test test_instance_tracker_test >+set(TEST_INSTANCE_TRACKER_TEST_SRC "internal/test_instance_tracker_test.cc") >+set(TEST_INSTANCE_TRACKER_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate test_instance_tracker_lib) >+ >+ >+absl_test( >+ TARGET >+ test_instance_tracker_test >+ SOURCES >+ ${TEST_INSTANCE_TRACKER_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${TEST_INSTANCE_TRACKER_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array.h >new file mode 100644 >index 0000000000000000000000000000000000000000..182258f623e13aea80b7578e1906dad9478388b0 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array.h >@@ -0,0 +1,512 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: fixed_array.h >+// ----------------------------------------------------------------------------- >+// >+// A `FixedArray<T>` represents a non-resizable array of `T` where the length of >+// the array can be determined at run-time. It is a good replacement for >+// non-standard and deprecated uses of `alloca()` and variable length arrays >+// within the GCC extension. (See >+// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html). >+// >+// `FixedArray` allocates small arrays inline, keeping performance fast by >+// avoiding heap operations. It also helps reduce the chances of >+// accidentally overflowing your stack if large input is passed to >+// your function. >+ >+#ifndef ABSL_CONTAINER_FIXED_ARRAY_H_ >+#define ABSL_CONTAINER_FIXED_ARRAY_H_ >+ >+#include <algorithm> >+#include <array> >+#include <cassert> >+#include <cstddef> >+#include <initializer_list> >+#include <iterator> >+#include <limits> >+#include <memory> >+#include <new> >+#include <type_traits> >+ >+#include "absl/algorithm/algorithm.h" >+#include "absl/base/dynamic_annotations.h" >+#include "absl/base/internal/throw_delegate.h" >+#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 { >+ >+constexpr static auto kFixedArrayUseDefault = static_cast<size_t>(-1); >+ >+// ----------------------------------------------------------------------------- >+// FixedArray >+// ----------------------------------------------------------------------------- >+// >+// 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 >+// to store inline based on `sizeof(T)`. If `inline_elements` is specified, the >+// `FixedArray` implementation will use inline storage for arrays with a >+// length <= `inline_elements`. >+// >+// Note that a `FixedArray` constructed with a `size_type` argument will >+// default-initialize its values by leaving trivially constructible types >+// uninitialized (e.g. int, int[4], double), and others default-constructed. >+// This matches the behavior of c-style arrays and `std::array`, but not >+// `std::vector`. >+// >+// Note that `FixedArray` does not provide a public allocator; if it requires a >+// heap allocation, it will do so with global `::operator new[]()` and >+// `::operator delete[]()`, even if T provides class-scope overrides for these >+// operators. >+template <typename T, size_t N = kFixedArrayUseDefault, >+ typename A = std::allocator<T>> >+class FixedArray { >+ static_assert(!std::is_array<T>::value || std::extent<T>::value > 0, >+ "Arrays with unknown bounds cannot be used with FixedArray."); >+ >+ static constexpr size_t kInlineBytesDefault = 256; >+ >+ using AllocatorTraits = std::allocator_traits<A>; >+ // std::iterator_traits isn't guaranteed to be SFINAE-friendly until C++17, >+ // but this seems to be mostly pedantic. >+ template <typename Iterator> >+ using EnableIfForwardIterator = absl::enable_if_t<std::is_convertible< >+ typename std::iterator_traits<Iterator>::iterator_category, >+ std::forward_iterator_tag>::value>; >+ static constexpr bool NoexceptCopyable() { >+ return std::is_nothrow_copy_constructible<StorageElement>::value && >+ absl::allocator_is_nothrow<allocator_type>::value; >+ } >+ static constexpr bool NoexceptMovable() { >+ return std::is_nothrow_move_constructible<StorageElement>::value && >+ absl::allocator_is_nothrow<allocator_type>::value; >+ } >+ static constexpr bool DefaultConstructorIsNonTrivial() { >+ return !absl::is_trivially_default_constructible<StorageElement>::value; >+ } >+ >+ public: >+ using allocator_type = typename AllocatorTraits::allocator_type; >+ using value_type = typename allocator_type::value_type; >+ using pointer = typename allocator_type::pointer; >+ using const_pointer = typename allocator_type::const_pointer; >+ using reference = typename allocator_type::reference; >+ using const_reference = typename allocator_type::const_reference; >+ using size_type = typename allocator_type::size_type; >+ using difference_type = typename allocator_type::difference_type; >+ using iterator = pointer; >+ using const_iterator = const_pointer; >+ using reverse_iterator = std::reverse_iterator<iterator>; >+ using const_reverse_iterator = std::reverse_iterator<const_iterator>; >+ >+ static constexpr size_type inline_elements = >+ (N == kFixedArrayUseDefault ? kInlineBytesDefault / sizeof(value_type) >+ : static_cast<size_type>(N)); >+ >+ FixedArray( >+ const FixedArray& other, >+ const allocator_type& a = allocator_type()) noexcept(NoexceptCopyable()) >+ : FixedArray(other.begin(), other.end(), a) {} >+ >+ FixedArray( >+ FixedArray&& other, >+ const allocator_type& a = allocator_type()) noexcept(NoexceptMovable()) >+ : FixedArray(std::make_move_iterator(other.begin()), >+ std::make_move_iterator(other.end()), a) {} >+ >+ // Creates an array object that can store `n` elements. >+ // Note that trivially constructible elements will be uninitialized. >+ explicit FixedArray(size_type n, const allocator_type& a = allocator_type()) >+ : storage_(n, a) { >+ if (DefaultConstructorIsNonTrivial()) { >+ memory_internal::ConstructStorage(storage_.alloc(), storage_.begin(), >+ storage_.end()); >+ } >+ } >+ >+ // Creates an array initialized with `n` copies of `val`. >+ FixedArray(size_type n, const value_type& val, >+ const allocator_type& a = allocator_type()) >+ : storage_(n, a) { >+ memory_internal::ConstructStorage(storage_.alloc(), storage_.begin(), >+ storage_.end(), val); >+ } >+ >+ // Creates an array initialized with the size and contents of `init_list`. >+ FixedArray(std::initializer_list<value_type> init_list, >+ const allocator_type& a = allocator_type()) >+ : FixedArray(init_list.begin(), init_list.end(), a) {} >+ >+ // Creates an array initialized with the elements from the input >+ // range. The array's size will always be `std::distance(first, last)`. >+ // REQUIRES: Iterator must be a forward_iterator or better. >+ template <typename Iterator, EnableIfForwardIterator<Iterator>* = nullptr> >+ FixedArray(Iterator first, Iterator last, >+ const allocator_type& a = allocator_type()) >+ : storage_(std::distance(first, last), a) { >+ memory_internal::CopyToStorageFromRange(storage_.alloc(), storage_.begin(), >+ first, last); >+ } >+ >+ ~FixedArray() noexcept { >+ for (auto* cur = storage_.begin(); cur != storage_.end(); ++cur) { >+ AllocatorTraits::destroy(*storage_.alloc(), cur); >+ } >+ } >+ >+ // Assignments are deleted because they break the invariant that the size of a >+ // `FixedArray` never changes. >+ void operator=(FixedArray&&) = delete; >+ void operator=(const FixedArray&) = delete; >+ >+ // FixedArray::size() >+ // >+ // Returns the length of the fixed array. >+ size_type size() const { return storage_.size(); } >+ >+ // FixedArray::max_size() >+ // >+ // Returns the largest possible value of `std::distance(begin(), end())` for a >+ // `FixedArray<T>`. This is equivalent to the most possible addressable bytes >+ // over the number of bytes taken by T. >+ constexpr size_type max_size() const { >+ return std::numeric_limits<difference_type>::max() / sizeof(value_type); >+ } >+ >+ // FixedArray::empty() >+ // >+ // Returns whether or not the fixed array is empty. >+ bool empty() const { return size() == 0; } >+ >+ // FixedArray::memsize() >+ // >+ // Returns the memory size of the fixed array in bytes. >+ size_t memsize() const { return size() * sizeof(value_type); } >+ >+ // FixedArray::data() >+ // >+ // Returns a const T* pointer to elements of the `FixedArray`. This pointer >+ // can be used to access (but not modify) the contained elements. >+ const_pointer data() const { return AsValueType(storage_.begin()); } >+ >+ // Overload of FixedArray::data() to return a T* pointer to elements of the >+ // fixed array. This pointer can be used to access and modify the contained >+ // elements. >+ pointer data() { return AsValueType(storage_.begin()); } >+ >+ // FixedArray::operator[] >+ // >+ // Returns a reference the ith element of the fixed array. >+ // REQUIRES: 0 <= i < size() >+ reference operator[](size_type i) { >+ assert(i < size()); >+ return data()[i]; >+ } >+ >+ // Overload of FixedArray::operator()[] to return a const reference to the >+ // ith element of the fixed array. >+ // REQUIRES: 0 <= i < size() >+ const_reference operator[](size_type i) const { >+ assert(i < size()); >+ return data()[i]; >+ } >+ >+ // FixedArray::at >+ // >+ // Bounds-checked access. Returns a reference to the ith element of the >+ // fiexed array, or throws std::out_of_range >+ reference at(size_type i) { >+ if (ABSL_PREDICT_FALSE(i >= size())) { >+ base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check"); >+ } >+ return data()[i]; >+ } >+ >+ // Overload of FixedArray::at() to return a const reference to the ith element >+ // of the fixed array. >+ const_reference at(size_type i) const { >+ if (ABSL_PREDICT_FALSE(i >= size())) { >+ base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check"); >+ } >+ return data()[i]; >+ } >+ >+ // FixedArray::front() >+ // >+ // Returns a reference to the first element of the fixed array. >+ reference front() { return *begin(); } >+ >+ // Overload of FixedArray::front() to return a reference to the first element >+ // of a fixed array of const values. >+ const_reference front() const { return *begin(); } >+ >+ // FixedArray::back() >+ // >+ // Returns a reference to the last element of the fixed array. >+ reference back() { return *(end() - 1); } >+ >+ // Overload of FixedArray::back() to return a reference to the last element >+ // of a fixed array of const values. >+ const_reference back() const { return *(end() - 1); } >+ >+ // FixedArray::begin() >+ // >+ // Returns an iterator to the beginning of the fixed array. >+ iterator begin() { return data(); } >+ >+ // Overload of FixedArray::begin() to return a const iterator to the >+ // beginning of the fixed array. >+ const_iterator begin() const { return data(); } >+ >+ // FixedArray::cbegin() >+ // >+ // Returns a const iterator to the beginning of the fixed array. >+ const_iterator cbegin() const { return begin(); } >+ >+ // FixedArray::end() >+ // >+ // Returns an iterator to the end of the fixed array. >+ iterator end() { return data() + size(); } >+ >+ // Overload of FixedArray::end() to return a const iterator to the end of the >+ // fixed array. >+ const_iterator end() const { return data() + size(); } >+ >+ // FixedArray::cend() >+ // >+ // Returns a const iterator to the end of the fixed array. >+ const_iterator cend() const { return end(); } >+ >+ // FixedArray::rbegin() >+ // >+ // Returns a reverse iterator from the end of the fixed array. >+ reverse_iterator rbegin() { return reverse_iterator(end()); } >+ >+ // Overload of FixedArray::rbegin() to return a const reverse iterator from >+ // the end of the fixed array. >+ const_reverse_iterator rbegin() const { >+ return const_reverse_iterator(end()); >+ } >+ >+ // FixedArray::crbegin() >+ // >+ // Returns a const reverse iterator from the end of the fixed array. >+ const_reverse_iterator crbegin() const { return rbegin(); } >+ >+ // FixedArray::rend() >+ // >+ // Returns a reverse iterator from the beginning of the fixed array. >+ reverse_iterator rend() { return reverse_iterator(begin()); } >+ >+ // Overload of FixedArray::rend() for returning a const reverse iterator >+ // from the beginning of the fixed array. >+ const_reverse_iterator rend() const { >+ return const_reverse_iterator(begin()); >+ } >+ >+ // FixedArray::crend() >+ // >+ // Returns a reverse iterator from the beginning of the fixed array. >+ const_reverse_iterator crend() const { return rend(); } >+ >+ // FixedArray::fill() >+ // >+ // Assigns the given `value` to all elements in the fixed array. >+ void fill(const value_type& val) { std::fill(begin(), end(), val); } >+ >+ // Relational operators. Equality operators are elementwise using >+ // `operator==`, while order operators order FixedArrays lexicographically. >+ friend bool operator==(const FixedArray& lhs, const FixedArray& rhs) { >+ return absl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); >+ } >+ >+ friend bool operator!=(const FixedArray& lhs, const FixedArray& rhs) { >+ return !(lhs == rhs); >+ } >+ >+ friend bool operator<(const FixedArray& lhs, const FixedArray& rhs) { >+ return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), >+ rhs.end()); >+ } >+ >+ friend bool operator>(const FixedArray& lhs, const FixedArray& rhs) { >+ return rhs < lhs; >+ } >+ >+ friend bool operator<=(const FixedArray& lhs, const FixedArray& rhs) { >+ return !(rhs < lhs); >+ } >+ >+ friend bool operator>=(const FixedArray& lhs, const FixedArray& rhs) { >+ return !(lhs < rhs); >+ } >+ private: >+ // StorageElement >+ // >+ // For FixedArrays with a C-style-array value_type, StorageElement is a POD >+ // wrapper struct called StorageElementWrapper that holds the value_type >+ // instance inside. This is needed for construction and destruction of the >+ // entire array regardless of how many dimensions it has. For all other cases, >+ // StorageElement is just an alias of value_type. >+ // >+ // Maintainer's Note: The simpler solution would be to simply wrap value_type >+ // in a struct whether it's an array or not. That causes some paranoid >+ // diagnostics to misfire, believing that 'data()' returns a pointer to a >+ // single element, rather than the packed array that it really is. >+ // e.g.: >+ // >+ // FixedArray<char> buf(1); >+ // sprintf(buf.data(), "foo"); >+ // >+ // error: call to int __builtin___sprintf_chk(etc...) >+ // will always overflow destination buffer [-Werror] >+ // >+ template <typename OuterT = value_type, >+ typename InnerT = absl::remove_extent_t<OuterT>, >+ size_t InnerN = std::extent<OuterT>::value> >+ struct StorageElementWrapper { >+ InnerT array[InnerN]; >+ }; >+ >+ using StorageElement = >+ absl::conditional_t<std::is_array<value_type>::value, >+ StorageElementWrapper<value_type>, value_type>; >+ using StorageElementBuffer = >+ absl::aligned_storage_t<sizeof(StorageElement), alignof(StorageElement)>; >+ >+ static pointer AsValueType(pointer ptr) { return ptr; } >+ static pointer AsValueType(StorageElementWrapper<value_type>* ptr) { >+ return std::addressof(ptr->array); >+ } >+ >+ static_assert(sizeof(StorageElement) == sizeof(value_type), ""); >+ static_assert(alignof(StorageElement) == alignof(value_type), ""); >+ >+ struct NonEmptyInlinedStorage { >+ StorageElement* data() { >+ return reinterpret_cast<StorageElement*>(inlined_storage_.data()); >+ } >+ >+#ifdef ADDRESS_SANITIZER >+ void* RedzoneBegin() { return &redzone_begin_; } >+ void* RedzoneEnd() { return &redzone_end_ + 1; } >+#endif // ADDRESS_SANITIZER >+ >+ void AnnotateConstruct(size_type); >+ void AnnotateDestruct(size_type); >+ >+ ABSL_ADDRESS_SANITIZER_REDZONE(redzone_begin_); >+ std::array<StorageElementBuffer, inline_elements> inlined_storage_; >+ ABSL_ADDRESS_SANITIZER_REDZONE(redzone_end_); >+ }; >+ >+ struct EmptyInlinedStorage { >+ StorageElement* data() { return nullptr; } >+ void AnnotateConstruct(size_type) {} >+ void AnnotateDestruct(size_type) {} >+ }; >+ >+ using InlinedStorage = >+ absl::conditional_t<inline_elements == 0, EmptyInlinedStorage, >+ NonEmptyInlinedStorage>; >+ >+ // Storage >+ // >+ // An instance of Storage manages the inline and out-of-line memory for >+ // instances of FixedArray. This guarantees that even when construction of >+ // individual elements fails in the FixedArray constructor body, the >+ // destructor for Storage will still be called and out-of-line memory will be >+ // properly deallocated. >+ // >+ class Storage : public InlinedStorage { >+ public: >+ Storage(size_type n, const allocator_type& a) >+ : size_alloc_(n, a), data_(InitializeData()) {} >+ >+ ~Storage() noexcept { >+ if (UsingInlinedStorage(size())) { >+ InlinedStorage::AnnotateDestruct(size()); >+ } else { >+ AllocatorTraits::deallocate(*alloc(), AsValueType(begin()), size()); >+ } >+ } >+ >+ size_type size() const { return size_alloc_.template get<0>(); } >+ StorageElement* begin() const { return data_; } >+ StorageElement* end() const { return begin() + size(); } >+ allocator_type* alloc() { >+ return std::addressof(size_alloc_.template get<1>()); >+ } >+ >+ private: >+ static bool UsingInlinedStorage(size_type n) { >+ return n <= inline_elements; >+ } >+ >+ StorageElement* InitializeData() { >+ if (UsingInlinedStorage(size())) { >+ InlinedStorage::AnnotateConstruct(size()); >+ return InlinedStorage::data(); >+ } else { >+ return reinterpret_cast<StorageElement*>( >+ AllocatorTraits::allocate(*alloc(), size())); >+ } >+ } >+ >+ // `CompressedTuple` takes advantage of EBCO for stateless `allocator_type`s >+ container_internal::CompressedTuple<size_type, allocator_type> size_alloc_; >+ StorageElement* data_; >+ }; >+ >+ Storage storage_; >+}; >+ >+template <typename T, size_t N, typename A> >+constexpr size_t FixedArray<T, N, A>::kInlineBytesDefault; >+ >+template <typename T, size_t N, typename A> >+constexpr typename FixedArray<T, N, A>::size_type >+ FixedArray<T, N, A>::inline_elements; >+ >+template <typename T, size_t N, typename A> >+void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateConstruct( >+ typename FixedArray<T, N, A>::size_type n) { >+#ifdef ADDRESS_SANITIZER >+ if (!n) return; >+ ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), RedzoneEnd(), data() + n); >+ ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), data(), RedzoneBegin()); >+#endif // ADDRESS_SANITIZER >+ static_cast<void>(n); // Mark used when not in asan mode >+} >+ >+template <typename T, size_t N, typename A> >+void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateDestruct( >+ typename FixedArray<T, N, A>::size_type n) { >+#ifdef ADDRESS_SANITIZER >+ if (!n) return; >+ ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), data() + n, RedzoneEnd()); >+ ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), RedzoneBegin(), data()); >+#endif // ADDRESS_SANITIZER >+ static_cast<void>(n); // Mark used when not in asan mode >+} >+} // namespace absl >+#endif // ABSL_CONTAINER_FIXED_ARRAY_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..b4f0cf2aeb04f03409b95bdcb53af5fecd578d8f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array_benchmark.cc >@@ -0,0 +1,66 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/container/fixed_array.h" >+ >+#include <stddef.h> >+#include <string> >+ >+#include "benchmark/benchmark.h" >+ >+namespace { >+ >+// For benchmarking -- simple class with constructor and destructor that >+// set an int to a constant.. >+class SimpleClass { >+ public: >+ SimpleClass() : i(3) { } >+ ~SimpleClass() { i = 0; } >+ private: >+ int i; >+}; >+ >+template <typename C, size_t stack_size> >+void BM_FixedArray(benchmark::State& state) { >+ const int size = state.range(0); >+ for (auto _ : state) { >+ absl::FixedArray<C, stack_size> fa(size); >+ benchmark::DoNotOptimize(fa.data()); >+ } >+} >+BENCHMARK_TEMPLATE(BM_FixedArray, char, absl::kFixedArrayUseDefault) >+ ->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, char, 0)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, char, 1)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, char, 16)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, char, 256)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, char, 65536)->Range(0, 1 << 16); >+ >+BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, absl::kFixedArrayUseDefault) >+ ->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 0)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 1)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 16)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 256)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 65536)->Range(0, 1 << 16); >+ >+BENCHMARK_TEMPLATE(BM_FixedArray, std::string, absl::kFixedArrayUseDefault) >+ ->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 0)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 1)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 16)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 256)->Range(0, 1 << 16); >+BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 65536)->Range(0, 1 << 16); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array_exception_safety_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array_exception_safety_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..c123c2a1c0d2d38484056c34f89101489e5c1424 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array_exception_safety_test.cc >@@ -0,0 +1,117 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <initializer_list> >+ >+#include "absl/container/fixed_array.h" >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/exception_safety_testing.h" >+ >+namespace absl { >+ >+namespace { >+ >+constexpr size_t kInlined = 25; >+constexpr size_t kSmallSize = kInlined / 2; >+constexpr size_t kLargeSize = kInlined * 2; >+ >+constexpr int kInitialValue = 5; >+constexpr int kUpdatedValue = 10; >+ >+using ::testing::TestThrowingCtor; >+ >+using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>; >+using FixedArr = absl::FixedArray<Thrower, kInlined>; >+ >+using MoveThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>; >+using MoveFixedArr = absl::FixedArray<MoveThrower, kInlined>; >+ >+TEST(FixedArrayExceptionSafety, CopyConstructor) { >+ auto small = FixedArr(kSmallSize); >+ TestThrowingCtor<FixedArr>(small); >+ >+ auto large = FixedArr(kLargeSize); >+ TestThrowingCtor<FixedArr>(large); >+} >+ >+TEST(FixedArrayExceptionSafety, MoveConstructor) { >+ TestThrowingCtor<FixedArr>(FixedArr(kSmallSize)); >+ TestThrowingCtor<FixedArr>(FixedArr(kLargeSize)); >+ >+ // TypeSpec::kNoThrowMove >+ TestThrowingCtor<MoveFixedArr>(MoveFixedArr(kSmallSize)); >+ TestThrowingCtor<MoveFixedArr>(MoveFixedArr(kLargeSize)); >+} >+ >+TEST(FixedArrayExceptionSafety, SizeConstructor) { >+ TestThrowingCtor<FixedArr>(kSmallSize); >+ TestThrowingCtor<FixedArr>(kLargeSize); >+} >+ >+TEST(FixedArrayExceptionSafety, SizeValueConstructor) { >+ TestThrowingCtor<FixedArr>(kSmallSize, Thrower()); >+ TestThrowingCtor<FixedArr>(kLargeSize, Thrower()); >+} >+ >+TEST(FixedArrayExceptionSafety, IteratorConstructor) { >+ auto small = FixedArr(kSmallSize); >+ TestThrowingCtor<FixedArr>(small.begin(), small.end()); >+ >+ auto large = FixedArr(kLargeSize); >+ TestThrowingCtor<FixedArr>(large.begin(), large.end()); >+} >+ >+TEST(FixedArrayExceptionSafety, InitListConstructor) { >+ constexpr int small_inlined = 3; >+ using SmallFixedArr = absl::FixedArray<Thrower, small_inlined>; >+ >+ TestThrowingCtor<SmallFixedArr>(std::initializer_list<Thrower>{}); >+ // Test inlined allocation >+ TestThrowingCtor<SmallFixedArr>( >+ std::initializer_list<Thrower>{Thrower{}, Thrower{}}); >+ // Test out of line allocation >+ TestThrowingCtor<SmallFixedArr>(std::initializer_list<Thrower>{ >+ Thrower{}, Thrower{}, Thrower{}, Thrower{}, Thrower{}}); >+} >+ >+testing::AssertionResult ReadMemory(FixedArr* fixed_arr) { >+ // Marked volatile to prevent optimization. Used for running asan tests. >+ volatile int sum = 0; >+ for (const auto& thrower : *fixed_arr) { >+ sum += thrower.Get(); >+ } >+ return testing::AssertionSuccess() << "Values sum to [" << sum << "]"; >+} >+ >+TEST(FixedArrayExceptionSafety, Fill) { >+ auto test_fill = testing::MakeExceptionSafetyTester() >+ .WithInvariants(ReadMemory) >+ .WithOperation([&](FixedArr* fixed_arr_ptr) { >+ auto thrower = >+ Thrower(kUpdatedValue, testing::nothrow_ctor); >+ fixed_arr_ptr->fill(thrower); >+ }); >+ >+ EXPECT_TRUE( >+ test_fill.WithInitialValue(FixedArr(kSmallSize, Thrower(kInitialValue))) >+ .Test()); >+ EXPECT_TRUE( >+ test_fill.WithInitialValue(FixedArr(kLargeSize, Thrower(kInitialValue))) >+ .Test()); >+} >+ >+} // namespace >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..b07ebcb6d9ca6b0e426ca63ac34c06f8140983ce >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/fixed_array_test.cc >@@ -0,0 +1,870 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/container/fixed_array.h" >+ >+#include <stdio.h> >+#include <cstring> >+#include <list> >+#include <memory> >+#include <numeric> >+#include <scoped_allocator> >+#include <stdexcept> >+#include <string> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/internal/exception_testing.h" >+#include "absl/memory/memory.h" >+ >+using ::testing::ElementsAreArray; >+ >+namespace { >+ >+// Helper routine to determine if a absl::FixedArray used stack allocation. >+template <typename ArrayType> >+static bool IsOnStack(const ArrayType& a) { >+ return a.size() <= ArrayType::inline_elements; >+} >+ >+class ConstructionTester { >+ public: >+ ConstructionTester() >+ : self_ptr_(this), >+ value_(0) { >+ constructions++; >+ } >+ ~ConstructionTester() { >+ assert(self_ptr_ == this); >+ self_ptr_ = nullptr; >+ destructions++; >+ } >+ >+ // These are incremented as elements are constructed and destructed so we can >+ // be sure all elements are properly cleaned up. >+ static int constructions; >+ static int destructions; >+ >+ void CheckConstructed() { >+ assert(self_ptr_ == this); >+ } >+ >+ void set(int value) { value_ = value; } >+ int get() { return value_; } >+ >+ private: >+ // self_ptr_ should always point to 'this' -- that's how we can be sure the >+ // constructor has been called. >+ ConstructionTester* self_ptr_; >+ int value_; >+}; >+ >+int ConstructionTester::constructions = 0; >+int ConstructionTester::destructions = 0; >+ >+// ThreeInts will initialize its three ints to the value stored in >+// ThreeInts::counter. The constructor increments counter so that each object >+// in an array of ThreeInts will have different values. >+class ThreeInts { >+ public: >+ ThreeInts() { >+ x_ = counter; >+ y_ = counter; >+ z_ = counter; >+ ++counter; >+ } >+ >+ static int counter; >+ >+ int x_, y_, z_; >+}; >+ >+int ThreeInts::counter = 0; >+ >+TEST(FixedArrayTest, CopyCtor) { >+ absl::FixedArray<int, 10> on_stack(5); >+ std::iota(on_stack.begin(), on_stack.end(), 0); >+ absl::FixedArray<int, 10> stack_copy = on_stack; >+ EXPECT_THAT(stack_copy, ElementsAreArray(on_stack)); >+ EXPECT_TRUE(IsOnStack(stack_copy)); >+ >+ absl::FixedArray<int, 10> allocated(15); >+ std::iota(allocated.begin(), allocated.end(), 0); >+ absl::FixedArray<int, 10> alloced_copy = allocated; >+ EXPECT_THAT(alloced_copy, ElementsAreArray(allocated)); >+ EXPECT_FALSE(IsOnStack(alloced_copy)); >+} >+ >+TEST(FixedArrayTest, MoveCtor) { >+ absl::FixedArray<std::unique_ptr<int>, 10> on_stack(5); >+ for (int i = 0; i < 5; ++i) { >+ on_stack[i] = absl::make_unique<int>(i); >+ } >+ >+ absl::FixedArray<std::unique_ptr<int>, 10> stack_copy = std::move(on_stack); >+ for (int i = 0; i < 5; ++i) EXPECT_EQ(*(stack_copy[i]), i); >+ EXPECT_EQ(stack_copy.size(), on_stack.size()); >+ >+ absl::FixedArray<std::unique_ptr<int>, 10> allocated(15); >+ for (int i = 0; i < 15; ++i) { >+ allocated[i] = absl::make_unique<int>(i); >+ } >+ >+ absl::FixedArray<std::unique_ptr<int>, 10> alloced_copy = >+ std::move(allocated); >+ for (int i = 0; i < 15; ++i) EXPECT_EQ(*(alloced_copy[i]), i); >+ EXPECT_EQ(allocated.size(), alloced_copy.size()); >+} >+ >+TEST(FixedArrayTest, SmallObjects) { >+ // Small object arrays >+ { >+ // Short arrays should be on the stack >+ absl::FixedArray<int> array(4); >+ EXPECT_TRUE(IsOnStack(array)); >+ } >+ >+ { >+ // Large arrays should be on the heap >+ absl::FixedArray<int> array(1048576); >+ EXPECT_FALSE(IsOnStack(array)); >+ } >+ >+ { >+ // Arrays of <= default size should be on the stack >+ absl::FixedArray<int, 100> array(100); >+ EXPECT_TRUE(IsOnStack(array)); >+ } >+ >+ { >+ // Arrays of > default size should be on the stack >+ absl::FixedArray<int, 100> array(101); >+ EXPECT_FALSE(IsOnStack(array)); >+ } >+ >+ { >+ // Arrays with different size elements should use approximately >+ // same amount of stack space >+ absl::FixedArray<int> array1(0); >+ absl::FixedArray<char> array2(0); >+ EXPECT_LE(sizeof(array1), sizeof(array2)+100); >+ EXPECT_LE(sizeof(array2), sizeof(array1)+100); >+ } >+ >+ { >+ // Ensure that vectors are properly constructed inside a fixed array. >+ absl::FixedArray<std::vector<int> > array(2); >+ EXPECT_EQ(0, array[0].size()); >+ EXPECT_EQ(0, array[1].size()); >+ } >+ >+ { >+ // Regardless of absl::FixedArray implementation, check that a type with a >+ // low alignment requirement and a non power-of-two size is initialized >+ // correctly. >+ ThreeInts::counter = 1; >+ absl::FixedArray<ThreeInts> array(2); >+ EXPECT_EQ(1, array[0].x_); >+ EXPECT_EQ(1, array[0].y_); >+ EXPECT_EQ(1, array[0].z_); >+ EXPECT_EQ(2, array[1].x_); >+ EXPECT_EQ(2, array[1].y_); >+ EXPECT_EQ(2, array[1].z_); >+ } >+} >+ >+TEST(FixedArrayTest, AtThrows) { >+ absl::FixedArray<int> a = {1, 2, 3}; >+ EXPECT_EQ(a.at(2), 3); >+ ABSL_BASE_INTERNAL_EXPECT_FAIL(a.at(3), std::out_of_range, >+ "failed bounds check"); >+} >+ >+TEST(FixedArrayRelationalsTest, EqualArrays) { >+ for (int i = 0; i < 10; ++i) { >+ absl::FixedArray<int, 5> a1(i); >+ std::iota(a1.begin(), a1.end(), 0); >+ absl::FixedArray<int, 5> a2(a1.begin(), a1.end()); >+ >+ EXPECT_TRUE(a1 == a2); >+ EXPECT_FALSE(a1 != a2); >+ EXPECT_TRUE(a2 == a1); >+ EXPECT_FALSE(a2 != a1); >+ EXPECT_FALSE(a1 < a2); >+ EXPECT_FALSE(a1 > a2); >+ EXPECT_FALSE(a2 < a1); >+ EXPECT_FALSE(a2 > a1); >+ EXPECT_TRUE(a1 <= a2); >+ EXPECT_TRUE(a1 >= a2); >+ EXPECT_TRUE(a2 <= a1); >+ EXPECT_TRUE(a2 >= a1); >+ } >+} >+ >+TEST(FixedArrayRelationalsTest, UnequalArrays) { >+ for (int i = 1; i < 10; ++i) { >+ absl::FixedArray<int, 5> a1(i); >+ std::iota(a1.begin(), a1.end(), 0); >+ absl::FixedArray<int, 5> a2(a1.begin(), a1.end()); >+ --a2[i / 2]; >+ >+ EXPECT_FALSE(a1 == a2); >+ EXPECT_TRUE(a1 != a2); >+ EXPECT_FALSE(a2 == a1); >+ EXPECT_TRUE(a2 != a1); >+ EXPECT_FALSE(a1 < a2); >+ EXPECT_TRUE(a1 > a2); >+ EXPECT_TRUE(a2 < a1); >+ EXPECT_FALSE(a2 > a1); >+ EXPECT_FALSE(a1 <= a2); >+ EXPECT_TRUE(a1 >= a2); >+ EXPECT_TRUE(a2 <= a1); >+ EXPECT_FALSE(a2 >= a1); >+ } >+} >+ >+template <int stack_elements> >+static void TestArray(int n) { >+ SCOPED_TRACE(n); >+ SCOPED_TRACE(stack_elements); >+ ConstructionTester::constructions = 0; >+ ConstructionTester::destructions = 0; >+ { >+ absl::FixedArray<ConstructionTester, stack_elements> array(n); >+ >+ EXPECT_THAT(array.size(), n); >+ EXPECT_THAT(array.memsize(), sizeof(ConstructionTester) * n); >+ EXPECT_THAT(array.begin() + n, array.end()); >+ >+ // Check that all elements were constructed >+ for (int i = 0; i < n; i++) { >+ array[i].CheckConstructed(); >+ } >+ // Check that no other elements were constructed >+ EXPECT_THAT(ConstructionTester::constructions, n); >+ >+ // Test operator[] >+ for (int i = 0; i < n; i++) { >+ array[i].set(i); >+ } >+ for (int i = 0; i < n; i++) { >+ EXPECT_THAT(array[i].get(), i); >+ EXPECT_THAT(array.data()[i].get(), i); >+ } >+ >+ // Test data() >+ for (int i = 0; i < n; i++) { >+ array.data()[i].set(i + 1); >+ } >+ for (int i = 0; i < n; i++) { >+ EXPECT_THAT(array[i].get(), i+1); >+ EXPECT_THAT(array.data()[i].get(), i+1); >+ } >+ } // Close scope containing 'array'. >+ >+ // Check that all constructed elements were destructed. >+ EXPECT_EQ(ConstructionTester::constructions, >+ ConstructionTester::destructions); >+} >+ >+template <int elements_per_inner_array, int inline_elements> >+static void TestArrayOfArrays(int n) { >+ SCOPED_TRACE(n); >+ SCOPED_TRACE(inline_elements); >+ SCOPED_TRACE(elements_per_inner_array); >+ ConstructionTester::constructions = 0; >+ ConstructionTester::destructions = 0; >+ { >+ using InnerArray = ConstructionTester[elements_per_inner_array]; >+ // Heap-allocate the FixedArray to avoid blowing the stack frame. >+ auto array_ptr = >+ absl::make_unique<absl::FixedArray<InnerArray, inline_elements>>(n); >+ auto& array = *array_ptr; >+ >+ ASSERT_EQ(array.size(), n); >+ ASSERT_EQ(array.memsize(), >+ sizeof(ConstructionTester) * elements_per_inner_array * n); >+ ASSERT_EQ(array.begin() + n, array.end()); >+ >+ // Check that all elements were constructed >+ for (int i = 0; i < n; i++) { >+ for (int j = 0; j < elements_per_inner_array; j++) { >+ (array[i])[j].CheckConstructed(); >+ } >+ } >+ // Check that no other elements were constructed >+ ASSERT_EQ(ConstructionTester::constructions, n * elements_per_inner_array); >+ >+ // Test operator[] >+ for (int i = 0; i < n; i++) { >+ for (int j = 0; j < elements_per_inner_array; j++) { >+ (array[i])[j].set(i * elements_per_inner_array + j); >+ } >+ } >+ for (int i = 0; i < n; i++) { >+ for (int j = 0; j < elements_per_inner_array; j++) { >+ ASSERT_EQ((array[i])[j].get(), i * elements_per_inner_array + j); >+ ASSERT_EQ((array.data()[i])[j].get(), i * elements_per_inner_array + j); >+ } >+ } >+ >+ // Test data() >+ for (int i = 0; i < n; i++) { >+ for (int j = 0; j < elements_per_inner_array; j++) { >+ (array.data()[i])[j].set((i + 1) * elements_per_inner_array + j); >+ } >+ } >+ for (int i = 0; i < n; i++) { >+ for (int j = 0; j < elements_per_inner_array; j++) { >+ ASSERT_EQ((array[i])[j].get(), >+ (i + 1) * elements_per_inner_array + j); >+ ASSERT_EQ((array.data()[i])[j].get(), >+ (i + 1) * elements_per_inner_array + j); >+ } >+ } >+ } // Close scope containing 'array'. >+ >+ // Check that all constructed elements were destructed. >+ EXPECT_EQ(ConstructionTester::constructions, >+ ConstructionTester::destructions); >+} >+ >+TEST(IteratorConstructorTest, NonInline) { >+ int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 }; >+ absl::FixedArray<int, ABSL_ARRAYSIZE(kInput) - 1> const fixed( >+ kInput, kInput + ABSL_ARRAYSIZE(kInput)); >+ ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size()); >+ for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) { >+ ASSERT_EQ(kInput[i], fixed[i]); >+ } >+} >+ >+TEST(IteratorConstructorTest, Inline) { >+ int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 }; >+ absl::FixedArray<int, ABSL_ARRAYSIZE(kInput)> const fixed( >+ kInput, kInput + ABSL_ARRAYSIZE(kInput)); >+ ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size()); >+ for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) { >+ ASSERT_EQ(kInput[i], fixed[i]); >+ } >+} >+ >+TEST(IteratorConstructorTest, NonPod) { >+ char const* kInput[] = >+ { "red", "orange", "yellow", "green", "blue", "indigo", "violet" }; >+ absl::FixedArray<std::string> const fixed(kInput, kInput + ABSL_ARRAYSIZE(kInput)); >+ ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size()); >+ for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) { >+ ASSERT_EQ(kInput[i], fixed[i]); >+ } >+} >+ >+TEST(IteratorConstructorTest, FromEmptyVector) { >+ std::vector<int> const empty; >+ absl::FixedArray<int> const fixed(empty.begin(), empty.end()); >+ EXPECT_EQ(0, fixed.size()); >+ EXPECT_EQ(empty.size(), fixed.size()); >+} >+ >+TEST(IteratorConstructorTest, FromNonEmptyVector) { >+ int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 }; >+ std::vector<int> const items(kInput, kInput + ABSL_ARRAYSIZE(kInput)); >+ absl::FixedArray<int> const fixed(items.begin(), items.end()); >+ ASSERT_EQ(items.size(), fixed.size()); >+ for (size_t i = 0; i < items.size(); ++i) { >+ ASSERT_EQ(items[i], fixed[i]); >+ } >+} >+ >+TEST(IteratorConstructorTest, FromBidirectionalIteratorRange) { >+ int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 }; >+ std::list<int> const items(kInput, kInput + ABSL_ARRAYSIZE(kInput)); >+ absl::FixedArray<int> const fixed(items.begin(), items.end()); >+ EXPECT_THAT(fixed, testing::ElementsAreArray(kInput)); >+} >+ >+TEST(InitListConstructorTest, InitListConstruction) { >+ absl::FixedArray<int> fixed = {1, 2, 3}; >+ EXPECT_THAT(fixed, testing::ElementsAreArray({1, 2, 3})); >+} >+ >+TEST(FillConstructorTest, NonEmptyArrays) { >+ absl::FixedArray<int> stack_array(4, 1); >+ EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1})); >+ >+ absl::FixedArray<int, 0> heap_array(4, 1); >+ EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1})); >+} >+ >+TEST(FillConstructorTest, EmptyArray) { >+ absl::FixedArray<int> empty_fill(0, 1); >+ absl::FixedArray<int> empty_size(0); >+ EXPECT_EQ(empty_fill, empty_size); >+} >+ >+TEST(FillConstructorTest, NotTriviallyCopyable) { >+ std::string str = "abcd"; >+ absl::FixedArray<std::string> strings = {str, str, str, str}; >+ >+ absl::FixedArray<std::string> array(4, str); >+ EXPECT_EQ(array, strings); >+} >+ >+TEST(FillConstructorTest, Disambiguation) { >+ absl::FixedArray<size_t> a(1, 2); >+ EXPECT_THAT(a, testing::ElementsAre(2)); >+} >+ >+TEST(FixedArrayTest, ManySizedArrays) { >+ std::vector<int> sizes; >+ for (int i = 1; i < 100; i++) sizes.push_back(i); >+ for (int i = 100; i <= 1000; i += 100) sizes.push_back(i); >+ for (int n : sizes) { >+ TestArray<0>(n); >+ TestArray<1>(n); >+ TestArray<64>(n); >+ TestArray<1000>(n); >+ } >+} >+ >+TEST(FixedArrayTest, ManySizedArraysOfArraysOf1) { >+ for (int n = 1; n < 1000; n++) { >+ ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 0>(n))); >+ ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1>(n))); >+ ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 64>(n))); >+ ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1000>(n))); >+ } >+} >+ >+TEST(FixedArrayTest, ManySizedArraysOfArraysOf2) { >+ for (int n = 1; n < 1000; n++) { >+ TestArrayOfArrays<2, 0>(n); >+ TestArrayOfArrays<2, 1>(n); >+ TestArrayOfArrays<2, 64>(n); >+ TestArrayOfArrays<2, 1000>(n); >+ } >+} >+ >+// If value_type is put inside of a struct container, >+// we might evoke this error in a hardened build unless data() is carefully >+// written, so check on that. >+// error: call to int __builtin___sprintf_chk(etc...) >+// will always overflow destination buffer [-Werror] >+TEST(FixedArrayTest, AvoidParanoidDiagnostics) { >+ absl::FixedArray<char, 32> buf(32); >+ sprintf(buf.data(), "foo"); // NOLINT(runtime/printf) >+} >+ >+TEST(FixedArrayTest, TooBigInlinedSpace) { >+ struct TooBig { >+ char c[1 << 20]; >+ }; // too big for even one on the stack >+ >+ // Simulate the data members of absl::FixedArray, a pointer and a size_t. >+ struct Data { >+ TooBig* p; >+ size_t size; >+ }; >+ >+ // Make sure TooBig objects are not inlined for 0 or default size. >+ static_assert(sizeof(absl::FixedArray<TooBig, 0>) == sizeof(Data), >+ "0-sized absl::FixedArray should have same size as Data."); >+ static_assert(alignof(absl::FixedArray<TooBig, 0>) == alignof(Data), >+ "0-sized absl::FixedArray should have same alignment as Data."); >+ static_assert(sizeof(absl::FixedArray<TooBig>) == sizeof(Data), >+ "default-sized absl::FixedArray should have same size as Data"); >+ static_assert( >+ alignof(absl::FixedArray<TooBig>) == alignof(Data), >+ "default-sized absl::FixedArray should have same alignment as Data."); >+} >+ >+// PickyDelete EXPECTs its class-scope deallocation funcs are unused. >+struct PickyDelete { >+ PickyDelete() {} >+ ~PickyDelete() {} >+ void operator delete(void* p) { >+ EXPECT_TRUE(false) << __FUNCTION__; >+ ::operator delete(p); >+ } >+ void operator delete[](void* p) { >+ EXPECT_TRUE(false) << __FUNCTION__; >+ ::operator delete[](p); >+ } >+}; >+ >+TEST(FixedArrayTest, UsesGlobalAlloc) { absl::FixedArray<PickyDelete, 0> a(5); } >+ >+ >+TEST(FixedArrayTest, Data) { >+ static const int kInput[] = { 2, 3, 5, 7, 11, 13, 17 }; >+ absl::FixedArray<int> fa(std::begin(kInput), std::end(kInput)); >+ EXPECT_EQ(fa.data(), &*fa.begin()); >+ EXPECT_EQ(fa.data(), &fa[0]); >+ >+ const absl::FixedArray<int>& cfa = fa; >+ EXPECT_EQ(cfa.data(), &*cfa.begin()); >+ EXPECT_EQ(cfa.data(), &cfa[0]); >+} >+ >+TEST(FixedArrayTest, Empty) { >+ absl::FixedArray<int> empty(0); >+ absl::FixedArray<int> inline_filled(1); >+ absl::FixedArray<int, 0> heap_filled(1); >+ EXPECT_TRUE(empty.empty()); >+ EXPECT_FALSE(inline_filled.empty()); >+ EXPECT_FALSE(heap_filled.empty()); >+} >+ >+TEST(FixedArrayTest, FrontAndBack) { >+ absl::FixedArray<int, 3 * sizeof(int)> inlined = {1, 2, 3}; >+ EXPECT_EQ(inlined.front(), 1); >+ EXPECT_EQ(inlined.back(), 3); >+ >+ absl::FixedArray<int, 0> allocated = {1, 2, 3}; >+ EXPECT_EQ(allocated.front(), 1); >+ EXPECT_EQ(allocated.back(), 3); >+ >+ absl::FixedArray<int> one_element = {1}; >+ EXPECT_EQ(one_element.front(), one_element.back()); >+} >+ >+TEST(FixedArrayTest, ReverseIteratorInlined) { >+ absl::FixedArray<int, 5 * sizeof(int)> a = {0, 1, 2, 3, 4}; >+ >+ int counter = 5; >+ for (absl::FixedArray<int>::reverse_iterator iter = a.rbegin(); >+ iter != a.rend(); ++iter) { >+ counter--; >+ EXPECT_EQ(counter, *iter); >+ } >+ EXPECT_EQ(counter, 0); >+ >+ counter = 5; >+ for (absl::FixedArray<int>::const_reverse_iterator iter = a.rbegin(); >+ iter != a.rend(); ++iter) { >+ counter--; >+ EXPECT_EQ(counter, *iter); >+ } >+ EXPECT_EQ(counter, 0); >+ >+ counter = 5; >+ for (auto iter = a.crbegin(); iter != a.crend(); ++iter) { >+ counter--; >+ EXPECT_EQ(counter, *iter); >+ } >+ EXPECT_EQ(counter, 0); >+} >+ >+TEST(FixedArrayTest, ReverseIteratorAllocated) { >+ absl::FixedArray<int, 0> a = {0, 1, 2, 3, 4}; >+ >+ int counter = 5; >+ for (absl::FixedArray<int>::reverse_iterator iter = a.rbegin(); >+ iter != a.rend(); ++iter) { >+ counter--; >+ EXPECT_EQ(counter, *iter); >+ } >+ EXPECT_EQ(counter, 0); >+ >+ counter = 5; >+ for (absl::FixedArray<int>::const_reverse_iterator iter = a.rbegin(); >+ iter != a.rend(); ++iter) { >+ counter--; >+ EXPECT_EQ(counter, *iter); >+ } >+ EXPECT_EQ(counter, 0); >+ >+ counter = 5; >+ for (auto iter = a.crbegin(); iter != a.crend(); ++iter) { >+ counter--; >+ EXPECT_EQ(counter, *iter); >+ } >+ EXPECT_EQ(counter, 0); >+} >+ >+TEST(FixedArrayTest, Fill) { >+ absl::FixedArray<int, 5 * sizeof(int)> inlined(5); >+ int fill_val = 42; >+ inlined.fill(fill_val); >+ for (int i : inlined) EXPECT_EQ(i, fill_val); >+ >+ absl::FixedArray<int, 0> allocated(5); >+ allocated.fill(fill_val); >+ for (int i : allocated) EXPECT_EQ(i, fill_val); >+ >+ // It doesn't do anything, just make sure this compiles. >+ absl::FixedArray<int> empty(0); >+ empty.fill(fill_val); >+} >+ >+// TODO(johnsoncj): Investigate InlinedStorage default initialization in GCC 4.x >+#ifndef __GNUC__ >+TEST(FixedArrayTest, DefaultCtorDoesNotValueInit) { >+ using T = char; >+ constexpr auto capacity = 10; >+ using FixedArrType = absl::FixedArray<T, capacity>; >+ using FixedArrBuffType = >+ absl::aligned_storage_t<sizeof(FixedArrType), alignof(FixedArrType)>; >+ constexpr auto scrubbed_bits = 0x95; >+ constexpr auto length = capacity / 2; >+ >+ FixedArrBuffType buff; >+ std::memset(std::addressof(buff), scrubbed_bits, sizeof(FixedArrBuffType)); >+ >+ FixedArrType* arr = >+ ::new (static_cast<void*>(std::addressof(buff))) FixedArrType(length); >+ EXPECT_THAT(*arr, testing::Each(scrubbed_bits)); >+ arr->~FixedArrType(); >+} >+#endif // __GNUC__ >+ >+// This is a stateful allocator, but the state lives outside of the >+// allocator (in whatever test is using the allocator). This is odd >+// but helps in tests where the allocator is propagated into nested >+// containers - that chain of allocators uses the same state and is >+// thus easier to query for aggregate allocation information. >+template <typename T> >+class CountingAllocator : public std::allocator<T> { >+ public: >+ using Alloc = std::allocator<T>; >+ using pointer = typename Alloc::pointer; >+ using size_type = typename Alloc::size_type; >+ >+ CountingAllocator() : bytes_used_(nullptr), instance_count_(nullptr) {} >+ explicit CountingAllocator(int64_t* b) >+ : bytes_used_(b), instance_count_(nullptr) {} >+ CountingAllocator(int64_t* b, int64_t* a) >+ : bytes_used_(b), instance_count_(a) {} >+ >+ template <typename U> >+ explicit CountingAllocator(const CountingAllocator<U>& x) >+ : Alloc(x), >+ bytes_used_(x.bytes_used_), >+ instance_count_(x.instance_count_) {} >+ >+ pointer allocate(size_type n, const void* const hint = nullptr) { >+ assert(bytes_used_ != nullptr); >+ *bytes_used_ += n * sizeof(T); >+ return Alloc::allocate(n, hint); >+ } >+ >+ void deallocate(pointer p, size_type n) { >+ Alloc::deallocate(p, n); >+ assert(bytes_used_ != nullptr); >+ *bytes_used_ -= n * sizeof(T); >+ } >+ >+ template <typename... Args> >+ void construct(pointer p, Args&&... args) { >+ Alloc::construct(p, absl::forward<Args>(args)...); >+ if (instance_count_) { >+ *instance_count_ += 1; >+ } >+ } >+ >+ void destroy(pointer p) { >+ Alloc::destroy(p); >+ if (instance_count_) { >+ *instance_count_ -= 1; >+ } >+ } >+ >+ template <typename U> >+ class rebind { >+ public: >+ using other = CountingAllocator<U>; >+ }; >+ >+ int64_t* bytes_used_; >+ int64_t* instance_count_; >+}; >+ >+TEST(AllocatorSupportTest, CountInlineAllocations) { >+ constexpr size_t inlined_size = 4; >+ using Alloc = CountingAllocator<int>; >+ using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>; >+ >+ int64_t allocated = 0; >+ int64_t active_instances = 0; >+ >+ { >+ const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7}; >+ >+ Alloc alloc(&allocated, &active_instances); >+ >+ AllocFxdArr arr(ia, ia + inlined_size, alloc); >+ static_cast<void>(arr); >+ } >+ >+ EXPECT_EQ(allocated, 0); >+ EXPECT_EQ(active_instances, 0); >+} >+ >+TEST(AllocatorSupportTest, CountOutoflineAllocations) { >+ constexpr size_t inlined_size = 4; >+ using Alloc = CountingAllocator<int>; >+ using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>; >+ >+ int64_t allocated = 0; >+ int64_t active_instances = 0; >+ >+ { >+ const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7}; >+ Alloc alloc(&allocated, &active_instances); >+ >+ AllocFxdArr arr(ia, ia + ABSL_ARRAYSIZE(ia), alloc); >+ >+ EXPECT_EQ(allocated, arr.size() * sizeof(int)); >+ static_cast<void>(arr); >+ } >+ >+ EXPECT_EQ(active_instances, 0); >+} >+ >+TEST(AllocatorSupportTest, CountCopyInlineAllocations) { >+ constexpr size_t inlined_size = 4; >+ using Alloc = CountingAllocator<int>; >+ using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>; >+ >+ int64_t allocated1 = 0; >+ int64_t allocated2 = 0; >+ int64_t active_instances = 0; >+ Alloc alloc(&allocated1, &active_instances); >+ Alloc alloc2(&allocated2, &active_instances); >+ >+ { >+ int initial_value = 1; >+ >+ AllocFxdArr arr1(inlined_size / 2, initial_value, alloc); >+ >+ EXPECT_EQ(allocated1, 0); >+ >+ AllocFxdArr arr2(arr1, alloc2); >+ >+ EXPECT_EQ(allocated2, 0); >+ static_cast<void>(arr1); >+ static_cast<void>(arr2); >+ } >+ >+ EXPECT_EQ(active_instances, 0); >+} >+ >+TEST(AllocatorSupportTest, CountCopyOutoflineAllocations) { >+ constexpr size_t inlined_size = 4; >+ using Alloc = CountingAllocator<int>; >+ using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>; >+ >+ int64_t allocated1 = 0; >+ int64_t allocated2 = 0; >+ int64_t active_instances = 0; >+ Alloc alloc(&allocated1, &active_instances); >+ Alloc alloc2(&allocated2, &active_instances); >+ >+ { >+ int initial_value = 1; >+ >+ AllocFxdArr arr1(inlined_size * 2, initial_value, alloc); >+ >+ EXPECT_EQ(allocated1, arr1.size() * sizeof(int)); >+ >+ AllocFxdArr arr2(arr1, alloc2); >+ >+ EXPECT_EQ(allocated2, inlined_size * 2 * sizeof(int)); >+ static_cast<void>(arr1); >+ static_cast<void>(arr2); >+ } >+ >+ EXPECT_EQ(active_instances, 0); >+} >+ >+TEST(AllocatorSupportTest, SizeValAllocConstructor) { >+ using testing::AllOf; >+ using testing::Each; >+ using testing::SizeIs; >+ >+ constexpr size_t inlined_size = 4; >+ using Alloc = CountingAllocator<int>; >+ using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>; >+ >+ { >+ auto len = inlined_size / 2; >+ auto val = 0; >+ int64_t allocated = 0; >+ AllocFxdArr arr(len, val, Alloc(&allocated)); >+ >+ EXPECT_EQ(allocated, 0); >+ EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0))); >+ } >+ >+ { >+ auto len = inlined_size * 2; >+ auto val = 0; >+ int64_t allocated = 0; >+ AllocFxdArr arr(len, val, Alloc(&allocated)); >+ >+ EXPECT_EQ(allocated, len * sizeof(int)); >+ EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0))); >+ } >+} >+ >+#ifdef ADDRESS_SANITIZER >+TEST(FixedArrayTest, AddressSanitizerAnnotations1) { >+ absl::FixedArray<int, 32> a(10); >+ int *raw = a.data(); >+ raw[0] = 0; >+ raw[9] = 0; >+ EXPECT_DEATH(raw[-2] = 0, "container-overflow"); >+ EXPECT_DEATH(raw[-1] = 0, "container-overflow"); >+ EXPECT_DEATH(raw[10] = 0, "container-overflow"); >+ EXPECT_DEATH(raw[31] = 0, "container-overflow"); >+} >+ >+TEST(FixedArrayTest, AddressSanitizerAnnotations2) { >+ absl::FixedArray<char, 17> a(12); >+ char *raw = a.data(); >+ raw[0] = 0; >+ raw[11] = 0; >+ EXPECT_DEATH(raw[-7] = 0, "container-overflow"); >+ EXPECT_DEATH(raw[-1] = 0, "container-overflow"); >+ EXPECT_DEATH(raw[12] = 0, "container-overflow"); >+ EXPECT_DEATH(raw[17] = 0, "container-overflow"); >+} >+ >+TEST(FixedArrayTest, AddressSanitizerAnnotations3) { >+ absl::FixedArray<uint64_t, 20> a(20); >+ uint64_t *raw = a.data(); >+ raw[0] = 0; >+ raw[19] = 0; >+ EXPECT_DEATH(raw[-1] = 0, "container-overflow"); >+ EXPECT_DEATH(raw[20] = 0, "container-overflow"); >+} >+ >+TEST(FixedArrayTest, AddressSanitizerAnnotations4) { >+ absl::FixedArray<ThreeInts> a(10); >+ ThreeInts *raw = a.data(); >+ raw[0] = ThreeInts(); >+ raw[9] = ThreeInts(); >+ // Note: raw[-1] is pointing to 12 bytes before the container range. However, >+ // there is only a 8-byte red zone before the container range, so we only >+ // access the last 4 bytes of the struct to make sure it stays within the red >+ // zone. >+ EXPECT_DEATH(raw[-1].z_ = 0, "container-overflow"); >+ EXPECT_DEATH(raw[10] = ThreeInts(), "container-overflow"); >+ // The actual size of storage is kDefaultBytes=256, 21*12 = 252, >+ // so reading raw[21] should still trigger the correct warning. >+ EXPECT_DEATH(raw[21] = ThreeInts(), "container-overflow"); >+} >+#endif // ADDRESS_SANITIZER >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/inlined_vector.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/inlined_vector.h >new file mode 100644 >index 0000000000000000000000000000000000000000..ca36fd3699b905c2ede9bb10725b4d9b66986877 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/inlined_vector.h >@@ -0,0 +1,1386 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: inlined_vector.h >+// ----------------------------------------------------------------------------- >+// >+// This header file contains the declaration and definition of an "inlined >+// vector" which behaves in an equivalent fashion to a `std::vector`, except >+// that storage for small sequences of the vector are provided inline without >+// requiring any heap allocation. >+ >+// An `absl::InlinedVector<T,N>` specifies the size N at which to inline as one >+// of its template parameters. Vectors of length <= N are provided inline. >+// Typically N is very small (e.g., 4) so that sequences that are expected to be >+// short do not require allocations. >+ >+// An `absl::InlinedVector` does not usually require a specific allocator; if >+// the inlined vector grows beyond its initial constraints, it will need to >+// allocate (as any normal `std::vector` would) and it will generally use the >+// default allocator in that case; optionally, a custom allocator may be >+// specified using an `absl::InlinedVector<T,N,A>` construction. >+ >+#ifndef ABSL_CONTAINER_INLINED_VECTOR_H_ >+#define ABSL_CONTAINER_INLINED_VECTOR_H_ >+ >+#include <algorithm> >+#include <cassert> >+#include <cstddef> >+#include <cstdlib> >+#include <cstring> >+#include <initializer_list> >+#include <iterator> >+#include <memory> >+#include <type_traits> >+#include <utility> >+ >+#include "absl/algorithm/algorithm.h" >+#include "absl/base/internal/throw_delegate.h" >+#include "absl/base/optimization.h" >+#include "absl/base/port.h" >+#include "absl/memory/memory.h" >+ >+namespace absl { >+ >+// ----------------------------------------------------------------------------- >+// InlinedVector >+// ----------------------------------------------------------------------------- >+// >+// An `absl::InlinedVector` is designed to be a drop-in replacement for >+// `std::vector` for use cases where the vector's size is sufficiently small >+// that it can be inlined. If the inlined vector does grow beyond its estimated >+// size, it will trigger an initial allocation on the heap, and will behave as a >+// `std:vector`. The API of the `absl::InlinedVector` within this file is >+// designed to cover the same API footprint as covered by `std::vector`. >+template <typename T, size_t N, typename A = std::allocator<T> > >+class InlinedVector { >+ using AllocatorTraits = std::allocator_traits<A>; >+ >+ public: >+ using allocator_type = A; >+ using value_type = typename allocator_type::value_type; >+ using pointer = typename allocator_type::pointer; >+ using const_pointer = typename allocator_type::const_pointer; >+ using reference = typename allocator_type::reference; >+ using const_reference = typename allocator_type::const_reference; >+ using size_type = typename allocator_type::size_type; >+ using difference_type = typename allocator_type::difference_type; >+ using iterator = pointer; >+ using const_iterator = const_pointer; >+ using reverse_iterator = std::reverse_iterator<iterator>; >+ using const_reverse_iterator = std::reverse_iterator<const_iterator>; >+ >+ InlinedVector() noexcept(noexcept(allocator_type())) >+ : allocator_and_tag_(allocator_type()) {} >+ >+ explicit InlinedVector(const allocator_type& alloc) noexcept >+ : allocator_and_tag_(alloc) {} >+ >+ // Create a vector with n copies of value_type(). >+ explicit InlinedVector(size_type n, >+ const allocator_type& alloc = allocator_type()) >+ : allocator_and_tag_(alloc) { >+ InitAssign(n); >+ } >+ >+ // Create a vector with n copies of elem >+ InlinedVector(size_type n, const value_type& elem, >+ const allocator_type& alloc = allocator_type()) >+ : allocator_and_tag_(alloc) { >+ InitAssign(n, elem); >+ } >+ >+ // Create and initialize with the elements [first .. last). >+ // The unused enable_if argument restricts this constructor so that it is >+ // elided when value_type is an integral type. This prevents ambiguous >+ // interpretation between a call to this constructor with two integral >+ // arguments and a call to the preceding (n, elem) constructor. >+ template <typename InputIterator> >+ InlinedVector( >+ InputIterator first, InputIterator last, >+ const allocator_type& alloc = allocator_type(), >+ typename std::enable_if<!std::is_integral<InputIterator>::value>::type* = >+ nullptr) >+ : allocator_and_tag_(alloc) { >+ AppendRange(first, last); >+ } >+ >+ InlinedVector(std::initializer_list<value_type> init, >+ const allocator_type& alloc = allocator_type()) >+ : allocator_and_tag_(alloc) { >+ AppendRange(init.begin(), init.end()); >+ } >+ >+ InlinedVector(const InlinedVector& v); >+ InlinedVector(const InlinedVector& v, const allocator_type& alloc); >+ >+ // This move constructor does not allocate and only moves the underlying >+ // objects, so its `noexcept` specification depends on whether moving the >+ // underlying objects can throw or not. We assume >+ // a) move constructors should only throw due to allocation failure and >+ // b) if `value_type`'s move constructor allocates, it uses the same >+ // allocation function as the `InlinedVector`'s allocator, so the move >+ // constructor is non-throwing if the allocator is non-throwing or >+ // `value_type`'s move constructor is specified as `noexcept`. >+ InlinedVector(InlinedVector&& v) noexcept( >+ absl::allocator_is_nothrow<allocator_type>::value || >+ std::is_nothrow_move_constructible<value_type>::value); >+ >+ // This move constructor allocates and also moves the underlying objects, so >+ // its `noexcept` specification depends on whether the allocation can throw >+ // and whether moving the underlying objects can throw. Based on the same >+ // assumptions above, the `noexcept` specification is dominated by whether the >+ // allocation can throw regardless of whether `value_type`'s move constructor >+ // is specified as `noexcept`. >+ InlinedVector(InlinedVector&& v, const allocator_type& alloc) noexcept( >+ absl::allocator_is_nothrow<allocator_type>::value); >+ >+ ~InlinedVector() { clear(); } >+ >+ InlinedVector& operator=(const InlinedVector& v) { >+ if (this == &v) { >+ return *this; >+ } >+ // Optimized to avoid reallocation. >+ // Prefer reassignment to copy construction for elements. >+ if (size() < v.size()) { // grow >+ reserve(v.size()); >+ std::copy(v.begin(), v.begin() + size(), begin()); >+ std::copy(v.begin() + size(), v.end(), std::back_inserter(*this)); >+ } else { // maybe shrink >+ erase(begin() + v.size(), end()); >+ std::copy(v.begin(), v.end(), begin()); >+ } >+ return *this; >+ } >+ >+ InlinedVector& operator=(InlinedVector&& v) { >+ if (this == &v) { >+ return *this; >+ } >+ if (v.allocated()) { >+ clear(); >+ tag().set_allocated_size(v.size()); >+ init_allocation(v.allocation()); >+ v.tag() = Tag(); >+ } else { >+ if (allocated()) clear(); >+ // Both are inlined now. >+ if (size() < v.size()) { >+ auto mid = std::make_move_iterator(v.begin() + size()); >+ std::copy(std::make_move_iterator(v.begin()), mid, begin()); >+ UninitializedCopy(mid, std::make_move_iterator(v.end()), end()); >+ } else { >+ auto new_end = std::copy(std::make_move_iterator(v.begin()), >+ std::make_move_iterator(v.end()), begin()); >+ Destroy(new_end, end()); >+ } >+ tag().set_inline_size(v.size()); >+ } >+ return *this; >+ } >+ >+ InlinedVector& operator=(std::initializer_list<value_type> init) { >+ AssignRange(init.begin(), init.end()); >+ return *this; >+ } >+ >+ // InlinedVector::assign() >+ // >+ // Replaces the contents of the inlined vector with copies of those in the >+ // iterator range [first, last). >+ template <typename InputIterator> >+ void assign( >+ InputIterator first, InputIterator last, >+ typename std::enable_if<!std::is_integral<InputIterator>::value>::type* = >+ nullptr) { >+ AssignRange(first, last); >+ } >+ >+ // Overload of `InlinedVector::assign()` to take values from elements of an >+ // initializer list >+ void assign(std::initializer_list<value_type> init) { >+ AssignRange(init.begin(), init.end()); >+ } >+ >+ // Overload of `InlinedVector::assign()` to replace the first `n` elements of >+ // the inlined vector with `elem` values. >+ void assign(size_type n, const value_type& elem) { >+ if (n <= size()) { // Possibly shrink >+ std::fill_n(begin(), n, elem); >+ erase(begin() + n, end()); >+ return; >+ } >+ // Grow >+ reserve(n); >+ std::fill_n(begin(), size(), elem); >+ if (allocated()) { >+ UninitializedFill(allocated_space() + size(), allocated_space() + n, >+ elem); >+ tag().set_allocated_size(n); >+ } else { >+ UninitializedFill(inlined_space() + size(), inlined_space() + n, elem); >+ tag().set_inline_size(n); >+ } >+ } >+ >+ // InlinedVector::size() >+ // >+ // Returns the number of elements in the inlined vector. >+ size_type size() const noexcept { return tag().size(); } >+ >+ // InlinedVector::empty() >+ // >+ // Checks if the inlined vector has no elements. >+ bool empty() const noexcept { return (size() == 0); } >+ >+ // InlinedVector::capacity() >+ // >+ // Returns the number of elements that can be stored in an inlined vector >+ // without requiring a reallocation of underlying memory. Note that for >+ // most inlined vectors, `capacity()` should equal its initial size `N`; for >+ // inlined vectors which exceed this capacity, they will no longer be inlined, >+ // and `capacity()` will equal its capacity on the allocated heap. >+ size_type capacity() const noexcept { >+ return allocated() ? allocation().capacity() : N; >+ } >+ >+ // InlinedVector::max_size() >+ // >+ // Returns the maximum number of elements the vector can hold. >+ size_type max_size() const noexcept { >+ // One bit of the size storage is used to indicate whether the inlined >+ // vector is allocated; as a result, the maximum size of the container that >+ // we can express is half of the max for our size type. >+ return std::numeric_limits<size_type>::max() / 2; >+ } >+ >+ // InlinedVector::data() >+ // >+ // Returns a const T* pointer to elements of the inlined vector. This pointer >+ // can be used to access (but not modify) the contained elements. >+ // Only results within the range `[0,size())` are defined. >+ const_pointer data() const noexcept { >+ return allocated() ? allocated_space() : inlined_space(); >+ } >+ >+ // Overload of InlinedVector::data() to return a T* pointer to elements of the >+ // inlined vector. This pointer can be used to access and modify the contained >+ // elements. >+ pointer data() noexcept { >+ return allocated() ? allocated_space() : inlined_space(); >+ } >+ >+ // InlinedVector::clear() >+ // >+ // Removes all elements from the inlined vector. >+ void clear() noexcept { >+ size_type s = size(); >+ if (allocated()) { >+ Destroy(allocated_space(), allocated_space() + s); >+ allocation().Dealloc(allocator()); >+ } else if (s != 0) { // do nothing for empty vectors >+ Destroy(inlined_space(), inlined_space() + s); >+ } >+ tag() = Tag(); >+ } >+ >+ // InlinedVector::at() >+ // >+ // Returns the ith element of an inlined vector. >+ const value_type& at(size_type i) const { >+ if (ABSL_PREDICT_FALSE(i >= size())) { >+ base_internal::ThrowStdOutOfRange( >+ "InlinedVector::at failed bounds check"); >+ } >+ return data()[i]; >+ } >+ >+ // InlinedVector::operator[] >+ // >+ // Returns the ith element of an inlined vector using the array operator. >+ const value_type& operator[](size_type i) const { >+ assert(i < size()); >+ return data()[i]; >+ } >+ >+ // Overload of InlinedVector::at() to return the ith element of an inlined >+ // vector. >+ value_type& at(size_type i) { >+ if (i >= size()) { >+ base_internal::ThrowStdOutOfRange( >+ "InlinedVector::at failed bounds check"); >+ } >+ return data()[i]; >+ } >+ >+ // Overload of InlinedVector::operator[] to return the ith element of an >+ // inlined vector. >+ value_type& operator[](size_type i) { >+ assert(i < size()); >+ return data()[i]; >+ } >+ >+ // InlinedVector::back() >+ // >+ // Returns a reference to the last element of an inlined vector. >+ value_type& back() { >+ assert(!empty()); >+ return at(size() - 1); >+ } >+ >+ // Overload of InlinedVector::back() returns a reference to the last element >+ // of an inlined vector of const values. >+ const value_type& back() const { >+ assert(!empty()); >+ return at(size() - 1); >+ } >+ >+ // InlinedVector::front() >+ // >+ // Returns a reference to the first element of an inlined vector. >+ value_type& front() { >+ assert(!empty()); >+ return at(0); >+ } >+ >+ // Overload of InlinedVector::front() returns a reference to the first element >+ // of an inlined vector of const values. >+ const value_type& front() const { >+ assert(!empty()); >+ return at(0); >+ } >+ >+ // InlinedVector::emplace_back() >+ // >+ // Constructs and appends an object to the inlined vector. >+ // >+ // Returns a reference to the inserted element. >+ template <typename... Args> >+ value_type& emplace_back(Args&&... args) { >+ size_type s = size(); >+ assert(s <= capacity()); >+ if (ABSL_PREDICT_FALSE(s == capacity())) { >+ return GrowAndEmplaceBack(std::forward<Args>(args)...); >+ } >+ assert(s < capacity()); >+ >+ value_type* space; >+ if (allocated()) { >+ tag().set_allocated_size(s + 1); >+ space = allocated_space(); >+ } else { >+ tag().set_inline_size(s + 1); >+ space = inlined_space(); >+ } >+ return Construct(space + s, std::forward<Args>(args)...); >+ } >+ >+ // InlinedVector::push_back() >+ // >+ // Appends a const element to the inlined vector. >+ void push_back(const value_type& t) { emplace_back(t); } >+ >+ // Overload of InlinedVector::push_back() to append a move-only element to the >+ // inlined vector. >+ void push_back(value_type&& t) { emplace_back(std::move(t)); } >+ >+ // InlinedVector::pop_back() >+ // >+ // Removes the last element (which is destroyed) in the inlined vector. >+ void pop_back() { >+ assert(!empty()); >+ size_type s = size(); >+ if (allocated()) { >+ Destroy(allocated_space() + s - 1, allocated_space() + s); >+ tag().set_allocated_size(s - 1); >+ } else { >+ Destroy(inlined_space() + s - 1, inlined_space() + s); >+ tag().set_inline_size(s - 1); >+ } >+ } >+ >+ // InlinedVector::resize() >+ // >+ // Resizes the inlined vector to contain `n` elements. If `n` is smaller than >+ // the inlined vector's current size, extra elements are destroyed. If `n` is >+ // larger than the initial size, new elements are value-initialized. >+ void resize(size_type n); >+ >+ // Overload of InlinedVector::resize() to resize the inlined vector to contain >+ // `n` elements. If `n` is larger than the current size, enough copies of >+ // `elem` are appended to increase its size to `n`. >+ void resize(size_type n, const value_type& elem); >+ >+ // InlinedVector::begin() >+ // >+ // Returns an iterator to the beginning of the inlined vector. >+ iterator begin() noexcept { return data(); } >+ >+ // Overload of InlinedVector::begin() for returning a const iterator to the >+ // beginning of the inlined vector. >+ const_iterator begin() const noexcept { return data(); } >+ >+ // InlinedVector::cbegin() >+ // >+ // Returns a const iterator to the beginning of the inlined vector. >+ const_iterator cbegin() const noexcept { return begin(); } >+ >+ // InlinedVector::end() >+ // >+ // Returns an iterator to the end of the inlined vector. >+ iterator end() noexcept { return data() + size(); } >+ >+ // Overload of InlinedVector::end() for returning a const iterator to the end >+ // of the inlined vector. >+ const_iterator end() const noexcept { return data() + size(); } >+ >+ // InlinedVector::cend() >+ // >+ // Returns a const iterator to the end of the inlined vector. >+ const_iterator cend() const noexcept { return end(); } >+ >+ // InlinedVector::rbegin() >+ // >+ // Returns a reverse iterator from the end of the inlined vector. >+ reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } >+ >+ // Overload of InlinedVector::rbegin() for returning a const reverse iterator >+ // from the end of the inlined vector. >+ const_reverse_iterator rbegin() const noexcept { >+ return const_reverse_iterator(end()); >+ } >+ >+ // InlinedVector::crbegin() >+ // >+ // Returns a const reverse iterator from the end of the inlined vector. >+ const_reverse_iterator crbegin() const noexcept { return rbegin(); } >+ >+ // InlinedVector::rend() >+ // >+ // Returns a reverse iterator from the beginning of the inlined vector. >+ reverse_iterator rend() noexcept { return reverse_iterator(begin()); } >+ >+ // Overload of InlinedVector::rend() for returning a const reverse iterator >+ // from the beginning of the inlined vector. >+ const_reverse_iterator rend() const noexcept { >+ return const_reverse_iterator(begin()); >+ } >+ >+ // InlinedVector::crend() >+ // >+ // Returns a reverse iterator from the beginning of the inlined vector. >+ const_reverse_iterator crend() const noexcept { return rend(); } >+ >+ // InlinedVector::emplace() >+ // >+ // Constructs and inserts an object to the inlined vector at the given >+ // `position`, returning an iterator pointing to the newly emplaced element. >+ template <typename... Args> >+ iterator emplace(const_iterator position, Args&&... args); >+ >+ // InlinedVector::insert() >+ // >+ // Inserts an element of the specified value at `position`, returning an >+ // iterator pointing to the newly inserted element. >+ iterator insert(const_iterator position, const value_type& v) { >+ return emplace(position, v); >+ } >+ >+ // Overload of InlinedVector::insert() for inserting an element of the >+ // specified rvalue, returning an iterator pointing to the newly inserted >+ // element. >+ iterator insert(const_iterator position, value_type&& v) { >+ return emplace(position, std::move(v)); >+ } >+ >+ // Overload of InlinedVector::insert() for inserting `n` elements of the >+ // specified value at `position`, returning an iterator pointing to the first >+ // of the newly inserted elements. >+ iterator insert(const_iterator position, size_type n, const value_type& v) { >+ return InsertWithCount(position, n, v); >+ } >+ >+ // Overload of `InlinedVector::insert()` to disambiguate the two >+ // three-argument overloads of `insert()`, returning an iterator pointing to >+ // the first of the newly inserted elements. >+ template <typename InputIterator, >+ typename = typename std::enable_if<std::is_convertible< >+ typename std::iterator_traits<InputIterator>::iterator_category, >+ std::input_iterator_tag>::value>::type> >+ iterator insert(const_iterator position, InputIterator first, >+ InputIterator last) { >+ using IterType = >+ typename std::iterator_traits<InputIterator>::iterator_category; >+ return InsertWithRange(position, first, last, IterType()); >+ } >+ >+ // Overload of InlinedVector::insert() for inserting a list of elements at >+ // `position`, returning an iterator pointing to the first of the newly >+ // inserted elements. >+ iterator insert(const_iterator position, >+ std::initializer_list<value_type> init) { >+ return insert(position, init.begin(), init.end()); >+ } >+ >+ // InlinedVector::erase() >+ // >+ // Erases the element at `position` of the inlined vector, returning an >+ // iterator pointing to the following element or the container's end if the >+ // last element was erased. >+ iterator erase(const_iterator position) { >+ assert(position >= begin()); >+ assert(position < end()); >+ >+ iterator pos = const_cast<iterator>(position); >+ std::move(pos + 1, end(), pos); >+ pop_back(); >+ return pos; >+ } >+ >+ // Overload of InlinedVector::erase() for erasing all elements in the >+ // iterator range [first, last) in the inlined vector, returning an iterator >+ // pointing to the first element following the range erased, or the >+ // container's end if range included the container's last element. >+ iterator erase(const_iterator first, const_iterator last); >+ >+ // InlinedVector::reserve() >+ // >+ // Enlarges the underlying representation of the inlined vector so it can hold >+ // at least `n` elements. This method does not change `size()` or the actual >+ // contents of the vector. >+ // >+ // Note that if `n` does not exceed the inlined vector's initial size `N`, >+ // `reserve()` will have no effect; if it does exceed its initial size, >+ // `reserve()` will trigger an initial allocation and move the inlined vector >+ // onto the heap. If the vector already exists on the heap and the requested >+ // size exceeds it, a reallocation will be performed. >+ void reserve(size_type n) { >+ if (n > capacity()) { >+ // Make room for new elements >+ EnlargeBy(n - size()); >+ } >+ } >+ >+ // InlinedVector::shrink_to_fit() >+ // >+ // Reduces memory usage by freeing unused memory. >+ // After this call `capacity()` will be equal to `max(N, size())`. >+ // >+ // If `size() <= N` and the elements are currently stored on the heap, they >+ // will be moved to the inlined storage and the heap memory deallocated. >+ // If `size() > N` and `size() < capacity()` the elements will be moved to >+ // a reallocated storage on heap. >+ void shrink_to_fit() { >+ const auto s = size(); >+ if (!allocated() || s == capacity()) { >+ // There's nothing to deallocate. >+ return; >+ } >+ >+ if (s <= N) { >+ // Move the elements to the inlined storage. >+ // We have to do this using a temporary, because inlined_storage and >+ // allocation_storage are in a union field. >+ auto temp = std::move(*this); >+ assign(std::make_move_iterator(temp.begin()), >+ std::make_move_iterator(temp.end())); >+ return; >+ } >+ >+ // Reallocate storage and move elements. >+ // We can't simply use the same approach as above, because assign() would >+ // call into reserve() internally and reserve larger capacity than we need. >+ Allocation new_allocation(allocator(), s); >+ UninitializedCopy(std::make_move_iterator(allocated_space()), >+ std::make_move_iterator(allocated_space() + s), >+ new_allocation.buffer()); >+ ResetAllocation(new_allocation, s); >+ } >+ >+ // InlinedVector::swap() >+ // >+ // Swaps the contents of this inlined vector with the contents of `other`. >+ void swap(InlinedVector& other); >+ >+ // InlinedVector::get_allocator() >+ // >+ // Returns the allocator of this inlined vector. >+ allocator_type get_allocator() const { return allocator(); } >+ >+ private: >+ static_assert(N > 0, "inlined vector with nonpositive size"); >+ >+ // It holds whether the vector is allocated or not in the lowest bit. >+ // The size is held in the high bits: >+ // size_ = (size << 1) | is_allocated; >+ // >+ // Maintainer's Note: size_type is user defined. The contract is limited to >+ // arithmetic operators to avoid depending on compliant overloaded bitwise >+ // operators. >+ class Tag { >+ public: >+ Tag() : size_(0) {} >+ size_type size() const { return size_ / 2; } >+ void add_size(size_type n) { size_ += n * 2; } >+ void set_inline_size(size_type n) { size_ = n * 2; } >+ void set_allocated_size(size_type n) { size_ = (n * 2) + 1; } >+ bool allocated() const { return size_ % 2; } >+ >+ private: >+ size_type size_; >+ }; >+ >+ // Derives from allocator_type to use the empty base class optimization. >+ // If the allocator_type is stateless, we can 'store' >+ // our instance of it for free. >+ class AllocatorAndTag : private allocator_type { >+ public: >+ explicit AllocatorAndTag(const allocator_type& a, Tag t = Tag()) >+ : allocator_type(a), tag_(t) {} >+ Tag& tag() { return tag_; } >+ const Tag& tag() const { return tag_; } >+ allocator_type& allocator() { return *this; } >+ const allocator_type& allocator() const { return *this; } >+ >+ private: >+ Tag tag_; >+ }; >+ >+ class Allocation { >+ public: >+ Allocation(allocator_type& a, // NOLINT(runtime/references) >+ size_type capacity) >+ : capacity_(capacity), >+ buffer_(AllocatorTraits::allocate(a, capacity_)) {} >+ >+ void Dealloc(allocator_type& a) { // NOLINT(runtime/references) >+ AllocatorTraits::deallocate(a, buffer(), capacity()); >+ } >+ >+ size_type capacity() const { return capacity_; } >+ const value_type* buffer() const { return buffer_; } >+ value_type* buffer() { return buffer_; } >+ >+ private: >+ size_type capacity_; >+ value_type* buffer_; >+ }; >+ >+ const Tag& tag() const { return allocator_and_tag_.tag(); } >+ Tag& tag() { return allocator_and_tag_.tag(); } >+ >+ Allocation& allocation() { >+ return reinterpret_cast<Allocation&>(rep_.allocation_storage.allocation); >+ } >+ const Allocation& allocation() const { >+ return reinterpret_cast<const Allocation&>( >+ rep_.allocation_storage.allocation); >+ } >+ void init_allocation(const Allocation& allocation) { >+ new (&rep_.allocation_storage.allocation) Allocation(allocation); >+ } >+ >+ // TODO(absl-team): investigate whether the reinterpret_cast is appropriate. >+ value_type* inlined_space() { >+ return reinterpret_cast<value_type*>( >+ std::addressof(rep_.inlined_storage.inlined[0])); >+ } >+ const value_type* inlined_space() const { >+ return reinterpret_cast<const value_type*>( >+ std::addressof(rep_.inlined_storage.inlined[0])); >+ } >+ >+ value_type* allocated_space() { return allocation().buffer(); } >+ const value_type* allocated_space() const { return allocation().buffer(); } >+ >+ const allocator_type& allocator() const { >+ return allocator_and_tag_.allocator(); >+ } >+ allocator_type& allocator() { return allocator_and_tag_.allocator(); } >+ >+ bool allocated() const { return tag().allocated(); } >+ >+ // Enlarge the underlying representation so we can store size_ + delta elems. >+ // The size is not changed, and any newly added memory is not initialized. >+ void EnlargeBy(size_type delta); >+ >+ // Shift all elements from position to end() n places to the right. >+ // If the vector needs to be enlarged, memory will be allocated. >+ // Returns iterators pointing to the start of the previously-initialized >+ // portion and the start of the uninitialized portion of the created gap. >+ // The number of initialized spots is pair.second - pair.first; >+ // the number of raw spots is n - (pair.second - pair.first). >+ // >+ // Updates the size of the InlinedVector internally. >+ std::pair<iterator, iterator> ShiftRight(const_iterator position, >+ size_type n); >+ >+ void ResetAllocation(Allocation new_allocation, size_type new_size) { >+ if (allocated()) { >+ Destroy(allocated_space(), allocated_space() + size()); >+ assert(begin() == allocated_space()); >+ allocation().Dealloc(allocator()); >+ allocation() = new_allocation; >+ } else { >+ Destroy(inlined_space(), inlined_space() + size()); >+ init_allocation(new_allocation); // bug: only init once >+ } >+ tag().set_allocated_size(new_size); >+ } >+ >+ template <typename... Args> >+ value_type& GrowAndEmplaceBack(Args&&... args) { >+ assert(size() == capacity()); >+ const size_type s = size(); >+ >+ Allocation new_allocation(allocator(), 2 * capacity()); >+ >+ value_type& new_element = >+ Construct(new_allocation.buffer() + s, std::forward<Args>(args)...); >+ UninitializedCopy(std::make_move_iterator(data()), >+ std::make_move_iterator(data() + s), >+ new_allocation.buffer()); >+ >+ ResetAllocation(new_allocation, s + 1); >+ >+ return new_element; >+ } >+ >+ void InitAssign(size_type n); >+ void InitAssign(size_type n, const value_type& t); >+ >+ template <typename... Args> >+ value_type& Construct(pointer p, Args&&... args) { >+ AllocatorTraits::construct(allocator(), p, std::forward<Args>(args)...); >+ return *p; >+ } >+ >+ template <typename Iter> >+ void UninitializedCopy(Iter src, Iter src_last, value_type* dst) { >+ for (; src != src_last; ++dst, ++src) Construct(dst, *src); >+ } >+ >+ template <typename... Args> >+ void UninitializedFill(value_type* dst, value_type* dst_last, >+ const Args&... args) { >+ for (; dst != dst_last; ++dst) Construct(dst, args...); >+ } >+ >+ // Destroy [ptr, ptr_last) in place. >+ void Destroy(value_type* ptr, value_type* ptr_last); >+ >+ template <typename Iter> >+ void AppendRange(Iter first, Iter last, std::input_iterator_tag) { >+ std::copy(first, last, std::back_inserter(*this)); >+ } >+ >+ // Faster path for forward iterators. >+ template <typename Iter> >+ void AppendRange(Iter first, Iter last, std::forward_iterator_tag); >+ >+ template <typename Iter> >+ void AppendRange(Iter first, Iter last) { >+ using IterTag = typename std::iterator_traits<Iter>::iterator_category; >+ AppendRange(first, last, IterTag()); >+ } >+ >+ template <typename Iter> >+ void AssignRange(Iter first, Iter last, std::input_iterator_tag); >+ >+ // Faster path for forward iterators. >+ template <typename Iter> >+ void AssignRange(Iter first, Iter last, std::forward_iterator_tag); >+ >+ template <typename Iter> >+ void AssignRange(Iter first, Iter last) { >+ using IterTag = typename std::iterator_traits<Iter>::iterator_category; >+ AssignRange(first, last, IterTag()); >+ } >+ >+ iterator InsertWithCount(const_iterator position, size_type n, >+ const value_type& v); >+ >+ template <typename InputIter> >+ iterator InsertWithRange(const_iterator position, InputIter first, >+ InputIter last, std::input_iterator_tag); >+ template <typename ForwardIter> >+ iterator InsertWithRange(const_iterator position, ForwardIter first, >+ ForwardIter last, std::forward_iterator_tag); >+ >+ AllocatorAndTag allocator_and_tag_; >+ >+ // Either the inlined or allocated representation >+ union Rep { >+ // Use struct to perform indirection that solves a bizarre compilation >+ // error on Visual Studio (all known versions). >+ struct { >+ typename std::aligned_storage<sizeof(value_type), >+ alignof(value_type)>::type inlined[N]; >+ } inlined_storage; >+ struct { >+ typename std::aligned_storage<sizeof(Allocation), >+ alignof(Allocation)>::type allocation; >+ } allocation_storage; >+ } rep_; >+}; >+ >+// ----------------------------------------------------------------------------- >+// InlinedVector Non-Member Functions >+// ----------------------------------------------------------------------------- >+ >+// swap() >+// >+// Swaps the contents of two inlined vectors. This convenience function >+// simply calls InlinedVector::swap(other_inlined_vector). >+template <typename T, size_t N, typename A> >+void swap(InlinedVector<T, N, A>& a, >+ InlinedVector<T, N, A>& b) noexcept(noexcept(a.swap(b))) { >+ a.swap(b); >+} >+ >+// operator==() >+// >+// Tests the equivalency of the contents of two inlined vectors. >+template <typename T, size_t N, typename A> >+bool operator==(const InlinedVector<T, N, A>& a, >+ const InlinedVector<T, N, A>& b) { >+ return absl::equal(a.begin(), a.end(), b.begin(), b.end()); >+} >+ >+// operator!=() >+// >+// Tests the inequality of the contents of two inlined vectors. >+template <typename T, size_t N, typename A> >+bool operator!=(const InlinedVector<T, N, A>& a, >+ const InlinedVector<T, N, A>& b) { >+ return !(a == b); >+} >+ >+// operator<() >+// >+// Tests whether the contents of one inlined vector are less than the contents >+// of another through a lexicographical comparison operation. >+template <typename T, size_t N, typename A> >+bool operator<(const InlinedVector<T, N, A>& a, >+ const InlinedVector<T, N, A>& b) { >+ return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); >+} >+ >+// operator>() >+// >+// Tests whether the contents of one inlined vector are greater than the >+// contents of another through a lexicographical comparison operation. >+template <typename T, size_t N, typename A> >+bool operator>(const InlinedVector<T, N, A>& a, >+ const InlinedVector<T, N, A>& b) { >+ return b < a; >+} >+ >+// operator<=() >+// >+// Tests whether the contents of one inlined vector are less than or equal to >+// the contents of another through a lexicographical comparison operation. >+template <typename T, size_t N, typename A> >+bool operator<=(const InlinedVector<T, N, A>& a, >+ const InlinedVector<T, N, A>& b) { >+ return !(b < a); >+} >+ >+// operator>=() >+// >+// Tests whether the contents of one inlined vector are greater than or equal to >+// the contents of another through a lexicographical comparison operation. >+template <typename T, size_t N, typename A> >+bool operator>=(const InlinedVector<T, N, A>& a, >+ const InlinedVector<T, N, A>& b) { >+ return !(a < b); >+} >+ >+// ----------------------------------------------------------------------------- >+// Implementation of InlinedVector >+// ----------------------------------------------------------------------------- >+// >+// Do not depend on any implementation details below this line. >+ >+template <typename T, size_t N, typename A> >+InlinedVector<T, N, A>::InlinedVector(const InlinedVector& v) >+ : allocator_and_tag_(v.allocator()) { >+ reserve(v.size()); >+ if (allocated()) { >+ UninitializedCopy(v.begin(), v.end(), allocated_space()); >+ tag().set_allocated_size(v.size()); >+ } else { >+ UninitializedCopy(v.begin(), v.end(), inlined_space()); >+ tag().set_inline_size(v.size()); >+ } >+} >+ >+template <typename T, size_t N, typename A> >+InlinedVector<T, N, A>::InlinedVector(const InlinedVector& v, >+ const allocator_type& alloc) >+ : allocator_and_tag_(alloc) { >+ reserve(v.size()); >+ if (allocated()) { >+ UninitializedCopy(v.begin(), v.end(), allocated_space()); >+ tag().set_allocated_size(v.size()); >+ } else { >+ UninitializedCopy(v.begin(), v.end(), inlined_space()); >+ tag().set_inline_size(v.size()); >+ } >+} >+ >+template <typename T, size_t N, typename A> >+InlinedVector<T, N, A>::InlinedVector(InlinedVector&& v) noexcept( >+ absl::allocator_is_nothrow<allocator_type>::value || >+ std::is_nothrow_move_constructible<value_type>::value) >+ : allocator_and_tag_(v.allocator_and_tag_) { >+ if (v.allocated()) { >+ // We can just steal the underlying buffer from the source. >+ // That leaves the source empty, so we clear its size. >+ init_allocation(v.allocation()); >+ v.tag() = Tag(); >+ } else { >+ UninitializedCopy(std::make_move_iterator(v.inlined_space()), >+ std::make_move_iterator(v.inlined_space() + v.size()), >+ inlined_space()); >+ } >+} >+ >+template <typename T, size_t N, typename A> >+InlinedVector<T, N, A>::InlinedVector( >+ InlinedVector&& v, >+ const allocator_type& >+ alloc) noexcept(absl::allocator_is_nothrow<allocator_type>::value) >+ : allocator_and_tag_(alloc) { >+ if (v.allocated()) { >+ if (alloc == v.allocator()) { >+ // We can just steal the allocation from the source. >+ tag() = v.tag(); >+ init_allocation(v.allocation()); >+ v.tag() = Tag(); >+ } else { >+ // We need to use our own allocator >+ reserve(v.size()); >+ UninitializedCopy(std::make_move_iterator(v.begin()), >+ std::make_move_iterator(v.end()), allocated_space()); >+ tag().set_allocated_size(v.size()); >+ } >+ } else { >+ UninitializedCopy(std::make_move_iterator(v.inlined_space()), >+ std::make_move_iterator(v.inlined_space() + v.size()), >+ inlined_space()); >+ tag().set_inline_size(v.size()); >+ } >+} >+ >+template <typename T, size_t N, typename A> >+void InlinedVector<T, N, A>::InitAssign(size_type n, const value_type& t) { >+ if (n > static_cast<size_type>(N)) { >+ Allocation new_allocation(allocator(), n); >+ init_allocation(new_allocation); >+ UninitializedFill(allocated_space(), allocated_space() + n, t); >+ tag().set_allocated_size(n); >+ } else { >+ UninitializedFill(inlined_space(), inlined_space() + n, t); >+ tag().set_inline_size(n); >+ } >+} >+ >+template <typename T, size_t N, typename A> >+void InlinedVector<T, N, A>::InitAssign(size_type n) { >+ if (n > static_cast<size_type>(N)) { >+ Allocation new_allocation(allocator(), n); >+ init_allocation(new_allocation); >+ UninitializedFill(allocated_space(), allocated_space() + n); >+ tag().set_allocated_size(n); >+ } else { >+ UninitializedFill(inlined_space(), inlined_space() + n); >+ tag().set_inline_size(n); >+ } >+} >+ >+template <typename T, size_t N, typename A> >+void InlinedVector<T, N, A>::resize(size_type n) { >+ size_type s = size(); >+ if (n < s) { >+ erase(begin() + n, end()); >+ return; >+ } >+ reserve(n); >+ assert(capacity() >= n); >+ >+ // Fill new space with elements constructed in-place. >+ if (allocated()) { >+ UninitializedFill(allocated_space() + s, allocated_space() + n); >+ tag().set_allocated_size(n); >+ } else { >+ UninitializedFill(inlined_space() + s, inlined_space() + n); >+ tag().set_inline_size(n); >+ } >+} >+ >+template <typename T, size_t N, typename A> >+void InlinedVector<T, N, A>::resize(size_type n, const value_type& elem) { >+ size_type s = size(); >+ if (n < s) { >+ erase(begin() + n, end()); >+ return; >+ } >+ reserve(n); >+ assert(capacity() >= n); >+ >+ // Fill new space with copies of 'elem'. >+ if (allocated()) { >+ UninitializedFill(allocated_space() + s, allocated_space() + n, elem); >+ tag().set_allocated_size(n); >+ } else { >+ UninitializedFill(inlined_space() + s, inlined_space() + n, elem); >+ tag().set_inline_size(n); >+ } >+} >+ >+template <typename T, size_t N, typename A> >+template <typename... Args> >+typename InlinedVector<T, N, A>::iterator InlinedVector<T, N, A>::emplace( >+ const_iterator position, Args&&... args) { >+ assert(position >= begin()); >+ assert(position <= end()); >+ if (position == end()) { >+ emplace_back(std::forward<Args>(args)...); >+ return end() - 1; >+ } >+ >+ T new_t = T(std::forward<Args>(args)...); >+ >+ auto range = ShiftRight(position, 1); >+ if (range.first == range.second) { >+ // constructing into uninitialized memory >+ Construct(range.first, std::move(new_t)); >+ } else { >+ // assigning into moved-from object >+ *range.first = T(std::move(new_t)); >+ } >+ >+ return range.first; >+} >+ >+template <typename T, size_t N, typename A> >+typename InlinedVector<T, N, A>::iterator InlinedVector<T, N, A>::erase( >+ const_iterator first, const_iterator last) { >+ assert(begin() <= first); >+ assert(first <= last); >+ assert(last <= end()); >+ >+ iterator range_start = const_cast<iterator>(first); >+ iterator range_end = const_cast<iterator>(last); >+ >+ size_type s = size(); >+ ptrdiff_t erase_gap = std::distance(range_start, range_end); >+ if (erase_gap > 0) { >+ pointer space; >+ if (allocated()) { >+ space = allocated_space(); >+ tag().set_allocated_size(s - erase_gap); >+ } else { >+ space = inlined_space(); >+ tag().set_inline_size(s - erase_gap); >+ } >+ std::move(range_end, space + s, range_start); >+ Destroy(space + s - erase_gap, space + s); >+ } >+ return range_start; >+} >+ >+template <typename T, size_t N, typename A> >+void InlinedVector<T, N, A>::swap(InlinedVector& other) { >+ using std::swap; // Augment ADL with std::swap. >+ if (&other == this) { >+ return; >+ } >+ if (allocated() && other.allocated()) { >+ // Both out of line, so just swap the tag, allocation, and allocator. >+ swap(tag(), other.tag()); >+ swap(allocation(), other.allocation()); >+ swap(allocator(), other.allocator()); >+ return; >+ } >+ if (!allocated() && !other.allocated()) { >+ // Both inlined: swap up to smaller size, then move remaining elements. >+ InlinedVector* a = this; >+ InlinedVector* b = &other; >+ if (size() < other.size()) { >+ swap(a, b); >+ } >+ >+ const size_type a_size = a->size(); >+ const size_type b_size = b->size(); >+ assert(a_size >= b_size); >+ // 'a' is larger. Swap the elements up to the smaller array size. >+ std::swap_ranges(a->inlined_space(), a->inlined_space() + b_size, >+ b->inlined_space()); >+ >+ // Move the remaining elements: A[b_size,a_size) -> B[b_size,a_size) >+ b->UninitializedCopy(a->inlined_space() + b_size, >+ a->inlined_space() + a_size, >+ b->inlined_space() + b_size); >+ a->Destroy(a->inlined_space() + b_size, a->inlined_space() + a_size); >+ >+ swap(a->tag(), b->tag()); >+ swap(a->allocator(), b->allocator()); >+ assert(b->size() == a_size); >+ assert(a->size() == b_size); >+ return; >+ } >+ // One is out of line, one is inline. >+ // We first move the elements from the inlined vector into the >+ // inlined space in the other vector. We then put the other vector's >+ // pointer/capacity into the originally inlined vector and swap >+ // the tags. >+ InlinedVector* a = this; >+ InlinedVector* b = &other; >+ if (a->allocated()) { >+ swap(a, b); >+ } >+ assert(!a->allocated()); >+ assert(b->allocated()); >+ const size_type a_size = a->size(); >+ const size_type b_size = b->size(); >+ // In an optimized build, b_size would be unused. >+ (void)b_size; >+ >+ // Made Local copies of size(), don't need tag() accurate anymore >+ swap(a->tag(), b->tag()); >+ >+ // Copy b_allocation out before b's union gets clobbered by inline_space. >+ Allocation b_allocation = b->allocation(); >+ >+ b->UninitializedCopy(a->inlined_space(), a->inlined_space() + a_size, >+ b->inlined_space()); >+ a->Destroy(a->inlined_space(), a->inlined_space() + a_size); >+ >+ a->allocation() = b_allocation; >+ >+ if (a->allocator() != b->allocator()) { >+ swap(a->allocator(), b->allocator()); >+ } >+ >+ assert(b->size() == a_size); >+ assert(a->size() == b_size); >+} >+ >+template <typename T, size_t N, typename A> >+void InlinedVector<T, N, A>::EnlargeBy(size_type delta) { >+ const size_type s = size(); >+ assert(s <= capacity()); >+ >+ size_type target = std::max(static_cast<size_type>(N), s + delta); >+ >+ // Compute new capacity by repeatedly doubling current capacity >+ // TODO(psrc): Check and avoid overflow? >+ size_type new_capacity = capacity(); >+ while (new_capacity < target) { >+ new_capacity <<= 1; >+ } >+ >+ Allocation new_allocation(allocator(), new_capacity); >+ >+ UninitializedCopy(std::make_move_iterator(data()), >+ std::make_move_iterator(data() + s), >+ new_allocation.buffer()); >+ >+ ResetAllocation(new_allocation, s); >+} >+ >+template <typename T, size_t N, typename A> >+auto InlinedVector<T, N, A>::ShiftRight(const_iterator position, size_type n) >+ -> std::pair<iterator, iterator> { >+ iterator start_used = const_cast<iterator>(position); >+ iterator start_raw = const_cast<iterator>(position); >+ size_type s = size(); >+ size_type required_size = s + n; >+ >+ if (required_size > capacity()) { >+ // Compute new capacity by repeatedly doubling current capacity >+ size_type new_capacity = capacity(); >+ while (new_capacity < required_size) { >+ new_capacity <<= 1; >+ } >+ // Move everyone into the new allocation, leaving a gap of n for the >+ // requested shift. >+ Allocation new_allocation(allocator(), new_capacity); >+ size_type index = position - begin(); >+ UninitializedCopy(std::make_move_iterator(data()), >+ std::make_move_iterator(data() + index), >+ new_allocation.buffer()); >+ UninitializedCopy(std::make_move_iterator(data() + index), >+ std::make_move_iterator(data() + s), >+ new_allocation.buffer() + index + n); >+ ResetAllocation(new_allocation, s); >+ >+ // New allocation means our iterator is invalid, so we'll recalculate. >+ // Since the entire gap is in new space, there's no used space to reuse. >+ start_raw = begin() + index; >+ start_used = start_raw; >+ } else { >+ // If we had enough space, it's a two-part move. Elements going into >+ // previously-unoccupied space need an UninitializedCopy. Elements >+ // going into a previously-occupied space are just a move. >+ iterator pos = const_cast<iterator>(position); >+ iterator raw_space = end(); >+ size_type slots_in_used_space = raw_space - pos; >+ size_type new_elements_in_used_space = std::min(n, slots_in_used_space); >+ size_type new_elements_in_raw_space = n - new_elements_in_used_space; >+ size_type old_elements_in_used_space = >+ slots_in_used_space - new_elements_in_used_space; >+ >+ UninitializedCopy(std::make_move_iterator(pos + old_elements_in_used_space), >+ std::make_move_iterator(raw_space), >+ raw_space + new_elements_in_raw_space); >+ std::move_backward(pos, pos + old_elements_in_used_space, raw_space); >+ >+ // If the gap is entirely in raw space, the used space starts where the raw >+ // space starts, leaving no elements in used space. If the gap is entirely >+ // in used space, the raw space starts at the end of the gap, leaving all >+ // elements accounted for within the used space. >+ start_used = pos; >+ start_raw = pos + new_elements_in_used_space; >+ } >+ tag().add_size(n); >+ return std::make_pair(start_used, start_raw); >+} >+ >+template <typename T, size_t N, typename A> >+void InlinedVector<T, N, A>::Destroy(value_type* ptr, value_type* ptr_last) { >+ for (value_type* p = ptr; p != ptr_last; ++p) { >+ AllocatorTraits::destroy(allocator(), p); >+ } >+ >+ // Overwrite unused memory with 0xab so we can catch uninitialized usage. >+ // Cast to void* to tell the compiler that we don't care that we might be >+ // scribbling on a vtable pointer. >+#ifndef NDEBUG >+ if (ptr != ptr_last) { >+ memset(reinterpret_cast<void*>(ptr), 0xab, sizeof(*ptr) * (ptr_last - ptr)); >+ } >+#endif >+} >+ >+template <typename T, size_t N, typename A> >+template <typename Iter> >+void InlinedVector<T, N, A>::AppendRange(Iter first, Iter last, >+ std::forward_iterator_tag) { >+ using Length = typename std::iterator_traits<Iter>::difference_type; >+ Length length = std::distance(first, last); >+ reserve(size() + length); >+ if (allocated()) { >+ UninitializedCopy(first, last, allocated_space() + size()); >+ tag().set_allocated_size(size() + length); >+ } else { >+ UninitializedCopy(first, last, inlined_space() + size()); >+ tag().set_inline_size(size() + length); >+ } >+} >+ >+template <typename T, size_t N, typename A> >+template <typename Iter> >+void InlinedVector<T, N, A>::AssignRange(Iter first, Iter last, >+ std::input_iterator_tag) { >+ // Optimized to avoid reallocation. >+ // Prefer reassignment to copy construction for elements. >+ iterator out = begin(); >+ for (; first != last && out != end(); ++first, ++out) { >+ *out = *first; >+ } >+ erase(out, end()); >+ std::copy(first, last, std::back_inserter(*this)); >+} >+ >+template <typename T, size_t N, typename A> >+template <typename Iter> >+void InlinedVector<T, N, A>::AssignRange(Iter first, Iter last, >+ std::forward_iterator_tag) { >+ using Length = typename std::iterator_traits<Iter>::difference_type; >+ Length length = std::distance(first, last); >+ // Prefer reassignment to copy construction for elements. >+ if (static_cast<size_type>(length) <= size()) { >+ erase(std::copy(first, last, begin()), end()); >+ return; >+ } >+ reserve(length); >+ iterator out = begin(); >+ for (; out != end(); ++first, ++out) *out = *first; >+ if (allocated()) { >+ UninitializedCopy(first, last, out); >+ tag().set_allocated_size(length); >+ } else { >+ UninitializedCopy(first, last, out); >+ tag().set_inline_size(length); >+ } >+} >+ >+template <typename T, size_t N, typename A> >+auto InlinedVector<T, N, A>::InsertWithCount(const_iterator position, >+ size_type n, const value_type& v) >+ -> iterator { >+ assert(position >= begin() && position <= end()); >+ if (n == 0) return const_cast<iterator>(position); >+ >+ value_type copy = v; >+ std::pair<iterator, iterator> it_pair = ShiftRight(position, n); >+ std::fill(it_pair.first, it_pair.second, copy); >+ UninitializedFill(it_pair.second, it_pair.first + n, copy); >+ >+ return it_pair.first; >+} >+ >+template <typename T, size_t N, typename A> >+template <typename InputIter> >+auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position, >+ InputIter first, InputIter last, >+ std::input_iterator_tag) >+ -> iterator { >+ assert(position >= begin() && position <= end()); >+ size_type index = position - cbegin(); >+ size_type i = index; >+ while (first != last) insert(begin() + i++, *first++); >+ return begin() + index; >+} >+ >+// Overload of InlinedVector::InsertWithRange() >+template <typename T, size_t N, typename A> >+template <typename ForwardIter> >+auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position, >+ ForwardIter first, >+ ForwardIter last, >+ std::forward_iterator_tag) >+ -> iterator { >+ assert(position >= begin() && position <= end()); >+ if (first == last) { >+ return const_cast<iterator>(position); >+ } >+ using Length = typename std::iterator_traits<ForwardIter>::difference_type; >+ Length n = std::distance(first, last); >+ std::pair<iterator, iterator> it_pair = ShiftRight(position, n); >+ size_type used_spots = it_pair.second - it_pair.first; >+ ForwardIter open_spot = std::next(first, used_spots); >+ std::copy(first, open_spot, it_pair.first); >+ UninitializedCopy(open_spot, last, it_pair.second); >+ return it_pair.first; >+} >+ >+} // namespace absl >+ >+#endif // ABSL_CONTAINER_INLINED_VECTOR_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..24f2174928a38b01fef99ae27cb89e4198265ab3 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc >@@ -0,0 +1,385 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/container/inlined_vector.h" >+ >+#include <string> >+#include <vector> >+ >+#include "benchmark/benchmark.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/strings/str_cat.h" >+ >+namespace { >+ >+using IntVec = absl::InlinedVector<int, 8>; >+ >+void BM_InlinedVectorFill(benchmark::State& state) { >+ const int len = state.range(0); >+ for (auto _ : state) { >+ IntVec v; >+ for (int i = 0; i < len; i++) { >+ v.push_back(i); >+ } >+ } >+ state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len); >+} >+BENCHMARK(BM_InlinedVectorFill)->Range(0, 1024); >+ >+void BM_InlinedVectorFillRange(benchmark::State& state) { >+ const int len = state.range(0); >+ std::unique_ptr<int[]> ia(new int[len]); >+ for (int i = 0; i < len; i++) { >+ ia[i] = i; >+ } >+ for (auto _ : state) { >+ IntVec v(ia.get(), ia.get() + len); >+ benchmark::DoNotOptimize(v); >+ } >+ state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len); >+} >+BENCHMARK(BM_InlinedVectorFillRange)->Range(0, 1024); >+ >+void BM_StdVectorFill(benchmark::State& state) { >+ const int len = state.range(0); >+ for (auto _ : state) { >+ std::vector<int> v; >+ for (int i = 0; i < len; i++) { >+ v.push_back(i); >+ } >+ } >+ state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len); >+} >+BENCHMARK(BM_StdVectorFill)->Range(0, 1024); >+ >+// The purpose of the next two benchmarks is to verify that >+// absl::InlinedVector is efficient when moving is more efficent than >+// copying. To do so, we use strings that are larger than the short >+// std::string optimization. >+bool StringRepresentedInline(std::string s) { >+ const char* chars = s.data(); >+ std::string s1 = std::move(s); >+ return s1.data() != chars; >+} >+ >+int GetNonShortStringOptimizationSize() { >+ for (int i = 24; i <= 192; i *= 2) { >+ if (!StringRepresentedInline(std::string(i, 'A'))) { >+ return i; >+ } >+ } >+ ABSL_RAW_LOG( >+ FATAL, >+ "Failed to find a std::string larger than the short std::string optimization"); >+ return -1; >+} >+ >+void BM_InlinedVectorFillString(benchmark::State& state) { >+ const int len = state.range(0); >+ const int no_sso = GetNonShortStringOptimizationSize(); >+ std::string strings[4] = {std::string(no_sso, 'A'), std::string(no_sso, 'B'), >+ std::string(no_sso, 'C'), std::string(no_sso, 'D')}; >+ >+ for (auto _ : state) { >+ absl::InlinedVector<std::string, 8> v; >+ for (int i = 0; i < len; i++) { >+ v.push_back(strings[i & 3]); >+ } >+ } >+ state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len); >+} >+BENCHMARK(BM_InlinedVectorFillString)->Range(0, 1024); >+ >+void BM_StdVectorFillString(benchmark::State& state) { >+ const int len = state.range(0); >+ const int no_sso = GetNonShortStringOptimizationSize(); >+ std::string strings[4] = {std::string(no_sso, 'A'), std::string(no_sso, 'B'), >+ std::string(no_sso, 'C'), std::string(no_sso, 'D')}; >+ >+ for (auto _ : state) { >+ std::vector<std::string> v; >+ for (int i = 0; i < len; i++) { >+ v.push_back(strings[i & 3]); >+ } >+ } >+ state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len); >+} >+BENCHMARK(BM_StdVectorFillString)->Range(0, 1024); >+ >+struct Buffer { // some arbitrary structure for benchmarking. >+ char* base; >+ int length; >+ int capacity; >+ void* user_data; >+}; >+ >+void BM_InlinedVectorTenAssignments(benchmark::State& state) { >+ const int len = state.range(0); >+ using BufferVec = absl::InlinedVector<Buffer, 2>; >+ >+ BufferVec src; >+ src.resize(len); >+ >+ BufferVec dst; >+ for (auto _ : state) { >+ for (int i = 0; i < 10; ++i) { >+ dst = src; >+ } >+ } >+} >+BENCHMARK(BM_InlinedVectorTenAssignments) >+ ->Arg(0)->Arg(1)->Arg(2)->Arg(3)->Arg(4)->Arg(20); >+ >+void BM_CreateFromContainer(benchmark::State& state) { >+ for (auto _ : state) { >+ absl::InlinedVector<int, 4> x(absl::InlinedVector<int, 4>{1, 2, 3}); >+ benchmark::DoNotOptimize(x); >+ } >+} >+BENCHMARK(BM_CreateFromContainer); >+ >+struct LargeCopyableOnly { >+ LargeCopyableOnly() : d(1024, 17) {} >+ LargeCopyableOnly(const LargeCopyableOnly& o) = default; >+ LargeCopyableOnly& operator=(const LargeCopyableOnly& o) = default; >+ >+ std::vector<int> d; >+}; >+ >+struct LargeCopyableSwappable { >+ LargeCopyableSwappable() : d(1024, 17) {} >+ LargeCopyableSwappable(const LargeCopyableSwappable& o) = default; >+ LargeCopyableSwappable(LargeCopyableSwappable&& o) = delete; >+ >+ LargeCopyableSwappable& operator=(LargeCopyableSwappable o) { >+ using std::swap; >+ swap(*this, o); >+ return *this; >+ } >+ LargeCopyableSwappable& operator=(LargeCopyableSwappable&& o) = delete; >+ >+ friend void swap(LargeCopyableSwappable& a, LargeCopyableSwappable& b) { >+ using std::swap; >+ swap(a.d, b.d); >+ } >+ >+ std::vector<int> d; >+}; >+ >+struct LargeCopyableMovable { >+ LargeCopyableMovable() : d(1024, 17) {} >+ // Use implicitly defined copy and move. >+ >+ std::vector<int> d; >+}; >+ >+struct LargeCopyableMovableSwappable { >+ LargeCopyableMovableSwappable() : d(1024, 17) {} >+ LargeCopyableMovableSwappable(const LargeCopyableMovableSwappable& o) = >+ default; >+ LargeCopyableMovableSwappable(LargeCopyableMovableSwappable&& o) = default; >+ >+ LargeCopyableMovableSwappable& operator=(LargeCopyableMovableSwappable o) { >+ using std::swap; >+ swap(*this, o); >+ return *this; >+ } >+ LargeCopyableMovableSwappable& operator=(LargeCopyableMovableSwappable&& o) = >+ default; >+ >+ friend void swap(LargeCopyableMovableSwappable& a, >+ LargeCopyableMovableSwappable& b) { >+ using std::swap; >+ swap(a.d, b.d); >+ } >+ >+ std::vector<int> d; >+}; >+ >+template <typename ElementType> >+void BM_SwapElements(benchmark::State& state) { >+ const int len = state.range(0); >+ using Vec = absl::InlinedVector<ElementType, 32>; >+ Vec a(len); >+ Vec b; >+ for (auto _ : state) { >+ using std::swap; >+ swap(a, b); >+ } >+} >+BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableOnly)->Range(0, 1024); >+BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableSwappable)->Range(0, 1024); >+BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableMovable)->Range(0, 1024); >+BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableMovableSwappable) >+ ->Range(0, 1024); >+ >+// The following benchmark is meant to track the efficiency of the vector size >+// as a function of stored type via the benchmark label. It is not meant to >+// output useful sizeof operator performance. The loop is a dummy operation >+// to fulfill the requirement of running the benchmark. >+template <typename VecType> >+void BM_Sizeof(benchmark::State& state) { >+ int size = 0; >+ for (auto _ : state) { >+ VecType vec; >+ size = sizeof(vec); >+ } >+ state.SetLabel(absl::StrCat("sz=", size)); >+} >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<char, 1>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<char, 4>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<char, 7>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<char, 8>); >+ >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<int, 1>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<int, 4>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<int, 7>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<int, 8>); >+ >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<void*, 1>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<void*, 4>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<void*, 7>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<void*, 8>); >+ >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<std::string, 1>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<std::string, 4>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<std::string, 7>); >+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<std::string, 8>); >+ >+void BM_InlinedVectorIndexInlined(benchmark::State& state) { >+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7}; >+ for (auto _ : state) { >+ for (int i = 0; i < 1000; ++i) { >+ benchmark::DoNotOptimize(v); >+ benchmark::DoNotOptimize(v[4]); >+ } >+ } >+ state.SetItemsProcessed(1000 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_InlinedVectorIndexInlined); >+ >+void BM_InlinedVectorIndexExternal(benchmark::State& state) { >+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; >+ for (auto _ : state) { >+ for (int i = 0; i < 1000; ++i) { >+ benchmark::DoNotOptimize(v); >+ benchmark::DoNotOptimize(v[4]); >+ } >+ } >+ state.SetItemsProcessed(1000 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_InlinedVectorIndexExternal); >+ >+void BM_StdVectorIndex(benchmark::State& state) { >+ std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; >+ for (auto _ : state) { >+ for (int i = 0; i < 1000; ++i) { >+ benchmark::DoNotOptimize(v); >+ benchmark::DoNotOptimize(v[4]); >+ } >+ } >+ state.SetItemsProcessed(1000 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_StdVectorIndex); >+ >+#define UNROLL_2(x) \ >+ benchmark::DoNotOptimize(x); \ >+ benchmark::DoNotOptimize(x); >+ >+#define UNROLL_4(x) UNROLL_2(x) UNROLL_2(x) >+#define UNROLL_8(x) UNROLL_4(x) UNROLL_4(x) >+#define UNROLL_16(x) UNROLL_8(x) UNROLL_8(x); >+ >+void BM_InlinedVectorDataInlined(benchmark::State& state) { >+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7}; >+ for (auto _ : state) { >+ UNROLL_16(v.data()); >+ } >+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_InlinedVectorDataInlined); >+ >+void BM_InlinedVectorDataExternal(benchmark::State& state) { >+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; >+ for (auto _ : state) { >+ UNROLL_16(v.data()); >+ } >+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_InlinedVectorDataExternal); >+ >+void BM_StdVectorData(benchmark::State& state) { >+ std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; >+ for (auto _ : state) { >+ UNROLL_16(v.data()); >+ } >+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_StdVectorData); >+ >+void BM_InlinedVectorSizeInlined(benchmark::State& state) { >+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7}; >+ for (auto _ : state) { >+ UNROLL_16(v.size()); >+ } >+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_InlinedVectorSizeInlined); >+ >+void BM_InlinedVectorSizeExternal(benchmark::State& state) { >+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; >+ for (auto _ : state) { >+ UNROLL_16(v.size()); >+ } >+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_InlinedVectorSizeExternal); >+ >+void BM_StdVectorSize(benchmark::State& state) { >+ std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; >+ for (auto _ : state) { >+ UNROLL_16(v.size()); >+ } >+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_StdVectorSize); >+ >+void BM_InlinedVectorEmptyInlined(benchmark::State& state) { >+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7}; >+ for (auto _ : state) { >+ UNROLL_16(v.empty()); >+ } >+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_InlinedVectorEmptyInlined); >+ >+void BM_InlinedVectorEmptyExternal(benchmark::State& state) { >+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; >+ for (auto _ : state) { >+ UNROLL_16(v.empty()); >+ } >+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_InlinedVectorEmptyExternal); >+ >+void BM_StdVectorEmpty(benchmark::State& state) { >+ std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; >+ for (auto _ : state) { >+ UNROLL_16(v.empty()); >+ } >+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations())); >+} >+BENCHMARK(BM_StdVectorEmpty); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/inlined_vector_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/inlined_vector_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..196a1bed976c4bbd060a0c81a30819aced4669b2 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/inlined_vector_test.cc >@@ -0,0 +1,1791 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/container/inlined_vector.h" >+ >+#include <algorithm> >+#include <forward_list> >+#include <list> >+#include <memory> >+#include <scoped_allocator> >+#include <sstream> >+#include <stdexcept> >+#include <string> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/attributes.h" >+#include "absl/base/internal/exception_testing.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/macros.h" >+#include "absl/container/internal/test_instance_tracker.h" >+#include "absl/memory/memory.h" >+#include "absl/strings/str_cat.h" >+ >+namespace { >+ >+using absl::test_internal::CopyableMovableInstance; >+using absl::test_internal::CopyableOnlyInstance; >+using absl::test_internal::InstanceTracker; >+using testing::AllOf; >+using testing::Each; >+using testing::ElementsAre; >+using testing::ElementsAreArray; >+using testing::Eq; >+using testing::Gt; >+using testing::PrintToString; >+ >+using IntVec = absl::InlinedVector<int, 8>; >+ >+MATCHER_P(SizeIs, n, "") { >+ return testing::ExplainMatchResult(n, arg.size(), result_listener); >+} >+ >+MATCHER_P(CapacityIs, n, "") { >+ return testing::ExplainMatchResult(n, arg.capacity(), result_listener); >+} >+ >+MATCHER_P(ValueIs, e, "") { >+ return testing::ExplainMatchResult(e, arg.value(), result_listener); >+} >+ >+// TODO(bsamwel): Add support for movable-only types. >+ >+// Test fixture for typed tests on BaseCountedInstance derived classes, see >+// test_instance_tracker.h. >+template <typename T> >+class InstanceTest : public ::testing::Test {}; >+TYPED_TEST_CASE_P(InstanceTest); >+ >+// A simple reference counted class to make sure that the proper elements are >+// destroyed in the erase(begin, end) test. >+class RefCounted { >+ public: >+ RefCounted(int value, int* count) : value_(value), count_(count) { >+ Ref(); >+ } >+ >+ RefCounted(const RefCounted& v) >+ : value_(v.value_), count_(v.count_) { >+ Ref(); >+ } >+ >+ ~RefCounted() { >+ Unref(); >+ count_ = nullptr; >+ } >+ >+ friend void swap(RefCounted& a, RefCounted& b) { >+ using std::swap; >+ swap(a.value_, b.value_); >+ swap(a.count_, b.count_); >+ } >+ >+ RefCounted& operator=(RefCounted v) { >+ using std::swap; >+ swap(*this, v); >+ return *this; >+ } >+ >+ void Ref() const { >+ ABSL_RAW_CHECK(count_ != nullptr, ""); >+ ++(*count_); >+ } >+ >+ void Unref() const { >+ --(*count_); >+ ABSL_RAW_CHECK(*count_ >= 0, ""); >+ } >+ >+ int value_; >+ int* count_; >+}; >+ >+using RefCountedVec = absl::InlinedVector<RefCounted, 8>; >+ >+// A class with a vtable pointer >+class Dynamic { >+ public: >+ virtual ~Dynamic() {} >+}; >+ >+using DynamicVec = absl::InlinedVector<Dynamic, 8>; >+ >+// Append 0..len-1 to *v >+template <typename Container> >+static void Fill(Container* v, int len, int offset = 0) { >+ for (int i = 0; i < len; i++) { >+ v->push_back(i + offset); >+ } >+} >+ >+static IntVec Fill(int len, int offset = 0) { >+ IntVec v; >+ Fill(&v, len, offset); >+ return v; >+} >+ >+// This is a stateful allocator, but the state lives outside of the >+// allocator (in whatever test is using the allocator). This is odd >+// but helps in tests where the allocator is propagated into nested >+// containers - that chain of allocators uses the same state and is >+// thus easier to query for aggregate allocation information. >+template <typename T> >+class CountingAllocator : public std::allocator<T> { >+ public: >+ using Alloc = std::allocator<T>; >+ using pointer = typename Alloc::pointer; >+ using size_type = typename Alloc::size_type; >+ >+ CountingAllocator() : bytes_used_(nullptr) {} >+ explicit CountingAllocator(int64_t* b) : bytes_used_(b) {} >+ >+ template <typename U> >+ CountingAllocator(const CountingAllocator<U>& x) >+ : Alloc(x), bytes_used_(x.bytes_used_) {} >+ >+ pointer allocate(size_type n, >+ std::allocator<void>::const_pointer hint = nullptr) { >+ assert(bytes_used_ != nullptr); >+ *bytes_used_ += n * sizeof(T); >+ return Alloc::allocate(n, hint); >+ } >+ >+ void deallocate(pointer p, size_type n) { >+ Alloc::deallocate(p, n); >+ assert(bytes_used_ != nullptr); >+ *bytes_used_ -= n * sizeof(T); >+ } >+ >+ template<typename U> >+ class rebind { >+ public: >+ using other = CountingAllocator<U>; >+ }; >+ >+ friend bool operator==(const CountingAllocator& a, >+ const CountingAllocator& b) { >+ return a.bytes_used_ == b.bytes_used_; >+ } >+ >+ friend bool operator!=(const CountingAllocator& a, >+ const CountingAllocator& b) { >+ return !(a == b); >+ } >+ >+ int64_t* bytes_used_; >+}; >+ >+TEST(IntVec, SimpleOps) { >+ for (int len = 0; len < 20; len++) { >+ IntVec v; >+ const IntVec& cv = v; // const alias >+ >+ Fill(&v, len); >+ EXPECT_EQ(len, v.size()); >+ EXPECT_LE(len, v.capacity()); >+ >+ for (int i = 0; i < len; i++) { >+ EXPECT_EQ(i, v[i]); >+ EXPECT_EQ(i, v.at(i)); >+ } >+ EXPECT_EQ(v.begin(), v.data()); >+ EXPECT_EQ(cv.begin(), cv.data()); >+ >+ int counter = 0; >+ for (IntVec::iterator iter = v.begin(); iter != v.end(); ++iter) { >+ EXPECT_EQ(counter, *iter); >+ counter++; >+ } >+ EXPECT_EQ(counter, len); >+ >+ counter = 0; >+ for (IntVec::const_iterator iter = v.begin(); iter != v.end(); ++iter) { >+ EXPECT_EQ(counter, *iter); >+ counter++; >+ } >+ EXPECT_EQ(counter, len); >+ >+ counter = 0; >+ for (IntVec::const_iterator iter = v.cbegin(); iter != v.cend(); ++iter) { >+ EXPECT_EQ(counter, *iter); >+ counter++; >+ } >+ EXPECT_EQ(counter, len); >+ >+ if (len > 0) { >+ EXPECT_EQ(0, v.front()); >+ EXPECT_EQ(len - 1, v.back()); >+ v.pop_back(); >+ EXPECT_EQ(len - 1, v.size()); >+ for (int i = 0; i < v.size(); ++i) { >+ EXPECT_EQ(i, v[i]); >+ EXPECT_EQ(i, v.at(i)); >+ } >+ } >+ } >+} >+ >+TEST(IntVec, AtThrows) { >+ IntVec v = {1, 2, 3}; >+ EXPECT_EQ(v.at(2), 3); >+ ABSL_BASE_INTERNAL_EXPECT_FAIL(v.at(3), std::out_of_range, >+ "failed bounds check"); >+} >+ >+TEST(IntVec, ReverseIterator) { >+ for (int len = 0; len < 20; len++) { >+ IntVec v; >+ Fill(&v, len); >+ >+ int counter = len; >+ for (IntVec::reverse_iterator iter = v.rbegin(); iter != v.rend(); ++iter) { >+ counter--; >+ EXPECT_EQ(counter, *iter); >+ } >+ EXPECT_EQ(counter, 0); >+ >+ counter = len; >+ for (IntVec::const_reverse_iterator iter = v.rbegin(); iter != v.rend(); >+ ++iter) { >+ counter--; >+ EXPECT_EQ(counter, *iter); >+ } >+ EXPECT_EQ(counter, 0); >+ >+ counter = len; >+ for (IntVec::const_reverse_iterator iter = v.crbegin(); iter != v.crend(); >+ ++iter) { >+ counter--; >+ EXPECT_EQ(counter, *iter); >+ } >+ EXPECT_EQ(counter, 0); >+ } >+} >+ >+TEST(IntVec, Erase) { >+ for (int len = 1; len < 20; len++) { >+ for (int i = 0; i < len; ++i) { >+ IntVec v; >+ Fill(&v, len); >+ v.erase(v.begin() + i); >+ EXPECT_EQ(len - 1, v.size()); >+ for (int j = 0; j < i; ++j) { >+ EXPECT_EQ(j, v[j]); >+ } >+ for (int j = i; j < len - 1; ++j) { >+ EXPECT_EQ(j + 1, v[j]); >+ } >+ } >+ } >+} >+ >+// At the end of this test loop, the elements between [erase_begin, erase_end) >+// should have reference counts == 0, and all others elements should have >+// reference counts == 1. >+TEST(RefCountedVec, EraseBeginEnd) { >+ for (int len = 1; len < 20; ++len) { >+ for (int erase_begin = 0; erase_begin < len; ++erase_begin) { >+ for (int erase_end = erase_begin; erase_end <= len; ++erase_end) { >+ std::vector<int> counts(len, 0); >+ RefCountedVec v; >+ for (int i = 0; i < len; ++i) { >+ v.push_back(RefCounted(i, &counts[i])); >+ } >+ >+ int erase_len = erase_end - erase_begin; >+ >+ v.erase(v.begin() + erase_begin, v.begin() + erase_end); >+ >+ EXPECT_EQ(len - erase_len, v.size()); >+ >+ // Check the elements before the first element erased. >+ for (int i = 0; i < erase_begin; ++i) { >+ EXPECT_EQ(i, v[i].value_); >+ } >+ >+ // Check the elements after the first element erased. >+ for (int i = erase_begin; i < v.size(); ++i) { >+ EXPECT_EQ(i + erase_len, v[i].value_); >+ } >+ >+ // Check that the elements at the beginning are preserved. >+ for (int i = 0; i < erase_begin; ++i) { >+ EXPECT_EQ(1, counts[i]); >+ } >+ >+ // Check that the erased elements are destroyed >+ for (int i = erase_begin; i < erase_end; ++i) { >+ EXPECT_EQ(0, counts[i]); >+ } >+ >+ // Check that the elements at the end are preserved. >+ for (int i = erase_end; i< len; ++i) { >+ EXPECT_EQ(1, counts[i]); >+ } >+ } >+ } >+ } >+} >+ >+struct NoDefaultCtor { >+ explicit NoDefaultCtor(int) {} >+}; >+struct NoCopy { >+ NoCopy() {} >+ NoCopy(const NoCopy&) = delete; >+}; >+struct NoAssign { >+ NoAssign() {} >+ NoAssign& operator=(const NoAssign&) = delete; >+}; >+struct MoveOnly { >+ MoveOnly() {} >+ MoveOnly(MoveOnly&&) = default; >+ MoveOnly& operator=(MoveOnly&&) = default; >+}; >+TEST(InlinedVectorTest, NoDefaultCtor) { >+ absl::InlinedVector<NoDefaultCtor, 1> v(10, NoDefaultCtor(2)); >+ (void)v; >+} >+TEST(InlinedVectorTest, NoCopy) { >+ absl::InlinedVector<NoCopy, 1> v(10); >+ (void)v; >+} >+TEST(InlinedVectorTest, NoAssign) { >+ absl::InlinedVector<NoAssign, 1> v(10); >+ (void)v; >+} >+TEST(InlinedVectorTest, MoveOnly) { >+ absl::InlinedVector<MoveOnly, 2> v; >+ v.push_back(MoveOnly{}); >+ v.push_back(MoveOnly{}); >+ v.push_back(MoveOnly{}); >+ v.erase(v.begin()); >+ v.push_back(MoveOnly{}); >+ v.erase(v.begin(), v.begin() + 1); >+ v.insert(v.begin(), MoveOnly{}); >+ v.emplace(v.begin()); >+ v.emplace(v.begin(), MoveOnly{}); >+} >+TEST(InlinedVectorTest, Noexcept) { >+ EXPECT_TRUE(std::is_nothrow_move_constructible<IntVec>::value); >+ EXPECT_TRUE((std::is_nothrow_move_constructible< >+ absl::InlinedVector<MoveOnly, 2>>::value)); >+ >+ struct MoveCanThrow { >+ MoveCanThrow(MoveCanThrow&&) {} >+ }; >+ EXPECT_EQ(absl::default_allocator_is_nothrow::value, >+ (std::is_nothrow_move_constructible< >+ absl::InlinedVector<MoveCanThrow, 2>>::value)); >+} >+ >+TEST(InlinedVectorTest, EmplaceBack) { >+ absl::InlinedVector<std::pair<std::string, int>, 1> v; >+ >+ auto& inlined_element = v.emplace_back("answer", 42); >+ EXPECT_EQ(&inlined_element, &v[0]); >+ EXPECT_EQ(inlined_element.first, "answer"); >+ EXPECT_EQ(inlined_element.second, 42); >+ >+ auto& allocated_element = v.emplace_back("taxicab", 1729); >+ EXPECT_EQ(&allocated_element, &v[1]); >+ EXPECT_EQ(allocated_element.first, "taxicab"); >+ EXPECT_EQ(allocated_element.second, 1729); >+} >+ >+TEST(InlinedVectorTest, ShrinkToFitGrowingVector) { >+ absl::InlinedVector<std::pair<std::string, int>, 1> v; >+ >+ v.shrink_to_fit(); >+ EXPECT_EQ(v.capacity(), 1); >+ >+ v.emplace_back("answer", 42); >+ v.shrink_to_fit(); >+ EXPECT_EQ(v.capacity(), 1); >+ >+ v.emplace_back("taxicab", 1729); >+ EXPECT_GE(v.capacity(), 2); >+ v.shrink_to_fit(); >+ EXPECT_EQ(v.capacity(), 2); >+ >+ v.reserve(100); >+ EXPECT_GE(v.capacity(), 100); >+ v.shrink_to_fit(); >+ EXPECT_EQ(v.capacity(), 2); >+} >+ >+TEST(InlinedVectorTest, ShrinkToFitEdgeCases) { >+ { >+ absl::InlinedVector<std::pair<std::string, int>, 1> v; >+ v.emplace_back("answer", 42); >+ v.emplace_back("taxicab", 1729); >+ EXPECT_GE(v.capacity(), 2); >+ v.pop_back(); >+ v.shrink_to_fit(); >+ EXPECT_EQ(v.capacity(), 1); >+ EXPECT_EQ(v[0].first, "answer"); >+ EXPECT_EQ(v[0].second, 42); >+ } >+ >+ { >+ absl::InlinedVector<std::string, 2> v(100); >+ v.resize(0); >+ v.shrink_to_fit(); >+ EXPECT_EQ(v.capacity(), 2); // inlined capacity >+ } >+ >+ { >+ absl::InlinedVector<std::string, 2> v(100); >+ v.resize(1); >+ v.shrink_to_fit(); >+ EXPECT_EQ(v.capacity(), 2); // inlined capacity >+ } >+ >+ { >+ absl::InlinedVector<std::string, 2> v(100); >+ v.resize(2); >+ v.shrink_to_fit(); >+ EXPECT_EQ(v.capacity(), 2); >+ } >+ >+ { >+ absl::InlinedVector<std::string, 2> v(100); >+ v.resize(3); >+ v.shrink_to_fit(); >+ EXPECT_EQ(v.capacity(), 3); >+ } >+} >+ >+TEST(IntVec, Insert) { >+ for (int len = 0; len < 20; len++) { >+ for (int pos = 0; pos <= len; pos++) { >+ { >+ // Single element >+ std::vector<int> std_v; >+ Fill(&std_v, len); >+ IntVec v; >+ Fill(&v, len); >+ >+ std_v.insert(std_v.begin() + pos, 9999); >+ IntVec::iterator it = v.insert(v.cbegin() + pos, 9999); >+ EXPECT_THAT(v, ElementsAreArray(std_v)); >+ EXPECT_EQ(it, v.cbegin() + pos); >+ } >+ { >+ // n elements >+ std::vector<int> std_v; >+ Fill(&std_v, len); >+ IntVec v; >+ Fill(&v, len); >+ >+ IntVec::size_type n = 5; >+ std_v.insert(std_v.begin() + pos, n, 9999); >+ IntVec::iterator it = v.insert(v.cbegin() + pos, n, 9999); >+ EXPECT_THAT(v, ElementsAreArray(std_v)); >+ EXPECT_EQ(it, v.cbegin() + pos); >+ } >+ { >+ // Iterator range (random access iterator) >+ std::vector<int> std_v; >+ Fill(&std_v, len); >+ IntVec v; >+ Fill(&v, len); >+ >+ const std::vector<int> input = {9999, 8888, 7777}; >+ std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend()); >+ IntVec::iterator it = >+ v.insert(v.cbegin() + pos, input.cbegin(), input.cend()); >+ EXPECT_THAT(v, ElementsAreArray(std_v)); >+ EXPECT_EQ(it, v.cbegin() + pos); >+ } >+ { >+ // Iterator range (forward iterator) >+ std::vector<int> std_v; >+ Fill(&std_v, len); >+ IntVec v; >+ Fill(&v, len); >+ >+ const std::forward_list<int> input = {9999, 8888, 7777}; >+ std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend()); >+ IntVec::iterator it = >+ v.insert(v.cbegin() + pos, input.cbegin(), input.cend()); >+ EXPECT_THAT(v, ElementsAreArray(std_v)); >+ EXPECT_EQ(it, v.cbegin() + pos); >+ } >+ { >+ // Iterator range (input iterator) >+ std::vector<int> std_v; >+ Fill(&std_v, len); >+ IntVec v; >+ Fill(&v, len); >+ >+ std_v.insert(std_v.begin() + pos, {9999, 8888, 7777}); >+ std::istringstream input("9999 8888 7777"); >+ IntVec::iterator it = >+ v.insert(v.cbegin() + pos, std::istream_iterator<int>(input), >+ std::istream_iterator<int>()); >+ EXPECT_THAT(v, ElementsAreArray(std_v)); >+ EXPECT_EQ(it, v.cbegin() + pos); >+ } >+ { >+ // Initializer list >+ std::vector<int> std_v; >+ Fill(&std_v, len); >+ IntVec v; >+ Fill(&v, len); >+ >+ std_v.insert(std_v.begin() + pos, {9999, 8888}); >+ IntVec::iterator it = v.insert(v.cbegin() + pos, {9999, 8888}); >+ EXPECT_THAT(v, ElementsAreArray(std_v)); >+ EXPECT_EQ(it, v.cbegin() + pos); >+ } >+ } >+ } >+} >+ >+TEST(RefCountedVec, InsertConstructorDestructor) { >+ // Make sure the proper construction/destruction happen during insert >+ // operations. >+ for (int len = 0; len < 20; len++) { >+ SCOPED_TRACE(len); >+ for (int pos = 0; pos <= len; pos++) { >+ SCOPED_TRACE(pos); >+ std::vector<int> counts(len, 0); >+ int inserted_count = 0; >+ RefCountedVec v; >+ for (int i = 0; i < len; ++i) { >+ SCOPED_TRACE(i); >+ v.push_back(RefCounted(i, &counts[i])); >+ } >+ >+ EXPECT_THAT(counts, Each(Eq(1))); >+ >+ RefCounted insert_element(9999, &inserted_count); >+ EXPECT_EQ(1, inserted_count); >+ v.insert(v.begin() + pos, insert_element); >+ EXPECT_EQ(2, inserted_count); >+ // Check that the elements at the end are preserved. >+ EXPECT_THAT(counts, Each(Eq(1))); >+ EXPECT_EQ(2, inserted_count); >+ } >+ } >+} >+ >+TEST(IntVec, Resize) { >+ for (int len = 0; len < 20; len++) { >+ IntVec v; >+ Fill(&v, len); >+ >+ // Try resizing up and down by k elements >+ static const int kResizeElem = 1000000; >+ for (int k = 0; k < 10; k++) { >+ // Enlarging resize >+ v.resize(len+k, kResizeElem); >+ EXPECT_EQ(len+k, v.size()); >+ EXPECT_LE(len+k, v.capacity()); >+ for (int i = 0; i < len+k; i++) { >+ if (i < len) { >+ EXPECT_EQ(i, v[i]); >+ } else { >+ EXPECT_EQ(kResizeElem, v[i]); >+ } >+ } >+ >+ // Shrinking resize >+ v.resize(len, kResizeElem); >+ EXPECT_EQ(len, v.size()); >+ EXPECT_LE(len, v.capacity()); >+ for (int i = 0; i < len; i++) { >+ EXPECT_EQ(i, v[i]); >+ } >+ } >+ } >+} >+ >+TEST(IntVec, InitWithLength) { >+ for (int len = 0; len < 20; len++) { >+ IntVec v(len, 7); >+ EXPECT_EQ(len, v.size()); >+ EXPECT_LE(len, v.capacity()); >+ for (int i = 0; i < len; i++) { >+ EXPECT_EQ(7, v[i]); >+ } >+ } >+} >+ >+TEST(IntVec, CopyConstructorAndAssignment) { >+ for (int len = 0; len < 20; len++) { >+ IntVec v; >+ Fill(&v, len); >+ EXPECT_EQ(len, v.size()); >+ EXPECT_LE(len, v.capacity()); >+ >+ IntVec v2(v); >+ EXPECT_TRUE(v == v2) << PrintToString(v) << PrintToString(v2); >+ >+ for (int start_len = 0; start_len < 20; start_len++) { >+ IntVec v3; >+ Fill(&v3, start_len, 99); // Add dummy elements that should go away >+ v3 = v; >+ EXPECT_TRUE(v == v3) << PrintToString(v) << PrintToString(v3); >+ } >+ } >+} >+ >+TEST(IntVec, AliasingCopyAssignment) { >+ for (int len = 0; len < 20; ++len) { >+ IntVec original; >+ Fill(&original, len); >+ IntVec dup = original; >+ dup = *&dup; >+ EXPECT_EQ(dup, original); >+ } >+} >+ >+TEST(IntVec, MoveConstructorAndAssignment) { >+ for (int len = 0; len < 20; len++) { >+ IntVec v_in; >+ const int inlined_capacity = v_in.capacity(); >+ Fill(&v_in, len); >+ EXPECT_EQ(len, v_in.size()); >+ EXPECT_LE(len, v_in.capacity()); >+ >+ { >+ IntVec v_temp(v_in); >+ auto* old_data = v_temp.data(); >+ IntVec v_out(std::move(v_temp)); >+ EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out); >+ if (v_in.size() > inlined_capacity) { >+ // Allocation is moved as a whole, data stays in place. >+ EXPECT_TRUE(v_out.data() == old_data); >+ } else { >+ EXPECT_FALSE(v_out.data() == old_data); >+ } >+ } >+ for (int start_len = 0; start_len < 20; start_len++) { >+ IntVec v_out; >+ Fill(&v_out, start_len, 99); // Add dummy elements that should go away >+ IntVec v_temp(v_in); >+ auto* old_data = v_temp.data(); >+ v_out = std::move(v_temp); >+ EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out); >+ if (v_in.size() > inlined_capacity) { >+ // Allocation is moved as a whole, data stays in place. >+ EXPECT_TRUE(v_out.data() == old_data); >+ } else { >+ EXPECT_FALSE(v_out.data() == old_data); >+ } >+ } >+ } >+} >+ >+class NotTriviallyDestructible { >+ public: >+ NotTriviallyDestructible() : p_(new int(1)) {} >+ explicit NotTriviallyDestructible(int i) : p_(new int(i)) {} >+ >+ NotTriviallyDestructible(const NotTriviallyDestructible& other) >+ : p_(new int(*other.p_)) {} >+ >+ NotTriviallyDestructible& operator=(const NotTriviallyDestructible& other) { >+ p_ = absl::make_unique<int>(*other.p_); >+ return *this; >+ } >+ >+ bool operator==(const NotTriviallyDestructible& other) const { >+ return *p_ == *other.p_; >+ } >+ >+ private: >+ std::unique_ptr<int> p_; >+}; >+ >+TEST(AliasingTest, Emplace) { >+ for (int i = 2; i < 20; ++i) { >+ absl::InlinedVector<NotTriviallyDestructible, 10> vec; >+ for (int j = 0; j < i; ++j) { >+ vec.push_back(NotTriviallyDestructible(j)); >+ } >+ vec.emplace(vec.begin(), vec[0]); >+ EXPECT_EQ(vec[0], vec[1]); >+ vec.emplace(vec.begin() + i / 2, vec[i / 2]); >+ EXPECT_EQ(vec[i / 2], vec[i / 2 + 1]); >+ vec.emplace(vec.end() - 1, vec.back()); >+ EXPECT_EQ(vec[vec.size() - 2], vec.back()); >+ } >+} >+ >+TEST(AliasingTest, InsertWithCount) { >+ for (int i = 1; i < 20; ++i) { >+ absl::InlinedVector<NotTriviallyDestructible, 10> vec; >+ for (int j = 0; j < i; ++j) { >+ vec.push_back(NotTriviallyDestructible(j)); >+ } >+ for (int n = 0; n < 5; ++n) { >+ // We use back where we can because it's guaranteed to become invalidated >+ vec.insert(vec.begin(), n, vec.back()); >+ auto b = vec.begin(); >+ EXPECT_TRUE( >+ std::all_of(b, b + n, [&vec](const NotTriviallyDestructible& x) { >+ return x == vec.back(); >+ })); >+ >+ auto m_idx = vec.size() / 2; >+ vec.insert(vec.begin() + m_idx, n, vec.back()); >+ auto m = vec.begin() + m_idx; >+ EXPECT_TRUE( >+ std::all_of(m, m + n, [&vec](const NotTriviallyDestructible& x) { >+ return x == vec.back(); >+ })); >+ >+ // We want distinct values so the equality test is meaningful, >+ // vec[vec.size() - 1] is also almost always invalidated. >+ auto old_e = vec.size() - 1; >+ auto val = vec[old_e]; >+ vec.insert(vec.end(), n, vec[old_e]); >+ auto e = vec.begin() + old_e; >+ EXPECT_TRUE(std::all_of( >+ e, e + n, >+ [&val](const NotTriviallyDestructible& x) { return x == val; })); >+ } >+ } >+} >+ >+TEST(OverheadTest, Storage) { >+ // Check for size overhead. >+ // In particular, ensure that std::allocator doesn't cost anything to store. >+ // The union should be absorbing some of the allocation bookkeeping overhead >+ // in the larger vectors, leaving only the size_ field as overhead. >+ EXPECT_EQ(2 * sizeof(int*), >+ sizeof(absl::InlinedVector<int*, 1>) - 1 * sizeof(int*)); >+ EXPECT_EQ(1 * sizeof(int*), >+ sizeof(absl::InlinedVector<int*, 2>) - 2 * sizeof(int*)); >+ EXPECT_EQ(1 * sizeof(int*), >+ sizeof(absl::InlinedVector<int*, 3>) - 3 * sizeof(int*)); >+ EXPECT_EQ(1 * sizeof(int*), >+ sizeof(absl::InlinedVector<int*, 4>) - 4 * sizeof(int*)); >+ EXPECT_EQ(1 * sizeof(int*), >+ sizeof(absl::InlinedVector<int*, 5>) - 5 * sizeof(int*)); >+ EXPECT_EQ(1 * sizeof(int*), >+ sizeof(absl::InlinedVector<int*, 6>) - 6 * sizeof(int*)); >+ EXPECT_EQ(1 * sizeof(int*), >+ sizeof(absl::InlinedVector<int*, 7>) - 7 * sizeof(int*)); >+ EXPECT_EQ(1 * sizeof(int*), >+ sizeof(absl::InlinedVector<int*, 8>) - 8 * sizeof(int*)); >+} >+ >+TEST(IntVec, Clear) { >+ for (int len = 0; len < 20; len++) { >+ SCOPED_TRACE(len); >+ IntVec v; >+ Fill(&v, len); >+ v.clear(); >+ EXPECT_EQ(0, v.size()); >+ EXPECT_EQ(v.begin(), v.end()); >+ } >+} >+ >+TEST(IntVec, Reserve) { >+ for (int len = 0; len < 20; len++) { >+ IntVec v; >+ Fill(&v, len); >+ >+ for (int newlen = 0; newlen < 100; newlen++) { >+ const int* start_rep = v.data(); >+ v.reserve(newlen); >+ const int* final_rep = v.data(); >+ if (newlen <= len) { >+ EXPECT_EQ(start_rep, final_rep); >+ } >+ EXPECT_LE(newlen, v.capacity()); >+ >+ // Filling up to newlen should not change rep >+ while (v.size() < newlen) { >+ v.push_back(0); >+ } >+ EXPECT_EQ(final_rep, v.data()); >+ } >+ } >+} >+ >+TEST(StringVec, SelfRefPushBack) { >+ std::vector<std::string> std_v; >+ absl::InlinedVector<std::string, 4> v; >+ const std::string s = "A quite long std::string to ensure heap."; >+ std_v.push_back(s); >+ v.push_back(s); >+ for (int i = 0; i < 20; ++i) { >+ EXPECT_THAT(v, ElementsAreArray(std_v)); >+ >+ v.push_back(v.back()); >+ std_v.push_back(std_v.back()); >+ } >+ EXPECT_THAT(v, ElementsAreArray(std_v)); >+} >+ >+TEST(StringVec, SelfRefPushBackWithMove) { >+ std::vector<std::string> std_v; >+ absl::InlinedVector<std::string, 4> v; >+ const std::string s = "A quite long std::string to ensure heap."; >+ std_v.push_back(s); >+ v.push_back(s); >+ for (int i = 0; i < 20; ++i) { >+ EXPECT_EQ(v.back(), std_v.back()); >+ >+ v.push_back(std::move(v.back())); >+ std_v.push_back(std::move(std_v.back())); >+ } >+ EXPECT_EQ(v.back(), std_v.back()); >+} >+ >+TEST(StringVec, SelfMove) { >+ const std::string s = "A quite long std::string to ensure heap."; >+ for (int len = 0; len < 20; len++) { >+ SCOPED_TRACE(len); >+ absl::InlinedVector<std::string, 8> v; >+ for (int i = 0; i < len; ++i) { >+ SCOPED_TRACE(i); >+ v.push_back(s); >+ } >+ // Indirection necessary to avoid compiler warning. >+ v = std::move(*(&v)); >+ // Ensure that the inlined vector is still in a valid state by copying it. >+ // We don't expect specific contents since a self-move results in an >+ // unspecified valid state. >+ std::vector<std::string> copy(v.begin(), v.end()); >+ } >+} >+ >+TEST(IntVec, Swap) { >+ for (int l1 = 0; l1 < 20; l1++) { >+ SCOPED_TRACE(l1); >+ for (int l2 = 0; l2 < 20; l2++) { >+ SCOPED_TRACE(l2); >+ IntVec a = Fill(l1, 0); >+ IntVec b = Fill(l2, 100); >+ { >+ using std::swap; >+ swap(a, b); >+ } >+ EXPECT_EQ(l1, b.size()); >+ EXPECT_EQ(l2, a.size()); >+ for (int i = 0; i < l1; i++) { >+ SCOPED_TRACE(i); >+ EXPECT_EQ(i, b[i]); >+ } >+ for (int i = 0; i < l2; i++) { >+ SCOPED_TRACE(i); >+ EXPECT_EQ(100 + i, a[i]); >+ } >+ } >+ } >+} >+ >+TYPED_TEST_P(InstanceTest, Swap) { >+ using Instance = TypeParam; >+ using InstanceVec = absl::InlinedVector<Instance, 8>; >+ for (int l1 = 0; l1 < 20; l1++) { >+ SCOPED_TRACE(l1); >+ for (int l2 = 0; l2 < 20; l2++) { >+ SCOPED_TRACE(l2); >+ InstanceTracker tracker; >+ InstanceVec a, b; >+ const size_t inlined_capacity = a.capacity(); >+ for (int i = 0; i < l1; i++) a.push_back(Instance(i)); >+ for (int i = 0; i < l2; i++) b.push_back(Instance(100+i)); >+ EXPECT_EQ(tracker.instances(), l1 + l2); >+ tracker.ResetCopiesMovesSwaps(); >+ { >+ using std::swap; >+ swap(a, b); >+ } >+ EXPECT_EQ(tracker.instances(), l1 + l2); >+ if (a.size() > inlined_capacity && b.size() > inlined_capacity) { >+ EXPECT_EQ(tracker.swaps(), 0); // Allocations are swapped. >+ EXPECT_EQ(tracker.moves(), 0); >+ } else if (a.size() <= inlined_capacity && b.size() <= inlined_capacity) { >+ EXPECT_EQ(tracker.swaps(), std::min(l1, l2)); >+ // TODO(bsamwel): This should use moves when the type is movable. >+ EXPECT_EQ(tracker.copies(), std::max(l1, l2) - std::min(l1, l2)); >+ } else { >+ // One is allocated and the other isn't. The allocation is transferred >+ // without copying elements, and the inlined instances are copied/moved. >+ EXPECT_EQ(tracker.swaps(), 0); >+ // TODO(bsamwel): This should use moves when the type is movable. >+ EXPECT_EQ(tracker.copies(), std::min(l1, l2)); >+ } >+ >+ EXPECT_EQ(l1, b.size()); >+ EXPECT_EQ(l2, a.size()); >+ for (int i = 0; i < l1; i++) { >+ EXPECT_EQ(i, b[i].value()); >+ } >+ for (int i = 0; i < l2; i++) { >+ EXPECT_EQ(100 + i, a[i].value()); >+ } >+ } >+ } >+} >+ >+TEST(IntVec, EqualAndNotEqual) { >+ IntVec a, b; >+ EXPECT_TRUE(a == b); >+ EXPECT_FALSE(a != b); >+ >+ a.push_back(3); >+ EXPECT_FALSE(a == b); >+ EXPECT_TRUE(a != b); >+ >+ b.push_back(3); >+ EXPECT_TRUE(a == b); >+ EXPECT_FALSE(a != b); >+ >+ b.push_back(7); >+ EXPECT_FALSE(a == b); >+ EXPECT_TRUE(a != b); >+ >+ a.push_back(6); >+ EXPECT_FALSE(a == b); >+ EXPECT_TRUE(a != b); >+ >+ a.clear(); >+ b.clear(); >+ for (int i = 0; i < 100; i++) { >+ a.push_back(i); >+ b.push_back(i); >+ EXPECT_TRUE(a == b); >+ EXPECT_FALSE(a != b); >+ >+ b[i] = b[i] + 1; >+ EXPECT_FALSE(a == b); >+ EXPECT_TRUE(a != b); >+ >+ b[i] = b[i] - 1; // Back to before >+ EXPECT_TRUE(a == b); >+ EXPECT_FALSE(a != b); >+ } >+} >+ >+TEST(IntVec, RelationalOps) { >+ IntVec a, b; >+ EXPECT_FALSE(a < b); >+ EXPECT_FALSE(b < a); >+ EXPECT_FALSE(a > b); >+ EXPECT_FALSE(b > a); >+ EXPECT_TRUE(a <= b); >+ EXPECT_TRUE(b <= a); >+ EXPECT_TRUE(a >= b); >+ EXPECT_TRUE(b >= a); >+ b.push_back(3); >+ EXPECT_TRUE(a < b); >+ EXPECT_FALSE(b < a); >+ EXPECT_FALSE(a > b); >+ EXPECT_TRUE(b > a); >+ EXPECT_TRUE(a <= b); >+ EXPECT_FALSE(b <= a); >+ EXPECT_FALSE(a >= b); >+ EXPECT_TRUE(b >= a); >+} >+ >+TYPED_TEST_P(InstanceTest, CountConstructorsDestructors) { >+ using Instance = TypeParam; >+ using InstanceVec = absl::InlinedVector<Instance, 8>; >+ InstanceTracker tracker; >+ for (int len = 0; len < 20; len++) { >+ SCOPED_TRACE(len); >+ tracker.ResetCopiesMovesSwaps(); >+ >+ InstanceVec v; >+ const size_t inlined_capacity = v.capacity(); >+ for (int i = 0; i < len; i++) { >+ v.push_back(Instance(i)); >+ } >+ EXPECT_EQ(tracker.instances(), len); >+ EXPECT_GE(tracker.copies() + tracker.moves(), >+ len); // More due to reallocation. >+ tracker.ResetCopiesMovesSwaps(); >+ >+ // Enlarging resize() must construct some objects >+ tracker.ResetCopiesMovesSwaps(); >+ v.resize(len + 10, Instance(100)); >+ EXPECT_EQ(tracker.instances(), len + 10); >+ if (len <= inlined_capacity && len + 10 > inlined_capacity) { >+ EXPECT_EQ(tracker.copies() + tracker.moves(), 10 + len); >+ } else { >+ // Only specify a minimum number of copies + moves. We don't want to >+ // depend on the reallocation policy here. >+ EXPECT_GE(tracker.copies() + tracker.moves(), >+ 10); // More due to reallocation. >+ } >+ >+ // Shrinking resize() must destroy some objects >+ tracker.ResetCopiesMovesSwaps(); >+ v.resize(len, Instance(100)); >+ EXPECT_EQ(tracker.instances(), len); >+ EXPECT_EQ(tracker.copies(), 0); >+ EXPECT_EQ(tracker.moves(), 0); >+ >+ // reserve() must not increase the number of initialized objects >+ SCOPED_TRACE("reserve"); >+ v.reserve(len+1000); >+ EXPECT_EQ(tracker.instances(), len); >+ EXPECT_EQ(tracker.copies() + tracker.moves(), len); >+ >+ // pop_back() and erase() must destroy one object >+ if (len > 0) { >+ tracker.ResetCopiesMovesSwaps(); >+ v.pop_back(); >+ EXPECT_EQ(tracker.instances(), len - 1); >+ EXPECT_EQ(tracker.copies(), 0); >+ EXPECT_EQ(tracker.moves(), 0); >+ >+ if (!v.empty()) { >+ tracker.ResetCopiesMovesSwaps(); >+ v.erase(v.begin()); >+ EXPECT_EQ(tracker.instances(), len - 2); >+ EXPECT_EQ(tracker.copies() + tracker.moves(), len - 2); >+ } >+ } >+ >+ tracker.ResetCopiesMovesSwaps(); >+ int instances_before_empty_erase = tracker.instances(); >+ v.erase(v.begin(), v.begin()); >+ EXPECT_EQ(tracker.instances(), instances_before_empty_erase); >+ EXPECT_EQ(tracker.copies() + tracker.moves(), 0); >+ } >+} >+ >+TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnCopyConstruction) { >+ using Instance = TypeParam; >+ using InstanceVec = absl::InlinedVector<Instance, 8>; >+ InstanceTracker tracker; >+ for (int len = 0; len < 20; len++) { >+ SCOPED_TRACE(len); >+ tracker.ResetCopiesMovesSwaps(); >+ >+ InstanceVec v; >+ for (int i = 0; i < len; i++) { >+ v.push_back(Instance(i)); >+ } >+ EXPECT_EQ(tracker.instances(), len); >+ EXPECT_GE(tracker.copies() + tracker.moves(), >+ len); // More due to reallocation. >+ tracker.ResetCopiesMovesSwaps(); >+ { // Copy constructor should create 'len' more instances. >+ InstanceVec v_copy(v); >+ EXPECT_EQ(tracker.instances(), len + len); >+ EXPECT_EQ(tracker.copies(), len); >+ EXPECT_EQ(tracker.moves(), 0); >+ } >+ EXPECT_EQ(tracker.instances(), len); >+ } >+} >+ >+TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveConstruction) { >+ using Instance = TypeParam; >+ using InstanceVec = absl::InlinedVector<Instance, 8>; >+ InstanceTracker tracker; >+ for (int len = 0; len < 20; len++) { >+ SCOPED_TRACE(len); >+ tracker.ResetCopiesMovesSwaps(); >+ >+ InstanceVec v; >+ const size_t inlined_capacity = v.capacity(); >+ for (int i = 0; i < len; i++) { >+ v.push_back(Instance(i)); >+ } >+ EXPECT_EQ(tracker.instances(), len); >+ EXPECT_GE(tracker.copies() + tracker.moves(), >+ len); // More due to reallocation. >+ tracker.ResetCopiesMovesSwaps(); >+ { >+ InstanceVec v_copy(std::move(v)); >+ if (len > inlined_capacity) { >+ // Allocation is moved as a whole. >+ EXPECT_EQ(tracker.instances(), len); >+ EXPECT_EQ(tracker.live_instances(), len); >+ // Tests an implementation detail, don't rely on this in your code. >+ EXPECT_EQ(v.size(), 0); // NOLINT misc-use-after-move >+ EXPECT_EQ(tracker.copies(), 0); >+ EXPECT_EQ(tracker.moves(), 0); >+ } else { >+ EXPECT_EQ(tracker.instances(), len + len); >+ if (Instance::supports_move()) { >+ EXPECT_EQ(tracker.live_instances(), len); >+ EXPECT_EQ(tracker.copies(), 0); >+ EXPECT_EQ(tracker.moves(), len); >+ } else { >+ EXPECT_EQ(tracker.live_instances(), len + len); >+ EXPECT_EQ(tracker.copies(), len); >+ EXPECT_EQ(tracker.moves(), 0); >+ } >+ } >+ EXPECT_EQ(tracker.swaps(), 0); >+ } >+ } >+} >+ >+TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnAssignment) { >+ using Instance = TypeParam; >+ using InstanceVec = absl::InlinedVector<Instance, 8>; >+ InstanceTracker tracker; >+ for (int len = 0; len < 20; len++) { >+ SCOPED_TRACE(len); >+ for (int longorshort = 0; longorshort <= 1; ++longorshort) { >+ SCOPED_TRACE(longorshort); >+ tracker.ResetCopiesMovesSwaps(); >+ >+ InstanceVec longer, shorter; >+ for (int i = 0; i < len; i++) { >+ longer.push_back(Instance(i)); >+ shorter.push_back(Instance(i)); >+ } >+ longer.push_back(Instance(len)); >+ EXPECT_EQ(tracker.instances(), len + len + 1); >+ EXPECT_GE(tracker.copies() + tracker.moves(), >+ len + len + 1); // More due to reallocation. >+ >+ tracker.ResetCopiesMovesSwaps(); >+ if (longorshort) { >+ shorter = longer; >+ EXPECT_EQ(tracker.instances(), (len + 1) + (len + 1)); >+ EXPECT_GE(tracker.copies() + tracker.moves(), >+ len + 1); // More due to reallocation. >+ } else { >+ longer = shorter; >+ EXPECT_EQ(tracker.instances(), len + len); >+ EXPECT_EQ(tracker.copies() + tracker.moves(), len); >+ } >+ } >+ } >+} >+ >+TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveAssignment) { >+ using Instance = TypeParam; >+ using InstanceVec = absl::InlinedVector<Instance, 8>; >+ InstanceTracker tracker; >+ for (int len = 0; len < 20; len++) { >+ SCOPED_TRACE(len); >+ for (int longorshort = 0; longorshort <= 1; ++longorshort) { >+ SCOPED_TRACE(longorshort); >+ tracker.ResetCopiesMovesSwaps(); >+ >+ InstanceVec longer, shorter; >+ const int inlined_capacity = longer.capacity(); >+ for (int i = 0; i < len; i++) { >+ longer.push_back(Instance(i)); >+ shorter.push_back(Instance(i)); >+ } >+ longer.push_back(Instance(len)); >+ EXPECT_EQ(tracker.instances(), len + len + 1); >+ EXPECT_GE(tracker.copies() + tracker.moves(), >+ len + len + 1); // More due to reallocation. >+ >+ tracker.ResetCopiesMovesSwaps(); >+ int src_len; >+ if (longorshort) { >+ src_len = len + 1; >+ shorter = std::move(longer); >+ } else { >+ src_len = len; >+ longer = std::move(shorter); >+ } >+ if (src_len > inlined_capacity) { >+ // Allocation moved as a whole. >+ EXPECT_EQ(tracker.instances(), src_len); >+ EXPECT_EQ(tracker.live_instances(), src_len); >+ EXPECT_EQ(tracker.copies(), 0); >+ EXPECT_EQ(tracker.moves(), 0); >+ } else { >+ // Elements are all copied. >+ EXPECT_EQ(tracker.instances(), src_len + src_len); >+ if (Instance::supports_move()) { >+ EXPECT_EQ(tracker.copies(), 0); >+ EXPECT_EQ(tracker.moves(), src_len); >+ EXPECT_EQ(tracker.live_instances(), src_len); >+ } else { >+ EXPECT_EQ(tracker.copies(), src_len); >+ EXPECT_EQ(tracker.moves(), 0); >+ EXPECT_EQ(tracker.live_instances(), src_len + src_len); >+ } >+ } >+ EXPECT_EQ(tracker.swaps(), 0); >+ } >+ } >+} >+ >+TEST(CountElemAssign, SimpleTypeWithInlineBacking) { >+ for (size_t original_size = 0; original_size <= 5; ++original_size) { >+ SCOPED_TRACE(original_size); >+ // Original contents are [12345, 12345, ...] >+ std::vector<int> original_contents(original_size, 12345); >+ >+ absl::InlinedVector<int, 2> v(original_contents.begin(), >+ original_contents.end()); >+ v.assign(2, 123); >+ EXPECT_THAT(v, AllOf(SizeIs(2), ElementsAre(123, 123))); >+ if (original_size <= 2) { >+ // If the original had inline backing, it should stay inline. >+ EXPECT_EQ(2, v.capacity()); >+ } >+ } >+} >+ >+TEST(CountElemAssign, SimpleTypeWithAllocation) { >+ for (size_t original_size = 0; original_size <= 5; ++original_size) { >+ SCOPED_TRACE(original_size); >+ // Original contents are [12345, 12345, ...] >+ std::vector<int> original_contents(original_size, 12345); >+ >+ absl::InlinedVector<int, 2> v(original_contents.begin(), >+ original_contents.end()); >+ v.assign(3, 123); >+ EXPECT_THAT(v, AllOf(SizeIs(3), ElementsAre(123, 123, 123))); >+ EXPECT_LE(v.size(), v.capacity()); >+ } >+} >+ >+TYPED_TEST_P(InstanceTest, CountElemAssignInlineBacking) { >+ using Instance = TypeParam; >+ for (size_t original_size = 0; original_size <= 5; ++original_size) { >+ SCOPED_TRACE(original_size); >+ // Original contents are [12345, 12345, ...] >+ std::vector<Instance> original_contents(original_size, Instance(12345)); >+ >+ absl::InlinedVector<Instance, 2> v(original_contents.begin(), >+ original_contents.end()); >+ v.assign(2, Instance(123)); >+ EXPECT_THAT(v, AllOf(SizeIs(2), ElementsAre(ValueIs(123), ValueIs(123)))); >+ if (original_size <= 2) { >+ // If the original had inline backing, it should stay inline. >+ EXPECT_EQ(2, v.capacity()); >+ } >+ } >+} >+ >+template <typename Instance> >+void InstanceCountElemAssignWithAllocationTest() { >+ for (size_t original_size = 0; original_size <= 5; ++original_size) { >+ SCOPED_TRACE(original_size); >+ // Original contents are [12345, 12345, ...] >+ std::vector<Instance> original_contents(original_size, Instance(12345)); >+ >+ absl::InlinedVector<Instance, 2> v(original_contents.begin(), >+ original_contents.end()); >+ v.assign(3, Instance(123)); >+ EXPECT_THAT(v, >+ AllOf(SizeIs(3), >+ ElementsAre(ValueIs(123), ValueIs(123), ValueIs(123)))); >+ EXPECT_LE(v.size(), v.capacity()); >+ } >+} >+TEST(CountElemAssign, WithAllocationCopyableInstance) { >+ InstanceCountElemAssignWithAllocationTest<CopyableOnlyInstance>(); >+} >+TEST(CountElemAssign, WithAllocationCopyableMovableInstance) { >+ InstanceCountElemAssignWithAllocationTest<CopyableMovableInstance>(); >+} >+ >+TEST(RangedConstructor, SimpleType) { >+ std::vector<int> source_v = {4, 5, 6}; >+ // First try to fit in inline backing >+ absl::InlinedVector<int, 4> v(source_v.begin(), source_v.end()); >+ EXPECT_EQ(3, v.size()); >+ EXPECT_EQ(4, v.capacity()); // Indication that we're still on inlined storage >+ EXPECT_EQ(4, v[0]); >+ EXPECT_EQ(5, v[1]); >+ EXPECT_EQ(6, v[2]); >+ >+ // Now, force a re-allocate >+ absl::InlinedVector<int, 2> realloc_v(source_v.begin(), source_v.end()); >+ EXPECT_EQ(3, realloc_v.size()); >+ EXPECT_LT(2, realloc_v.capacity()); >+ EXPECT_EQ(4, realloc_v[0]); >+ EXPECT_EQ(5, realloc_v[1]); >+ EXPECT_EQ(6, realloc_v[2]); >+} >+ >+// Test for ranged constructors using Instance as the element type and >+// SourceContainer as the source container type. >+template <typename Instance, typename SourceContainer, int inlined_capacity> >+void InstanceRangedConstructorTestForContainer() { >+ InstanceTracker tracker; >+ SourceContainer source_v = {Instance(0), Instance(1)}; >+ tracker.ResetCopiesMovesSwaps(); >+ absl::InlinedVector<Instance, inlined_capacity> v(source_v.begin(), >+ source_v.end()); >+ EXPECT_EQ(2, v.size()); >+ EXPECT_LT(1, v.capacity()); >+ EXPECT_EQ(0, v[0].value()); >+ EXPECT_EQ(1, v[1].value()); >+ EXPECT_EQ(tracker.copies(), 2); >+ EXPECT_EQ(tracker.moves(), 0); >+} >+ >+template <typename Instance, int inlined_capacity> >+void InstanceRangedConstructorTestWithCapacity() { >+ // Test with const and non-const, random access and non-random-access sources. >+ // TODO(bsamwel): Test with an input iterator source. >+ { >+ SCOPED_TRACE("std::list"); >+ InstanceRangedConstructorTestForContainer<Instance, std::list<Instance>, >+ inlined_capacity>(); >+ { >+ SCOPED_TRACE("const std::list"); >+ InstanceRangedConstructorTestForContainer< >+ Instance, const std::list<Instance>, inlined_capacity>(); >+ } >+ { >+ SCOPED_TRACE("std::vector"); >+ InstanceRangedConstructorTestForContainer<Instance, std::vector<Instance>, >+ inlined_capacity>(); >+ } >+ { >+ SCOPED_TRACE("const std::vector"); >+ InstanceRangedConstructorTestForContainer< >+ Instance, const std::vector<Instance>, inlined_capacity>(); >+ } >+ } >+} >+ >+TYPED_TEST_P(InstanceTest, RangedConstructor) { >+ using Instance = TypeParam; >+ SCOPED_TRACE("capacity=1"); >+ InstanceRangedConstructorTestWithCapacity<Instance, 1>(); >+ SCOPED_TRACE("capacity=2"); >+ InstanceRangedConstructorTestWithCapacity<Instance, 2>(); >+} >+ >+TEST(RangedConstructor, ElementsAreConstructed) { >+ std::vector<std::string> source_v = {"cat", "dog"}; >+ >+ // Force expansion and re-allocation of v. Ensures that when the vector is >+ // expanded that new elements are constructed. >+ absl::InlinedVector<std::string, 1> v(source_v.begin(), source_v.end()); >+ EXPECT_EQ("cat", v[0]); >+ EXPECT_EQ("dog", v[1]); >+} >+ >+TEST(RangedAssign, SimpleType) { >+ // Test for all combinations of original sizes (empty and non-empty inline, >+ // and out of line) and target sizes. >+ for (size_t original_size = 0; original_size <= 5; ++original_size) { >+ SCOPED_TRACE(original_size); >+ // Original contents are [12345, 12345, ...] >+ std::vector<int> original_contents(original_size, 12345); >+ >+ for (size_t target_size = 0; target_size <= 5; ++target_size) { >+ SCOPED_TRACE(target_size); >+ >+ // New contents are [3, 4, ...] >+ std::vector<int> new_contents; >+ for (size_t i = 0; i < target_size; ++i) { >+ new_contents.push_back(i + 3); >+ } >+ >+ absl::InlinedVector<int, 3> v(original_contents.begin(), >+ original_contents.end()); >+ v.assign(new_contents.begin(), new_contents.end()); >+ >+ EXPECT_EQ(new_contents.size(), v.size()); >+ EXPECT_LE(new_contents.size(), v.capacity()); >+ if (target_size <= 3 && original_size <= 3) { >+ // Storage should stay inline when target size is small. >+ EXPECT_EQ(3, v.capacity()); >+ } >+ EXPECT_THAT(v, ElementsAreArray(new_contents)); >+ } >+ } >+} >+ >+// Returns true if lhs and rhs have the same value. >+template <typename Instance> >+static bool InstanceValuesEqual(const Instance& lhs, const Instance& rhs) { >+ return lhs.value() == rhs.value(); >+} >+ >+// Test for ranged assign() using Instance as the element type and >+// SourceContainer as the source container type. >+template <typename Instance, typename SourceContainer> >+void InstanceRangedAssignTestForContainer() { >+ // Test for all combinations of original sizes (empty and non-empty inline, >+ // and out of line) and target sizes. >+ for (size_t original_size = 0; original_size <= 5; ++original_size) { >+ SCOPED_TRACE(original_size); >+ // Original contents are [12345, 12345, ...] >+ std::vector<Instance> original_contents(original_size, Instance(12345)); >+ >+ for (size_t target_size = 0; target_size <= 5; ++target_size) { >+ SCOPED_TRACE(target_size); >+ >+ // New contents are [3, 4, ...] >+ // Generate data using a non-const container, because SourceContainer >+ // itself may be const. >+ // TODO(bsamwel): Test with an input iterator. >+ std::vector<Instance> new_contents_in; >+ for (size_t i = 0; i < target_size; ++i) { >+ new_contents_in.push_back(Instance(i + 3)); >+ } >+ SourceContainer new_contents(new_contents_in.begin(), >+ new_contents_in.end()); >+ >+ absl::InlinedVector<Instance, 3> v(original_contents.begin(), >+ original_contents.end()); >+ v.assign(new_contents.begin(), new_contents.end()); >+ >+ EXPECT_EQ(new_contents.size(), v.size()); >+ EXPECT_LE(new_contents.size(), v.capacity()); >+ if (target_size <= 3 && original_size <= 3) { >+ // Storage should stay inline when target size is small. >+ EXPECT_EQ(3, v.capacity()); >+ } >+ EXPECT_TRUE(std::equal(v.begin(), v.end(), new_contents.begin(), >+ InstanceValuesEqual<Instance>)); >+ } >+ } >+} >+ >+TYPED_TEST_P(InstanceTest, RangedAssign) { >+ using Instance = TypeParam; >+ // Test with const and non-const, random access and non-random-access sources. >+ // TODO(bsamwel): Test with an input iterator source. >+ SCOPED_TRACE("std::list"); >+ InstanceRangedAssignTestForContainer<Instance, std::list<Instance>>(); >+ SCOPED_TRACE("const std::list"); >+ InstanceRangedAssignTestForContainer<Instance, const std::list<Instance>>(); >+ SCOPED_TRACE("std::vector"); >+ InstanceRangedAssignTestForContainer<Instance, std::vector<Instance>>(); >+ SCOPED_TRACE("const std::vector"); >+ InstanceRangedAssignTestForContainer<Instance, const std::vector<Instance>>(); >+} >+ >+TEST(InitializerListConstructor, SimpleTypeWithInlineBacking) { >+ EXPECT_THAT((absl::InlinedVector<int, 4>{4, 5, 6}), >+ AllOf(SizeIs(3), CapacityIs(4), ElementsAre(4, 5, 6))); >+} >+ >+TEST(InitializerListConstructor, SimpleTypeWithReallocationRequired) { >+ EXPECT_THAT((absl::InlinedVector<int, 2>{4, 5, 6}), >+ AllOf(SizeIs(3), CapacityIs(Gt(2)), ElementsAre(4, 5, 6))); >+} >+ >+TEST(InitializerListConstructor, DisparateTypesInList) { >+ EXPECT_THAT((absl::InlinedVector<int, 2>{-7, 8ULL}), ElementsAre(-7, 8)); >+ >+ EXPECT_THAT((absl::InlinedVector<std::string, 2>{"foo", std::string("bar")}), >+ ElementsAre("foo", "bar")); >+} >+ >+TEST(InitializerListConstructor, ComplexTypeWithInlineBacking) { >+ EXPECT_THAT((absl::InlinedVector<CopyableMovableInstance, 1>{ >+ CopyableMovableInstance(0)}), >+ AllOf(SizeIs(1), CapacityIs(1), ElementsAre(ValueIs(0)))); >+} >+ >+TEST(InitializerListConstructor, ComplexTypeWithReallocationRequired) { >+ EXPECT_THAT( >+ (absl::InlinedVector<CopyableMovableInstance, 1>{ >+ CopyableMovableInstance(0), CopyableMovableInstance(1)}), >+ AllOf(SizeIs(2), CapacityIs(Gt(1)), ElementsAre(ValueIs(0), ValueIs(1)))); >+} >+ >+TEST(InitializerListAssign, SimpleTypeFitsInlineBacking) { >+ for (size_t original_size = 0; original_size <= 4; ++original_size) { >+ SCOPED_TRACE(original_size); >+ >+ absl::InlinedVector<int, 2> v1(original_size, 12345); >+ const size_t original_capacity_v1 = v1.capacity(); >+ v1.assign({3}); >+ EXPECT_THAT( >+ v1, AllOf(SizeIs(1), CapacityIs(original_capacity_v1), ElementsAre(3))); >+ >+ absl::InlinedVector<int, 2> v2(original_size, 12345); >+ const size_t original_capacity_v2 = v2.capacity(); >+ v2 = {3}; >+ EXPECT_THAT( >+ v2, AllOf(SizeIs(1), CapacityIs(original_capacity_v2), ElementsAre(3))); >+ } >+} >+ >+TEST(InitializerListAssign, SimpleTypeDoesNotFitInlineBacking) { >+ for (size_t original_size = 0; original_size <= 4; ++original_size) { >+ SCOPED_TRACE(original_size); >+ absl::InlinedVector<int, 2> v1(original_size, 12345); >+ v1.assign({3, 4, 5}); >+ EXPECT_THAT(v1, AllOf(SizeIs(3), ElementsAre(3, 4, 5))); >+ EXPECT_LE(3, v1.capacity()); >+ >+ absl::InlinedVector<int, 2> v2(original_size, 12345); >+ v2 = {3, 4, 5}; >+ EXPECT_THAT(v2, AllOf(SizeIs(3), ElementsAre(3, 4, 5))); >+ EXPECT_LE(3, v2.capacity()); >+ } >+} >+ >+TEST(InitializerListAssign, DisparateTypesInList) { >+ absl::InlinedVector<int, 2> v_int1; >+ v_int1.assign({-7, 8ULL}); >+ EXPECT_THAT(v_int1, ElementsAre(-7, 8)); >+ >+ absl::InlinedVector<int, 2> v_int2; >+ v_int2 = {-7, 8ULL}; >+ EXPECT_THAT(v_int2, ElementsAre(-7, 8)); >+ >+ absl::InlinedVector<std::string, 2> v_string1; >+ v_string1.assign({"foo", std::string("bar")}); >+ EXPECT_THAT(v_string1, ElementsAre("foo", "bar")); >+ >+ absl::InlinedVector<std::string, 2> v_string2; >+ v_string2 = {"foo", std::string("bar")}; >+ EXPECT_THAT(v_string2, ElementsAre("foo", "bar")); >+} >+ >+TYPED_TEST_P(InstanceTest, InitializerListAssign) { >+ using Instance = TypeParam; >+ for (size_t original_size = 0; original_size <= 4; ++original_size) { >+ SCOPED_TRACE(original_size); >+ absl::InlinedVector<Instance, 2> v(original_size, Instance(12345)); >+ const size_t original_capacity = v.capacity(); >+ v.assign({Instance(3)}); >+ EXPECT_THAT(v, AllOf(SizeIs(1), CapacityIs(original_capacity), >+ ElementsAre(ValueIs(3)))); >+ } >+ for (size_t original_size = 0; original_size <= 4; ++original_size) { >+ SCOPED_TRACE(original_size); >+ absl::InlinedVector<Instance, 2> v(original_size, Instance(12345)); >+ v.assign({Instance(3), Instance(4), Instance(5)}); >+ EXPECT_THAT(v, AllOf(SizeIs(3), >+ ElementsAre(ValueIs(3), ValueIs(4), ValueIs(5)))); >+ EXPECT_LE(3, v.capacity()); >+ } >+} >+ >+REGISTER_TYPED_TEST_CASE_P(InstanceTest, Swap, CountConstructorsDestructors, >+ CountConstructorsDestructorsOnCopyConstruction, >+ CountConstructorsDestructorsOnMoveConstruction, >+ CountConstructorsDestructorsOnAssignment, >+ CountConstructorsDestructorsOnMoveAssignment, >+ CountElemAssignInlineBacking, RangedConstructor, >+ RangedAssign, InitializerListAssign); >+ >+using InstanceTypes = >+ ::testing::Types<CopyableOnlyInstance, CopyableMovableInstance>; >+INSTANTIATE_TYPED_TEST_CASE_P(InstanceTestOnTypes, InstanceTest, InstanceTypes); >+ >+TEST(DynamicVec, DynamicVecCompiles) { >+ DynamicVec v; >+ (void)v; >+} >+ >+TEST(AllocatorSupportTest, Constructors) { >+ using MyAlloc = CountingAllocator<int>; >+ using AllocVec = absl::InlinedVector<int, 4, MyAlloc>; >+ const int ia[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; >+ int64_t allocated = 0; >+ MyAlloc alloc(&allocated); >+ { AllocVec ABSL_ATTRIBUTE_UNUSED v; } >+ { AllocVec ABSL_ATTRIBUTE_UNUSED v(alloc); } >+ { AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc); } >+ { AllocVec ABSL_ATTRIBUTE_UNUSED v({1, 2, 3}, alloc); } >+ >+ AllocVec v2; >+ { AllocVec ABSL_ATTRIBUTE_UNUSED v(v2, alloc); } >+ { AllocVec ABSL_ATTRIBUTE_UNUSED v(std::move(v2), alloc); } >+} >+ >+TEST(AllocatorSupportTest, CountAllocations) { >+ using MyAlloc = CountingAllocator<int>; >+ using AllocVec = absl::InlinedVector<int, 4, MyAlloc>; >+ const int ia[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; >+ int64_t allocated = 0; >+ MyAlloc alloc(&allocated); >+ { >+ AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + 4, alloc); >+ EXPECT_THAT(allocated, 0); >+ } >+ EXPECT_THAT(allocated, 0); >+ { >+ AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc); >+ EXPECT_THAT(allocated, v.size() * sizeof(int)); >+ } >+ EXPECT_THAT(allocated, 0); >+ { >+ AllocVec v(4, 1, alloc); >+ EXPECT_THAT(allocated, 0); >+ >+ int64_t allocated2 = 0; >+ MyAlloc alloc2(&allocated2); >+ AllocVec v2(v, alloc2); >+ EXPECT_THAT(allocated2, 0); >+ >+ int64_t allocated3 = 0; >+ MyAlloc alloc3(&allocated3); >+ AllocVec v3(std::move(v), alloc3); >+ EXPECT_THAT(allocated3, 0); >+ } >+ EXPECT_THAT(allocated, 0); >+ { >+ AllocVec v(8, 2, alloc); >+ EXPECT_THAT(allocated, v.size() * sizeof(int)); >+ >+ int64_t allocated2 = 0; >+ MyAlloc alloc2(&allocated2); >+ AllocVec v2(v, alloc2); >+ EXPECT_THAT(allocated2, v2.size() * sizeof(int)); >+ >+ int64_t allocated3 = 0; >+ MyAlloc alloc3(&allocated3); >+ AllocVec v3(std::move(v), alloc3); >+ EXPECT_THAT(allocated3, v3.size() * sizeof(int)); >+ } >+ EXPECT_EQ(allocated, 0); >+ { >+ // Test shrink_to_fit deallocations. >+ AllocVec v(8, 2, alloc); >+ EXPECT_EQ(allocated, 8 * sizeof(int)); >+ v.resize(5); >+ EXPECT_EQ(allocated, 8 * sizeof(int)); >+ v.shrink_to_fit(); >+ EXPECT_EQ(allocated, 5 * sizeof(int)); >+ v.resize(4); >+ EXPECT_EQ(allocated, 5 * sizeof(int)); >+ v.shrink_to_fit(); >+ EXPECT_EQ(allocated, 0); >+ } >+} >+ >+TEST(AllocatorSupportTest, SwapBothAllocated) { >+ using MyAlloc = CountingAllocator<int>; >+ using AllocVec = absl::InlinedVector<int, 4, MyAlloc>; >+ int64_t allocated1 = 0; >+ int64_t allocated2 = 0; >+ { >+ const int ia1[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; >+ const int ia2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; >+ MyAlloc a1(&allocated1); >+ MyAlloc a2(&allocated2); >+ AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1); >+ AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2); >+ EXPECT_LT(v1.capacity(), v2.capacity()); >+ EXPECT_THAT(allocated1, v1.capacity() * sizeof(int)); >+ EXPECT_THAT(allocated2, v2.capacity() * sizeof(int)); >+ v1.swap(v2); >+ EXPECT_THAT(v1, ElementsAreArray(ia2)); >+ EXPECT_THAT(v2, ElementsAreArray(ia1)); >+ EXPECT_THAT(allocated1, v2.capacity() * sizeof(int)); >+ EXPECT_THAT(allocated2, v1.capacity() * sizeof(int)); >+ } >+ EXPECT_THAT(allocated1, 0); >+ EXPECT_THAT(allocated2, 0); >+} >+ >+TEST(AllocatorSupportTest, SwapOneAllocated) { >+ using MyAlloc = CountingAllocator<int>; >+ using AllocVec = absl::InlinedVector<int, 4, MyAlloc>; >+ int64_t allocated1 = 0; >+ int64_t allocated2 = 0; >+ { >+ const int ia1[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; >+ const int ia2[] = { 0, 1, 2, 3 }; >+ MyAlloc a1(&allocated1); >+ MyAlloc a2(&allocated2); >+ AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1); >+ AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2); >+ EXPECT_THAT(allocated1, v1.capacity() * sizeof(int)); >+ EXPECT_THAT(allocated2, 0); >+ v1.swap(v2); >+ EXPECT_THAT(v1, ElementsAreArray(ia2)); >+ EXPECT_THAT(v2, ElementsAreArray(ia1)); >+ EXPECT_THAT(allocated1, v2.capacity() * sizeof(int)); >+ EXPECT_THAT(allocated2, 0); >+ EXPECT_TRUE(v2.get_allocator() == a1); >+ EXPECT_TRUE(v1.get_allocator() == a2); >+ } >+ EXPECT_THAT(allocated1, 0); >+ EXPECT_THAT(allocated2, 0); >+} >+ >+TEST(AllocatorSupportTest, ScopedAllocatorWorks) { >+ using StdVector = std::vector<int, CountingAllocator<int>>; >+ using MyAlloc = >+ std::scoped_allocator_adaptor<CountingAllocator<StdVector>>; >+ using AllocVec = absl::InlinedVector<StdVector, 4, MyAlloc>; >+ >+ int64_t allocated = 0; >+ AllocVec vec(MyAlloc{CountingAllocator<StdVector>{&allocated}}); >+ EXPECT_EQ(allocated, 0); >+ >+ // This default constructs a vector<int>, but the allocator should pass itself >+ // into the vector<int>. >+ // The absl::InlinedVector does not allocate any memory. >+ // The vector<int> does not allocate any memory. >+ vec.resize(1); >+ EXPECT_EQ(allocated, 0); >+ >+ // We make vector<int> allocate memory. >+ // It must go through the allocator even though we didn't construct the >+ // vector directly. >+ vec[0].push_back(1); >+ EXPECT_EQ(allocated, sizeof(int) * 1); >+ >+ // Another allocating vector. >+ vec.push_back(vec[0]); >+ EXPECT_EQ(allocated, sizeof(int) * 2); >+ >+ // Overflow the inlined memory. >+ // The absl::InlinedVector will now allocate. >+ vec.resize(5); >+ EXPECT_EQ(allocated, sizeof(int) * 2 + sizeof(StdVector) * 8); >+ >+ // Adding one more in external mode should also work. >+ vec.push_back(vec[0]); >+ EXPECT_EQ(allocated, sizeof(int) * 3 + sizeof(StdVector) * 8); >+ >+ // And extending these should still work. >+ vec[0].push_back(1); >+ EXPECT_EQ(allocated, sizeof(int) * 4 + sizeof(StdVector) * 8); >+ >+ vec.clear(); >+ EXPECT_EQ(allocated, 0); >+} >+ >+TEST(AllocatorSupportTest, SizeAllocConstructor) { >+ constexpr int inlined_size = 4; >+ using Alloc = CountingAllocator<int>; >+ using AllocVec = absl::InlinedVector<int, inlined_size, Alloc>; >+ >+ { >+ auto len = inlined_size / 2; >+ int64_t allocated = 0; >+ auto v = AllocVec(len, Alloc(&allocated)); >+ >+ // Inline storage used; allocator should not be invoked >+ EXPECT_THAT(allocated, 0); >+ EXPECT_THAT(v, AllOf(SizeIs(len), Each(0))); >+ } >+ >+ { >+ auto len = inlined_size * 2; >+ int64_t allocated = 0; >+ auto v = AllocVec(len, Alloc(&allocated)); >+ >+ // Out of line storage used; allocation of 8 elements expected >+ EXPECT_THAT(allocated, len * sizeof(int)); >+ EXPECT_THAT(v, AllOf(SizeIs(len), Each(0))); >+ } >+} >+} // anonymous namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h >new file mode 100644 >index 0000000000000000000000000000000000000000..cc52614f5b37ff3774beb3103cba1be950be9d7b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h >@@ -0,0 +1,175 @@ >+// 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. >+// >+// Helper class to perform the Empty Base Optimization. >+// Ts can contain classes and non-classes, empty or not. For the ones that >+// are empty classes, we perform the optimization. If all types in Ts are empty >+// classes, then CompressedTuple<Ts...> is itself an empty class. >+// >+// To access the members, use member get<N>() function. >+// >+// Eg: >+// absl::container_internal::CompressedTuple<int, T1, T2, T3> value(7, t1, t2, >+// t3); >+// assert(value.get<0>() == 7); >+// T1& t1 = value.get<1>(); >+// const T2& t2 = value.get<2>(); >+// ... >+// >+// http://en.cppreference.com/w/cpp/language/ebo >+ >+#ifndef ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ >+#define ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ >+ >+#include <tuple> >+#include <type_traits> >+#include <utility> >+ >+#include "absl/utility/utility.h" >+ >+#ifdef _MSC_VER >+// We need to mark these classes with this declspec to ensure that >+// CompressedTuple happens. >+#define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC __declspec(empty_bases) >+#else // _MSC_VER >+#define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC >+#endif // _MSC_VER >+ >+namespace absl { >+namespace container_internal { >+ >+template <typename... Ts> >+class CompressedTuple; >+ >+namespace internal_compressed_tuple { >+ >+template <typename D, size_t I> >+struct Elem; >+template <typename... B, size_t I> >+struct Elem<CompressedTuple<B...>, I> >+ : std::tuple_element<I, std::tuple<B...>> {}; >+template <typename D, size_t I> >+using ElemT = typename Elem<D, I>::type; >+ >+// Use the __is_final intrinsic if available. Where it's not available, classes >+// declared with the 'final' specifier cannot be used as CompressedTuple >+// elements. >+// TODO(sbenza): Replace this with std::is_final in C++14. >+template <typename T> >+constexpr bool IsFinal() { >+#if defined(__clang__) || defined(__GNUC__) >+ return __is_final(T); >+#else >+ return false; >+#endif >+} >+ >+template <typename T> >+constexpr bool ShouldUseBase() { >+ return std::is_class<T>::value && std::is_empty<T>::value && !IsFinal<T>(); >+} >+ >+// The storage class provides two specializations: >+// - For empty classes, it stores T as a base class. >+// - For everything else, it stores T as a member. >+template <typename D, size_t I, bool = ShouldUseBase<ElemT<D, I>>()> >+struct Storage { >+ using T = ElemT<D, I>; >+ T value; >+ constexpr Storage() = default; >+ explicit constexpr Storage(T&& v) : value(absl::forward<T>(v)) {} >+ constexpr const T& get() const { return value; } >+ T& get() { return value; } >+}; >+ >+template <typename D, size_t I> >+struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC Storage<D, I, true> >+ : ElemT<D, I> { >+ using T = internal_compressed_tuple::ElemT<D, I>; >+ constexpr Storage() = default; >+ explicit constexpr Storage(T&& v) : T(absl::forward<T>(v)) {} >+ constexpr const T& get() const { return *this; } >+ T& get() { return *this; } >+}; >+ >+template <typename D, typename I> >+struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl; >+ >+template <typename... Ts, size_t... I> >+struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC >+ CompressedTupleImpl<CompressedTuple<Ts...>, absl::index_sequence<I...>> >+ // We use the dummy identity function through std::integral_constant to >+ // convince MSVC of accepting and expanding I in that context. Without it >+ // you would get: >+ // error C3548: 'I': parameter pack cannot be used in this context >+ : Storage<CompressedTuple<Ts...>, >+ std::integral_constant<size_t, I>::value>... { >+ constexpr CompressedTupleImpl() = default; >+ explicit constexpr CompressedTupleImpl(Ts&&... args) >+ : Storage<CompressedTuple<Ts...>, I>(absl::forward<Ts>(args))... {} >+}; >+ >+} // namespace internal_compressed_tuple >+ >+// Helper class to perform the Empty Base Class Optimization. >+// Ts can contain classes and non-classes, empty or not. For the ones that >+// are empty classes, we perform the CompressedTuple. If all types in Ts are >+// empty classes, then CompressedTuple<Ts...> is itself an empty class. >+// >+// To access the members, use member .get<N>() function. >+// >+// Eg: >+// absl::container_internal::CompressedTuple<int, T1, T2, T3> value(7, t1, t2, >+// t3); >+// assert(value.get<0>() == 7); >+// T1& t1 = value.get<1>(); >+// const T2& t2 = value.get<2>(); >+// ... >+// >+// http://en.cppreference.com/w/cpp/language/ebo >+template <typename... Ts> >+class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple >+ : private internal_compressed_tuple::CompressedTupleImpl< >+ CompressedTuple<Ts...>, absl::index_sequence_for<Ts...>> { >+ private: >+ template <int I> >+ using ElemT = internal_compressed_tuple::ElemT<CompressedTuple, I>; >+ >+ public: >+ constexpr CompressedTuple() = default; >+ explicit constexpr CompressedTuple(Ts... base) >+ : CompressedTuple::CompressedTupleImpl(absl::forward<Ts>(base)...) {} >+ >+ template <int I> >+ ElemT<I>& get() { >+ return internal_compressed_tuple::Storage<CompressedTuple, I>::get(); >+ } >+ >+ template <int I> >+ constexpr const ElemT<I>& get() const { >+ return internal_compressed_tuple::Storage<CompressedTuple, I>::get(); >+ } >+}; >+ >+// Explicit specialization for a zero-element tuple >+// (needed to avoid ambiguous overloads for the default constructor). >+template <> >+class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple<> {}; >+ >+} // namespace container_internal >+} // namespace absl >+ >+#undef ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC >+ >+#endif // ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/compressed_tuple_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/compressed_tuple_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..45030c675ee1adaf24272401b26cbd9ac53a97a7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/compressed_tuple_test.cc >@@ -0,0 +1,166 @@ >+// 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/container/internal/compressed_tuple.h" >+ >+#include <string> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+ >+namespace absl { >+namespace container_internal { >+namespace { >+ >+template <int> >+struct Empty {}; >+ >+template <typename T> >+struct NotEmpty { >+ T value; >+}; >+ >+template <typename T, typename U> >+struct TwoValues { >+ T value1; >+ U value2; >+}; >+ >+TEST(CompressedTupleTest, Sizeof) { >+ EXPECT_EQ(sizeof(int), sizeof(CompressedTuple<int>)); >+ EXPECT_EQ(sizeof(int), sizeof(CompressedTuple<int, Empty<0>>)); >+ EXPECT_EQ(sizeof(int), sizeof(CompressedTuple<int, Empty<0>, Empty<1>>)); >+ EXPECT_EQ(sizeof(int), >+ sizeof(CompressedTuple<int, Empty<0>, Empty<1>, Empty<2>>)); >+ >+ EXPECT_EQ(sizeof(TwoValues<int, double>), >+ sizeof(CompressedTuple<int, NotEmpty<double>>)); >+ EXPECT_EQ(sizeof(TwoValues<int, double>), >+ sizeof(CompressedTuple<int, Empty<0>, NotEmpty<double>>)); >+ EXPECT_EQ(sizeof(TwoValues<int, double>), >+ sizeof(CompressedTuple<int, Empty<0>, NotEmpty<double>, Empty<1>>)); >+} >+ >+TEST(CompressedTupleTest, Access) { >+ struct S { >+ std::string x; >+ }; >+ CompressedTuple<int, Empty<0>, S> x(7, {}, S{"ABC"}); >+ EXPECT_EQ(sizeof(x), sizeof(TwoValues<int, S>)); >+ EXPECT_EQ(7, x.get<0>()); >+ EXPECT_EQ("ABC", x.get<2>().x); >+} >+ >+TEST(CompressedTupleTest, NonClasses) { >+ CompressedTuple<int, const char*> x(7, "ABC"); >+ EXPECT_EQ(7, x.get<0>()); >+ EXPECT_STREQ("ABC", x.get<1>()); >+} >+ >+TEST(CompressedTupleTest, MixClassAndNonClass) { >+ CompressedTuple<int, const char*, Empty<0>, NotEmpty<double>> x(7, "ABC", {}, >+ {1.25}); >+ struct Mock { >+ int v; >+ const char* p; >+ double d; >+ }; >+ EXPECT_EQ(sizeof(x), sizeof(Mock)); >+ EXPECT_EQ(7, x.get<0>()); >+ EXPECT_STREQ("ABC", x.get<1>()); >+ EXPECT_EQ(1.25, x.get<3>().value); >+} >+ >+TEST(CompressedTupleTest, Nested) { >+ CompressedTuple<int, CompressedTuple<int>, >+ CompressedTuple<int, CompressedTuple<int>>> >+ x(1, CompressedTuple<int>(2), >+ CompressedTuple<int, CompressedTuple<int>>(3, CompressedTuple<int>(4))); >+ EXPECT_EQ(1, x.get<0>()); >+ EXPECT_EQ(2, x.get<1>().get<0>()); >+ EXPECT_EQ(3, x.get<2>().get<0>()); >+ EXPECT_EQ(4, x.get<2>().get<1>().get<0>()); >+ >+ CompressedTuple<Empty<0>, Empty<0>, >+ CompressedTuple<Empty<0>, CompressedTuple<Empty<0>>>> >+ y; >+ std::set<Empty<0>*> empties{&y.get<0>(), &y.get<1>(), &y.get<2>().get<0>(), >+ &y.get<2>().get<1>().get<0>()}; >+#ifdef _MSC_VER >+ // MSVC has a bug where many instances of the same base class are layed out in >+ // the same address when using __declspec(empty_bases). >+ // This will be fixed in a future version of MSVC. >+ int expected = 1; >+#else >+ int expected = 4; >+#endif >+ EXPECT_EQ(expected, sizeof(y)); >+ EXPECT_EQ(expected, empties.size()); >+ EXPECT_EQ(sizeof(y), sizeof(Empty<0>) * empties.size()); >+ >+ EXPECT_EQ(4 * sizeof(char), >+ sizeof(CompressedTuple<CompressedTuple<char, char>, >+ CompressedTuple<char, char>>)); >+ EXPECT_TRUE( >+ (std::is_empty<CompressedTuple<CompressedTuple<Empty<0>>, >+ CompressedTuple<Empty<1>>>>::value)); >+} >+ >+TEST(CompressedTupleTest, Reference) { >+ int i = 7; >+ std::string s = "Very long std::string that goes in the heap"; >+ CompressedTuple<int, int&, std::string, std::string&> x(i, i, s, s); >+ >+ // Sanity check. We should have not moved from `s` >+ EXPECT_EQ(s, "Very long std::string that goes in the heap"); >+ >+ EXPECT_EQ(x.get<0>(), x.get<1>()); >+ EXPECT_NE(&x.get<0>(), &x.get<1>()); >+ EXPECT_EQ(&x.get<1>(), &i); >+ >+ EXPECT_EQ(x.get<2>(), x.get<3>()); >+ EXPECT_NE(&x.get<2>(), &x.get<3>()); >+ EXPECT_EQ(&x.get<3>(), &s); >+} >+ >+TEST(CompressedTupleTest, NoElements) { >+ CompressedTuple<> x; >+ static_cast<void>(x); // Silence -Wunused-variable. >+ EXPECT_TRUE(std::is_empty<CompressedTuple<>>::value); >+} >+ >+TEST(CompressedTupleTest, Constexpr) { >+ constexpr CompressedTuple<int, double, CompressedTuple<int>> x( >+ 7, 1.25, CompressedTuple<int>(5)); >+ constexpr int x0 = x.get<0>(); >+ constexpr double x1 = x.get<1>(); >+ constexpr int x2 = x.get<2>().get<0>(); >+ EXPECT_EQ(x0, 7); >+ EXPECT_EQ(x1, 1.25); >+ EXPECT_EQ(x2, 5); >+} >+ >+#if defined(__clang__) || defined(__GNUC__) >+TEST(CompressedTupleTest, EmptyFinalClass) { >+ struct S final { >+ int f() const { return 5; } >+ }; >+ CompressedTuple<S> x; >+ EXPECT_EQ(x.get<0>().f(), 5); >+} >+#endif >+ >+} // namespace >+} // namespace container_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..fe00aca8fb98f120f235202369b0b5be876d4747 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.cc >@@ -0,0 +1,26 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/container/internal/test_instance_tracker.h" >+ >+namespace absl { >+namespace test_internal { >+int BaseCountedInstance::num_instances_ = 0; >+int BaseCountedInstance::num_live_instances_ = 0; >+int BaseCountedInstance::num_moves_ = 0; >+int BaseCountedInstance::num_copies_ = 0; >+int BaseCountedInstance::num_swaps_ = 0; >+ >+} // namespace test_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.h >new file mode 100644 >index 0000000000000000000000000000000000000000..cf8f3a531e6212fcaa13d6535170af86bffa698a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.h >@@ -0,0 +1,220 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_ >+#define ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_ >+ >+#include <cstdlib> >+#include <ostream> >+ >+namespace absl { >+namespace test_internal { >+ >+// A type that counts number of occurences of the type, the live occurrences of >+// the type, as well as the number of copies, moves, and swaps that have >+// occurred on the type. This is used as a base class for the copyable, >+// copyable+movable, and movable types below that are used in actual tests. Use >+// InstanceTracker in tests to track the number of instances. >+class BaseCountedInstance { >+ public: >+ explicit BaseCountedInstance(int x) : value_(x) { >+ ++num_instances_; >+ ++num_live_instances_; >+ } >+ BaseCountedInstance(const BaseCountedInstance& x) >+ : value_(x.value_), is_live_(x.is_live_) { >+ ++num_instances_; >+ if (is_live_) ++num_live_instances_; >+ ++num_copies_; >+ } >+ BaseCountedInstance(BaseCountedInstance&& x) >+ : value_(x.value_), is_live_(x.is_live_) { >+ x.is_live_ = false; >+ ++num_instances_; >+ ++num_moves_; >+ } >+ ~BaseCountedInstance() { >+ --num_instances_; >+ if (is_live_) --num_live_instances_; >+ } >+ >+ BaseCountedInstance& operator=(const BaseCountedInstance& x) { >+ value_ = x.value_; >+ if (is_live_) --num_live_instances_; >+ is_live_ = x.is_live_; >+ if (is_live_) ++num_live_instances_; >+ ++num_copies_; >+ return *this; >+ } >+ BaseCountedInstance& operator=(BaseCountedInstance&& x) { >+ value_ = x.value_; >+ if (is_live_) --num_live_instances_; >+ is_live_ = x.is_live_; >+ x.is_live_ = false; >+ ++num_moves_; >+ return *this; >+ } >+ >+ int value() const { >+ if (!is_live_) std::abort(); >+ return value_; >+ } >+ >+ friend std::ostream& operator<<(std::ostream& o, >+ const BaseCountedInstance& v) { >+ return o << "[value:" << v.value() << "]"; >+ } >+ >+ // Implementation of efficient swap() that counts swaps. >+ static void SwapImpl( >+ BaseCountedInstance& lhs, // NOLINT(runtime/references) >+ BaseCountedInstance& rhs) { // NOLINT(runtime/references) >+ using std::swap; >+ swap(lhs.value_, rhs.value_); >+ swap(lhs.is_live_, rhs.is_live_); >+ ++BaseCountedInstance::num_swaps_; >+ } >+ >+ private: >+ friend class InstanceTracker; >+ >+ int value_; >+ >+ // Indicates if the value is live, ie it hasn't been moved away from. >+ bool is_live_ = true; >+ >+ // Number of instances. >+ static int num_instances_; >+ >+ // Number of live instances (those that have not been moved away from.) >+ static int num_live_instances_; >+ >+ // Number of times that BaseCountedInstance objects were moved. >+ static int num_moves_; >+ >+ // Number of times that BaseCountedInstance objects were copied. >+ static int num_copies_; >+ >+ // Number of times that BaseCountedInstance objects were swapped. >+ static int num_swaps_; >+}; >+ >+// Helper to track the BaseCountedInstance instance counters. Expects that the >+// number of instances and live_instances are the same when it is constructed >+// and when it is destructed. >+class InstanceTracker { >+ public: >+ InstanceTracker() >+ : start_instances_(BaseCountedInstance::num_instances_), >+ start_live_instances_(BaseCountedInstance::num_live_instances_) { >+ ResetCopiesMovesSwaps(); >+ } >+ ~InstanceTracker() { >+ if (instances() != 0) std::abort(); >+ if (live_instances() != 0) std::abort(); >+ } >+ >+ // Returns the number of BaseCountedInstance instances both containing valid >+ // values and those moved away from compared to when the InstanceTracker was >+ // constructed >+ int instances() const { >+ return BaseCountedInstance::num_instances_ - start_instances_; >+ } >+ >+ // Returns the number of live BaseCountedInstance instances compared to when >+ // the InstanceTracker was constructed >+ int live_instances() const { >+ return BaseCountedInstance::num_live_instances_ - start_live_instances_; >+ } >+ >+ // Returns the number of moves on BaseCountedInstance objects since >+ // construction or since the last call to ResetCopiesMovesSwaps(). >+ int moves() const { return BaseCountedInstance::num_moves_ - start_moves_; } >+ >+ // Returns the number of copies on BaseCountedInstance objects since >+ // construction or the last call to ResetCopiesMovesSwaps(). >+ int copies() const { >+ return BaseCountedInstance::num_copies_ - start_copies_; >+ } >+ >+ // Returns the number of swaps on BaseCountedInstance objects since >+ // construction or the last call to ResetCopiesMovesSwaps(). >+ int swaps() const { return BaseCountedInstance::num_swaps_ - start_swaps_; } >+ >+ // Resets the base values for moves, copies and swaps to the current values, >+ // so that subsequent Get*() calls for moves, copies and swaps will compare to >+ // the situation at the point of this call. >+ void ResetCopiesMovesSwaps() { >+ start_moves_ = BaseCountedInstance::num_moves_; >+ start_copies_ = BaseCountedInstance::num_copies_; >+ start_swaps_ = BaseCountedInstance::num_swaps_; >+ } >+ >+ private: >+ int start_instances_; >+ int start_live_instances_; >+ int start_moves_; >+ int start_copies_; >+ int start_swaps_; >+}; >+ >+// Copyable, not movable. >+class CopyableOnlyInstance : public BaseCountedInstance { >+ public: >+ explicit CopyableOnlyInstance(int x) : BaseCountedInstance(x) {} >+ CopyableOnlyInstance(const CopyableOnlyInstance& rhs) = default; >+ CopyableOnlyInstance& operator=(const CopyableOnlyInstance& rhs) = default; >+ >+ friend void swap(CopyableOnlyInstance& lhs, CopyableOnlyInstance& rhs) { >+ BaseCountedInstance::SwapImpl(lhs, rhs); >+ } >+ >+ static bool supports_move() { return false; } >+}; >+ >+// Copyable and movable. >+class CopyableMovableInstance : public BaseCountedInstance { >+ public: >+ explicit CopyableMovableInstance(int x) : BaseCountedInstance(x) {} >+ CopyableMovableInstance(const CopyableMovableInstance& rhs) = default; >+ CopyableMovableInstance(CopyableMovableInstance&& rhs) = default; >+ CopyableMovableInstance& operator=(const CopyableMovableInstance& rhs) = >+ default; >+ CopyableMovableInstance& operator=(CopyableMovableInstance&& rhs) = default; >+ >+ friend void swap(CopyableMovableInstance& lhs, CopyableMovableInstance& rhs) { >+ BaseCountedInstance::SwapImpl(lhs, rhs); >+ } >+ >+ static bool supports_move() { return true; } >+}; >+ >+// Only movable, not default-constructible. >+class MovableOnlyInstance : public BaseCountedInstance { >+ public: >+ explicit MovableOnlyInstance(int x) : BaseCountedInstance(x) {} >+ MovableOnlyInstance(MovableOnlyInstance&& other) = default; >+ MovableOnlyInstance& operator=(MovableOnlyInstance&& other) = default; >+ >+ friend void swap(MovableOnlyInstance& lhs, MovableOnlyInstance& rhs) { >+ BaseCountedInstance::SwapImpl(lhs, rhs); >+ } >+ >+ static bool supports_move() { return true; } >+}; >+ >+} // namespace test_internal >+} // namespace absl >+ >+#endif // ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/test_instance_tracker_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/test_instance_tracker_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..9efb6771cf086db16fef39460c591921ecd5f691 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/container/internal/test_instance_tracker_test.cc >@@ -0,0 +1,160 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/container/internal/test_instance_tracker.h" >+ >+#include "gtest/gtest.h" >+ >+namespace { >+ >+using absl::test_internal::CopyableMovableInstance; >+using absl::test_internal::CopyableOnlyInstance; >+using absl::test_internal::InstanceTracker; >+using absl::test_internal::MovableOnlyInstance; >+ >+TEST(TestInstanceTracker, CopyableMovable) { >+ InstanceTracker tracker; >+ CopyableMovableInstance src(1); >+ EXPECT_EQ(1, src.value()) << src; >+ CopyableMovableInstance copy(src); >+ CopyableMovableInstance move(std::move(src)); >+ EXPECT_EQ(1, tracker.copies()); >+ EXPECT_EQ(1, tracker.moves()); >+ EXPECT_EQ(0, tracker.swaps()); >+ EXPECT_EQ(3, tracker.instances()); >+ EXPECT_EQ(2, tracker.live_instances()); >+ tracker.ResetCopiesMovesSwaps(); >+ >+ CopyableMovableInstance copy_assign(1); >+ copy_assign = copy; >+ CopyableMovableInstance move_assign(1); >+ move_assign = std::move(move); >+ EXPECT_EQ(1, tracker.copies()); >+ EXPECT_EQ(1, tracker.moves()); >+ EXPECT_EQ(0, tracker.swaps()); >+ EXPECT_EQ(5, tracker.instances()); >+ EXPECT_EQ(3, tracker.live_instances()); >+ tracker.ResetCopiesMovesSwaps(); >+ >+ { >+ using std::swap; >+ swap(move_assign, copy); >+ swap(copy, move_assign); >+ EXPECT_EQ(2, tracker.swaps()); >+ EXPECT_EQ(0, tracker.copies()); >+ EXPECT_EQ(0, tracker.moves()); >+ EXPECT_EQ(5, tracker.instances()); >+ EXPECT_EQ(3, tracker.live_instances()); >+ } >+} >+ >+TEST(TestInstanceTracker, CopyableOnly) { >+ InstanceTracker tracker; >+ CopyableOnlyInstance src(1); >+ EXPECT_EQ(1, src.value()) << src; >+ CopyableOnlyInstance copy(src); >+ CopyableOnlyInstance copy2(std::move(src)); // NOLINT >+ EXPECT_EQ(2, tracker.copies()); >+ EXPECT_EQ(0, tracker.moves()); >+ EXPECT_EQ(3, tracker.instances()); >+ EXPECT_EQ(3, tracker.live_instances()); >+ tracker.ResetCopiesMovesSwaps(); >+ >+ CopyableOnlyInstance copy_assign(1); >+ copy_assign = copy; >+ CopyableOnlyInstance copy_assign2(1); >+ copy_assign2 = std::move(copy2); // NOLINT >+ EXPECT_EQ(2, tracker.copies()); >+ EXPECT_EQ(0, tracker.moves()); >+ EXPECT_EQ(5, tracker.instances()); >+ EXPECT_EQ(5, tracker.live_instances()); >+ tracker.ResetCopiesMovesSwaps(); >+ >+ { >+ using std::swap; >+ swap(src, copy); >+ swap(copy, src); >+ EXPECT_EQ(2, tracker.swaps()); >+ EXPECT_EQ(0, tracker.copies()); >+ EXPECT_EQ(0, tracker.moves()); >+ EXPECT_EQ(5, tracker.instances()); >+ EXPECT_EQ(5, tracker.live_instances()); >+ } >+} >+ >+TEST(TestInstanceTracker, MovableOnly) { >+ InstanceTracker tracker; >+ MovableOnlyInstance src(1); >+ EXPECT_EQ(1, src.value()) << src; >+ MovableOnlyInstance move(std::move(src)); >+ MovableOnlyInstance move_assign(2); >+ move_assign = std::move(move); >+ EXPECT_EQ(3, tracker.instances()); >+ EXPECT_EQ(1, tracker.live_instances()); >+ EXPECT_EQ(2, tracker.moves()); >+ EXPECT_EQ(0, tracker.copies()); >+ tracker.ResetCopiesMovesSwaps(); >+ >+ { >+ using std::swap; >+ MovableOnlyInstance other(2); >+ swap(move_assign, other); >+ swap(other, move_assign); >+ EXPECT_EQ(2, tracker.swaps()); >+ EXPECT_EQ(0, tracker.copies()); >+ EXPECT_EQ(0, tracker.moves()); >+ EXPECT_EQ(4, tracker.instances()); >+ EXPECT_EQ(2, tracker.live_instances()); >+ } >+} >+ >+TEST(TestInstanceTracker, ExistingInstances) { >+ CopyableMovableInstance uncounted_instance(1); >+ CopyableMovableInstance uncounted_live_instance( >+ std::move(uncounted_instance)); >+ InstanceTracker tracker; >+ EXPECT_EQ(0, tracker.instances()); >+ EXPECT_EQ(0, tracker.live_instances()); >+ EXPECT_EQ(0, tracker.copies()); >+ { >+ CopyableMovableInstance instance1(1); >+ EXPECT_EQ(1, tracker.instances()); >+ EXPECT_EQ(1, tracker.live_instances()); >+ EXPECT_EQ(0, tracker.copies()); >+ EXPECT_EQ(0, tracker.moves()); >+ { >+ InstanceTracker tracker2; >+ CopyableMovableInstance instance2(instance1); >+ CopyableMovableInstance instance3(std::move(instance2)); >+ EXPECT_EQ(3, tracker.instances()); >+ EXPECT_EQ(2, tracker.live_instances()); >+ EXPECT_EQ(1, tracker.copies()); >+ EXPECT_EQ(1, tracker.moves()); >+ EXPECT_EQ(2, tracker2.instances()); >+ EXPECT_EQ(1, tracker2.live_instances()); >+ EXPECT_EQ(1, tracker2.copies()); >+ EXPECT_EQ(1, tracker2.moves()); >+ } >+ EXPECT_EQ(1, tracker.instances()); >+ EXPECT_EQ(1, tracker.live_instances()); >+ EXPECT_EQ(1, tracker.copies()); >+ EXPECT_EQ(1, tracker.moves()); >+ } >+ EXPECT_EQ(0, tracker.instances()); >+ EXPECT_EQ(0, tracker.live_instances()); >+ EXPECT_EQ(1, tracker.copies()); >+ EXPECT_EQ(1, tracker.moves()); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/copts.bzl b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/copts.bzl >new file mode 100644 >index 0000000000000000000000000000000000000000..0168ac5abddc39ff7c4781ff5e3e2e9be0a2057e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/copts.bzl >@@ -0,0 +1,154 @@ >+"""absl specific copts. >+ >+Flags specified here must not impact ABI. Code compiled with and without these >+opts will be linked together, and in some cases headers compiled with and >+without these options will be part of the same program. >+""" >+GCC_FLAGS = [ >+ "-Wall", >+ "-Wextra", >+ "-Wcast-qual", >+ "-Wconversion-null", >+ "-Wmissing-declarations", >+ "-Woverlength-strings", >+ "-Wpointer-arith", >+ "-Wunused-local-typedefs", >+ "-Wunused-result", >+ "-Wvarargs", >+ "-Wvla", # variable-length array >+ "-Wwrite-strings", >+ # Google style does not use unsigned integers, though STL containers >+ # have unsigned types. >+ "-Wno-sign-compare", >+] >+ >+GCC_TEST_FLAGS = [ >+ "-Wno-conversion-null", >+ "-Wno-missing-declarations", >+ "-Wno-sign-compare", >+ "-Wno-unused-function", >+ "-Wno-unused-parameter", >+ "-Wno-unused-private-field", >+] >+ >+# Docs on single flags is preceded by a comment. >+# Docs on groups of flags is preceded by ###. >+ >+LLVM_FLAGS = [ >+ # All warnings are treated as errors by implicit -Werror flag >+ "-Wall", >+ "-Wextra", >+ "-Weverything", >+ # Abseil does not support C++98 >+ "-Wno-c++98-compat-pedantic", >+ # Turns off all implicit conversion warnings. Most are re-enabled below. >+ "-Wno-conversion", >+ "-Wno-covered-switch-default", >+ "-Wno-deprecated", >+ "-Wno-disabled-macro-expansion", >+ "-Wno-double-promotion", >+ ### >+ # Turned off as they include valid C++ code. >+ "-Wno-comma", >+ "-Wno-extra-semi", >+ "-Wno-packed", >+ "-Wno-padded", >+ ### >+ "-Wno-float-conversion", >+ "-Wno-float-equal", >+ "-Wno-format-nonliteral", >+ # Too aggressive: warns on Clang extensions enclosed in Clang-only >+ # compilation paths. >+ "-Wno-gcc-compat", >+ ### >+ # Some internal globals are necessary. Don't do this at home. >+ "-Wno-global-constructors", >+ "-Wno-exit-time-destructors", >+ ### >+ "-Wno-nested-anon-types", >+ "-Wno-non-modular-include-in-module", >+ "-Wno-old-style-cast", >+ # Warns on preferred usage of non-POD types such as string_view >+ "-Wno-range-loop-analysis", >+ "-Wno-reserved-id-macro", >+ "-Wno-shorten-64-to-32", >+ "-Wno-switch-enum", >+ "-Wno-thread-safety-negative", >+ "-Wno-undef", >+ "-Wno-unknown-warning-option", >+ "-Wno-unreachable-code", >+ # Causes warnings on include guards >+ "-Wno-unused-macros", >+ "-Wno-weak-vtables", >+ ### >+ # Implicit conversion warnings turned off by -Wno-conversion >+ # which are re-enabled below. >+ "-Wbitfield-enum-conversion", >+ "-Wbool-conversion", >+ "-Wconstant-conversion", >+ "-Wenum-conversion", >+ "-Wint-conversion", >+ "-Wliteral-conversion", >+ "-Wnon-literal-null-conversion", >+ "-Wnull-conversion", >+ "-Wobjc-literal-conversion", >+ "-Wno-sign-conversion", >+ "-Wstring-conversion", >+ ### >+] >+ >+LLVM_TEST_FLAGS = [ >+ "-Wno-c99-extensions", >+ "-Wno-missing-noreturn", >+ "-Wno-missing-prototypes", >+ "-Wno-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", >+] >+ >+MSVC_FLAGS = [ >+ "/W3", >+ "/WX", >+ "/wd4005", # macro-redefinition >+ "/wd4068", # unknown pragma >+ "/wd4244", # conversion from 'type1' to 'type2', possible loss of data >+ "/wd4267", # conversion from 'size_t' to 'type', possible loss of data >+ "/wd4800", # forcing value to bool 'true' or 'false' (performance warning) >+ "/DNOMINMAX", # Don't define min and max macros (windows.h) >+ "/DWIN32_LEAN_AND_MEAN", # Don't bloat namespace with incompatible winsock versions. >+ "/D_CRT_SECURE_NO_WARNINGS", # Don't warn about usage of insecure C functions >+] >+ >+MSVC_TEST_FLAGS = [ >+ "/wd4018", # signed/unsigned mismatch >+ "/wd4101", # unreferenced local variable >+ "/wd4503", # decorated name length exceeded, name was truncated >+] >+ >+# /Wall with msvc includes unhelpful warnings such as C4711, C4710, ... >+ABSL_DEFAULT_COPTS = select({ >+ "//absl:windows": MSVC_FLAGS, >+ "//absl:llvm_compiler": LLVM_FLAGS, >+ "//conditions:default": GCC_FLAGS, >+}) >+ >+# in absence of modules (--compiler=gcc or -c opt), cc_tests leak their copts >+# to their (included header) dependencies and fail to build outside absl >+ABSL_TEST_COPTS = ABSL_DEFAULT_COPTS + select({ >+ "//absl:windows": MSVC_TEST_FLAGS, >+ "//absl:llvm_compiler": LLVM_TEST_FLAGS, >+ "//conditions:default": GCC_TEST_FLAGS, >+}) >+ >+ABSL_EXCEPTIONS_FLAG = select({ >+ "//absl:windows": ["/U_HAS_EXCEPTIONS", "/D_HAS_EXCEPTIONS=1", "/EHsc"], >+ "//conditions:default": ["-fexceptions"], >+}) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..e1e7fced69fb9a9cf448493deeacde9864d97989 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/BUILD.bazel >@@ -0,0 +1,305 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+) >+ >+package( >+ default_visibility = ["//visibility:public"], >+) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+cc_library( >+ name = "stacktrace", >+ srcs = [ >+ "stacktrace.cc", >+ ], >+ hdrs = ["stacktrace.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":debugging_internal", >+ "//absl/base", >+ "//absl/base:core_headers", >+ ], >+) >+ >+cc_library( >+ name = "symbolize", >+ srcs = [ >+ "symbolize.cc", >+ "symbolize_elf.inc", >+ "symbolize_unimplemented.inc", >+ "symbolize_win32.inc", >+ ], >+ hdrs = [ >+ "internal/symbolize.h", >+ "symbolize.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":debugging_internal", >+ ":demangle_internal", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "//absl/base:malloc_internal", >+ ], >+) >+ >+cc_test( >+ name = "symbolize_test", >+ srcs = ["symbolize_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":stack_consumption", >+ ":symbolize", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "//absl/memory", >+ "@com_google_googletest//:gtest", >+ ], >+) >+ >+cc_library( >+ name = "examine_stack", >+ srcs = [ >+ "internal/examine_stack.cc", >+ ], >+ hdrs = [ >+ "internal/examine_stack.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":stacktrace", >+ ":symbolize", >+ "//absl/base", >+ "//absl/base:core_headers", >+ ], >+) >+ >+cc_library( >+ name = "failure_signal_handler", >+ srcs = ["failure_signal_handler.cc"], >+ hdrs = ["failure_signal_handler.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":examine_stack", >+ ":stacktrace", >+ "//absl/base", >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ ], >+) >+ >+cc_test( >+ name = "failure_signal_handler_test", >+ srcs = ["failure_signal_handler_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ linkopts = select({ >+ "//absl:windows": [], >+ "//conditions:default": ["-pthread"], >+ }), >+ deps = [ >+ ":failure_signal_handler", >+ ":stacktrace", >+ ":symbolize", >+ "//absl/base", >+ "//absl/strings", >+ "@com_google_googletest//:gtest", >+ ], >+) >+ >+cc_library( >+ name = "debugging_internal", >+ srcs = [ >+ "internal/address_is_readable.cc", >+ "internal/elf_mem_image.cc", >+ "internal/vdso_support.cc", >+ ], >+ hdrs = [ >+ "internal/address_is_readable.h", >+ "internal/elf_mem_image.h", >+ "internal/stacktrace_aarch64-inl.inc", >+ "internal/stacktrace_arm-inl.inc", >+ "internal/stacktrace_config.h", >+ "internal/stacktrace_generic-inl.inc", >+ "internal/stacktrace_powerpc-inl.inc", >+ "internal/stacktrace_unimplemented-inl.inc", >+ "internal/stacktrace_win32-inl.inc", >+ "internal/stacktrace_x86-inl.inc", >+ "internal/vdso_support.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/base", >+ "//absl/base:dynamic_annotations", >+ ], >+) >+ >+cc_library( >+ name = "demangle_internal", >+ srcs = ["internal/demangle.cc"], >+ hdrs = ["internal/demangle.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/base", >+ "//absl/base:core_headers", >+ ], >+) >+ >+cc_test( >+ name = "demangle_test", >+ srcs = ["internal/demangle_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":demangle_internal", >+ ":stack_consumption", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "//absl/memory", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_library( >+ name = "leak_check", >+ srcs = select({ >+ # The leak checking interface depends on weak function >+ # declarations that may not necessarily have definitions. >+ # Windows doesn't support this, and ios requires >+ # guaranteed definitions for weak symbols. >+ "//absl:ios": [], >+ "//absl:windows": [], >+ "//conditions:default": [ >+ "leak_check.cc", >+ ], >+ }), >+ hdrs = select({ >+ "//absl:ios": [], >+ "//absl:windows": [], >+ "//conditions:default": ["leak_check.h"], >+ }), >+ deps = ["//absl/base:core_headers"], >+) >+ >+# Adding a dependency to leak_check_disable will disable >+# sanitizer leak checking (asan/lsan) in a test without >+# the need to mess around with build features. >+cc_library( >+ name = "leak_check_disable", >+ srcs = ["leak_check_disable.cc"], >+ linkstatic = 1, >+ alwayslink = 1, >+) >+ >+# These targets exists for use in tests only, explicitly configuring the >+# LEAK_SANITIZER macro. It must be linked with -fsanitize=leak for lsan. >+ABSL_LSAN_LINKOPTS = select({ >+ "//absl:llvm_compiler": ["-fsanitize=leak"], >+ "//conditions:default": [], >+}) >+ >+cc_library( >+ name = "leak_check_api_enabled_for_testing", >+ testonly = 1, >+ srcs = ["leak_check.cc"], >+ hdrs = ["leak_check.h"], >+ copts = select({ >+ "//absl:llvm_compiler": ["-DLEAK_SANITIZER"], >+ "//conditions:default": [], >+ }), >+ visibility = ["//visibility:private"], >+) >+ >+cc_library( >+ name = "leak_check_api_disabled_for_testing", >+ testonly = 1, >+ srcs = ["leak_check.cc"], >+ hdrs = ["leak_check.h"], >+ copts = ["-ULEAK_SANITIZER"], >+ visibility = ["//visibility:private"], >+) >+ >+cc_test( >+ name = "leak_check_test", >+ srcs = ["leak_check_test.cc"], >+ copts = select({ >+ "//absl:llvm_compiler": ["-DABSL_EXPECT_LEAK_SANITIZER"], >+ "//conditions:default": [], >+ }), >+ linkopts = ABSL_LSAN_LINKOPTS, >+ deps = [ >+ ":leak_check_api_enabled_for_testing", >+ "//absl/base", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "leak_check_no_lsan_test", >+ srcs = ["leak_check_test.cc"], >+ copts = ["-UABSL_EXPECT_LEAK_SANITIZER"], >+ deps = [ >+ ":leak_check_api_disabled_for_testing", >+ "//absl/base", # for raw_logging >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+# Test that leak checking is skipped when lsan is enabled but >+# ":leak_check_disable" is linked in. >+# >+# This test should fail in the absence of a dependency on ":leak_check_disable" >+cc_test( >+ name = "disabled_leak_check_test", >+ srcs = ["leak_check_fail_test.cc"], >+ linkopts = ABSL_LSAN_LINKOPTS, >+ deps = [ >+ ":leak_check_api_enabled_for_testing", >+ ":leak_check_disable", >+ "//absl/base", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_library( >+ name = "stack_consumption", >+ testonly = 1, >+ srcs = ["internal/stack_consumption.cc"], >+ hdrs = ["internal/stack_consumption.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ "//absl/base", >+ "//absl/base:core_headers", >+ ], >+) >+ >+cc_test( >+ name = "stack_consumption_test", >+ srcs = ["internal/stack_consumption_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":stack_consumption", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..b50b0a6ddc8321968eb1fa176321bc8e1f974254 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/BUILD.gn >@@ -0,0 +1,245 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+import("//build/config/sanitizers/sanitizers.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("stacktrace") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "stacktrace.cc", >+ ] >+ public = [ >+ "stacktrace.h", >+ ] >+ deps = [ >+ ":debugging_internal", >+ "../base", >+ "../base:core_headers", >+ ] >+} >+ >+source_set("symbolize") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "symbolize.cc", >+ "symbolize_elf.inc", >+ "symbolize_unimplemented.inc", >+ "symbolize_win32.inc", >+ ] >+ public = [ >+ "internal/symbolize.h", >+ "symbolize.h", >+ ] >+ deps = [ >+ ":debugging_internal", >+ ":demangle_internal", >+ "../base", >+ "../base:core_headers", >+ "../base:malloc_internal", >+ ] >+} >+ >+source_set("examine_stack") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/examine_stack.cc", >+ ] >+ public = [ >+ "internal/examine_stack.h", >+ ] >+ visibility = [] >+ visibility += [ ":*" ] >+ deps = [ >+ ":stacktrace", >+ ":symbolize", >+ "../base", >+ "../base:core_headers", >+ ] >+} >+ >+source_set("failure_signal_handler") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "failure_signal_handler.cc" >+ ] >+ public = [ >+ "failure_signal_handler.h" >+ ] >+ deps = [ >+ ":examine_stack", >+ ":stacktrace", >+ "../base", >+ "../base:config", >+ "../base:core_headers", >+ ] >+} >+ >+source_set("debugging_internal") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/address_is_readable.cc", >+ "internal/elf_mem_image.cc", >+ "internal/vdso_support.cc", >+ ] >+ public = [ >+ "internal/address_is_readable.h", >+ "internal/elf_mem_image.h", >+ "internal/stacktrace_config.h", >+ "internal/vdso_support.h", >+ ] >+ deps = [ >+ "../base", >+ "../base:dynamic_annotations", >+ ] >+} >+ >+source_set("demangle_internal") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/demangle.cc", >+ ] >+ public = [ >+ "internal/demangle.h", >+ ] >+ deps = [ >+ "../base", >+ "../base:core_headers", >+ ] >+} >+ >+source_set("leak_check") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ if (is_ios || is_win) { >+ sources = [] >+ public = [] >+ } else { >+ sources = [ >+ "leak_check.cc", >+ ] >+ public = [ >+ "leak_check.h", >+ ] >+ } >+ deps = [ >+ "../base:core_headers", >+ ] >+} >+ >+source_set("leak_check_disable") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "leak_check_disable.cc", >+ ] >+} >+ >+if (is_lsan) { >+ source_set("leak_check_api_enabled_for_testing") { >+ testonly = true >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "leak_check.cc", >+ ] >+ public = [ >+ "leak_check.h", >+ ] >+ visibility = [] >+ visibility += [ ":*" ] >+ } >+} else { >+ source_set("leak_check_api_disabled_for_testing") { >+ testonly = true >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "leak_check.cc", >+ ] >+ public = [ >+ "leak_check.h", >+ ] >+ visibility = [] >+ visibility += [ ":*" ] >+ } >+} >+ >+source_set("stack_consumption") { >+ testonly = true >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/stack_consumption.cc", >+ ] >+ public = [ >+ "internal/stack_consumption.h", >+ ] >+ deps = [ >+ "../base", >+ "../base:core_headers", >+ ] >+ visibility = [] >+ visibility += [ ":*" ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4af2ec8a41143cbb1181407f04ebb13547cf52e8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/CMakeLists.txt >@@ -0,0 +1,217 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+list(APPEND DEBUGGING_PUBLIC_HEADERS >+ "failure_signal_handler.h" >+ "leak_check.h" >+ "stacktrace.h" >+ "symbolize.h" >+) >+ >+# TODO(cohenjon) The below is all kinds of wrong. Make this match what we do in >+# Bazel >+list(APPEND DEBUGGING_INTERNAL_HEADERS >+ "internal/address_is_readable.h" >+ "internal/demangle.h" >+ "internal/elf_mem_image.h" >+ "internal/examine_stack.h" >+ "internal/stacktrace_config.h" >+ "internal/symbolize.h" >+ "internal/vdso_support.h" >+) >+ >+list(APPEND DEBUGGING_INTERNAL_SRC >+ "internal/address_is_readable.cc" >+ "internal/elf_mem_image.cc" >+ "internal/vdso_support.cc" >+) >+ >+ >+list(APPEND STACKTRACE_SRC >+ "stacktrace.cc" >+ ${DEBUGGING_INTERNAL_SRC} >+ ${DEBUGGING_PUBLIC_HEADERS} >+ ${DEBUGGING_INTERNAL_HEADERS} >+) >+ >+list(APPEND SYMBOLIZE_SRC >+ "symbolize.cc" >+ "symbolize_elf.inc" >+ "symbolize_unimplemented.inc" >+ "symbolize_win32.inc" >+ "internal/demangle.cc" >+ ${DEBUGGING_PUBLIC_HEADERS} >+ ${DEBUGGING_INTERNAL_HEADERS} >+ ${DEBUGGING_INTERNAL_SRC} >+) >+ >+list(APPEND FAILURE_SIGNAL_HANDLER_SRC >+ "failure_signal_handler.cc" >+ ${DEBUGGING_PUBLIC_HEADERS} >+) >+ >+list(APPEND EXAMINE_STACK_SRC >+ "internal/examine_stack.cc" >+ ${DEBUGGING_PUBLIC_HEADERS} >+ ${DEBUGGING_INTERNAL_HEADERS} >+) >+ >+absl_library( >+ TARGET >+ absl_stacktrace >+ SOURCES >+ ${STACKTRACE_SRC} >+ EXPORT_NAME >+ stacktrace >+) >+ >+absl_library( >+ TARGET >+ absl_symbolize >+ SOURCES >+ ${SYMBOLIZE_SRC} >+ PUBLIC_LIBRARIES >+ absl::base >+ absl_malloc_internal >+ EXPORT_NAME >+ symbolize >+) >+ >+absl_library( >+ TARGET >+ absl_failure_signal_handler >+ SOURCES >+ ${FAILURE_SIGNAL_HANDLER_SRC} >+ PUBLIC_LIBRARIES >+ absl_base absl::examine_stack absl::stacktrace absl_synchronization >+ EXPORT_NAME >+ failure_signal_handler >+) >+ >+# Internal-only. Projects external to Abseil should not depend >+# directly on this library. >+absl_library( >+ TARGET >+ absl_examine_stack >+ SOURCES >+ ${EXAMINE_STACK_SRC} >+ EXPORT_NAME >+ examine_stack >+) >+ >+list(APPEND LEAK_CHECK_SRC >+ "leak_check.cc" >+) >+ >+ >+# leak_check library >+absl_library( >+ TARGET >+ absl_leak_check >+ SOURCES >+ ${LEAK_CHECK_SRC} >+ PUBLIC_LIBRARIES >+ absl_base >+ EXPORT_NAME >+ leak_check >+) >+ >+ >+# component target >+absl_header_library( >+ TARGET >+ absl_debugging >+ PUBLIC_LIBRARIES >+ absl_stacktrace absl_leak_check >+ EXPORT_NAME >+ debugging >+) >+ >+# >+## TESTS >+# >+ >+list(APPEND STACK_CONSUMPTION_SRC >+ "internal/stack_consumption.cc" >+ "internal/stack_consumption.h" >+) >+ >+absl_library( >+ TARGET >+ absl_stack_consumption >+ SOURCES >+ ${STACK_CONSUMPTION_SRC} >+) >+ >+absl_test( >+ TARGET >+ absl_stack_consumption_test >+ SOURCES >+ "internal/stack_consumption_test.cc" >+ PUBLIC_LIBRARIES >+ absl_stack_consumption >+ absl::base >+) >+ >+list(APPEND DEMANGLE_TEST_SRC "internal/demangle_test.cc") >+ >+absl_test( >+ TARGET >+ demangle_test >+ SOURCES >+ ${DEMANGLE_TEST_SRC} >+ PUBLIC_LIBRARIES >+ absl_symbolize absl_stack_consumption >+) >+ >+list(APPEND SYMBOLIZE_TEST_SRC "symbolize_test.cc") >+ >+absl_test( >+ TARGET >+ symbolize_test >+ SOURCES >+ ${SYMBOLIZE_TEST_SRC} >+ PUBLIC_LIBRARIES >+ absl::base absl::memory absl_symbolize absl_stack_consumption >+) >+ >+list(APPEND FAILURE_SIGNAL_HANDLER_TEST_SRC "failure_signal_handler_test.cc") >+ >+absl_test( >+ TARGET >+ failure_signal_handler_test >+ SOURCES >+ ${FAILURE_SIGNAL_HANDLER_TEST_SRC} >+ PUBLIC_LIBRARIES >+ absl_examine_stack >+ absl_failure_signal_handler >+ absl_stacktrace >+ absl_symbolize >+ absl::base >+ absl::strings >+) >+ >+# test leak_check_test >+list(APPEND LEAK_CHECK_TEST_SRC "leak_check_test.cc") >+ >+absl_test( >+ TARGET >+ leak_check_test >+ SOURCES >+ ${LEAK_CHECK_TEST_SRC} >+ PUBLIC_LIBRARIES >+ absl_leak_check >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/failure_signal_handler.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/failure_signal_handler.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..d4b957bc2e418f4681cbf804a80a167792ee3db8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/failure_signal_handler.cc >@@ -0,0 +1,355 @@ >+// >+// 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/debugging/failure_signal_handler.h" >+ >+#include "absl/base/config.h" >+ >+#ifdef _WIN32 >+#include <windows.h> >+#else >+#include <unistd.h> >+#endif >+ >+#ifdef ABSL_HAVE_MMAP >+#include <sys/mman.h> >+#endif >+ >+#include <algorithm> >+#include <atomic> >+#include <cerrno> >+#include <csignal> >+#include <cstdio> >+#include <cstring> >+#include <ctime> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/sysinfo.h" >+#include "absl/debugging/internal/examine_stack.h" >+#include "absl/debugging/stacktrace.h" >+ >+#ifndef _WIN32 >+#define ABSL_HAVE_SIGACTION >+#endif >+ >+namespace absl { >+ >+ABSL_CONST_INIT static FailureSignalHandlerOptions fsh_options; >+ >+// Resets the signal handler for signo to the default action for that >+// signal, then raises the signal. >+static void RaiseToDefaultHandler(int signo) { >+ signal(signo, SIG_DFL); >+ raise(signo); >+} >+ >+struct FailureSignalData { >+ const int signo; >+ const char* const as_string; >+#ifdef ABSL_HAVE_SIGACTION >+ struct sigaction previous_action; >+ // StructSigaction is used to silence -Wmissing-field-initializers. >+ using StructSigaction = struct sigaction; >+ #define FSD_PREVIOUS_INIT FailureSignalData::StructSigaction() >+#else >+ void (*previous_handler)(int); >+ #define FSD_PREVIOUS_INIT SIG_DFL >+#endif >+}; >+ >+ABSL_CONST_INIT static FailureSignalData failure_signal_data[] = { >+ {SIGSEGV, "SIGSEGV", FSD_PREVIOUS_INIT}, >+ {SIGILL, "SIGILL", FSD_PREVIOUS_INIT}, >+ {SIGFPE, "SIGFPE", FSD_PREVIOUS_INIT}, >+ {SIGABRT, "SIGABRT", FSD_PREVIOUS_INIT}, >+ {SIGTERM, "SIGTERM", FSD_PREVIOUS_INIT}, >+#ifndef _WIN32 >+ {SIGBUS, "SIGBUS", FSD_PREVIOUS_INIT}, >+ {SIGTRAP, "SIGTRAP", FSD_PREVIOUS_INIT}, >+#endif >+}; >+ >+#undef FSD_PREVIOUS_INIT >+ >+static void RaiseToPreviousHandler(int signo) { >+ // Search for the previous handler. >+ for (const auto& it : failure_signal_data) { >+ if (it.signo == signo) { >+#ifdef ABSL_HAVE_SIGACTION >+ sigaction(signo, &it.previous_action, nullptr); >+#else >+ signal(signo, it.previous_handler); >+#endif >+ raise(signo); >+ return; >+ } >+ } >+ >+ // Not found, use the default handler. >+ RaiseToDefaultHandler(signo); >+} >+ >+namespace debugging_internal { >+ >+const char* FailureSignalToString(int signo) { >+ for (const auto& it : failure_signal_data) { >+ if (it.signo == signo) { >+ return it.as_string; >+ } >+ } >+ return ""; >+} >+ >+} // namespace debugging_internal >+ >+#ifndef _WIN32 >+ >+static bool SetupAlternateStackOnce() { >+ const size_t page_mask = getpagesize() - 1; >+ size_t stack_size = (std::max(SIGSTKSZ, 65536) + page_mask) & ~page_mask; >+#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ >+ defined(THREAD_SANITIZER) >+ // Account for sanitizer instrumentation requiring additional stack space. >+ stack_size *= 5; >+#endif >+ >+ stack_t sigstk; >+ memset(&sigstk, 0, sizeof(sigstk)); >+ sigstk.ss_size = stack_size; >+ >+#ifdef ABSL_HAVE_MMAP >+#ifndef MAP_STACK >+#define MAP_STACK 0 >+#endif >+#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) >+#define MAP_ANONYMOUS MAP_ANON >+#endif >+ sigstk.ss_sp = mmap(nullptr, sigstk.ss_size, PROT_READ | PROT_WRITE, >+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); >+ if (sigstk.ss_sp == MAP_FAILED) { >+ ABSL_RAW_LOG(FATAL, "mmap() for alternate signal stack failed"); >+ } >+#else >+ sigstk.ss_sp = malloc(sigstk.ss_size); >+ if (sigstk.ss_sp == nullptr) { >+ ABSL_RAW_LOG(FATAL, "malloc() for alternate signal stack failed"); >+ } >+#endif >+ >+ if (sigaltstack(&sigstk, nullptr) != 0) { >+ ABSL_RAW_LOG(FATAL, "sigaltstack() failed with errno=%d", errno); >+ } >+ return true; >+} >+ >+#endif >+ >+#ifdef ABSL_HAVE_SIGACTION >+ >+// Sets up an alternate stack for signal handlers once. >+// Returns the appropriate flag for sig_action.sa_flags >+// if the system supports using an alternate stack. >+static int MaybeSetupAlternateStack() { >+#ifndef _WIN32 >+ ABSL_ATTRIBUTE_UNUSED static const bool kOnce = SetupAlternateStackOnce(); >+ return SA_ONSTACK; >+#else >+ return 0; >+#endif >+} >+ >+static void InstallOneFailureHandler(FailureSignalData* data, >+ void (*handler)(int, siginfo_t*, void*)) { >+ struct sigaction act; >+ memset(&act, 0, sizeof(act)); >+ sigemptyset(&act.sa_mask); >+ act.sa_flags |= SA_SIGINFO; >+ // SA_NODEFER is required to handle SIGABRT from >+ // ImmediateAbortSignalHandler(). >+ act.sa_flags |= SA_NODEFER; >+ if (fsh_options.use_alternate_stack) { >+ act.sa_flags |= MaybeSetupAlternateStack(); >+ } >+ act.sa_sigaction = handler; >+ ABSL_RAW_CHECK(sigaction(data->signo, &act, &data->previous_action) == 0, >+ "sigaction() failed"); >+} >+ >+#else >+ >+static void InstallOneFailureHandler(FailureSignalData* data, >+ void (*handler)(int)) { >+ data->previous_handler = signal(data->signo, handler); >+ ABSL_RAW_CHECK(data->previous_handler != SIG_ERR, "signal() failed"); >+} >+ >+#endif >+ >+static void WriteToStderr(const char* data) { >+ int old_errno = errno; >+ absl::raw_logging_internal::SafeWriteToStderr(data, strlen(data)); >+ errno = old_errno; >+} >+ >+static void WriteSignalMessage(int signo, void (*writerfn)(const char*)) { >+ char buf[64]; >+ const char* const signal_string = >+ debugging_internal::FailureSignalToString(signo); >+ if (signal_string != nullptr && signal_string[0] != '\0') { >+ snprintf(buf, sizeof(buf), "*** %s received at time=%ld ***\n", >+ signal_string, >+ static_cast<long>(time(nullptr))); // NOLINT(runtime/int) >+ } else { >+ snprintf(buf, sizeof(buf), "*** Signal %d received at time=%ld ***\n", >+ signo, static_cast<long>(time(nullptr))); // NOLINT(runtime/int) >+ } >+ writerfn(buf); >+} >+ >+// `void*` might not be big enough to store `void(*)(const char*)`. >+struct WriterFnStruct { >+ void (*writerfn)(const char*); >+}; >+ >+// Many of the absl::debugging_internal::Dump* functions in >+// examine_stack.h take a writer function pointer that has a void* arg >+// for historical reasons. failure_signal_handler_writer only takes a >+// data pointer. This function converts between these types. >+static void WriterFnWrapper(const char* data, void* arg) { >+ static_cast<WriterFnStruct*>(arg)->writerfn(data); >+} >+ >+// Convenient wrapper around DumpPCAndFrameSizesAndStackTrace() for signal >+// handlers. "noinline" so that GetStackFrames() skips the top-most stack >+// frame for this function. >+ABSL_ATTRIBUTE_NOINLINE static void WriteStackTrace( >+ void* ucontext, bool symbolize_stacktrace, >+ void (*writerfn)(const char*, void*), void* writerfn_arg) { >+ constexpr int kNumStackFrames = 32; >+ void* stack[kNumStackFrames]; >+ int frame_sizes[kNumStackFrames]; >+ int min_dropped_frames; >+ int depth = absl::GetStackFramesWithContext( >+ stack, frame_sizes, kNumStackFrames, >+ 1, // Do not include this function in stack trace. >+ ucontext, &min_dropped_frames); >+ absl::debugging_internal::DumpPCAndFrameSizesAndStackTrace( >+ absl::debugging_internal::GetProgramCounter(ucontext), stack, frame_sizes, >+ depth, min_dropped_frames, symbolize_stacktrace, writerfn, writerfn_arg); >+} >+ >+// Called by AbslFailureSignalHandler() to write the failure info. It is >+// called once with writerfn set to WriteToStderr() and then possibly >+// with writerfn set to the user provided function. >+static void WriteFailureInfo(int signo, void* ucontext, >+ void (*writerfn)(const char*)) { >+ WriterFnStruct writerfn_struct{writerfn}; >+ WriteSignalMessage(signo, writerfn); >+ WriteStackTrace(ucontext, fsh_options.symbolize_stacktrace, WriterFnWrapper, >+ &writerfn_struct); >+} >+ >+// absl::SleepFor() can't be used here since AbslInternalSleepFor() >+// may be overridden to do something that isn't async-signal-safe on >+// some platforms. >+static void PortableSleepForSeconds(int seconds) { >+#ifdef _WIN32 >+ Sleep(seconds * 1000); >+#else >+ struct timespec sleep_time; >+ sleep_time.tv_sec = seconds; >+ sleep_time.tv_nsec = 0; >+ while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) {} >+#endif >+} >+ >+#ifdef ABSL_HAVE_ALARM >+// AbslFailureSignalHandler() installs this as a signal handler for >+// SIGALRM, then sets an alarm to be delivered to the program after a >+// set amount of time. If AbslFailureSignalHandler() hangs for more than >+// the alarm timeout, ImmediateAbortSignalHandler() will abort the >+// program. >+static void ImmediateAbortSignalHandler(int) { >+ RaiseToDefaultHandler(SIGABRT); >+} >+#endif >+ >+// absl::base_internal::GetTID() returns pid_t on most platforms, but >+// returns absl::base_internal::pid_t on Windows. >+using GetTidType = decltype(absl::base_internal::GetTID()); >+ABSL_CONST_INIT static std::atomic<GetTidType> failed_tid(0); >+ >+#ifndef ABSL_HAVE_SIGACTION >+static void AbslFailureSignalHandler(int signo) { >+ void* ucontext = nullptr; >+#else >+static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) { >+#endif >+ >+ const GetTidType this_tid = absl::base_internal::GetTID(); >+ GetTidType previous_failed_tid = 0; >+ if (!failed_tid.compare_exchange_strong( >+ previous_failed_tid, static_cast<intptr_t>(this_tid), >+ std::memory_order_acq_rel, std::memory_order_relaxed)) { >+ ABSL_RAW_LOG( >+ ERROR, >+ "Signal %d raised at PC=%p while already in AbslFailureSignalHandler()", >+ signo, absl::debugging_internal::GetProgramCounter(ucontext)); >+ if (this_tid != previous_failed_tid) { >+ // Another thread is already in AbslFailureSignalHandler(), so wait >+ // a bit for it to finish. If the other thread doesn't kill us, >+ // we do so after sleeping. >+ PortableSleepForSeconds(3); >+ RaiseToDefaultHandler(signo); >+ // The recursively raised signal may be blocked until we return. >+ return; >+ } >+ } >+ >+#ifdef ABSL_HAVE_ALARM >+ // Set an alarm to abort the program in case this code hangs or deadlocks. >+ if (fsh_options.alarm_on_failure_secs > 0) { >+ alarm(0); // Cancel any existing alarms. >+ signal(SIGALRM, ImmediateAbortSignalHandler); >+ alarm(fsh_options.alarm_on_failure_secs); >+ } >+#endif >+ >+ // First write to stderr. >+ WriteFailureInfo(signo, ucontext, WriteToStderr); >+ >+ // Riskier code (because it is less likely to be async-signal-safe) >+ // goes after this point. >+ if (fsh_options.writerfn != nullptr) { >+ WriteFailureInfo(signo, ucontext, fsh_options.writerfn); >+ } >+ >+ if (fsh_options.call_previous_handler) { >+ RaiseToPreviousHandler(signo); >+ } else { >+ RaiseToDefaultHandler(signo); >+ } >+} >+ >+void InstallFailureSignalHandler(const FailureSignalHandlerOptions& options) { >+ fsh_options = options; >+ for (auto& it : failure_signal_data) { >+ InstallOneFailureHandler(&it, AbslFailureSignalHandler); >+ } >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/failure_signal_handler.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/failure_signal_handler.h >new file mode 100644 >index 0000000000000000000000000000000000000000..c57954e5875cac4d8971d90600fb8cc60130d8eb >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/failure_signal_handler.h >@@ -0,0 +1,117 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: failure_signal_handler.h >+// ----------------------------------------------------------------------------- >+// >+// This file configures the Abseil *failure signal handler* to capture and dump >+// useful debugging information (such as a stacktrace) upon program failure. >+// >+// To use the failure signal handler, call `absl::InstallFailureSignalHandler()` >+// very early in your program, usually in the first few lines of main(): >+// >+// int main(int argc, char** argv) { >+// // Initialize the symbolizer to get a human-readable stack trace >+// absl::InitializeSymbolizer(argv[0]); >+// >+// absl::FailureSignalHandlerOptions options; >+// absl::InstallFailureSignalHandler(options); >+// DoSomethingInteresting(); >+// return 0; >+// } >+// >+// Any program that raises a fatal signal (such as `SIGSEGV`, `SIGILL`, >+// `SIGFPE`, `SIGABRT`, `SIGTERM`, `SIGBUG`, and `SIGTRAP`) will call the >+// installed failure signal handler and provide debugging information to stderr. >+// >+// Note that you should *not* install the Abseil failure signal handler more >+// than once. You may, of course, have another (non-Abseil) failure signal >+// handler installed (which would be triggered if Abseil's failure signal >+// handler sets `call_previous_handler` to `true`). >+ >+#ifndef ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ >+#define ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ >+ >+namespace absl { >+ >+// FailureSignalHandlerOptions >+// >+// Struct for holding `absl::InstallFailureSignalHandler()` configuration >+// options. >+struct FailureSignalHandlerOptions { >+ // If true, try to symbolize the stacktrace emitted on failure, provided that >+ // you have initialized a symbolizer for that purpose. (See symbolize.h for >+ // more information.) >+ bool symbolize_stacktrace = true; >+ >+ // If true, try to run signal handlers on an alternate stack (if supported on >+ // the given platform). An alternate stack is useful for program crashes due >+ // to a stack overflow; by running on a alternate stack, the signal handler >+ // may run even when normal stack space has been exausted. The downside of >+ // using an alternate stack is that extra memory for the alternate stack needs >+ // to be pre-allocated. >+ bool use_alternate_stack = true; >+ >+ // If positive, indicates the number of seconds after which the failure signal >+ // handler is invoked to abort the program. Setting such an alarm is useful in >+ // cases where the failure signal handler itself may become hung or >+ // deadlocked. >+ int alarm_on_failure_secs = 3; >+ >+ // If true, call the previously registered signal handler for the signal that >+ // was received (if one was registered) after the existing signal handler >+ // runs. This mechanism can be used to chain signal handlers together. >+ // >+ // If false, the signal is raised to the default handler for that signal >+ // (which normally terminates the program). >+ // >+ // IMPORTANT: If true, the chained fatal signal handlers must not try to >+ // recover from the fatal signal. Instead, they should terminate the program >+ // via some mechanism, like raising the default handler for the signal, or by >+ // calling `_exit()`. Note that the failure signal handler may put parts of >+ // the Abseil library into a state from which they cannot recover. >+ bool call_previous_handler = false; >+ >+ // If non-null, indicates a pointer to a callback function that will be called >+ // upon failure, with a std::string argument containing failure data. This function >+ // may be used as a hook to write failure data to a secondary location, such >+ // as a log file. This function may also be called with null data, as a hint >+ // to flush any buffered data before the program may be terminated. Consider >+ // flushing any buffered data in all calls to this function. >+ // >+ // Since this function runs within a signal handler, it should be >+ // async-signal-safe if possible. >+ // See http://man7.org/linux/man-pages/man7/signal-safety.7.html >+ void (*writerfn)(const char*) = nullptr; >+}; >+ >+// InstallFailureSignalHandler() >+// >+// Installs a signal handler for the common failure signals `SIGSEGV`, `SIGILL`, >+// `SIGFPE`, `SIGABRT`, `SIGTERM`, `SIGBUG`, and `SIGTRAP` (provided they exist >+// on the given platform). The failure signal handler dumps program failure data >+// useful for debugging in an unspecified format to stderr. This data may >+// include the program counter, a stacktrace, and register information on some >+// systems; do not rely on an exact format for the output, as it is subject to >+// change. >+void InstallFailureSignalHandler(const FailureSignalHandlerOptions& options); >+ >+namespace debugging_internal { >+const char* FailureSignalToString(int signo); >+} // namespace debugging_internal >+ >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..ba520910f47f217f28dc48d42bc2535c263ef03d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc >@@ -0,0 +1,155 @@ >+// >+// 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/debugging/failure_signal_handler.h" >+ >+#include <csignal> >+#include <cstdio> >+#include <cstdlib> >+#include <cstring> >+#include <fstream> >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/debugging/stacktrace.h" >+#include "absl/debugging/symbolize.h" >+#include "absl/strings/match.h" >+#include "absl/strings/str_cat.h" >+ >+namespace { >+ >+#if GTEST_HAS_DEATH_TEST >+ >+// For the parameterized death tests. GetParam() returns the signal number. >+using FailureSignalHandlerDeathTest = ::testing::TestWithParam<int>; >+ >+// This function runs in a fork()ed process on most systems. >+void InstallHandlerAndRaise(int signo) { >+ absl::InstallFailureSignalHandler(absl::FailureSignalHandlerOptions()); >+ raise(signo); >+} >+ >+TEST_P(FailureSignalHandlerDeathTest, AbslFailureSignal) { >+ const int signo = GetParam(); >+ std::string exit_regex = absl::StrCat( >+ "\\*\\*\\* ", absl::debugging_internal::FailureSignalToString(signo), >+ " received at time="); >+#ifndef _WIN32 >+ EXPECT_EXIT(InstallHandlerAndRaise(signo), testing::KilledBySignal(signo), >+ exit_regex); >+#else >+ // Windows doesn't have testing::KilledBySignal(). >+ EXPECT_DEATH(InstallHandlerAndRaise(signo), exit_regex); >+#endif >+} >+ >+ABSL_CONST_INIT FILE* error_file = nullptr; >+ >+void WriteToErrorFile(const char* msg) { >+ if (msg != nullptr) { >+ ABSL_RAW_CHECK(fwrite(msg, strlen(msg), 1, error_file) == 1, >+ "fwrite() failed"); >+ } >+ ABSL_RAW_CHECK(fflush(error_file) == 0, "fflush() failed"); >+} >+ >+std::string GetTmpDir() { >+ // TEST_TMPDIR is set by Bazel. Try the others when not running under Bazel. >+ static const char* const kTmpEnvVars[] = {"TEST_TMPDIR", "TMPDIR", "TEMP", >+ "TEMPDIR", "TMP"}; >+ for (const char* const var : kTmpEnvVars) { >+ const char* tmp_dir = std::getenv(var); >+ if (tmp_dir != nullptr) { >+ return tmp_dir; >+ } >+ } >+ >+ // Try something reasonable. >+ return "/tmp"; >+} >+ >+// This function runs in a fork()ed process on most systems. >+void InstallHandlerWithWriteToFileAndRaise(const char* file, int signo) { >+ error_file = fopen(file, "w"); >+ ABSL_RAW_CHECK(error_file != nullptr, "Failed create error_file"); >+ absl::FailureSignalHandlerOptions options; >+ options.writerfn = WriteToErrorFile; >+ absl::InstallFailureSignalHandler(options); >+ raise(signo); >+} >+ >+TEST_P(FailureSignalHandlerDeathTest, AbslFatalSignalsWithWriterFn) { >+ const int signo = GetParam(); >+ std::string tmp_dir = GetTmpDir(); >+ std::string file = absl::StrCat(tmp_dir, "/signo_", signo); >+ >+ std::string exit_regex = absl::StrCat( >+ "\\*\\*\\* ", absl::debugging_internal::FailureSignalToString(signo), >+ " received at time="); >+#ifndef _WIN32 >+ EXPECT_EXIT(InstallHandlerWithWriteToFileAndRaise(file.c_str(), signo), >+ testing::KilledBySignal(signo), exit_regex); >+#else >+ // Windows doesn't have testing::KilledBySignal(). >+ EXPECT_DEATH(InstallHandlerWithWriteToFileAndRaise(file.c_str(), signo), >+ exit_regex); >+#endif >+ >+ // Open the file in this process and check its contents. >+ std::fstream error_output(file); >+ ASSERT_TRUE(error_output.is_open()) << file; >+ std::string error_line; >+ std::getline(error_output, error_line); >+ EXPECT_TRUE(absl::StartsWith( >+ error_line, >+ absl::StrCat("*** ", >+ absl::debugging_internal::FailureSignalToString(signo), >+ " received at "))); >+ >+ if (absl::debugging_internal::StackTraceWorksForTest()) { >+ std::getline(error_output, error_line); >+ EXPECT_TRUE(absl::StartsWith(error_line, "PC: ")); >+ } >+} >+ >+constexpr int kFailureSignals[] = { >+ SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGTERM, >+#ifndef _WIN32 >+ SIGBUS, SIGTRAP, >+#endif >+}; >+ >+std::string SignalParamToString(const ::testing::TestParamInfo<int>& info) { >+ std::string result = absl::debugging_internal::FailureSignalToString(info.param); >+ if (result.empty()) { >+ result = absl::StrCat(info.param); >+ } >+ return result; >+} >+ >+INSTANTIATE_TEST_CASE_P(AbslDeathTest, FailureSignalHandlerDeathTest, >+ ::testing::ValuesIn(kFailureSignals), >+ SignalParamToString); >+ >+#endif // GTEST_HAS_DEATH_TEST >+ >+} // namespace >+ >+int main(int argc, char** argv) { >+ absl::InitializeSymbolizer(argv[0]); >+ testing::InitGoogleTest(&argc, argv); >+ return RUN_ALL_TESTS(); >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..7455aa0b416456e04b7e388520cd00d084007788 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc >@@ -0,0 +1,133 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// base::AddressIsReadable() probes an address to see whether it is readable, >+// without faulting. >+ >+#include "absl/debugging/internal/address_is_readable.h" >+ >+#if !defined(__linux__) || defined(__ANDROID__) >+ >+namespace absl { >+namespace debugging_internal { >+ >+// On platforms other than Linux, just return true. >+bool AddressIsReadable(const void* /* addr */) { return true; } >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#else >+ >+#include <fcntl.h> >+#include <sys/syscall.h> >+#include <unistd.h> >+#include <atomic> >+#include <cerrno> >+#include <cstdint> >+ >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+namespace debugging_internal { >+ >+// Pack a pid and two file descriptors into a 64-bit word, >+// using 16, 24, and 24 bits for each respectively. >+static uint64_t Pack(uint64_t pid, uint64_t read_fd, uint64_t write_fd) { >+ ABSL_RAW_CHECK((read_fd >> 24) == 0 && (write_fd >> 24) == 0, >+ "fd out of range"); >+ return (pid << 48) | ((read_fd & 0xffffff) << 24) | (write_fd & 0xffffff); >+} >+ >+// Unpack x into a pid and two file descriptors, where x was created with >+// Pack(). >+static void Unpack(uint64_t x, int *pid, int *read_fd, int *write_fd) { >+ *pid = x >> 48; >+ *read_fd = (x >> 24) & 0xffffff; >+ *write_fd = x & 0xffffff; >+} >+ >+// Return whether the byte at *addr is readable, without faulting. >+// Save and restores errno. Returns true on systems where >+// unimplemented. >+// This is a namespace-scoped variable for correct zero-initialization. >+static std::atomic<uint64_t> pid_and_fds; // initially 0, an invalid pid. >+bool AddressIsReadable(const void *addr) { >+ int save_errno = errno; >+ // We test whether a byte is readable by using write(). Normally, this would >+ // be done via a cached file descriptor to /dev/null, but linux fails to >+ // check whether the byte is readable when the destination is /dev/null, so >+ // we use a cached pipe. We store the pid of the process that created the >+ // pipe to handle the case where a process forks, and the child closes all >+ // the file descriptors and then calls this routine. This is not perfect: >+ // the child could use the routine, then close all file descriptors and then >+ // use this routine again. But the likely use of this routine is when >+ // crashing, to test the validity of pages when dumping the stack. Beware >+ // that we may leak file descriptors, but we're unlikely to leak many. >+ int bytes_written; >+ int current_pid = getpid() & 0xffff; // we use only the low order 16 bits >+ do { // until we do not get EBADF trying to use file descriptors >+ int pid; >+ int read_fd; >+ int write_fd; >+ uint64_t local_pid_and_fds = pid_and_fds.load(std::memory_order_relaxed); >+ Unpack(local_pid_and_fds, &pid, &read_fd, &write_fd); >+ while (current_pid != pid) { >+ int p[2]; >+ // new pipe >+ if (pipe(p) != 0) { >+ ABSL_RAW_LOG(FATAL, "Failed to create pipe, errno=%d", errno); >+ } >+ fcntl(p[0], F_SETFD, FD_CLOEXEC); >+ fcntl(p[1], F_SETFD, FD_CLOEXEC); >+ uint64_t new_pid_and_fds = Pack(current_pid, p[0], p[1]); >+ if (pid_and_fds.compare_exchange_strong( >+ local_pid_and_fds, new_pid_and_fds, std::memory_order_relaxed, >+ std::memory_order_relaxed)) { >+ local_pid_and_fds = new_pid_and_fds; // fds exposed to other threads >+ } else { // fds not exposed to other threads; we can close them. >+ close(p[0]); >+ close(p[1]); >+ local_pid_and_fds = pid_and_fds.load(std::memory_order_relaxed); >+ } >+ Unpack(local_pid_and_fds, &pid, &read_fd, &write_fd); >+ } >+ errno = 0; >+ // Use syscall(SYS_write, ...) instead of write() to prevent ASAN >+ // and other checkers from complaining about accesses to arbitrary >+ // memory. >+ do { >+ bytes_written = syscall(SYS_write, write_fd, addr, 1); >+ } while (bytes_written == -1 && errno == EINTR); >+ if (bytes_written == 1) { // remove the byte from the pipe >+ char c; >+ while (read(read_fd, &c, 1) == -1 && errno == EINTR) { >+ } >+ } >+ if (errno == EBADF) { // Descriptors invalid. >+ // If pid_and_fds contains the problematic file descriptors we just used, >+ // this call will forget them, and the loop will try again. >+ pid_and_fds.compare_exchange_strong(local_pid_and_fds, 0, >+ std::memory_order_relaxed, >+ std::memory_order_relaxed); >+ } >+ } while (errno == EBADF); >+ errno = save_errno; >+ return bytes_written == 1; >+} >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9d48030065c8113b417e94a7989969c3c6ee7d49 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.h >@@ -0,0 +1,29 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ >+#define ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ >+ >+namespace absl { >+namespace debugging_internal { >+ >+// Return whether the byte at *addr is readable, without faulting. >+// Save and restores errno. >+bool AddressIsReadable(const void *addr); >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/demangle.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/demangle.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..c9ca2f3bdb170e77d28dec15795ba58829fb868a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/demangle.cc >@@ -0,0 +1,1862 @@ >+// 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. >+ >+// For reference check out: >+// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling >+// >+// Note that we only have partial C++11 support yet. >+ >+#include "absl/debugging/internal/demangle.h" >+ >+#include <cstdint> >+#include <cstdio> >+#include <limits> >+ >+namespace absl { >+namespace debugging_internal { >+ >+typedef struct { >+ const char *abbrev; >+ const char *real_name; >+ // Number of arguments in <expression> context, or 0 if disallowed. >+ int arity; >+} AbbrevPair; >+ >+// List of operators from Itanium C++ ABI. >+static const AbbrevPair kOperatorList[] = { >+ // New has special syntax (not currently supported). >+ {"nw", "new", 0}, >+ {"na", "new[]", 0}, >+ >+ // Works except that the 'gs' prefix is not supported. >+ {"dl", "delete", 1}, >+ {"da", "delete[]", 1}, >+ >+ {"ps", "+", 1}, // "positive" >+ {"ng", "-", 1}, // "negative" >+ {"ad", "&", 1}, // "address-of" >+ {"de", "*", 1}, // "dereference" >+ {"co", "~", 1}, >+ >+ {"pl", "+", 2}, >+ {"mi", "-", 2}, >+ {"ml", "*", 2}, >+ {"dv", "/", 2}, >+ {"rm", "%", 2}, >+ {"an", "&", 2}, >+ {"or", "|", 2}, >+ {"eo", "^", 2}, >+ {"aS", "=", 2}, >+ {"pL", "+=", 2}, >+ {"mI", "-=", 2}, >+ {"mL", "*=", 2}, >+ {"dV", "/=", 2}, >+ {"rM", "%=", 2}, >+ {"aN", "&=", 2}, >+ {"oR", "|=", 2}, >+ {"eO", "^=", 2}, >+ {"ls", "<<", 2}, >+ {"rs", ">>", 2}, >+ {"lS", "<<=", 2}, >+ {"rS", ">>=", 2}, >+ {"eq", "==", 2}, >+ {"ne", "!=", 2}, >+ {"lt", "<", 2}, >+ {"gt", ">", 2}, >+ {"le", "<=", 2}, >+ {"ge", ">=", 2}, >+ {"nt", "!", 1}, >+ {"aa", "&&", 2}, >+ {"oo", "||", 2}, >+ {"pp", "++", 1}, >+ {"mm", "--", 1}, >+ {"cm", ",", 2}, >+ {"pm", "->*", 2}, >+ {"pt", "->", 0}, // Special syntax >+ {"cl", "()", 0}, // Special syntax >+ {"ix", "[]", 2}, >+ {"qu", "?", 3}, >+ {"st", "sizeof", 0}, // Special syntax >+ {"sz", "sizeof", 1}, // Not a real operator name, but used in expressions. >+ {nullptr, nullptr, 0}, >+}; >+ >+// List of builtin types from Itanium C++ ABI. >+static const AbbrevPair kBuiltinTypeList[] = { >+ {"v", "void", 0}, >+ {"w", "wchar_t", 0}, >+ {"b", "bool", 0}, >+ {"c", "char", 0}, >+ {"a", "signed char", 0}, >+ {"h", "unsigned char", 0}, >+ {"s", "short", 0}, >+ {"t", "unsigned short", 0}, >+ {"i", "int", 0}, >+ {"j", "unsigned int", 0}, >+ {"l", "long", 0}, >+ {"m", "unsigned long", 0}, >+ {"x", "long long", 0}, >+ {"y", "unsigned long long", 0}, >+ {"n", "__int128", 0}, >+ {"o", "unsigned __int128", 0}, >+ {"f", "float", 0}, >+ {"d", "double", 0}, >+ {"e", "long double", 0}, >+ {"g", "__float128", 0}, >+ {"z", "ellipsis", 0}, >+ {nullptr, nullptr, 0}, >+}; >+ >+// List of substitutions Itanium C++ ABI. >+static const AbbrevPair kSubstitutionList[] = { >+ {"St", "", 0}, >+ {"Sa", "allocator", 0}, >+ {"Sb", "basic_string", 0}, >+ // std::basic_string<char, std::char_traits<char>,std::allocator<char> > >+ {"Ss", "string", 0}, >+ // std::basic_istream<char, std::char_traits<char> > >+ {"Si", "istream", 0}, >+ // std::basic_ostream<char, std::char_traits<char> > >+ {"So", "ostream", 0}, >+ // std::basic_iostream<char, std::char_traits<char> > >+ {"Sd", "iostream", 0}, >+ {nullptr, nullptr, 0}, >+}; >+ >+// State needed for demangling. This struct is copied in almost every stack >+// frame, so every byte counts. >+typedef struct { >+ int mangled_idx; // Cursor of mangled name. >+ int out_cur_idx; // Cursor of output std::string. >+ int prev_name_idx; // For constructors/destructors. >+ signed int prev_name_length : 16; // For constructors/destructors. >+ signed int nest_level : 15; // For nested names. >+ unsigned int append : 1; // Append flag. >+ // Note: for some reason MSVC can't pack "bool append : 1" into the same int >+ // with the above two fields, so we use an int instead. Amusingly it can pack >+ // "signed bool" as expected, but relying on that to continue to be a legal >+ // type seems ill-advised (as it's illegal in at least clang). >+} ParseState; >+ >+static_assert(sizeof(ParseState) == 4 * sizeof(int), >+ "unexpected size of ParseState"); >+ >+// One-off state for demangling that's not subject to backtracking -- either >+// constant data, data that's intentionally immune to backtracking (steps), or >+// data that would never be changed by backtracking anyway (recursion_depth). >+// >+// Only one copy of this exists for each call to Demangle, so the size of this >+// struct is nearly inconsequential. >+typedef struct { >+ const char *mangled_begin; // Beginning of input std::string. >+ char *out; // Beginning of output std::string. >+ int out_end_idx; // One past last allowed output character. >+ int recursion_depth; // For stack exhaustion prevention. >+ int steps; // Cap how much work we'll do, regardless of depth. >+ ParseState parse_state; // Backtrackable state copied for most frames. >+} State; >+ >+namespace { >+// Prevent deep recursion / stack exhaustion. >+// Also prevent unbounded handling of complex inputs. >+class ComplexityGuard { >+ public: >+ explicit ComplexityGuard(State *state) : state_(state) { >+ ++state->recursion_depth; >+ ++state->steps; >+ } >+ ~ComplexityGuard() { --state_->recursion_depth; } >+ >+ // 256 levels of recursion seems like a reasonable upper limit on depth. >+ // 128 is not enough to demagle synthetic tests from demangle_unittest.txt: >+ // "_ZaaZZZZ..." and "_ZaaZcvZcvZ..." >+ static constexpr int kRecursionDepthLimit = 256; >+ >+ // We're trying to pick a charitable upper-limit on how many parse steps are >+ // necessary to handle something that a human could actually make use of. >+ // This is mostly in place as a bound on how much work we'll do if we are >+ // asked to demangle an mangled name from an untrusted source, so it should be >+ // much larger than the largest expected symbol, but much smaller than the >+ // amount of work we can do in, e.g., a second. >+ // >+ // Some real-world symbols from an arbitrary binary started failing between >+ // 2^12 and 2^13, so we multiply the latter by an extra factor of 16 to set >+ // the limit. >+ // >+ // Spending one second on 2^17 parse steps would require each step to take >+ // 7.6us, or ~30000 clock cycles, so it's safe to say this can be done in >+ // under a second. >+ static constexpr int kParseStepsLimit = 1 << 17; >+ >+ bool IsTooComplex() const { >+ return state_->recursion_depth > kRecursionDepthLimit || >+ state_->steps > kParseStepsLimit; >+ } >+ >+ private: >+ State *state_; >+}; >+} // namespace >+ >+// We don't use strlen() in libc since it's not guaranteed to be async >+// signal safe. >+static size_t StrLen(const char *str) { >+ size_t len = 0; >+ while (*str != '\0') { >+ ++str; >+ ++len; >+ } >+ return len; >+} >+ >+// Returns true if "str" has at least "n" characters remaining. >+static bool AtLeastNumCharsRemaining(const char *str, int n) { >+ for (int i = 0; i < n; ++i) { >+ if (str[i] == '\0') { >+ return false; >+ } >+ } >+ return true; >+} >+ >+// Returns true if "str" has "prefix" as a prefix. >+static bool StrPrefix(const char *str, const char *prefix) { >+ size_t i = 0; >+ while (str[i] != '\0' && prefix[i] != '\0' && str[i] == prefix[i]) { >+ ++i; >+ } >+ return prefix[i] == '\0'; // Consumed everything in "prefix". >+} >+ >+static void InitState(State *state, const char *mangled, char *out, >+ int out_size) { >+ state->mangled_begin = mangled; >+ state->out = out; >+ state->out_end_idx = out_size; >+ state->recursion_depth = 0; >+ state->steps = 0; >+ >+ state->parse_state.mangled_idx = 0; >+ state->parse_state.out_cur_idx = 0; >+ state->parse_state.prev_name_idx = 0; >+ state->parse_state.prev_name_length = -1; >+ state->parse_state.nest_level = -1; >+ state->parse_state.append = true; >+} >+ >+static inline const char *RemainingInput(State *state) { >+ return &state->mangled_begin[state->parse_state.mangled_idx]; >+} >+ >+// Returns true and advances "mangled_idx" if we find "one_char_token" >+// at "mangled_idx" position. It is assumed that "one_char_token" does >+// not contain '\0'. >+static bool ParseOneCharToken(State *state, const char one_char_token) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (RemainingInput(state)[0] == one_char_token) { >+ ++state->parse_state.mangled_idx; >+ return true; >+ } >+ return false; >+} >+ >+// Returns true and advances "mangled_cur" if we find "two_char_token" >+// at "mangled_cur" position. It is assumed that "two_char_token" does >+// not contain '\0'. >+static bool ParseTwoCharToken(State *state, const char *two_char_token) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (RemainingInput(state)[0] == two_char_token[0] && >+ RemainingInput(state)[1] == two_char_token[1]) { >+ state->parse_state.mangled_idx += 2; >+ return true; >+ } >+ return false; >+} >+ >+// Returns true and advances "mangled_cur" if we find any character in >+// "char_class" at "mangled_cur" position. >+static bool ParseCharClass(State *state, const char *char_class) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (RemainingInput(state)[0] == '\0') { >+ return false; >+ } >+ const char *p = char_class; >+ for (; *p != '\0'; ++p) { >+ if (RemainingInput(state)[0] == *p) { >+ ++state->parse_state.mangled_idx; >+ return true; >+ } >+ } >+ return false; >+} >+ >+static bool ParseDigit(State *state, int *digit) { >+ char c = RemainingInput(state)[0]; >+ if (ParseCharClass(state, "0123456789")) { >+ if (digit != nullptr) { >+ *digit = c - '0'; >+ } >+ return true; >+ } >+ return false; >+} >+ >+// This function is used for handling an optional non-terminal. >+static bool Optional(bool /*status*/) { return true; } >+ >+// This function is used for handling <non-terminal>+ syntax. >+typedef bool (*ParseFunc)(State *); >+static bool OneOrMore(ParseFunc parse_func, State *state) { >+ if (parse_func(state)) { >+ while (parse_func(state)) { >+ } >+ return true; >+ } >+ return false; >+} >+ >+// This function is used for handling <non-terminal>* syntax. The function >+// always returns true and must be followed by a termination token or a >+// terminating sequence not handled by parse_func (e.g. >+// ParseOneCharToken(state, 'E')). >+static bool ZeroOrMore(ParseFunc parse_func, State *state) { >+ while (parse_func(state)) { >+ } >+ return true; >+} >+ >+// Append "str" at "out_cur_idx". If there is an overflow, out_cur_idx is >+// set to out_end_idx+1. The output std::string is ensured to >+// always terminate with '\0' as long as there is no overflow. >+static void Append(State *state, const char *const str, const int length) { >+ for (int i = 0; i < length; ++i) { >+ if (state->parse_state.out_cur_idx + 1 < >+ state->out_end_idx) { // +1 for '\0' >+ state->out[state->parse_state.out_cur_idx++] = str[i]; >+ } else { >+ // signal overflow >+ state->parse_state.out_cur_idx = state->out_end_idx + 1; >+ break; >+ } >+ } >+ if (state->parse_state.out_cur_idx < state->out_end_idx) { >+ state->out[state->parse_state.out_cur_idx] = >+ '\0'; // Terminate it with '\0' >+ } >+} >+ >+// We don't use equivalents in libc to avoid locale issues. >+static bool IsLower(char c) { return c >= 'a' && c <= 'z'; } >+ >+static bool IsAlpha(char c) { >+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); >+} >+ >+static bool IsDigit(char c) { return c >= '0' && c <= '9'; } >+ >+// Returns true if "str" is a function clone suffix. These suffixes are used >+// by GCC 4.5.x and later versions (and our locally-modified version of GCC >+// 4.4.x) to indicate functions which have been cloned during optimization. >+// We treat any sequence (.<alpha>+.<digit>+)+ as a function clone suffix. >+static bool IsFunctionCloneSuffix(const char *str) { >+ size_t i = 0; >+ while (str[i] != '\0') { >+ // Consume a single .<alpha>+.<digit>+ sequence. >+ if (str[i] != '.' || !IsAlpha(str[i + 1])) { >+ return false; >+ } >+ i += 2; >+ while (IsAlpha(str[i])) { >+ ++i; >+ } >+ if (str[i] != '.' || !IsDigit(str[i + 1])) { >+ return false; >+ } >+ i += 2; >+ while (IsDigit(str[i])) { >+ ++i; >+ } >+ } >+ return true; // Consumed everything in "str". >+} >+ >+static bool EndsWith(State *state, const char chr) { >+ return state->parse_state.out_cur_idx > 0 && >+ chr == state->out[state->parse_state.out_cur_idx - 1]; >+} >+ >+// Append "str" with some tweaks, iff "append" state is true. >+static void MaybeAppendWithLength(State *state, const char *const str, >+ const int length) { >+ if (state->parse_state.append && length > 0) { >+ // Append a space if the output buffer ends with '<' and "str" >+ // starts with '<' to avoid <<<. >+ if (str[0] == '<' && EndsWith(state, '<')) { >+ Append(state, " ", 1); >+ } >+ // Remember the last identifier name for ctors/dtors. >+ if (IsAlpha(str[0]) || str[0] == '_') { >+ state->parse_state.prev_name_idx = state->parse_state.out_cur_idx; >+ state->parse_state.prev_name_length = length; >+ } >+ Append(state, str, length); >+ } >+} >+ >+// Appends a positive decimal number to the output if appending is enabled. >+static bool MaybeAppendDecimal(State *state, unsigned int val) { >+ // Max {32-64}-bit unsigned int is 20 digits. >+ constexpr size_t kMaxLength = 20; >+ char buf[kMaxLength]; >+ >+ // We can't use itoa or sprintf as neither is specified to be >+ // async-signal-safe. >+ if (state->parse_state.append) { >+ // We can't have a one-before-the-beginning pointer, so instead start with >+ // one-past-the-end and manipulate one character before the pointer. >+ char *p = &buf[kMaxLength]; >+ do { // val=0 is the only input that should write a leading zero digit. >+ *--p = (val % 10) + '0'; >+ val /= 10; >+ } while (p > buf && val != 0); >+ >+ // 'p' landed on the last character we set. How convenient. >+ Append(state, p, kMaxLength - (p - buf)); >+ } >+ >+ return true; >+} >+ >+// A convenient wrapper around MaybeAppendWithLength(). >+// Returns true so that it can be placed in "if" conditions. >+static bool MaybeAppend(State *state, const char *const str) { >+ if (state->parse_state.append) { >+ int length = StrLen(str); >+ MaybeAppendWithLength(state, str, length); >+ } >+ return true; >+} >+ >+// This function is used for handling nested names. >+static bool EnterNestedName(State *state) { >+ state->parse_state.nest_level = 0; >+ return true; >+} >+ >+// This function is used for handling nested names. >+static bool LeaveNestedName(State *state, int16_t prev_value) { >+ state->parse_state.nest_level = prev_value; >+ return true; >+} >+ >+// Disable the append mode not to print function parameters, etc. >+static bool DisableAppend(State *state) { >+ state->parse_state.append = false; >+ return true; >+} >+ >+// Restore the append mode to the previous state. >+static bool RestoreAppend(State *state, bool prev_value) { >+ state->parse_state.append = prev_value; >+ return true; >+} >+ >+// Increase the nest level for nested names. >+static void MaybeIncreaseNestLevel(State *state) { >+ if (state->parse_state.nest_level > -1) { >+ ++state->parse_state.nest_level; >+ } >+} >+ >+// Appends :: for nested names if necessary. >+static void MaybeAppendSeparator(State *state) { >+ if (state->parse_state.nest_level >= 1) { >+ MaybeAppend(state, "::"); >+ } >+} >+ >+// Cancel the last separator if necessary. >+static void MaybeCancelLastSeparator(State *state) { >+ if (state->parse_state.nest_level >= 1 && state->parse_state.append && >+ state->parse_state.out_cur_idx >= 2) { >+ state->parse_state.out_cur_idx -= 2; >+ state->out[state->parse_state.out_cur_idx] = '\0'; >+ } >+} >+ >+// Returns true if the identifier of the given length pointed to by >+// "mangled_cur" is anonymous namespace. >+static bool IdentifierIsAnonymousNamespace(State *state, int length) { >+ // Returns true if "anon_prefix" is a proper prefix of "mangled_cur". >+ static const char anon_prefix[] = "_GLOBAL__N_"; >+ return (length > static_cast<int>(sizeof(anon_prefix) - 1) && >+ StrPrefix(RemainingInput(state), anon_prefix)); >+} >+ >+// Forward declarations of our parsing functions. >+static bool ParseMangledName(State *state); >+static bool ParseEncoding(State *state); >+static bool ParseName(State *state); >+static bool ParseUnscopedName(State *state); >+static bool ParseNestedName(State *state); >+static bool ParsePrefix(State *state); >+static bool ParseUnqualifiedName(State *state); >+static bool ParseSourceName(State *state); >+static bool ParseLocalSourceName(State *state); >+static bool ParseUnnamedTypeName(State *state); >+static bool ParseNumber(State *state, int *number_out); >+static bool ParseFloatNumber(State *state); >+static bool ParseSeqId(State *state); >+static bool ParseIdentifier(State *state, int length); >+static bool ParseOperatorName(State *state, int *arity); >+static bool ParseSpecialName(State *state); >+static bool ParseCallOffset(State *state); >+static bool ParseNVOffset(State *state); >+static bool ParseVOffset(State *state); >+static bool ParseCtorDtorName(State *state); >+static bool ParseDecltype(State *state); >+static bool ParseType(State *state); >+static bool ParseCVQualifiers(State *state); >+static bool ParseBuiltinType(State *state); >+static bool ParseFunctionType(State *state); >+static bool ParseBareFunctionType(State *state); >+static bool ParseClassEnumType(State *state); >+static bool ParseArrayType(State *state); >+static bool ParsePointerToMemberType(State *state); >+static bool ParseTemplateParam(State *state); >+static bool ParseTemplateTemplateParam(State *state); >+static bool ParseTemplateArgs(State *state); >+static bool ParseTemplateArg(State *state); >+static bool ParseBaseUnresolvedName(State *state); >+static bool ParseUnresolvedName(State *state); >+static bool ParseExpression(State *state); >+static bool ParseExprPrimary(State *state); >+static bool ParseExprCastValue(State *state); >+static bool ParseLocalName(State *state); >+static bool ParseLocalNameSuffix(State *state); >+static bool ParseDiscriminator(State *state); >+static bool ParseSubstitution(State *state, bool accept_std); >+ >+// Implementation note: the following code is a straightforward >+// translation of the Itanium C++ ABI defined in BNF with a couple of >+// exceptions. >+// >+// - Support GNU extensions not defined in the Itanium C++ ABI >+// - <prefix> and <template-prefix> are combined to avoid infinite loop >+// - Reorder patterns to shorten the code >+// - Reorder patterns to give greedier functions precedence >+// We'll mark "Less greedy than" for these cases in the code >+// >+// Each parsing function changes the parse state and returns true on >+// success, or returns false and doesn't change the parse state (note: >+// the parse-steps counter increases regardless of success or failure). >+// To ensure that the parse state isn't changed in the latter case, we >+// save the original state before we call multiple parsing functions >+// consecutively with &&, and restore it if unsuccessful. See >+// ParseEncoding() as an example of this convention. We follow the >+// convention throughout the code. >+// >+// Originally we tried to do demangling without following the full ABI >+// syntax but it turned out we needed to follow the full syntax to >+// parse complicated cases like nested template arguments. Note that >+// implementing a full-fledged demangler isn't trivial (libiberty's >+// cp-demangle.c has +4300 lines). >+// >+// Note that (foo) in <(foo) ...> is a modifier to be ignored. >+// >+// Reference: >+// - Itanium C++ ABI >+// <https://mentorembedded.github.io/cxx-abi/abi.html#mangling> >+ >+// <mangled-name> ::= _Z <encoding> >+static bool ParseMangledName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ return ParseTwoCharToken(state, "_Z") && ParseEncoding(state); >+} >+ >+// <encoding> ::= <(function) name> <bare-function-type> >+// ::= <(data) name> >+// ::= <special-name> >+static bool ParseEncoding(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ // Implementing the first two productions together as <name> >+ // [<bare-function-type>] avoids exponential blowup of backtracking. >+ // >+ // Since Optional(...) can't fail, there's no need to copy the state for >+ // backtracking. >+ if (ParseName(state) && Optional(ParseBareFunctionType(state))) { >+ return true; >+ } >+ >+ if (ParseSpecialName(state)) { >+ return true; >+ } >+ return false; >+} >+ >+// <name> ::= <nested-name> >+// ::= <unscoped-template-name> <template-args> >+// ::= <unscoped-name> >+// ::= <local-name> >+static bool ParseName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (ParseNestedName(state) || ParseLocalName(state)) { >+ return true; >+ } >+ >+ // We reorganize the productions to avoid re-parsing unscoped names. >+ // - Inline <unscoped-template-name> productions: >+ // <name> ::= <substitution> <template-args> >+ // ::= <unscoped-name> <template-args> >+ // ::= <unscoped-name> >+ // - Merge the two productions that start with unscoped-name: >+ // <name> ::= <unscoped-name> [<template-args>] >+ >+ ParseState copy = state->parse_state; >+ // "std<...>" isn't a valid name. >+ if (ParseSubstitution(state, /*accept_std=*/false) && >+ ParseTemplateArgs(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Note there's no need to restore state after this since only the first >+ // subparser can fail. >+ return ParseUnscopedName(state) && Optional(ParseTemplateArgs(state)); >+} >+ >+// <unscoped-name> ::= <unqualified-name> >+// ::= St <unqualified-name> >+static bool ParseUnscopedName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (ParseUnqualifiedName(state)) { >+ return true; >+ } >+ >+ ParseState copy = state->parse_state; >+ if (ParseTwoCharToken(state, "St") && MaybeAppend(state, "std::") && >+ ParseUnqualifiedName(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <ref-qualifer> ::= R // lvalue method reference qualifier >+// ::= O // rvalue method reference qualifier >+static inline bool ParseRefQualifier(State *state) { >+ return ParseCharClass(state, "OR"); >+} >+ >+// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> >+// <unqualified-name> E >+// ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> >+// <template-args> E >+static bool ParseNestedName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'N') && EnterNestedName(state) && >+ Optional(ParseCVQualifiers(state)) && >+ Optional(ParseRefQualifier(state)) && ParsePrefix(state) && >+ LeaveNestedName(state, copy.nest_level) && >+ ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// This part is tricky. If we literally translate them to code, we'll >+// end up infinite loop. Hence we merge them to avoid the case. >+// >+// <prefix> ::= <prefix> <unqualified-name> >+// ::= <template-prefix> <template-args> >+// ::= <template-param> >+// ::= <substitution> >+// ::= # empty >+// <template-prefix> ::= <prefix> <(template) unqualified-name> >+// ::= <template-param> >+// ::= <substitution> >+static bool ParsePrefix(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ bool has_something = false; >+ while (true) { >+ MaybeAppendSeparator(state); >+ if (ParseTemplateParam(state) || >+ ParseSubstitution(state, /*accept_std=*/true) || >+ ParseUnscopedName(state) || >+ (ParseOneCharToken(state, 'M') && ParseUnnamedTypeName(state))) { >+ has_something = true; >+ MaybeIncreaseNestLevel(state); >+ continue; >+ } >+ MaybeCancelLastSeparator(state); >+ if (has_something && ParseTemplateArgs(state)) { >+ return ParsePrefix(state); >+ } else { >+ break; >+ } >+ } >+ return true; >+} >+ >+// <unqualified-name> ::= <operator-name> >+// ::= <ctor-dtor-name> >+// ::= <source-name> >+// ::= <local-source-name> // GCC extension; see below. >+// ::= <unnamed-type-name> >+static bool ParseUnqualifiedName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ return (ParseOperatorName(state, nullptr) || ParseCtorDtorName(state) || >+ ParseSourceName(state) || ParseLocalSourceName(state) || >+ ParseUnnamedTypeName(state)); >+} >+ >+// <source-name> ::= <positive length number> <identifier> >+static bool ParseSourceName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ int length = -1; >+ if (ParseNumber(state, &length) && ParseIdentifier(state, length)) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <local-source-name> ::= L <source-name> [<discriminator>] >+// >+// References: >+// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 >+// http://gcc.gnu.org/viewcvs?view=rev&revision=124467 >+static bool ParseLocalSourceName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'L') && ParseSourceName(state) && >+ Optional(ParseDiscriminator(state))) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <unnamed-type-name> ::= Ut [<(nonnegative) number>] _ >+// ::= <closure-type-name> >+// <closure-type-name> ::= Ul <lambda-sig> E [<(nonnegative) number>] _ >+// <lambda-sig> ::= <(parameter) type>+ >+static bool ParseUnnamedTypeName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ // Type's 1-based index n is encoded as { "", n == 1; itoa(n-2), otherwise }. >+ // Optionally parse the encoded value into 'which' and add 2 to get the index. >+ int which = -1; >+ >+ // Unnamed type local to function or class. >+ if (ParseTwoCharToken(state, "Ut") && Optional(ParseNumber(state, &which)) && >+ which <= std::numeric_limits<int>::max() - 2 && // Don't overflow. >+ ParseOneCharToken(state, '_')) { >+ MaybeAppend(state, "{unnamed type#"); >+ MaybeAppendDecimal(state, 2 + which); >+ MaybeAppend(state, "}"); >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Closure type. >+ which = -1; >+ if (ParseTwoCharToken(state, "Ul") && DisableAppend(state) && >+ OneOrMore(ParseType, state) && RestoreAppend(state, copy.append) && >+ ParseOneCharToken(state, 'E') && Optional(ParseNumber(state, &which)) && >+ which <= std::numeric_limits<int>::max() - 2 && // Don't overflow. >+ ParseOneCharToken(state, '_')) { >+ MaybeAppend(state, "{lambda()#"); >+ MaybeAppendDecimal(state, 2 + which); >+ MaybeAppend(state, "}"); >+ return true; >+ } >+ state->parse_state = copy; >+ >+ return false; >+} >+ >+// <number> ::= [n] <non-negative decimal integer> >+// If "number_out" is non-null, then *number_out is set to the value of the >+// parsed number on success. >+static bool ParseNumber(State *state, int *number_out) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ bool negative = false; >+ if (ParseOneCharToken(state, 'n')) { >+ negative = true; >+ } >+ const char *p = RemainingInput(state); >+ uint64_t number = 0; >+ for (; *p != '\0'; ++p) { >+ if (IsDigit(*p)) { >+ number = number * 10 + (*p - '0'); >+ } else { >+ break; >+ } >+ } >+ // Apply the sign with uint64_t arithmetic so overflows aren't UB. Gives >+ // "incorrect" results for out-of-range inputs, but negative values only >+ // appear for literals, which aren't printed. >+ if (negative) { >+ number = ~number + 1; >+ } >+ if (p != RemainingInput(state)) { // Conversion succeeded. >+ state->parse_state.mangled_idx += p - RemainingInput(state); >+ if (number_out != nullptr) { >+ // Note: possibly truncate "number". >+ *number_out = number; >+ } >+ return true; >+ } >+ return false; >+} >+ >+// Floating-point literals are encoded using a fixed-length lowercase >+// hexadecimal std::string. >+static bool ParseFloatNumber(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ const char *p = RemainingInput(state); >+ for (; *p != '\0'; ++p) { >+ if (!IsDigit(*p) && !(*p >= 'a' && *p <= 'f')) { >+ break; >+ } >+ } >+ if (p != RemainingInput(state)) { // Conversion succeeded. >+ state->parse_state.mangled_idx += p - RemainingInput(state); >+ return true; >+ } >+ return false; >+} >+ >+// The <seq-id> is a sequence number in base 36, >+// using digits and upper case letters >+static bool ParseSeqId(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ const char *p = RemainingInput(state); >+ for (; *p != '\0'; ++p) { >+ if (!IsDigit(*p) && !(*p >= 'A' && *p <= 'Z')) { >+ break; >+ } >+ } >+ if (p != RemainingInput(state)) { // Conversion succeeded. >+ state->parse_state.mangled_idx += p - RemainingInput(state); >+ return true; >+ } >+ return false; >+} >+ >+// <identifier> ::= <unqualified source code identifier> (of given length) >+static bool ParseIdentifier(State *state, int length) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (length < 0 || !AtLeastNumCharsRemaining(RemainingInput(state), length)) { >+ return false; >+ } >+ if (IdentifierIsAnonymousNamespace(state, length)) { >+ MaybeAppend(state, "(anonymous namespace)"); >+ } else { >+ MaybeAppendWithLength(state, RemainingInput(state), length); >+ } >+ state->parse_state.mangled_idx += length; >+ return true; >+} >+ >+// <operator-name> ::= nw, and other two letters cases >+// ::= cv <type> # (cast) >+// ::= v <digit> <source-name> # vendor extended operator >+static bool ParseOperatorName(State *state, int *arity) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (!AtLeastNumCharsRemaining(RemainingInput(state), 2)) { >+ return false; >+ } >+ // First check with "cv" (cast) case. >+ ParseState copy = state->parse_state; >+ if (ParseTwoCharToken(state, "cv") && MaybeAppend(state, "operator ") && >+ EnterNestedName(state) && ParseType(state) && >+ LeaveNestedName(state, copy.nest_level)) { >+ if (arity != nullptr) { >+ *arity = 1; >+ } >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Then vendor extended operators. >+ if (ParseOneCharToken(state, 'v') && ParseDigit(state, arity) && >+ ParseSourceName(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Other operator names should start with a lower alphabet followed >+ // by a lower/upper alphabet. >+ if (!(IsLower(RemainingInput(state)[0]) && >+ IsAlpha(RemainingInput(state)[1]))) { >+ return false; >+ } >+ // We may want to perform a binary search if we really need speed. >+ const AbbrevPair *p; >+ for (p = kOperatorList; p->abbrev != nullptr; ++p) { >+ if (RemainingInput(state)[0] == p->abbrev[0] && >+ RemainingInput(state)[1] == p->abbrev[1]) { >+ if (arity != nullptr) { >+ *arity = p->arity; >+ } >+ MaybeAppend(state, "operator"); >+ if (IsLower(*p->real_name)) { // new, delete, etc. >+ MaybeAppend(state, " "); >+ } >+ MaybeAppend(state, p->real_name); >+ state->parse_state.mangled_idx += 2; >+ return true; >+ } >+ } >+ return false; >+} >+ >+// <special-name> ::= TV <type> >+// ::= TT <type> >+// ::= TI <type> >+// ::= TS <type> >+// ::= Tc <call-offset> <call-offset> <(base) encoding> >+// ::= GV <(object) name> >+// ::= T <call-offset> <(base) encoding> >+// G++ extensions: >+// ::= TC <type> <(offset) number> _ <(base) type> >+// ::= TF <type> >+// ::= TJ <type> >+// ::= GR <name> >+// ::= GA <encoding> >+// ::= Th <call-offset> <(base) encoding> >+// ::= Tv <call-offset> <(base) encoding> >+// >+// Note: we don't care much about them since they don't appear in >+// stack traces. The are special data. >+static bool ParseSpecialName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTIS") && >+ ParseType(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseTwoCharToken(state, "Tc") && ParseCallOffset(state) && >+ ParseCallOffset(state) && ParseEncoding(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseTwoCharToken(state, "GV") && ParseName(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseOneCharToken(state, 'T') && ParseCallOffset(state) && >+ ParseEncoding(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // G++ extensions >+ if (ParseTwoCharToken(state, "TC") && ParseType(state) && >+ ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') && >+ DisableAppend(state) && ParseType(state)) { >+ RestoreAppend(state, copy.append); >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "FJ") && >+ ParseType(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseTwoCharToken(state, "GR") && ParseName(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseTwoCharToken(state, "GA") && ParseEncoding(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "hv") && >+ ParseCallOffset(state) && ParseEncoding(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <call-offset> ::= h <nv-offset> _ >+// ::= v <v-offset> _ >+static bool ParseCallOffset(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'h') && ParseNVOffset(state) && >+ ParseOneCharToken(state, '_')) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseOneCharToken(state, 'v') && ParseVOffset(state) && >+ ParseOneCharToken(state, '_')) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ return false; >+} >+ >+// <nv-offset> ::= <(offset) number> >+static bool ParseNVOffset(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ return ParseNumber(state, nullptr); >+} >+ >+// <v-offset> ::= <(offset) number> _ <(virtual offset) number> >+static bool ParseVOffset(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') && >+ ParseNumber(state, nullptr)) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <ctor-dtor-name> ::= C1 | C2 | C3 >+// ::= D0 | D1 | D2 >+// # GCC extensions: "unified" constructor/destructor. See >+// # https://github.com/gcc-mirror/gcc/blob/7ad17b583c3643bd4557f29b8391ca7ef08391f5/gcc/cp/mangle.c#L1847 >+// ::= C4 | D4 >+static bool ParseCtorDtorName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'C') && ParseCharClass(state, "1234")) { >+ const char *const prev_name = state->out + state->parse_state.prev_name_idx; >+ MaybeAppendWithLength(state, prev_name, >+ state->parse_state.prev_name_length); >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "0124")) { >+ const char *const prev_name = state->out + state->parse_state.prev_name_idx; >+ MaybeAppend(state, "~"); >+ MaybeAppendWithLength(state, prev_name, >+ state->parse_state.prev_name_length); >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <decltype> ::= Dt <expression> E # decltype of an id-expression or class >+// # member access (C++0x) >+// ::= DT <expression> E # decltype of an expression (C++0x) >+static bool ParseDecltype(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "tT") && >+ ParseExpression(state) && ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ return false; >+} >+ >+// <type> ::= <CV-qualifiers> <type> >+// ::= P <type> # pointer-to >+// ::= R <type> # reference-to >+// ::= O <type> # rvalue reference-to (C++0x) >+// ::= C <type> # complex pair (C 2000) >+// ::= G <type> # imaginary (C 2000) >+// ::= U <source-name> <type> # vendor extended type qualifier >+// ::= <builtin-type> >+// ::= <function-type> >+// ::= <class-enum-type> # note: just an alias for <name> >+// ::= <array-type> >+// ::= <pointer-to-member-type> >+// ::= <template-template-param> <template-args> >+// ::= <template-param> >+// ::= <decltype> >+// ::= <substitution> >+// ::= Dp <type> # pack expansion of (C++0x) >+// >+static bool ParseType(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ >+ // We should check CV-qualifers, and PRGC things first. >+ // >+ // CV-qualifiers overlap with some operator names, but an operator name is not >+ // valid as a type. To avoid an ambiguity that can lead to exponential time >+ // complexity, refuse to backtrack the CV-qualifiers. >+ // >+ // _Z4aoeuIrMvvE >+ // => _Z 4aoeuI rM v v E >+ // aoeu<operator%=, void, void> >+ // => _Z 4aoeuI r Mv v E >+ // aoeu<void void::* restrict> >+ // >+ // By consuming the CV-qualifiers first, the former parse is disabled. >+ if (ParseCVQualifiers(state)) { >+ const bool result = ParseType(state); >+ if (!result) state->parse_state = copy; >+ return result; >+ } >+ state->parse_state = copy; >+ >+ // Similarly, these tag characters can overlap with other <name>s resulting in >+ // two different parse prefixes that land on <template-args> in the same >+ // place, such as "C3r1xI...". So, disable the "ctor-name = C3" parse by >+ // refusing to backtrack the tag characters. >+ if (ParseCharClass(state, "OPRCG")) { >+ const bool result = ParseType(state); >+ if (!result) state->parse_state = copy; >+ return result; >+ } >+ state->parse_state = copy; >+ >+ if (ParseTwoCharToken(state, "Dp") && ParseType(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseOneCharToken(state, 'U') && ParseSourceName(state) && >+ ParseType(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseBuiltinType(state) || ParseFunctionType(state) || >+ ParseClassEnumType(state) || ParseArrayType(state) || >+ ParsePointerToMemberType(state) || ParseDecltype(state) || >+ // "std" on its own isn't a type. >+ ParseSubstitution(state, /*accept_std=*/false)) { >+ return true; >+ } >+ >+ if (ParseTemplateTemplateParam(state) && ParseTemplateArgs(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Less greedy than <template-template-param> <template-args>. >+ if (ParseTemplateParam(state)) { >+ return true; >+ } >+ >+ return false; >+} >+ >+// <CV-qualifiers> ::= [r] [V] [K] >+// We don't allow empty <CV-qualifiers> to avoid infinite loop in >+// ParseType(). >+static bool ParseCVQualifiers(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ int num_cv_qualifiers = 0; >+ num_cv_qualifiers += ParseOneCharToken(state, 'r'); >+ num_cv_qualifiers += ParseOneCharToken(state, 'V'); >+ num_cv_qualifiers += ParseOneCharToken(state, 'K'); >+ return num_cv_qualifiers > 0; >+} >+ >+// <builtin-type> ::= v, etc. >+// ::= u <source-name> >+static bool ParseBuiltinType(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ const AbbrevPair *p; >+ for (p = kBuiltinTypeList; p->abbrev != nullptr; ++p) { >+ if (RemainingInput(state)[0] == p->abbrev[0]) { >+ MaybeAppend(state, p->real_name); >+ ++state->parse_state.mangled_idx; >+ return true; >+ } >+ } >+ >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <function-type> ::= F [Y] <bare-function-type> E >+static bool ParseFunctionType(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'F') && >+ Optional(ParseOneCharToken(state, 'Y')) && ParseBareFunctionType(state) && >+ ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <bare-function-type> ::= <(signature) type>+ >+static bool ParseBareFunctionType(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ DisableAppend(state); >+ if (OneOrMore(ParseType, state)) { >+ RestoreAppend(state, copy.append); >+ MaybeAppend(state, "()"); >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <class-enum-type> ::= <name> >+static bool ParseClassEnumType(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ return ParseName(state); >+} >+ >+// <array-type> ::= A <(positive dimension) number> _ <(element) type> >+// ::= A [<(dimension) expression>] _ <(element) type> >+static bool ParseArrayType(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'A') && ParseNumber(state, nullptr) && >+ ParseOneCharToken(state, '_') && ParseType(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseOneCharToken(state, 'A') && Optional(ParseExpression(state)) && >+ ParseOneCharToken(state, '_') && ParseType(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <pointer-to-member-type> ::= M <(class) type> <(member) type> >+static bool ParsePointerToMemberType(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'M') && ParseType(state) && ParseType(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <template-param> ::= T_ >+// ::= T <parameter-2 non-negative number> _ >+static bool ParseTemplateParam(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (ParseTwoCharToken(state, "T_")) { >+ MaybeAppend(state, "?"); // We don't support template substitutions. >+ return true; >+ } >+ >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'T') && ParseNumber(state, nullptr) && >+ ParseOneCharToken(state, '_')) { >+ MaybeAppend(state, "?"); // We don't support template substitutions. >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <template-template-param> ::= <template-param> >+// ::= <substitution> >+static bool ParseTemplateTemplateParam(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ return (ParseTemplateParam(state) || >+ // "std" on its own isn't a template. >+ ParseSubstitution(state, /*accept_std=*/false)); >+} >+ >+// <template-args> ::= I <template-arg>+ E >+static bool ParseTemplateArgs(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ DisableAppend(state); >+ if (ParseOneCharToken(state, 'I') && OneOrMore(ParseTemplateArg, state) && >+ ParseOneCharToken(state, 'E')) { >+ RestoreAppend(state, copy.append); >+ MaybeAppend(state, "<>"); >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <template-arg> ::= <type> >+// ::= <expr-primary> >+// ::= J <template-arg>* E # argument pack >+// ::= X <expression> E >+static bool ParseTemplateArg(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'J') && ZeroOrMore(ParseTemplateArg, state) && >+ ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // There can be significant overlap between the following leading to >+ // exponential backtracking: >+ // >+ // <expr-primary> ::= L <type> <expr-cast-value> E >+ // e.g. L 2xxIvE 1 E >+ // <type> ==> <local-source-name> <template-args> >+ // e.g. L 2xx IvE >+ // >+ // This means parsing an entire <type> twice, and <type> can contain >+ // <template-arg>, so this can generate exponential backtracking. There is >+ // only overlap when the remaining input starts with "L <source-name>", so >+ // parse all cases that can start this way jointly to share the common prefix. >+ // >+ // We have: >+ // >+ // <template-arg> ::= <type> >+ // ::= <expr-primary> >+ // >+ // First, drop all the productions of <type> that must start with something >+ // other than 'L'. All that's left is <class-enum-type>; inline it. >+ // >+ // <type> ::= <nested-name> # starts with 'N' >+ // ::= <unscoped-name> >+ // ::= <unscoped-template-name> <template-args> >+ // ::= <local-name> # starts with 'Z' >+ // >+ // Drop and inline again: >+ // >+ // <type> ::= <unscoped-name> >+ // ::= <unscoped-name> <template-args> >+ // ::= <substitution> <template-args> # starts with 'S' >+ // >+ // Merge the first two, inline <unscoped-name>, drop last: >+ // >+ // <type> ::= <unqualified-name> [<template-args>] >+ // ::= St <unqualified-name> [<template-args>] # starts with 'S' >+ // >+ // Drop and inline: >+ // >+ // <type> ::= <operator-name> [<template-args>] # starts with lowercase >+ // ::= <ctor-dtor-name> [<template-args>] # starts with 'C' or 'D' >+ // ::= <source-name> [<template-args>] # starts with digit >+ // ::= <local-source-name> [<template-args>] >+ // ::= <unnamed-type-name> [<template-args>] # starts with 'U' >+ // >+ // One more time: >+ // >+ // <type> ::= L <source-name> [<template-args>] >+ // >+ // Likewise with <expr-primary>: >+ // >+ // <expr-primary> ::= L <type> <expr-cast-value> E >+ // ::= LZ <encoding> E # cannot overlap; drop >+ // ::= L <mangled_name> E # cannot overlap; drop >+ // >+ // By similar reasoning as shown above, the only <type>s starting with >+ // <source-name> are "<source-name> [<template-args>]". Inline this. >+ // >+ // <expr-primary> ::= L <source-name> [<template-args>] <expr-cast-value> E >+ // >+ // Now inline both of these into <template-arg>: >+ // >+ // <template-arg> ::= L <source-name> [<template-args>] >+ // ::= L <source-name> [<template-args>] <expr-cast-value> E >+ // >+ // Merge them and we're done: >+ // <template-arg> >+ // ::= L <source-name> [<template-args>] [<expr-cast-value> E] >+ if (ParseLocalSourceName(state) && Optional(ParseTemplateArgs(state))) { >+ copy = state->parse_state; >+ if (ParseExprCastValue(state) && ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy; >+ return true; >+ } >+ >+ // Now that the overlapping cases can't reach this code, we can safely call >+ // both of these. >+ if (ParseType(state) || ParseExprPrimary(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseOneCharToken(state, 'X') && ParseExpression(state) && >+ ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <unresolved-type> ::= <template-param> [<template-args>] >+// ::= <decltype> >+// ::= <substitution> >+static inline bool ParseUnresolvedType(State *state) { >+ // No ComplexityGuard because we don't copy the state in this stack frame. >+ return (ParseTemplateParam(state) && Optional(ParseTemplateArgs(state))) || >+ ParseDecltype(state) || ParseSubstitution(state, /*accept_std=*/false); >+} >+ >+// <simple-id> ::= <source-name> [<template-args>] >+static inline bool ParseSimpleId(State *state) { >+ // No ComplexityGuard because we don't copy the state in this stack frame. >+ >+ // Note: <simple-id> cannot be followed by a parameter pack; see comment in >+ // ParseUnresolvedType. >+ return ParseSourceName(state) && Optional(ParseTemplateArgs(state)); >+} >+ >+// <base-unresolved-name> ::= <source-name> [<template-args>] >+// ::= on <operator-name> [<template-args>] >+// ::= dn <destructor-name> >+static bool ParseBaseUnresolvedName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ >+ if (ParseSimpleId(state)) { >+ return true; >+ } >+ >+ ParseState copy = state->parse_state; >+ if (ParseTwoCharToken(state, "on") && ParseOperatorName(state, nullptr) && >+ Optional(ParseTemplateArgs(state))) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseTwoCharToken(state, "dn") && >+ (ParseUnresolvedType(state) || ParseSimpleId(state))) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ return false; >+} >+ >+// <unresolved-name> ::= [gs] <base-unresolved-name> >+// ::= sr <unresolved-type> <base-unresolved-name> >+// ::= srN <unresolved-type> <unresolved-qualifier-level>+ E >+// <base-unresolved-name> >+// ::= [gs] sr <unresolved-qualifier-level>+ E >+// <base-unresolved-name> >+static bool ParseUnresolvedName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ >+ ParseState copy = state->parse_state; >+ if (Optional(ParseTwoCharToken(state, "gs")) && >+ ParseBaseUnresolvedName(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseTwoCharToken(state, "sr") && ParseUnresolvedType(state) && >+ ParseBaseUnresolvedName(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseTwoCharToken(state, "sr") && ParseOneCharToken(state, 'N') && >+ ParseUnresolvedType(state) && >+ OneOrMore(/* <unresolved-qualifier-level> ::= */ ParseSimpleId, state) && >+ ParseOneCharToken(state, 'E') && ParseBaseUnresolvedName(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (Optional(ParseTwoCharToken(state, "gs")) && >+ ParseTwoCharToken(state, "sr") && >+ OneOrMore(/* <unresolved-qualifier-level> ::= */ ParseSimpleId, state) && >+ ParseOneCharToken(state, 'E') && ParseBaseUnresolvedName(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ return false; >+} >+ >+// <expression> ::= <1-ary operator-name> <expression> >+// ::= <2-ary operator-name> <expression> <expression> >+// ::= <3-ary operator-name> <expression> <expression> <expression> >+// ::= cl <expression>+ E >+// ::= cv <type> <expression> # type (expression) >+// ::= cv <type> _ <expression>* E # type (expr-list) >+// ::= st <type> >+// ::= <template-param> >+// ::= <function-param> >+// ::= <expr-primary> >+// ::= dt <expression> <unresolved-name> # expr.name >+// ::= pt <expression> <unresolved-name> # expr->name >+// ::= sp <expression> # argument pack expansion >+// ::= sr <type> <unqualified-name> <template-args> >+// ::= sr <type> <unqualified-name> >+// <function-param> ::= fp <(top-level) CV-qualifiers> _ >+// ::= fp <(top-level) CV-qualifiers> <number> _ >+// ::= fL <number> p <(top-level) CV-qualifiers> _ >+// ::= fL <number> p <(top-level) CV-qualifiers> <number> _ >+static bool ParseExpression(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (ParseTemplateParam(state) || ParseExprPrimary(state)) { >+ return true; >+ } >+ >+ // Object/function call expression. >+ ParseState copy = state->parse_state; >+ if (ParseTwoCharToken(state, "cl") && OneOrMore(ParseExpression, state) && >+ ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Function-param expression (level 0). >+ if (ParseTwoCharToken(state, "fp") && Optional(ParseCVQualifiers(state)) && >+ Optional(ParseNumber(state, nullptr)) && ParseOneCharToken(state, '_')) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Function-param expression (level 1+). >+ if (ParseTwoCharToken(state, "fL") && Optional(ParseNumber(state, nullptr)) && >+ ParseOneCharToken(state, 'p') && Optional(ParseCVQualifiers(state)) && >+ Optional(ParseNumber(state, nullptr)) && ParseOneCharToken(state, '_')) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Parse the conversion expressions jointly to avoid re-parsing the <type> in >+ // their common prefix. Parsed as: >+ // <expression> ::= cv <type> <conversion-args> >+ // <conversion-args> ::= _ <expression>* E >+ // ::= <expression> >+ // >+ // Also don't try ParseOperatorName after seeing "cv", since ParseOperatorName >+ // also needs to accept "cv <type>" in other contexts. >+ if (ParseTwoCharToken(state, "cv")) { >+ if (ParseType(state)) { >+ ParseState copy2 = state->parse_state; >+ if (ParseOneCharToken(state, '_') && ZeroOrMore(ParseExpression, state) && >+ ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy2; >+ if (ParseExpression(state)) { >+ return true; >+ } >+ } >+ } else { >+ // Parse unary, binary, and ternary operator expressions jointly, taking >+ // care not to re-parse subexpressions repeatedly. Parse like: >+ // <expression> ::= <operator-name> <expression> >+ // [<one-to-two-expressions>] >+ // <one-to-two-expressions> ::= <expression> [<expression>] >+ int arity = -1; >+ if (ParseOperatorName(state, &arity) && >+ arity > 0 && // 0 arity => disabled. >+ (arity < 3 || ParseExpression(state)) && >+ (arity < 2 || ParseExpression(state)) && >+ (arity < 1 || ParseExpression(state))) { >+ return true; >+ } >+ } >+ state->parse_state = copy; >+ >+ // sizeof type >+ if (ParseTwoCharToken(state, "st") && ParseType(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Object and pointer member access expressions. >+ if ((ParseTwoCharToken(state, "dt") || ParseTwoCharToken(state, "pt")) && >+ ParseExpression(state) && ParseType(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Parameter pack expansion >+ if (ParseTwoCharToken(state, "sp") && ParseExpression(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ return ParseUnresolvedName(state); >+} >+ >+// <expr-primary> ::= L <type> <(value) number> E >+// ::= L <type> <(value) float> E >+// ::= L <mangled-name> E >+// // A bug in g++'s C++ ABI version 2 (-fabi-version=2). >+// ::= LZ <encoding> E >+// >+// Warning, subtle: the "bug" LZ production above is ambiguous with the first >+// production where <type> starts with <local-name>, which can lead to >+// exponential backtracking in two scenarios: >+// >+// - When whatever follows the E in the <local-name> in the first production is >+// not a name, we backtrack the whole <encoding> and re-parse the whole thing. >+// >+// - When whatever follows the <local-name> in the first production is not a >+// number and this <expr-primary> may be followed by a name, we backtrack the >+// <name> and re-parse it. >+// >+// Moreover this ambiguity isn't always resolved -- for example, the following >+// has two different parses: >+// >+// _ZaaILZ4aoeuE1x1EvE >+// => operator&&<aoeu, x, E, void> >+// => operator&&<(aoeu::x)(1), void> >+// >+// To resolve this, we just do what GCC's demangler does, and refuse to parse >+// casts to <local-name> types. >+static bool ParseExprPrimary(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ >+ // The "LZ" special case: if we see LZ, we commit to accept "LZ <encoding> E" >+ // or fail, no backtracking. >+ if (ParseTwoCharToken(state, "LZ")) { >+ if (ParseEncoding(state) && ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ >+ state->parse_state = copy; >+ return false; >+ } >+ >+ // The merged cast production. >+ if (ParseOneCharToken(state, 'L') && ParseType(state) && >+ ParseExprCastValue(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseOneCharToken(state, 'L') && ParseMangledName(state) && >+ ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ return false; >+} >+ >+// <number> or <float>, followed by 'E', as described above ParseExprPrimary. >+static bool ParseExprCastValue(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ // We have to be able to backtrack after accepting a number because we could >+ // have e.g. "7fffE", which will accept "7" as a number but then fail to find >+ // the 'E'. >+ ParseState copy = state->parse_state; >+ if (ParseNumber(state, nullptr) && ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ if (ParseFloatNumber(state) && ParseOneCharToken(state, 'E')) { >+ return true; >+ } >+ state->parse_state = copy; >+ >+ return false; >+} >+ >+// <local-name> ::= Z <(function) encoding> E <(entity) name> [<discriminator>] >+// ::= Z <(function) encoding> E s [<discriminator>] >+// >+// Parsing a common prefix of these two productions together avoids an >+// exponential blowup of backtracking. Parse like: >+// <local-name> := Z <encoding> E <local-name-suffix> >+// <local-name-suffix> ::= s [<discriminator>] >+// ::= <name> [<discriminator>] >+ >+static bool ParseLocalNameSuffix(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ >+ if (MaybeAppend(state, "::") && ParseName(state) && >+ Optional(ParseDiscriminator(state))) { >+ return true; >+ } >+ >+ // Since we're not going to overwrite the above "::" by re-parsing the >+ // <encoding> (whose trailing '\0' byte was in the byte now holding the >+ // first ':'), we have to rollback the "::" if the <name> parse failed. >+ if (state->parse_state.append) { >+ state->out[state->parse_state.out_cur_idx - 2] = '\0'; >+ } >+ >+ return ParseOneCharToken(state, 's') && Optional(ParseDiscriminator(state)); >+} >+ >+static bool ParseLocalName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) && >+ ParseOneCharToken(state, 'E') && ParseLocalNameSuffix(state)) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <discriminator> := _ <(non-negative) number> >+static bool ParseDiscriminator(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr)) { >+ return true; >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// <substitution> ::= S_ >+// ::= S <seq-id> _ >+// ::= St, etc. >+// >+// "St" is special in that it's not valid as a standalone name, and it *is* >+// allowed to precede a name without being wrapped in "N...E". This means that >+// if we accept it on its own, we can accept "St1a" and try to parse >+// template-args, then fail and backtrack, accept "St" on its own, then "1a" as >+// an unqualified name and re-parse the same template-args. To block this >+// exponential backtracking, we disable it with 'accept_std=false' in >+// problematic contexts. >+static bool ParseSubstitution(State *state, bool accept_std) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (ParseTwoCharToken(state, "S_")) { >+ MaybeAppend(state, "?"); // We don't support substitutions. >+ return true; >+ } >+ >+ ParseState copy = state->parse_state; >+ if (ParseOneCharToken(state, 'S') && ParseSeqId(state) && >+ ParseOneCharToken(state, '_')) { >+ MaybeAppend(state, "?"); // We don't support substitutions. >+ return true; >+ } >+ state->parse_state = copy; >+ >+ // Expand abbreviations like "St" => "std". >+ if (ParseOneCharToken(state, 'S')) { >+ const AbbrevPair *p; >+ for (p = kSubstitutionList; p->abbrev != nullptr; ++p) { >+ if (RemainingInput(state)[0] == p->abbrev[1] && >+ (accept_std || p->abbrev[1] != 't')) { >+ MaybeAppend(state, "std"); >+ if (p->real_name[0] != '\0') { >+ MaybeAppend(state, "::"); >+ MaybeAppend(state, p->real_name); >+ } >+ ++state->parse_state.mangled_idx; >+ return true; >+ } >+ } >+ } >+ state->parse_state = copy; >+ return false; >+} >+ >+// Parse <mangled-name>, optionally followed by either a function-clone suffix >+// or version suffix. Returns true only if all of "mangled_cur" was consumed. >+static bool ParseTopLevelMangledName(State *state) { >+ ComplexityGuard guard(state); >+ if (guard.IsTooComplex()) return false; >+ if (ParseMangledName(state)) { >+ if (RemainingInput(state)[0] != '\0') { >+ // Drop trailing function clone suffix, if any. >+ if (IsFunctionCloneSuffix(RemainingInput(state))) { >+ return true; >+ } >+ // Append trailing version suffix if any. >+ // ex. _Z3foo@@GLIBCXX_3.4 >+ if (RemainingInput(state)[0] == '@') { >+ MaybeAppend(state, RemainingInput(state)); >+ return true; >+ } >+ return false; // Unconsumed suffix. >+ } >+ return true; >+ } >+ return false; >+} >+ >+static bool Overflowed(const State *state) { >+ return state->parse_state.out_cur_idx >= state->out_end_idx; >+} >+ >+// The demangler entry point. >+bool Demangle(const char *mangled, char *out, int out_size) { >+ State state; >+ InitState(&state, mangled, out, out_size); >+ return ParseTopLevelMangledName(&state) && !Overflowed(&state); >+} >+ >+} // namespace debugging_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/demangle.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/demangle.h >new file mode 100644 >index 0000000000000000000000000000000000000000..2e75564ed35b47a1e2e2c7a8d8cddfe82d0661d1 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/demangle.h >@@ -0,0 +1,67 @@ >+// 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. >+ >+// An async-signal-safe and thread-safe demangler for Itanium C++ ABI >+// (aka G++ V3 ABI). >+// >+// The demangler is implemented to be used in async signal handlers to >+// symbolize stack traces. We cannot use libstdc++'s >+// abi::__cxa_demangle() in such signal handlers since it's not async >+// signal safe (it uses malloc() internally). >+// >+// Note that this demangler doesn't support full demangling. More >+// specifically, it doesn't print types of function parameters and >+// types of template arguments. It just skips them. However, it's >+// still very useful to extract basic information such as class, >+// function, constructor, destructor, and operator names. >+// >+// See the implementation note in demangle.cc if you are interested. >+// >+// Example: >+// >+// | Mangled Name | The Demangler | abi::__cxa_demangle() >+// |---------------|---------------|----------------------- >+// | _Z1fv | f() | f() >+// | _Z1fi | f() | f(int) >+// | _Z3foo3bar | foo() | foo(bar) >+// | _Z1fIiEvi | f<>() | void f<int>(int) >+// | _ZN1N1fE | N::f | N::f >+// | _ZN3Foo3BarEv | Foo::Bar() | Foo::Bar() >+// | _Zrm1XS_" | operator%() | operator%(X, X) >+// | _ZN3FooC1Ev | Foo::Foo() | Foo::Foo() >+// | _Z1fSs | f() | f(std::basic_string<char, >+// | | | std::char_traits<char>, >+// | | | std::allocator<char> >) >+// >+// See the unit test for more examples. >+// >+// Note: we might want to write demanglers for ABIs other than Itanium >+// C++ ABI in the future. >+// >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ >+#define ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ >+ >+namespace absl { >+namespace debugging_internal { >+ >+// Demangle `mangled`. On success, return true and write the >+// demangled symbol name to `out`. Otherwise, return false. >+// `out` is modified even if demangling is unsuccessful. >+bool Demangle(const char *mangled, char *out, int out_size); >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..b9d9008f0077e660baab226b30a9fd3e4e8640a4 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc >@@ -0,0 +1,191 @@ >+// 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/debugging/internal/demangle.h" >+ >+#include <cstdlib> >+#include <string> >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/debugging/internal/stack_consumption.h" >+#include "absl/memory/memory.h" >+ >+namespace absl { >+namespace debugging_internal { >+namespace { >+ >+// A wrapper function for Demangle() to make the unit test simple. >+static const char *DemangleIt(const char * const mangled) { >+ static char demangled[4096]; >+ if (Demangle(mangled, demangled, sizeof(demangled))) { >+ return demangled; >+ } else { >+ return mangled; >+ } >+} >+ >+// Test corner cases of bounary conditions. >+TEST(Demangle, CornerCases) { >+ char tmp[10]; >+ EXPECT_TRUE(Demangle("_Z6foobarv", tmp, sizeof(tmp))); >+ // sizeof("foobar()") == 9 >+ EXPECT_STREQ("foobar()", tmp); >+ EXPECT_TRUE(Demangle("_Z6foobarv", tmp, 9)); >+ EXPECT_STREQ("foobar()", tmp); >+ EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 8)); // Not enough. >+ EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 1)); >+ EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 0)); >+ EXPECT_FALSE(Demangle("_Z6foobarv", nullptr, 0)); // Should not cause SEGV. >+ EXPECT_FALSE(Demangle("_Z1000000", tmp, 9)); >+} >+ >+// Test handling of functions suffixed with .clone.N, which is used >+// by GCC 4.5.x (and our locally-modified version of GCC 4.4.x), and >+// .constprop.N and .isra.N, which are used by GCC 4.6.x. These >+// suffixes are used to indicate functions which have been cloned >+// during optimization. We ignore these suffixes. >+TEST(Demangle, Clones) { >+ char tmp[20]; >+ EXPECT_TRUE(Demangle("_ZL3Foov", tmp, sizeof(tmp))); >+ EXPECT_STREQ("Foo()", tmp); >+ EXPECT_TRUE(Demangle("_ZL3Foov.clone.3", tmp, sizeof(tmp))); >+ EXPECT_STREQ("Foo()", tmp); >+ EXPECT_TRUE(Demangle("_ZL3Foov.constprop.80", tmp, sizeof(tmp))); >+ EXPECT_STREQ("Foo()", tmp); >+ EXPECT_TRUE(Demangle("_ZL3Foov.isra.18", tmp, sizeof(tmp))); >+ EXPECT_STREQ("Foo()", tmp); >+ EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp))); >+ EXPECT_STREQ("Foo()", tmp); >+ // Invalid (truncated), should not demangle. >+ EXPECT_FALSE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp))); >+ // Invalid (.clone. not followed by number), should not demangle. >+ EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp))); >+ // Invalid (.clone. followed by non-number), should not demangle. >+ EXPECT_FALSE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp))); >+ // Invalid (.constprop. not followed by number), should not demangle. >+ EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp))); >+} >+ >+// Tests that verify that Demangle footprint is within some limit. >+// They are not to be run under sanitizers as the sanitizers increase >+// stack consumption by about 4x. >+#if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \ >+ !ADDRESS_SANITIZER && !MEMORY_SANITIZER && !THREAD_SANITIZER >+ >+static const char *g_mangled; >+static char g_demangle_buffer[4096]; >+static char *g_demangle_result; >+ >+static void DemangleSignalHandler(int signo) { >+ if (Demangle(g_mangled, g_demangle_buffer, sizeof(g_demangle_buffer))) { >+ g_demangle_result = g_demangle_buffer; >+ } else { >+ g_demangle_result = nullptr; >+ } >+} >+ >+// Call Demangle and figure out the stack footprint of this call. >+static const char *DemangleStackConsumption(const char *mangled, >+ int *stack_consumed) { >+ g_mangled = mangled; >+ *stack_consumed = GetSignalHandlerStackConsumption(DemangleSignalHandler); >+ ABSL_RAW_LOG(INFO, "Stack consumption of Demangle: %d", *stack_consumed); >+ return g_demangle_result; >+} >+ >+// Demangle stack consumption should be within 8kB for simple mangled names >+// with some level of nesting. With alternate signal stack we have 64K, >+// but some signal handlers run on thread stack, and could have arbitrarily >+// little space left (so we don't want to make this number too large). >+const int kStackConsumptionUpperLimit = 8192; >+ >+// Returns a mangled name nested to the given depth. >+static std::string NestedMangledName(int depth) { >+ std::string mangled_name = "_Z1a"; >+ if (depth > 0) { >+ mangled_name += "IXL"; >+ mangled_name += NestedMangledName(depth - 1); >+ mangled_name += "EEE"; >+ } >+ return mangled_name; >+} >+ >+TEST(Demangle, DemangleStackConsumption) { >+ // Measure stack consumption of Demangle for nested mangled names of varying >+ // depth. Since Demangle is implemented as a recursive descent parser, >+ // stack consumption will grow as the nesting depth increases. By measuring >+ // the stack consumption for increasing depths, we can see the growing >+ // impact of any stack-saving changes made to the code for Demangle. >+ int stack_consumed = 0; >+ >+ const char *demangled = >+ DemangleStackConsumption("_Z6foobarv", &stack_consumed); >+ EXPECT_STREQ("foobar()", demangled); >+ EXPECT_GT(stack_consumed, 0); >+ EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); >+ >+ const std::string nested_mangled_name0 = NestedMangledName(0); >+ demangled = DemangleStackConsumption(nested_mangled_name0.c_str(), >+ &stack_consumed); >+ EXPECT_STREQ("a", demangled); >+ EXPECT_GT(stack_consumed, 0); >+ EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); >+ >+ const std::string nested_mangled_name1 = NestedMangledName(1); >+ demangled = DemangleStackConsumption(nested_mangled_name1.c_str(), >+ &stack_consumed); >+ EXPECT_STREQ("a<>", demangled); >+ EXPECT_GT(stack_consumed, 0); >+ EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); >+ >+ const std::string nested_mangled_name2 = NestedMangledName(2); >+ demangled = DemangleStackConsumption(nested_mangled_name2.c_str(), >+ &stack_consumed); >+ EXPECT_STREQ("a<>", demangled); >+ EXPECT_GT(stack_consumed, 0); >+ EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); >+ >+ const std::string nested_mangled_name3 = NestedMangledName(3); >+ demangled = DemangleStackConsumption(nested_mangled_name3.c_str(), >+ &stack_consumed); >+ EXPECT_STREQ("a<>", demangled); >+ EXPECT_GT(stack_consumed, 0); >+ EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); >+} >+ >+#endif // Stack consumption tests >+ >+static void TestOnInput(const char* input) { >+ static const int kOutSize = 1048576; >+ auto out = absl::make_unique<char[]>(kOutSize); >+ Demangle(input, out.get(), kOutSize); >+} >+ >+TEST(DemangleRegression, NegativeLength) { >+ TestOnInput("_ZZn4"); >+} >+TEST(DemangleRegression, DeeplyNestedArrayType) { >+ const int depth = 100000; >+ std::string data = "_ZStI"; >+ data.reserve(data.size() + 3 * depth + 1); >+ for (int i = 0; i < depth; i++) { >+ data += "A1_"; >+ } >+ TestOnInput(data.c_str()); >+} >+ >+} // namespace >+} // namespace debugging_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..3f747e7f958ec12a6e5f1e2cdaa996806116d1ff >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc >@@ -0,0 +1,380 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Allow dynamic symbol lookup in an in-memory Elf image. >+// >+ >+#include "absl/debugging/internal/elf_mem_image.h" >+ >+#ifdef ABSL_HAVE_ELF_MEM_IMAGE // defined in elf_mem_image.h >+ >+#include <string.h> >+#include <cassert> >+#include <cstddef> >+#include "absl/base/internal/raw_logging.h" >+ >+// From binutils/include/elf/common.h (this doesn't appear to be documented >+// anywhere else). >+// >+// /* This flag appears in a Versym structure. It means that the symbol >+// is hidden, and is only visible with an explicit version number. >+// This is a GNU extension. */ >+// #define VERSYM_HIDDEN 0x8000 >+// >+// /* This is the mask for the rest of the Versym information. */ >+// #define VERSYM_VERSION 0x7fff >+ >+#define VERSYM_VERSION 0x7fff >+ >+namespace absl { >+namespace debugging_internal { >+ >+namespace { >+ >+#if __WORDSIZE == 32 >+const int kElfClass = ELFCLASS32; >+int ElfBind(const ElfW(Sym) *symbol) { return ELF32_ST_BIND(symbol->st_info); } >+int ElfType(const ElfW(Sym) *symbol) { return ELF32_ST_TYPE(symbol->st_info); } >+#elif __WORDSIZE == 64 >+const int kElfClass = ELFCLASS64; >+int ElfBind(const ElfW(Sym) *symbol) { return ELF64_ST_BIND(symbol->st_info); } >+int ElfType(const ElfW(Sym) *symbol) { return ELF64_ST_TYPE(symbol->st_info); } >+#else >+const int kElfClass = -1; >+int ElfBind(const ElfW(Sym) *) { >+ ABSL_RAW_LOG(FATAL, "Unexpected word size"); >+ return 0; >+} >+int ElfType(const ElfW(Sym) *) { >+ ABSL_RAW_LOG(FATAL, "Unexpected word size"); >+ return 0; >+} >+#endif >+ >+// Extract an element from one of the ELF tables, cast it to desired type. >+// This is just a simple arithmetic and a glorified cast. >+// Callers are responsible for bounds checking. >+template <typename T> >+const T *GetTableElement(const ElfW(Ehdr) * ehdr, ElfW(Off) table_offset, >+ ElfW(Word) element_size, size_t index) { >+ return reinterpret_cast<const T*>(reinterpret_cast<const char *>(ehdr) >+ + table_offset >+ + index * element_size); >+} >+ >+} // namespace >+ >+// The value of this variable doesn't matter; it's used only for its >+// unique address. >+const int ElfMemImage::kInvalidBaseSentinel = 0; >+ >+ElfMemImage::ElfMemImage(const void *base) { >+ ABSL_RAW_CHECK(base != kInvalidBase, "bad pointer"); >+ Init(base); >+} >+ >+int ElfMemImage::GetNumSymbols() const { >+ if (!hash_) { >+ return 0; >+ } >+ // See http://www.caldera.com/developers/gabi/latest/ch5.dynamic.html#hash >+ return hash_[1]; >+} >+ >+const ElfW(Sym) *ElfMemImage::GetDynsym(int index) const { >+ ABSL_RAW_CHECK(index < GetNumSymbols(), "index out of range"); >+ return dynsym_ + index; >+} >+ >+const ElfW(Versym) *ElfMemImage::GetVersym(int index) const { >+ ABSL_RAW_CHECK(index < GetNumSymbols(), "index out of range"); >+ return versym_ + index; >+} >+ >+const ElfW(Phdr) *ElfMemImage::GetPhdr(int index) const { >+ ABSL_RAW_CHECK(index < ehdr_->e_phnum, "index out of range"); >+ return GetTableElement<ElfW(Phdr)>(ehdr_, >+ ehdr_->e_phoff, >+ ehdr_->e_phentsize, >+ index); >+} >+ >+const char *ElfMemImage::GetDynstr(ElfW(Word) offset) const { >+ ABSL_RAW_CHECK(offset < strsize_, "offset out of range"); >+ return dynstr_ + offset; >+} >+ >+const void *ElfMemImage::GetSymAddr(const ElfW(Sym) *sym) const { >+ if (sym->st_shndx == SHN_UNDEF || sym->st_shndx >= SHN_LORESERVE) { >+ // Symbol corresponds to "special" (e.g. SHN_ABS) section. >+ return reinterpret_cast<const void *>(sym->st_value); >+ } >+ ABSL_RAW_CHECK(link_base_ < sym->st_value, "symbol out of range"); >+ return GetTableElement<char>(ehdr_, 0, 1, sym->st_value - link_base_); >+} >+ >+const ElfW(Verdef) *ElfMemImage::GetVerdef(int index) const { >+ ABSL_RAW_CHECK(0 <= index && static_cast<size_t>(index) <= verdefnum_, >+ "index out of range"); >+ const ElfW(Verdef) *version_definition = verdef_; >+ while (version_definition->vd_ndx < index && version_definition->vd_next) { >+ const char *const version_definition_as_char = >+ reinterpret_cast<const char *>(version_definition); >+ version_definition = >+ reinterpret_cast<const ElfW(Verdef) *>(version_definition_as_char + >+ version_definition->vd_next); >+ } >+ return version_definition->vd_ndx == index ? version_definition : nullptr; >+} >+ >+const ElfW(Verdaux) *ElfMemImage::GetVerdefAux( >+ const ElfW(Verdef) *verdef) const { >+ return reinterpret_cast<const ElfW(Verdaux) *>(verdef+1); >+} >+ >+const char *ElfMemImage::GetVerstr(ElfW(Word) offset) const { >+ ABSL_RAW_CHECK(offset < strsize_, "offset out of range"); >+ return dynstr_ + offset; >+} >+ >+void ElfMemImage::Init(const void *base) { >+ ehdr_ = nullptr; >+ dynsym_ = nullptr; >+ dynstr_ = nullptr; >+ versym_ = nullptr; >+ verdef_ = nullptr; >+ hash_ = nullptr; >+ strsize_ = 0; >+ verdefnum_ = 0; >+ link_base_ = ~0L; // Sentinel: PT_LOAD .p_vaddr can't possibly be this. >+ if (!base) { >+ return; >+ } >+ const char *const base_as_char = reinterpret_cast<const char *>(base); >+ if (base_as_char[EI_MAG0] != ELFMAG0 || base_as_char[EI_MAG1] != ELFMAG1 || >+ base_as_char[EI_MAG2] != ELFMAG2 || base_as_char[EI_MAG3] != ELFMAG3) { >+ assert(false); >+ return; >+ } >+ int elf_class = base_as_char[EI_CLASS]; >+ if (elf_class != kElfClass) { >+ assert(false); >+ return; >+ } >+ switch (base_as_char[EI_DATA]) { >+ case ELFDATA2LSB: { >+ if (__LITTLE_ENDIAN != __BYTE_ORDER) { >+ assert(false); >+ return; >+ } >+ break; >+ } >+ case ELFDATA2MSB: { >+ if (__BIG_ENDIAN != __BYTE_ORDER) { >+ assert(false); >+ return; >+ } >+ break; >+ } >+ default: { >+ assert(false); >+ return; >+ } >+ } >+ >+ ehdr_ = reinterpret_cast<const ElfW(Ehdr) *>(base); >+ const ElfW(Phdr) *dynamic_program_header = nullptr; >+ for (int i = 0; i < ehdr_->e_phnum; ++i) { >+ const ElfW(Phdr) *const program_header = GetPhdr(i); >+ switch (program_header->p_type) { >+ case PT_LOAD: >+ if (!~link_base_) { >+ link_base_ = program_header->p_vaddr; >+ } >+ break; >+ case PT_DYNAMIC: >+ dynamic_program_header = program_header; >+ break; >+ } >+ } >+ if (!~link_base_ || !dynamic_program_header) { >+ assert(false); >+ // Mark this image as not present. Can not recur infinitely. >+ Init(nullptr); >+ return; >+ } >+ ptrdiff_t relocation = >+ base_as_char - reinterpret_cast<const char *>(link_base_); >+ ElfW(Dyn) *dynamic_entry = >+ reinterpret_cast<ElfW(Dyn) *>(dynamic_program_header->p_vaddr + >+ relocation); >+ for (; dynamic_entry->d_tag != DT_NULL; ++dynamic_entry) { >+ const ElfW(Xword) value = dynamic_entry->d_un.d_val + relocation; >+ switch (dynamic_entry->d_tag) { >+ case DT_HASH: >+ hash_ = reinterpret_cast<ElfW(Word) *>(value); >+ break; >+ case DT_SYMTAB: >+ dynsym_ = reinterpret_cast<ElfW(Sym) *>(value); >+ break; >+ case DT_STRTAB: >+ dynstr_ = reinterpret_cast<const char *>(value); >+ break; >+ case DT_VERSYM: >+ versym_ = reinterpret_cast<ElfW(Versym) *>(value); >+ break; >+ case DT_VERDEF: >+ verdef_ = reinterpret_cast<ElfW(Verdef) *>(value); >+ break; >+ case DT_VERDEFNUM: >+ verdefnum_ = dynamic_entry->d_un.d_val; >+ break; >+ case DT_STRSZ: >+ strsize_ = dynamic_entry->d_un.d_val; >+ break; >+ default: >+ // Unrecognized entries explicitly ignored. >+ break; >+ } >+ } >+ if (!hash_ || !dynsym_ || !dynstr_ || !versym_ || >+ !verdef_ || !verdefnum_ || !strsize_) { >+ assert(false); // invalid VDSO >+ // Mark this image as not present. Can not recur infinitely. >+ Init(nullptr); >+ return; >+ } >+} >+ >+bool ElfMemImage::LookupSymbol(const char *name, >+ const char *version, >+ int type, >+ SymbolInfo *info_out) const { >+ for (const SymbolInfo& info : *this) { >+ if (strcmp(info.name, name) == 0 && strcmp(info.version, version) == 0 && >+ ElfType(info.symbol) == type) { >+ if (info_out) { >+ *info_out = info; >+ } >+ return true; >+ } >+ } >+ return false; >+} >+ >+bool ElfMemImage::LookupSymbolByAddress(const void *address, >+ SymbolInfo *info_out) const { >+ for (const SymbolInfo& info : *this) { >+ const char *const symbol_start = >+ reinterpret_cast<const char *>(info.address); >+ const char *const symbol_end = symbol_start + info.symbol->st_size; >+ if (symbol_start <= address && address < symbol_end) { >+ if (info_out) { >+ // Client wants to know details for that symbol (the usual case). >+ if (ElfBind(info.symbol) == STB_GLOBAL) { >+ // Strong symbol; just return it. >+ *info_out = info; >+ return true; >+ } else { >+ // Weak or local. Record it, but keep looking for a strong one. >+ *info_out = info; >+ } >+ } else { >+ // Client only cares if there is an overlapping symbol. >+ return true; >+ } >+ } >+ } >+ return false; >+} >+ >+ElfMemImage::SymbolIterator::SymbolIterator(const void *const image, int index) >+ : index_(index), image_(image) { >+} >+ >+const ElfMemImage::SymbolInfo *ElfMemImage::SymbolIterator::operator->() const { >+ return &info_; >+} >+ >+const ElfMemImage::SymbolInfo& ElfMemImage::SymbolIterator::operator*() const { >+ return info_; >+} >+ >+bool ElfMemImage::SymbolIterator::operator==(const SymbolIterator &rhs) const { >+ return this->image_ == rhs.image_ && this->index_ == rhs.index_; >+} >+ >+bool ElfMemImage::SymbolIterator::operator!=(const SymbolIterator &rhs) const { >+ return !(*this == rhs); >+} >+ >+ElfMemImage::SymbolIterator &ElfMemImage::SymbolIterator::operator++() { >+ this->Update(1); >+ return *this; >+} >+ >+ElfMemImage::SymbolIterator ElfMemImage::begin() const { >+ SymbolIterator it(this, 0); >+ it.Update(0); >+ return it; >+} >+ >+ElfMemImage::SymbolIterator ElfMemImage::end() const { >+ return SymbolIterator(this, GetNumSymbols()); >+} >+ >+void ElfMemImage::SymbolIterator::Update(int increment) { >+ const ElfMemImage *image = reinterpret_cast<const ElfMemImage *>(image_); >+ ABSL_RAW_CHECK(image->IsPresent() || increment == 0, ""); >+ if (!image->IsPresent()) { >+ return; >+ } >+ index_ += increment; >+ if (index_ >= image->GetNumSymbols()) { >+ index_ = image->GetNumSymbols(); >+ return; >+ } >+ const ElfW(Sym) *symbol = image->GetDynsym(index_); >+ const ElfW(Versym) *version_symbol = image->GetVersym(index_); >+ ABSL_RAW_CHECK(symbol && version_symbol, ""); >+ const char *const symbol_name = image->GetDynstr(symbol->st_name); >+ const ElfW(Versym) version_index = version_symbol[0] & VERSYM_VERSION; >+ const ElfW(Verdef) *version_definition = nullptr; >+ const char *version_name = ""; >+ if (symbol->st_shndx == SHN_UNDEF) { >+ // Undefined symbols reference DT_VERNEED, not DT_VERDEF, and >+ // version_index could well be greater than verdefnum_, so calling >+ // GetVerdef(version_index) may trigger assertion. >+ } else { >+ version_definition = image->GetVerdef(version_index); >+ } >+ if (version_definition) { >+ // I am expecting 1 or 2 auxiliary entries: 1 for the version itself, >+ // optional 2nd if the version has a parent. >+ ABSL_RAW_CHECK( >+ version_definition->vd_cnt == 1 || version_definition->vd_cnt == 2, >+ "wrong number of entries"); >+ const ElfW(Verdaux) *version_aux = image->GetVerdefAux(version_definition); >+ version_name = image->GetVerstr(version_aux->vda_name); >+ } >+ info_.name = symbol_name; >+ info_.version = version_name; >+ info_.address = image->GetSymAddr(symbol); >+ info_.symbol = symbol; >+} >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_HAVE_ELF_MEM_IMAGE >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h >new file mode 100644 >index 0000000000000000000000000000000000000000..3b577268954337d4b1525086ad84db7944e366b9 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h >@@ -0,0 +1,130 @@ >+/* >+ * Copyright 2017 The Abseil Authors. >+ * >+ * Licensed under the Apache License, Version 2.0 (the "License"); >+ * you may not use this file except in compliance with the License. >+ * You may obtain a copy of the License at >+ * >+ * http://www.apache.org/licenses/LICENSE-2.0 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+ >+// Allow dynamic symbol lookup for in-memory Elf images. >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_ELF_MEM_IMAGE_H_ >+#define ABSL_DEBUGGING_INTERNAL_ELF_MEM_IMAGE_H_ >+ >+// Including this will define the __GLIBC__ macro if glibc is being >+// used. >+#include <climits> >+ >+// Maybe one day we can rewrite this file not to require the elf >+// symbol extensions in glibc, but for right now we need them. >+#ifdef ABSL_HAVE_ELF_MEM_IMAGE >+#error ABSL_HAVE_ELF_MEM_IMAGE cannot be directly set >+#endif >+ >+#if defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) && \ >+ !defined(__asmjs__) && !defined(__wasm__) >+#define ABSL_HAVE_ELF_MEM_IMAGE 1 >+#endif >+ >+#if ABSL_HAVE_ELF_MEM_IMAGE >+ >+#include <link.h> // for ElfW >+ >+namespace absl { >+namespace debugging_internal { >+ >+// An in-memory ELF image (may not exist on disk). >+class ElfMemImage { >+ private: >+ // Sentinel: there could never be an elf image at &kInvalidBaseSentinel. >+ static const int kInvalidBaseSentinel; >+ >+ public: >+ // Sentinel: there could never be an elf image at this address. >+ static constexpr const void *const kInvalidBase = >+ static_cast<const void*>(&kInvalidBaseSentinel); >+ >+ // Information about a single vdso symbol. >+ // All pointers are into .dynsym, .dynstr, or .text of the VDSO. >+ // Do not free() them or modify through them. >+ struct SymbolInfo { >+ const char *name; // E.g. "__vdso_getcpu" >+ const char *version; // E.g. "LINUX_2.6", could be "" >+ // for unversioned symbol. >+ const void *address; // Relocated symbol address. >+ const ElfW(Sym) *symbol; // Symbol in the dynamic symbol table. >+ }; >+ >+ // Supports iteration over all dynamic symbols. >+ class SymbolIterator { >+ public: >+ friend class ElfMemImage; >+ const SymbolInfo *operator->() const; >+ const SymbolInfo &operator*() const; >+ SymbolIterator& operator++(); >+ bool operator!=(const SymbolIterator &rhs) const; >+ bool operator==(const SymbolIterator &rhs) const; >+ private: >+ SymbolIterator(const void *const image, int index); >+ void Update(int incr); >+ SymbolInfo info_; >+ int index_; >+ const void *const image_; >+ }; >+ >+ >+ explicit ElfMemImage(const void *base); >+ void Init(const void *base); >+ bool IsPresent() const { return ehdr_ != nullptr; } >+ const ElfW(Phdr)* GetPhdr(int index) const; >+ const ElfW(Sym)* GetDynsym(int index) const; >+ const ElfW(Versym)* GetVersym(int index) const; >+ const ElfW(Verdef)* GetVerdef(int index) const; >+ const ElfW(Verdaux)* GetVerdefAux(const ElfW(Verdef) *verdef) const; >+ const char* GetDynstr(ElfW(Word) offset) const; >+ const void* GetSymAddr(const ElfW(Sym) *sym) const; >+ const char* GetVerstr(ElfW(Word) offset) const; >+ int GetNumSymbols() const; >+ >+ SymbolIterator begin() const; >+ SymbolIterator end() const; >+ >+ // Look up versioned dynamic symbol in the image. >+ // Returns false if image is not present, or doesn't contain given >+ // symbol/version/type combination. >+ // If info_out is non-null, additional details are filled in. >+ bool LookupSymbol(const char *name, const char *version, >+ int symbol_type, SymbolInfo *info_out) const; >+ >+ // Find info about symbol (if any) which overlaps given address. >+ // Returns true if symbol was found; false if image isn't present >+ // or doesn't have a symbol overlapping given address. >+ // If info_out is non-null, additional details are filled in. >+ bool LookupSymbolByAddress(const void *address, SymbolInfo *info_out) const; >+ >+ private: >+ const ElfW(Ehdr) *ehdr_; >+ const ElfW(Sym) *dynsym_; >+ const ElfW(Versym) *versym_; >+ const ElfW(Verdef) *verdef_; >+ const ElfW(Word) *hash_; >+ const char *dynstr_; >+ size_t strsize_; >+ size_t verdefnum_; >+ ElfW(Addr) link_base_; // Link-time base (p_vaddr of first PT_LOAD). >+}; >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_HAVE_ELF_MEM_IMAGE >+ >+#endif // ABSL_DEBUGGING_INTERNAL_ELF_MEM_IMAGE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..faf888367356fef22340f534b15be5690ae71f2e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc >@@ -0,0 +1,153 @@ >+// >+// 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/debugging/internal/examine_stack.h" >+ >+#ifndef _WIN32 >+#include <unistd.h> >+#endif >+ >+#include <csignal> >+#include <cstdio> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/macros.h" >+#include "absl/debugging/stacktrace.h" >+#include "absl/debugging/symbolize.h" >+ >+namespace absl { >+namespace debugging_internal { >+ >+// Returns the program counter from signal context, nullptr if >+// unknown. vuc is a ucontext_t*. We use void* to avoid the use of >+// ucontext_t on non-POSIX systems. >+void* GetProgramCounter(void* vuc) { >+#ifdef __linux__ >+ if (vuc != nullptr) { >+ ucontext_t* context = reinterpret_cast<ucontext_t*>(vuc); >+#if defined(__aarch64__) >+ return reinterpret_cast<void*>(context->uc_mcontext.pc); >+#elif defined(__arm__) >+ return reinterpret_cast<void*>(context->uc_mcontext.arm_pc); >+#elif defined(__i386__) >+ if (14 < ABSL_ARRAYSIZE(context->uc_mcontext.gregs)) >+ return reinterpret_cast<void*>(context->uc_mcontext.gregs[14]); >+#elif defined(__mips__) >+ return reinterpret_cast<void*>(context->uc_mcontext.pc); >+#elif defined(__powerpc64__) >+ return reinterpret_cast<void*>(context->uc_mcontext.gp_regs[32]); >+#elif defined(__powerpc__) >+ return reinterpret_cast<void*>(context->uc_mcontext.regs->nip); >+#elif defined(__s390__) && !defined(__s390x__) >+ return reinterpret_cast<void*>(context->uc_mcontext.psw.addr & 0x7fffffff); >+#elif defined(__s390__) && defined(__s390x__) >+ return reinterpret_cast<void*>(context->uc_mcontext.psw.addr); >+#elif defined(__x86_64__) >+ if (16 < ABSL_ARRAYSIZE(context->uc_mcontext.gregs)) >+ return reinterpret_cast<void*>(context->uc_mcontext.gregs[16]); >+#else >+#error "Undefined Architecture." >+#endif >+ } >+#elif defined(__akaros__) >+ auto* ctx = reinterpret_cast<struct user_context*>(vuc); >+ return reinterpret_cast<void*>(get_user_ctx_pc(ctx)); >+#endif >+ static_cast<void>(vuc); >+ return nullptr; >+} >+ >+// The %p field width for printf() functions is two characters per byte, >+// and two extra for the leading "0x". >+static constexpr int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*); >+ >+// Print a program counter, its stack frame size, and its symbol name. >+// Note that there is a separate symbolize_pc argument. Return addresses may be >+// at the end of the function, and this allows the caller to back up from pc if >+// appropriate. >+static void DumpPCAndFrameSizeAndSymbol(void (*writerfn)(const char*, void*), >+ void* writerfn_arg, void* pc, >+ void* symbolize_pc, int framesize, >+ const char* const prefix) { >+ char tmp[1024]; >+ const char* symbol = "(unknown)"; >+ if (absl::Symbolize(symbolize_pc, tmp, sizeof(tmp))) { >+ symbol = tmp; >+ } >+ char buf[1024]; >+ if (framesize <= 0) { >+ snprintf(buf, sizeof(buf), "%s@ %*p (unknown) %s\n", prefix, >+ kPrintfPointerFieldWidth, pc, symbol); >+ } else { >+ snprintf(buf, sizeof(buf), "%s@ %*p %9d %s\n", prefix, >+ kPrintfPointerFieldWidth, pc, framesize, symbol); >+ } >+ writerfn(buf, writerfn_arg); >+} >+ >+// Print a program counter and the corresponding stack frame size. >+static void DumpPCAndFrameSize(void (*writerfn)(const char*, void*), >+ void* writerfn_arg, void* pc, int framesize, >+ const char* const prefix) { >+ char buf[100]; >+ if (framesize <= 0) { >+ snprintf(buf, sizeof(buf), "%s@ %*p (unknown)\n", prefix, >+ kPrintfPointerFieldWidth, pc); >+ } else { >+ snprintf(buf, sizeof(buf), "%s@ %*p %9d\n", prefix, >+ kPrintfPointerFieldWidth, pc, framesize); >+ } >+ writerfn(buf, writerfn_arg); >+} >+ >+void DumpPCAndFrameSizesAndStackTrace( >+ void* pc, void* const stack[], int frame_sizes[], int depth, >+ int min_dropped_frames, bool symbolize_stacktrace, >+ void (*writerfn)(const char*, void*), void* writerfn_arg) { >+ if (pc != nullptr) { >+ // We don't know the stack frame size for PC, use 0. >+ if (symbolize_stacktrace) { >+ DumpPCAndFrameSizeAndSymbol(writerfn, writerfn_arg, pc, pc, 0, "PC: "); >+ } else { >+ DumpPCAndFrameSize(writerfn, writerfn_arg, pc, 0, "PC: "); >+ } >+ } >+ for (int i = 0; i < depth; i++) { >+ if (symbolize_stacktrace) { >+ // Pass the previous address of pc as the symbol address because pc is a >+ // return address, and an overrun may occur when the function ends with a >+ // call to a function annotated noreturn (e.g. CHECK). Note that we don't >+ // do this for pc above, as the adjustment is only correct for return >+ // addresses. >+ DumpPCAndFrameSizeAndSymbol(writerfn, writerfn_arg, stack[i], >+ reinterpret_cast<char*>(stack[i]) - 1, >+ frame_sizes[i], " "); >+ } else { >+ DumpPCAndFrameSize(writerfn, writerfn_arg, stack[i], frame_sizes[i], >+ " "); >+ } >+ } >+ if (min_dropped_frames > 0) { >+ char buf[100]; >+ snprintf(buf, sizeof(buf), " @ ... and at least %d more frames\n", >+ min_dropped_frames); >+ writerfn(buf, writerfn_arg); >+ } >+} >+ >+} // namespace debugging_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/examine_stack.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/examine_stack.h >new file mode 100644 >index 0000000000000000000000000000000000000000..a16c03b2748f6861e8e1543a153b0c5dfdc0aa01 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/examine_stack.h >@@ -0,0 +1,38 @@ >+// >+// 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_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ >+#define ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ >+ >+namespace absl { >+namespace debugging_internal { >+ >+// Returns the program counter from signal context, or nullptr if >+// unknown. `vuc` is a ucontext_t*. We use void* to avoid the use of >+// ucontext_t on non-POSIX systems. >+void* GetProgramCounter(void* vuc); >+ >+// Uses `writerfn` to dump the program counter, stack trace, and stack >+// frame sizes. >+void DumpPCAndFrameSizesAndStackTrace( >+ void* pc, void* const stack[], int frame_sizes[], int depth, >+ int min_dropped_frames, bool symbolize_stacktrace, >+ void (*writerfn)(const char*, void*), void* writerfn_arg); >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stack_consumption.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stack_consumption.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..2b3b972ea53902c195de5a1a9dc9579718a170b3 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stack_consumption.cc >@@ -0,0 +1,172 @@ >+// >+// 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/debugging/internal/stack_consumption.h" >+ >+#ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION >+ >+#include <signal.h> >+#include <sys/mman.h> >+#include <unistd.h> >+ >+#include <string.h> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+namespace debugging_internal { >+namespace { >+ >+// This code requires that we know the direction in which the stack >+// grows. It is commonly believed that this can be detected by putting >+// a variable on the stack and then passing its address to a function >+// that compares the address of this variable to the address of a >+// variable on the function's own stack. However, this is unspecified >+// behavior in C++: If two pointers p and q of the same type point to >+// different objects that are not members of the same object or >+// elements of the same array or to different functions, or if only >+// one of them is null, the results of p<q, p>q, p<=q, and p>=q are >+// unspecified. Therefore, instead we hardcode the direction of the >+// stack on platforms we know about. >+#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) >+constexpr bool kStackGrowsDown = true; >+#else >+#error Need to define kStackGrowsDown >+#endif >+ >+// To measure the stack footprint of some code, we create a signal handler >+// (for SIGUSR2 say) that exercises this code on an alternate stack. This >+// alternate stack is initialized to some known pattern (0x55, 0x55, 0x55, >+// ...). We then self-send this signal, and after the signal handler returns, >+// look at the alternate stack buffer to see what portion has been touched. >+// >+// This trick gives us the the stack footprint of the signal handler. But the >+// signal handler, even before the code for it is exercised, consumes some >+// stack already. We however only want the stack usage of the code inside the >+// signal handler. To measure this accurately, we install two signal handlers: >+// one that does nothing and just returns, and the user-provided signal >+// handler. The difference between the stack consumption of these two signals >+// handlers should give us the stack foorprint of interest. >+ >+void EmptySignalHandler(int) {} >+ >+// This is arbitrary value, and could be increase further, at the cost of >+// memset()ting it all to known sentinel value. >+constexpr int kAlternateStackSize = 64 << 10; // 64KiB >+ >+constexpr int kSafetyMargin = 32; >+constexpr char kAlternateStackFillValue = 0x55; >+ >+// These helper functions look at the alternate stack buffer, and figure >+// out what portion of this buffer has been touched - this is the stack >+// consumption of the signal handler running on this alternate stack. >+// This function will return -1 if the alternate stack buffer has not been >+// touched. It will abort the program if the buffer has overflowed or is about >+// to overflow. >+int GetStackConsumption(const void* const altstack) { >+ const char* begin; >+ int increment; >+ if (kStackGrowsDown) { >+ begin = reinterpret_cast<const char*>(altstack); >+ increment = 1; >+ } else { >+ begin = reinterpret_cast<const char*>(altstack) + kAlternateStackSize - 1; >+ increment = -1; >+ } >+ >+ for (int usage_count = kAlternateStackSize; usage_count > 0; --usage_count) { >+ if (*begin != kAlternateStackFillValue) { >+ ABSL_RAW_CHECK(usage_count <= kAlternateStackSize - kSafetyMargin, >+ "Buffer has overflowed or is about to overflow"); >+ return usage_count; >+ } >+ begin += increment; >+ } >+ >+ ABSL_RAW_LOG(FATAL, "Unreachable code"); >+ return -1; >+} >+ >+} // namespace >+ >+int GetSignalHandlerStackConsumption(void (*signal_handler)(int)) { >+ // The alt-signal-stack cannot be heap allocated because there is a >+ // bug in glibc-2.2 where some signal handler setup code looks at the >+ // current stack pointer to figure out what thread is currently running. >+ // Therefore, the alternate stack must be allocated from the main stack >+ // itself. >+ void* altstack = mmap(nullptr, kAlternateStackSize, PROT_READ | PROT_WRITE, >+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); >+ ABSL_RAW_CHECK(altstack != MAP_FAILED, "mmap() failed"); >+ >+ // Set up the alt-signal-stack (and save the older one). >+ stack_t sigstk; >+ memset(&sigstk, 0, sizeof(sigstk)); >+ stack_t old_sigstk; >+ sigstk.ss_sp = altstack; >+ sigstk.ss_size = kAlternateStackSize; >+ sigstk.ss_flags = 0; >+ ABSL_RAW_CHECK(sigaltstack(&sigstk, &old_sigstk) == 0, >+ "sigaltstack() failed"); >+ >+ // Set up SIGUSR1 and SIGUSR2 signal handlers (and save the older ones). >+ struct sigaction sa; >+ memset(&sa, 0, sizeof(sa)); >+ struct sigaction old_sa1, old_sa2; >+ sigemptyset(&sa.sa_mask); >+ sa.sa_flags = SA_ONSTACK; >+ >+ // SIGUSR1 maps to EmptySignalHandler. >+ sa.sa_handler = EmptySignalHandler; >+ ABSL_RAW_CHECK(sigaction(SIGUSR1, &sa, &old_sa1) == 0, "sigaction() failed"); >+ >+ // SIGUSR2 maps to signal_handler. >+ sa.sa_handler = signal_handler; >+ ABSL_RAW_CHECK(sigaction(SIGUSR2, &sa, &old_sa2) == 0, "sigaction() failed"); >+ >+ // Send SIGUSR1 signal and measure the stack consumption of the empty >+ // signal handler. >+ // The first signal might use more stack space. Run once and ignore the >+ // results to get that out of the way. >+ ABSL_RAW_CHECK(kill(getpid(), SIGUSR1) == 0, "kill() failed"); >+ >+ memset(altstack, kAlternateStackFillValue, kAlternateStackSize); >+ ABSL_RAW_CHECK(kill(getpid(), SIGUSR1) == 0, "kill() failed"); >+ int base_stack_consumption = GetStackConsumption(altstack); >+ >+ // Send SIGUSR2 signal and measure the stack consumption of signal_handler. >+ ABSL_RAW_CHECK(kill(getpid(), SIGUSR2) == 0, "kill() failed"); >+ int signal_handler_stack_consumption = GetStackConsumption(altstack); >+ >+ // Now restore the old alt-signal-stack and signal handlers. >+ ABSL_RAW_CHECK(sigaltstack(&old_sigstk, nullptr) == 0, >+ "sigaltstack() failed"); >+ ABSL_RAW_CHECK(sigaction(SIGUSR1, &old_sa1, nullptr) == 0, >+ "sigaction() failed"); >+ ABSL_RAW_CHECK(sigaction(SIGUSR2, &old_sa2, nullptr) == 0, >+ "sigaction() failed"); >+ >+ ABSL_RAW_CHECK(munmap(altstack, kAlternateStackSize) == 0, "munmap() failed"); >+ if (signal_handler_stack_consumption != -1 && base_stack_consumption != -1) { >+ return signal_handler_stack_consumption - base_stack_consumption; >+ } >+ return -1; >+} >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stack_consumption.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stack_consumption.h >new file mode 100644 >index 0000000000000000000000000000000000000000..4c5fa0f0d821d4963e34a82d458d02c04e566803 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stack_consumption.h >@@ -0,0 +1,45 @@ >+// >+// 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. >+ >+// Helper function for measuring stack consumption of signal handlers. >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_STACK_CONSUMPTION_H_ >+#define ABSL_DEBUGGING_INTERNAL_STACK_CONSUMPTION_H_ >+ >+// The code in this module is not portable. >+// Use this feature test macro to detect its availability. >+#ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION >+#error ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION cannot be set directly >+#elif !defined(__APPLE__) && !defined(_WIN32) && \ >+ (defined(__i386__) || defined(__x86_64__) || defined(__ppc__)) >+#define ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION 1 >+ >+namespace absl { >+namespace debugging_internal { >+ >+// Returns the stack consumption in bytes for the code exercised by >+// signal_handler. To measure stack consumption, signal_handler is registered >+// as a signal handler, so the code that it exercises must be async-signal >+// safe. The argument of signal_handler is an implementation detail of signal >+// handlers and should ignored by the code for signal_handler. Use global >+// variables to pass information between your test code and signal_handler. >+int GetSignalHandlerStackConsumption(void (*signal_handler)(int)); >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION >+ >+#endif // ABSL_DEBUGGING_INTERNAL_STACK_CONSUMPTION_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..5ce3846ec44971590c342c48c6776a16e71cac8c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc >@@ -0,0 +1,48 @@ >+// >+// 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/debugging/internal/stack_consumption.h" >+ >+#ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION >+ >+#include <string.h> >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+namespace debugging_internal { >+namespace { >+ >+static void SimpleSignalHandler(int signo) { >+ char buf[100]; >+ memset(buf, 'a', sizeof(buf)); >+ >+ // Never true, but prevents compiler from optimizing buf out. >+ if (signo == 0) { >+ ABSL_RAW_LOG(INFO, "%p", static_cast<void*>(buf)); >+ } >+} >+ >+TEST(SignalHandlerStackConsumptionTest, MeasuresStackConsumption) { >+ // Our handler should consume reasonable number of bytes. >+ EXPECT_GE(GetSignalHandlerStackConsumption(SimpleSignalHandler), 100); >+} >+ >+} // namespace >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..7ed6b3eb82dc2f039ac08531c0b17eb1bb976ed9 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc >@@ -0,0 +1,190 @@ >+#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_AARCH64_INL_H_ >+#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_AARCH64_INL_H_ >+ >+// Generate stack tracer for aarch64 >+ >+#if defined(__linux__) >+#include <sys/mman.h> >+#include <ucontext.h> >+#include <unistd.h> >+#endif >+ >+#include <atomic> >+#include <cassert> >+#include <cstdint> >+#include <iostream> >+ >+#include "absl/base/attributes.h" >+#include "absl/debugging/internal/address_is_readable.h" >+#include "absl/debugging/internal/vdso_support.h" // a no-op on non-elf or non-glibc systems >+#include "absl/debugging/stacktrace.h" >+ >+static const uintptr_t kUnknownFrameSize = 0; >+ >+#if defined(__linux__) >+// Returns the address of the VDSO __kernel_rt_sigreturn function, if present. >+static const unsigned char* GetKernelRtSigreturnAddress() { >+ constexpr uintptr_t kImpossibleAddress = 1; >+ ABSL_CONST_INIT static std::atomic<uintptr_t> memoized{kImpossibleAddress}; >+ uintptr_t address = memoized.load(std::memory_order_relaxed); >+ if (address != kImpossibleAddress) { >+ return reinterpret_cast<const unsigned char*>(address); >+ } >+ >+ address = reinterpret_cast<uintptr_t>(nullptr); >+ >+#ifdef ABSL_HAVE_VDSO_SUPPORT >+ absl::debugging_internal::VDSOSupport vdso; >+ if (vdso.IsPresent()) { >+ absl::debugging_internal::VDSOSupport::SymbolInfo symbol_info; >+ if (!vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_2.6.39", STT_FUNC, >+ &symbol_info) || >+ symbol_info.address == nullptr) { >+ // Unexpected: VDSO is present, yet the expected symbol is missing >+ // or null. >+ assert(false && "VDSO is present, but doesn't have expected symbol"); >+ } else { >+ if (reinterpret_cast<uintptr_t>(symbol_info.address) != >+ kImpossibleAddress) { >+ address = reinterpret_cast<uintptr_t>(symbol_info.address); >+ } else { >+ assert(false && "VDSO returned invalid address"); >+ } >+ } >+ } >+#endif >+ >+ memoized.store(address, std::memory_order_relaxed); >+ return reinterpret_cast<const unsigned char*>(address); >+} >+#endif // __linux__ >+ >+// Compute the size of a stack frame in [low..high). We assume that >+// low < high. Return size of kUnknownFrameSize. >+template<typename T> >+static inline uintptr_t ComputeStackFrameSize(const T* low, >+ const T* high) { >+ const char* low_char_ptr = reinterpret_cast<const char *>(low); >+ const char* high_char_ptr = reinterpret_cast<const char *>(high); >+ return low < high ? high_char_ptr - low_char_ptr : kUnknownFrameSize; >+} >+ >+// Given a pointer to a stack frame, locate and return the calling >+// stackframe, or return null if no stackframe can be found. Perform sanity >+// checks (the strictness of which is controlled by the boolean parameter >+// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. >+template<bool STRICT_UNWINDING, bool WITH_CONTEXT> >+static void **NextStackFrame(void **old_frame_pointer, const void *uc) { >+ void **new_frame_pointer = reinterpret_cast<void**>(*old_frame_pointer); >+ bool check_frame_size = true; >+ >+#if defined(__linux__) >+ if (WITH_CONTEXT && uc != nullptr) { >+ // Check to see if next frame's return address is __kernel_rt_sigreturn. >+ if (old_frame_pointer[1] == GetKernelRtSigreturnAddress()) { >+ const ucontext_t *ucv = static_cast<const ucontext_t *>(uc); >+ // old_frame_pointer[0] is not suitable for unwinding, look at >+ // ucontext to discover frame pointer before signal. >+ void **const pre_signal_frame_pointer = >+ reinterpret_cast<void **>(ucv->uc_mcontext.regs[29]); >+ >+ // Check that alleged frame pointer is actually readable. This is to >+ // prevent "double fault" in case we hit the first fault due to e.g. >+ // stack corruption. >+ if (!absl::debugging_internal::AddressIsReadable( >+ pre_signal_frame_pointer)) >+ return nullptr; >+ >+ // Alleged frame pointer is readable, use it for further unwinding. >+ new_frame_pointer = pre_signal_frame_pointer; >+ >+ // Skip frame size check if we return from a signal. We may be using a >+ // an alternate stack for signals. >+ check_frame_size = false; >+ } >+ } >+#endif >+ >+ // aarch64 ABI requires stack pointer to be 16-byte-aligned. >+ if ((reinterpret_cast<uintptr_t>(new_frame_pointer) & 15) != 0) >+ return nullptr; >+ >+ // Check frame size. In strict mode, we assume frames to be under >+ // 100,000 bytes. In non-strict mode, we relax the limit to 1MB. >+ if (check_frame_size) { >+ const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000; >+ const uintptr_t frame_size = >+ ComputeStackFrameSize(old_frame_pointer, new_frame_pointer); >+ if (frame_size == kUnknownFrameSize || frame_size > max_size) >+ return nullptr; >+ } >+ >+ return new_frame_pointer; >+} >+ >+template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> >+static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, >+ const void *ucp, int *min_dropped_frames) { >+#ifdef __GNUC__ >+ void **frame_pointer = reinterpret_cast<void**>(__builtin_frame_address(0)); >+#else >+# error reading stack point not yet supported on this platform. >+#endif >+ >+ skip_count++; // Skip the frame for this function. >+ int n = 0; >+ >+ // The frame pointer points to low address of a frame. The first 64-bit >+ // word of a frame points to the next frame up the call chain, which normally >+ // is just after the high address of the current frame. The second word of >+ // a frame contains return adress of to the caller. To find a pc value >+ // associated with the current frame, we need to go down a level in the call >+ // chain. So we remember return the address of the last frame seen. This >+ // does not work for the first stack frame, which belongs to UnwindImp() but >+ // we skip the frame for UnwindImp() anyway. >+ void* prev_return_address = nullptr; >+ >+ while (frame_pointer && n < max_depth) { >+ // The absl::GetStackFrames routine is called when we are in some >+ // informational context (the failure signal handler for example). >+ // Use the non-strict unwinding rules to produce a stack trace >+ // that is as complete as possible (even if it contains a few bogus >+ // entries in some rare cases). >+ void **next_frame_pointer = >+ NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp); >+ >+ if (skip_count > 0) { >+ skip_count--; >+ } else { >+ result[n] = prev_return_address; >+ if (IS_STACK_FRAMES) { >+ sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer); >+ } >+ n++; >+ } >+ prev_return_address = frame_pointer[1]; >+ frame_pointer = next_frame_pointer; >+ } >+ if (min_dropped_frames != nullptr) { >+ // Implementation detail: we clamp the max of frames we are willing to >+ // count, so as not to spend too much time in the loop below. >+ const int kMaxUnwind = 200; >+ int j = 0; >+ for (; frame_pointer != nullptr && j < kMaxUnwind; j++) { >+ frame_pointer = >+ NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp); >+ } >+ *min_dropped_frames = j; >+ } >+ return n; >+} >+ >+namespace absl { >+namespace debugging_internal { >+bool StackTraceWorksForTest() { >+ return true; >+} >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_AARCH64_INL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..c84083379bb237e11d9a1264c8db7a4479a86f70 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc >@@ -0,0 +1,123 @@ >+// Copyright 2011 and onwards Google Inc. >+// All rights reserved. >+// >+// Author: Doug Kwan >+// This is inspired by Craig Silverstein's PowerPC stacktrace code. >+// >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_ARM_INL_H_ >+#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_ARM_INL_H_ >+ >+#include <cstdint> >+ >+#include "absl/debugging/stacktrace.h" >+ >+// WARNING: >+// This only works if all your code is in either ARM or THUMB mode. With >+// interworking, the frame pointer of the caller can either be in r11 (ARM >+// mode) or r7 (THUMB mode). A callee only saves the frame pointer of its >+// mode in a fixed location on its stack frame. If the caller is a different >+// mode, there is no easy way to find the frame pointer. It can either be >+// still in the designated register or saved on stack along with other callee >+// saved registers. >+ >+// Given a pointer to a stack frame, locate and return the calling >+// stackframe, or return nullptr if no stackframe can be found. Perform sanity >+// checks (the strictness of which is controlled by the boolean parameter >+// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. >+template<bool STRICT_UNWINDING> >+static void **NextStackFrame(void **old_sp) { >+ void **new_sp = (void**) old_sp[-1]; >+ >+ // Check that the transition from frame pointer old_sp to frame >+ // pointer new_sp isn't clearly bogus >+ if (STRICT_UNWINDING) { >+ // With the stack growing downwards, older stack frame must be >+ // at a greater address that the current one. >+ if (new_sp <= old_sp) return nullptr; >+ // Assume stack frames larger than 100,000 bytes are bogus. >+ if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return nullptr; >+ } else { >+ // In the non-strict mode, allow discontiguous stack frames. >+ // (alternate-signal-stacks for example). >+ if (new_sp == old_sp) return nullptr; >+ // And allow frames upto about 1MB. >+ if ((new_sp > old_sp) >+ && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return nullptr; >+ } >+ if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return nullptr; >+ return new_sp; >+} >+ >+// This ensures that absl::GetStackTrace sets up the Link Register properly. >+#ifdef __GNUC__ >+void StacktraceArmDummyFunction() __attribute__((noinline)); >+void StacktraceArmDummyFunction() { __asm__ volatile(""); } >+#else >+# error StacktraceArmDummyFunction() needs to be ported to this platform. >+#endif >+ >+template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> >+static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, >+ const void * /* ucp */, int *min_dropped_frames) { >+#ifdef __GNUC__ >+ void **sp = reinterpret_cast<void**>(__builtin_frame_address(0)); >+#else >+# error reading stack point not yet supported on this platform. >+#endif >+ >+ // On ARM, the return address is stored in the link register (r14). >+ // This is not saved on the stack frame of a leaf function. To >+ // simplify code that reads return addresses, we call a dummy >+ // function so that the return address of this function is also >+ // stored in the stack frame. This works at least for gcc. >+ StacktraceArmDummyFunction(); >+ >+ int n = 0; >+ while (sp && n < max_depth) { >+ // The absl::GetStackFrames routine is called when we are in some >+ // informational context (the failure signal handler for example). >+ // Use the non-strict unwinding rules to produce a stack trace >+ // that is as complete as possible (even if it contains a few bogus >+ // entries in some rare cases). >+ void **next_sp = NextStackFrame<!IS_STACK_FRAMES>(sp); >+ >+ if (skip_count > 0) { >+ skip_count--; >+ } else { >+ result[n] = *sp; >+ >+ if (IS_STACK_FRAMES) { >+ if (next_sp > sp) { >+ sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp; >+ } else { >+ // A frame-size of 0 is used to indicate unknown frame size. >+ sizes[n] = 0; >+ } >+ } >+ n++; >+ } >+ sp = next_sp; >+ } >+ if (min_dropped_frames != nullptr) { >+ // Implementation detail: we clamp the max of frames we are willing to >+ // count, so as not to spend too much time in the loop below. >+ const int kMaxUnwind = 200; >+ int j = 0; >+ for (; sp != nullptr && j < kMaxUnwind; j++) { >+ sp = NextStackFrame<!IS_STACK_FRAMES>(sp); >+ } >+ *min_dropped_frames = j; >+ } >+ return n; >+} >+ >+namespace absl { >+namespace debugging_internal { >+bool StackTraceWorksForTest() { >+ return false; >+} >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_ARM_INL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h >new file mode 100644 >index 0000000000000000000000000000000000000000..dd713da8c0c7d76509d032b08263de17486ffa6e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h >@@ -0,0 +1,69 @@ >+/* >+ * Copyright 2017 The Abseil Authors. >+ * >+ * Licensed under the Apache License, Version 2.0 (the "License"); >+ * you may not use this file except in compliance with the License. >+ * You may obtain a copy of the License at >+ * >+ * http://www.apache.org/licenses/LICENSE-2.0 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ >+ * Defines ABSL_STACKTRACE_INL_HEADER to the *-inl.h containing >+ * actual unwinder implementation. >+ * This header is "private" to stacktrace.cc. >+ * DO NOT include it into any other files. >+*/ >+#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_ >+#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_ >+ >+#if defined(ABSL_STACKTRACE_INL_HEADER) >+#error ABSL_STACKTRACE_INL_HEADER cannot be directly set >+ >+#elif defined(_WIN32) >+#define ABSL_STACKTRACE_INL_HEADER \ >+ "absl/debugging/internal/stacktrace_win32-inl.inc" >+ >+#elif defined(__linux__) && !defined(__ANDROID__) >+ >+#if !defined(NO_FRAME_POINTER) >+# if defined(__i386__) || defined(__x86_64__) >+#define ABSL_STACKTRACE_INL_HEADER \ >+ "absl/debugging/internal/stacktrace_x86-inl.inc" >+# elif defined(__ppc__) || defined(__PPC__) >+#define ABSL_STACKTRACE_INL_HEADER \ >+ "absl/debugging/internal/stacktrace_powerpc-inl.inc" >+# elif defined(__aarch64__) >+#define ABSL_STACKTRACE_INL_HEADER \ >+ "absl/debugging/internal/stacktrace_aarch64-inl.inc" >+# elif defined(__arm__) >+#define ABSL_STACKTRACE_INL_HEADER \ >+ "absl/debugging/internal/stacktrace_arm-inl.inc" >+# else >+#define ABSL_STACKTRACE_INL_HEADER \ >+ "absl/debugging/internal/stacktrace_unimplemented-inl.inc" >+# endif >+#else // defined(NO_FRAME_POINTER) >+# if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) >+#define ABSL_STACKTRACE_INL_HEADER \ >+ "absl/debugging/internal/stacktrace_generic-inl.inc" >+# elif defined(__ppc__) || defined(__PPC__) >+#define ABSL_STACKTRACE_INL_HEADER \ >+ "absl/debugging/internal/stacktrace_generic-inl.inc" >+# else >+#define ABSL_STACKTRACE_INL_HEADER \ >+ "absl/debugging/internal/stacktrace_unimplemented-inl.inc" >+# endif >+#endif // NO_FRAME_POINTER >+ >+#else >+#define ABSL_STACKTRACE_INL_HEADER \ >+ "absl/debugging/internal/stacktrace_unimplemented-inl.inc" >+ >+#endif >+ >+#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..2c9ca410c6083dfa1758ab1155841f7feed2ac2b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc >@@ -0,0 +1,59 @@ >+// Copyright 2000 - 2007 Google Inc. >+// All rights reserved. >+// >+// Author: Sanjay Ghemawat >+// >+// Portable implementation - just use glibc >+// >+// Note: The glibc implementation may cause a call to malloc. >+// This can cause a deadlock in HeapProfiler. >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_GENERIC_INL_H_ >+#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_GENERIC_INL_H_ >+ >+#include <execinfo.h> >+#include <cstring> >+ >+#include "absl/debugging/stacktrace.h" >+ >+template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> >+static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, >+ const void *ucp, int *min_dropped_frames) { >+ static const int kStackLength = 64; >+ void * stack[kStackLength]; >+ int size; >+ >+ size = backtrace(stack, kStackLength); >+ skip_count++; // we want to skip the current frame as well >+ int result_count = size - skip_count; >+ if (result_count < 0) >+ result_count = 0; >+ if (result_count > max_depth) >+ result_count = max_depth; >+ for (int i = 0; i < result_count; i++) >+ result[i] = stack[i + skip_count]; >+ >+ if (IS_STACK_FRAMES) { >+ // No implementation for finding out the stack frame sizes yet. >+ memset(sizes, 0, sizeof(*sizes) * result_count); >+ } >+ if (min_dropped_frames != nullptr) { >+ if (size - skip_count - max_depth > 0) { >+ *min_dropped_frames = size - skip_count - max_depth; >+ } else { >+ *min_dropped_frames = 0; >+ } >+ } >+ >+ return result_count; >+} >+ >+namespace absl { >+namespace debugging_internal { >+bool StackTraceWorksForTest() { >+ return true; >+} >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_GENERIC_INL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..860ac2b3e582510595cbcbffb2b9dcf101c2c559 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc >@@ -0,0 +1,246 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Produce stack trace. I'm guessing (hoping!) the code is much like >+// for x86. For apple machines, at least, it seems to be; see >+// http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html >+// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK >+// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882 >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_ >+#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_ >+ >+#if defined(__linux__) >+#include <asm/ptrace.h> // for PT_NIP. >+#include <ucontext.h> // for ucontext_t >+#endif >+ >+#include <unistd.h> >+#include <cassert> >+#include <cstdint> >+#include <cstdio> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/optimization.h" >+#include "absl/base/port.h" >+#include "absl/debugging/stacktrace.h" >+#include "absl/debugging/internal/address_is_readable.h" >+#include "absl/debugging/internal/vdso_support.h" // a no-op on non-elf or non-glibc systems >+ >+// Given a stack pointer, return the saved link register value. >+// Note that this is the link register for a callee. >+static inline void *StacktracePowerPCGetLR(void **sp) { >+ // PowerPC has 3 main ABIs, which say where in the stack the >+ // Link Register is. For DARWIN and AIX (used by apple and >+ // linux ppc64), it's in sp[2]. For SYSV (used by linux ppc), >+ // it's in sp[1]. >+#if defined(_CALL_AIX) || defined(_CALL_DARWIN) >+ return *(sp+2); >+#elif defined(_CALL_SYSV) >+ return *(sp+1); >+#elif defined(__APPLE__) || defined(__FreeBSD__) || \ >+ (defined(__linux__) && defined(__PPC64__)) >+ // This check is in case the compiler doesn't define _CALL_AIX/etc. >+ return *(sp+2); >+#elif defined(__linux) >+ // This check is in case the compiler doesn't define _CALL_SYSV. >+ return *(sp+1); >+#else >+#error Need to specify the PPC ABI for your archiecture. >+#endif >+} >+ >+// Given a pointer to a stack frame, locate and return the calling >+// stackframe, or return null if no stackframe can be found. Perform sanity >+// checks (the strictness of which is controlled by the boolean parameter >+// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. >+template<bool STRICT_UNWINDING, bool IS_WITH_CONTEXT> >+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. >+ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. >+static void **NextStackFrame(void **old_sp, const void *uc) { >+ void **new_sp = (void **) *old_sp; >+ enum { kStackAlignment = 16 }; >+ >+ // Check that the transition from frame pointer old_sp to frame >+ // pointer new_sp isn't clearly bogus >+ if (STRICT_UNWINDING) { >+ // With the stack growing downwards, older stack frame must be >+ // at a greater address that the current one. >+ if (new_sp <= old_sp) return nullptr; >+ // Assume stack frames larger than 100,000 bytes are bogus. >+ if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return nullptr; >+ } else { >+ // In the non-strict mode, allow discontiguous stack frames. >+ // (alternate-signal-stacks for example). >+ if (new_sp == old_sp) return nullptr; >+ // And allow frames upto about 1MB. >+ if ((new_sp > old_sp) >+ && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return nullptr; >+ } >+ if ((uintptr_t)new_sp % kStackAlignment != 0) return nullptr; >+ >+#if defined(__linux__) >+ enum StackTraceKernelSymbolStatus { >+ kNotInitialized = 0, kAddressValid, kAddressInvalid }; >+ >+ if (IS_WITH_CONTEXT && uc != nullptr) { >+ static StackTraceKernelSymbolStatus kernel_symbol_status = >+ kNotInitialized; // Sentinel: not computed yet. >+ // Initialize with sentinel value: __kernel_rt_sigtramp_rt64 can not >+ // possibly be there. >+ static const unsigned char *kernel_sigtramp_rt64_address = nullptr; >+ if (kernel_symbol_status == kNotInitialized) { >+ absl::debugging_internal::VDSOSupport vdso; >+ if (vdso.IsPresent()) { >+ absl::debugging_internal::VDSOSupport::SymbolInfo >+ sigtramp_rt64_symbol_info; >+ if (!vdso.LookupSymbol( >+ "__kernel_sigtramp_rt64", "LINUX_2.6.15", >+ absl::debugging_internal::VDSOSupport::kVDSOSymbolType, >+ &sigtramp_rt64_symbol_info) || >+ sigtramp_rt64_symbol_info.address == nullptr) { >+ // Unexpected: VDSO is present, yet the expected symbol is missing >+ // or null. >+ assert(false && "VDSO is present, but doesn't have expected symbol"); >+ kernel_symbol_status = kAddressInvalid; >+ } else { >+ kernel_sigtramp_rt64_address = >+ reinterpret_cast<const unsigned char *>( >+ sigtramp_rt64_symbol_info.address); >+ kernel_symbol_status = kAddressValid; >+ } >+ } else { >+ kernel_symbol_status = kAddressInvalid; >+ } >+ } >+ >+ if (new_sp != nullptr && >+ kernel_symbol_status == kAddressValid && >+ StacktracePowerPCGetLR(new_sp) == kernel_sigtramp_rt64_address) { >+ const ucontext_t* signal_context = >+ reinterpret_cast<const ucontext_t*>(uc); >+ void **const sp_before_signal = >+ reinterpret_cast<void**>(signal_context->uc_mcontext.gp_regs[PT_R1]); >+ // Check that alleged sp before signal is nonnull and is reasonably >+ // aligned. >+ if (sp_before_signal != nullptr && >+ ((uintptr_t)sp_before_signal % kStackAlignment) == 0) { >+ // Check that alleged stack pointer is actually readable. This is to >+ // prevent a "double fault" in case we hit the first fault due to e.g. >+ // a stack corruption. >+ if (absl::debugging_internal::AddressIsReadable(sp_before_signal)) { >+ // Alleged stack pointer is readable, use it for further unwinding. >+ new_sp = sp_before_signal; >+ } >+ } >+ } >+ } >+#endif >+ >+ return new_sp; >+} >+ >+// This ensures that absl::GetStackTrace sets up the Link Register properly. >+ABSL_ATTRIBUTE_NOINLINE static void AbslStacktracePowerPCDummyFunction() { >+ ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); >+} >+ >+template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> >+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. >+ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. >+static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, >+ const void *ucp, int *min_dropped_frames) { >+ void **sp; >+ // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther) >+ // and Darwin 8.8.1 (Tiger) use as 1.38. This means we have to use a >+ // different asm syntax. I don't know quite the best way to discriminate >+ // systems using the old as from the new one; I've gone with __APPLE__. >+#ifdef __APPLE__ >+ __asm__ volatile ("mr %0,r1" : "=r" (sp)); >+#else >+ __asm__ volatile ("mr %0,1" : "=r" (sp)); >+#endif >+ >+ // On PowerPC, the "Link Register" or "Link Record" (LR), is a stack >+ // entry that holds the return address of the subroutine call (what >+ // instruction we run after our function finishes). This is the >+ // same as the stack-pointer of our parent routine, which is what we >+ // want here. While the compiler will always(?) set up LR for >+ // subroutine calls, it may not for leaf functions (such as this one). >+ // This routine forces the compiler (at least gcc) to push it anyway. >+ AbslStacktracePowerPCDummyFunction(); >+ >+ // The LR save area is used by the callee, so the top entry is bogus. >+ skip_count++; >+ >+ int n = 0; >+ >+ // Unlike ABIs of X86 and ARM, PowerPC ABIs say that return address (in >+ // the link register) of a function call is stored in the caller's stack >+ // frame instead of the callee's. When we look for the return address >+ // associated with a stack frame, we need to make sure that there is a >+ // caller frame before it. So we call NextStackFrame before entering the >+ // loop below and check next_sp instead of sp for loop termination. >+ // The outermost frame is set up by runtimes and it does not have a >+ // caller frame, so it is skipped. >+ >+ // The absl::GetStackFrames routine is called when we are in some >+ // informational context (the failure signal handler for example). >+ // Use the non-strict unwinding rules to produce a stack trace >+ // that is as complete as possible (even if it contains a few >+ // bogus entries in some rare cases). >+ void **next_sp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(sp, ucp); >+ >+ while (next_sp && n < max_depth) { >+ if (skip_count > 0) { >+ skip_count--; >+ } else { >+ result[n] = StacktracePowerPCGetLR(sp); >+ if (IS_STACK_FRAMES) { >+ if (next_sp > sp) { >+ sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp; >+ } else { >+ // A frame-size of 0 is used to indicate unknown frame size. >+ sizes[n] = 0; >+ } >+ } >+ n++; >+ } >+ >+ sp = next_sp; >+ next_sp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(sp, ucp); >+ } >+ >+ if (min_dropped_frames != nullptr) { >+ // Implementation detail: we clamp the max of frames we are willing to >+ // count, so as not to spend too much time in the loop below. >+ const int kMaxUnwind = 1000; >+ int j = 0; >+ for (; next_sp != nullptr && j < kMaxUnwind; j++) { >+ next_sp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(next_sp, ucp); >+ } >+ *min_dropped_frames = j; >+ } >+ return n; >+} >+ >+namespace absl { >+namespace debugging_internal { >+bool StackTraceWorksForTest() { >+ return true; >+} >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..e256fdd4ae76e6f8ab15c7b3abc3fdc6cb6114f6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc >@@ -0,0 +1,22 @@ >+#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_UNIMPLEMENTED_INL_H_ >+#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_UNIMPLEMENTED_INL_H_ >+ >+template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> >+static int UnwindImpl(void** /* result */, int* /* sizes */, >+ int /* max_depth */, int /* skip_count */, >+ const void* /* ucp */, int *min_dropped_frames) { >+ if (min_dropped_frames != nullptr) { >+ *min_dropped_frames = 0; >+ } >+ return 0; >+} >+ >+namespace absl { >+namespace debugging_internal { >+bool StackTraceWorksForTest() { >+ return false; >+} >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_UNIMPLEMENTED_INL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..a8f8a56afb3748220d502e26a1921091ed6ab07a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc >@@ -0,0 +1,83 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Produces a stack trace for Windows. Normally, one could use >+// stacktrace_x86-inl.h or stacktrace_x86_64-inl.h -- and indeed, that >+// should work for binaries compiled using MSVC in "debug" mode. >+// However, in "release" mode, Windows uses frame-pointer >+// optimization, which makes getting a stack trace very difficult. >+// >+// There are several approaches one can take. One is to use Windows >+// intrinsics like StackWalk64. These can work, but have restrictions >+// on how successful they can be. Another attempt is to write a >+// version of stacktrace_x86-inl.h that has heuristic support for >+// dealing with FPO, similar to what WinDbg does (see >+// http://www.nynaeve.net/?p=97). There are (non-working) examples of >+// these approaches, complete with TODOs, in stacktrace_win32-inl.h#1 >+// >+// The solution we've ended up doing is to call the undocumented >+// windows function RtlCaptureStackBackTrace, which probably doesn't >+// work with FPO but at least is fast, and doesn't require a symbol >+// server. >+// >+// This code is inspired by a patch from David Vitek: >+// http://code.google.com/p/google-perftools/issues/detail?id=83 >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_WIN32_INL_H_ >+#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_WIN32_INL_H_ >+ >+#include <windows.h> // for GetProcAddress and GetModuleHandle >+#include <cassert> >+ >+typedef USHORT NTAPI RtlCaptureStackBackTrace_Function( >+ IN ULONG frames_to_skip, >+ IN ULONG frames_to_capture, >+ OUT PVOID *backtrace, >+ OUT PULONG backtrace_hash); >+ >+// Load the function we need at static init time, where we don't have >+// to worry about someone else holding the loader's lock. >+static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn = >+ (RtlCaptureStackBackTrace_Function*) >+ GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace"); >+ >+template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> >+static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, >+ const void *ucp, int *min_dropped_frames) { >+ int n = 0; >+ if (!RtlCaptureStackBackTrace_fn) { >+ // can't find a stacktrace with no function to call >+ } else { >+ n = (int)RtlCaptureStackBackTrace_fn(skip_count + 2, max_depth, result, 0); >+ } >+ if (IS_STACK_FRAMES) { >+ // No implementation for finding out the stack frame sizes yet. >+ memset(sizes, 0, sizeof(*sizes) * n); >+ } >+ if (min_dropped_frames != nullptr) { >+ // Not implemented. >+ *min_dropped_frames = 0; >+ } >+ return n; >+} >+ >+namespace absl { >+namespace debugging_internal { >+bool StackTraceWorksForTest() { >+ return false; >+} >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_WIN32_INL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..ac85b920332417ccf00c1396132544df8b352eb8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc >@@ -0,0 +1,337 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Produce stack trace >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_X86_INL_INC_ >+#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_X86_INL_INC_ >+ >+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) >+#include <ucontext.h> // for ucontext_t >+#endif >+ >+#if !defined(_WIN32) >+#include <unistd.h> >+#endif >+ >+#include <cassert> >+#include <cstdint> >+ >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+#include "absl/debugging/internal/address_is_readable.h" >+#include "absl/debugging/internal/vdso_support.h" // a no-op on non-elf or non-glibc systems >+#include "absl/debugging/stacktrace.h" >+#include "absl/base/internal/raw_logging.h" >+ >+#if defined(__linux__) && defined(__i386__) >+// Count "push %reg" instructions in VDSO __kernel_vsyscall(), >+// preceeding "syscall" or "sysenter". >+// If __kernel_vsyscall uses frame pointer, answer 0. >+// >+// kMaxBytes tells how many instruction bytes of __kernel_vsyscall >+// to analyze before giving up. Up to kMaxBytes+1 bytes of >+// instructions could be accessed. >+// >+// Here are known __kernel_vsyscall instruction sequences: >+// >+// SYSENTER (linux-2.6.26/arch/x86/vdso/vdso32/sysenter.S). >+// Used on Intel. >+// 0xffffe400 <__kernel_vsyscall+0>: push %ecx >+// 0xffffe401 <__kernel_vsyscall+1>: push %edx >+// 0xffffe402 <__kernel_vsyscall+2>: push %ebp >+// 0xffffe403 <__kernel_vsyscall+3>: mov %esp,%ebp >+// 0xffffe405 <__kernel_vsyscall+5>: sysenter >+// >+// SYSCALL (see linux-2.6.26/arch/x86/vdso/vdso32/syscall.S). >+// Used on AMD. >+// 0xffffe400 <__kernel_vsyscall+0>: push %ebp >+// 0xffffe401 <__kernel_vsyscall+1>: mov %ecx,%ebp >+// 0xffffe403 <__kernel_vsyscall+3>: syscall >+// >+ >+// The sequence below isn't actually expected in Google fleet, >+// here only for completeness. Remove this comment from OSS release. >+ >+// i386 (see linux-2.6.26/arch/x86/vdso/vdso32/int80.S) >+// 0xffffe400 <__kernel_vsyscall+0>: int $0x80 >+// 0xffffe401 <__kernel_vsyscall+1>: ret >+// >+static const int kMaxBytes = 10; >+ >+// We use assert()s instead of DCHECK()s -- this is too low level >+// for DCHECK(). >+ >+static int CountPushInstructions(const unsigned char *const addr) { >+ int result = 0; >+ for (int i = 0; i < kMaxBytes; ++i) { >+ if (addr[i] == 0x89) { >+ // "mov reg,reg" >+ if (addr[i + 1] == 0xE5) { >+ // Found "mov %esp,%ebp". >+ return 0; >+ } >+ ++i; // Skip register encoding byte. >+ } else if (addr[i] == 0x0F && >+ (addr[i + 1] == 0x34 || addr[i + 1] == 0x05)) { >+ // Found "sysenter" or "syscall". >+ return result; >+ } else if ((addr[i] & 0xF0) == 0x50) { >+ // Found "push %reg". >+ ++result; >+ } else if (addr[i] == 0xCD && addr[i + 1] == 0x80) { >+ // Found "int $0x80" >+ assert(result == 0); >+ return 0; >+ } else { >+ // Unexpected instruction. >+ assert(false && "unexpected instruction in __kernel_vsyscall"); >+ return 0; >+ } >+ } >+ // Unexpected: didn't find SYSENTER or SYSCALL in >+ // [__kernel_vsyscall, __kernel_vsyscall + kMaxBytes) interval. >+ assert(false && "did not find SYSENTER or SYSCALL in __kernel_vsyscall"); >+ return 0; >+} >+#endif >+ >+// Assume stack frames larger than 100,000 bytes are bogus. >+static const int kMaxFrameBytes = 100000; >+ >+// Returns the stack frame pointer from signal context, 0 if unknown. >+// vuc is a ucontext_t *. We use void* to avoid the use >+// of ucontext_t on non-POSIX systems. >+static uintptr_t GetFP(const void *vuc) { >+#if !defined(__linux__) >+ static_cast<void>(vuc); // Avoid an unused argument compiler warning. >+#else >+ if (vuc != nullptr) { >+ auto *uc = reinterpret_cast<const ucontext_t *>(vuc); >+#if defined(__i386__) >+ const auto bp = uc->uc_mcontext.gregs[REG_EBP]; >+ const auto sp = uc->uc_mcontext.gregs[REG_ESP]; >+#elif defined(__x86_64__) >+ const auto bp = uc->uc_mcontext.gregs[REG_RBP]; >+ const auto sp = uc->uc_mcontext.gregs[REG_RSP]; >+#else >+ const uintptr_t bp = 0; >+ const uintptr_t sp = 0; >+#endif >+ // Sanity-check that the base pointer is valid. It should be as long as >+ // SHRINK_WRAP_FRAME_POINTER is not set, but it's possible that some code in >+ // the process is compiled with --copt=-fomit-frame-pointer or >+ // --copt=-momit-leaf-frame-pointer. >+ // >+ // TODO(bcmills): -momit-leaf-frame-pointer is currently the default >+ // behavior when building with clang. Talk to the C++ toolchain team about >+ // fixing that. >+ if (bp >= sp && bp - sp <= kMaxFrameBytes) return bp; >+ >+ // If bp isn't a plausible frame pointer, return the stack pointer instead. >+ // If we're lucky, it points to the start of a stack frame; otherwise, we'll >+ // get one frame of garbage in the stack trace and fail the sanity check on >+ // the next iteration. >+ return sp; >+ } >+#endif >+ return 0; >+} >+ >+// Given a pointer to a stack frame, locate and return the calling >+// stackframe, or return null if no stackframe can be found. Perform sanity >+// checks (the strictness of which is controlled by the boolean parameter >+// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. >+template <bool STRICT_UNWINDING, bool WITH_CONTEXT> >+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. >+ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. >+static void **NextStackFrame(void **old_fp, const void *uc) { >+ void **new_fp = (void **)*old_fp; >+ >+#if defined(__linux__) && defined(__i386__) >+ if (WITH_CONTEXT && uc != nullptr) { >+ // How many "push %reg" instructions are there at __kernel_vsyscall? >+ // This is constant for a given kernel and processor, so compute >+ // it only once. >+ static int num_push_instructions = -1; // Sentinel: not computed yet. >+ // Initialize with sentinel value: __kernel_rt_sigreturn can not possibly >+ // be there. >+ static const unsigned char *kernel_rt_sigreturn_address = nullptr; >+ static const unsigned char *kernel_vsyscall_address = nullptr; >+ if (num_push_instructions == -1) { >+ absl::debugging_internal::VDSOSupport vdso; >+ if (vdso.IsPresent()) { >+ absl::debugging_internal::VDSOSupport::SymbolInfo >+ rt_sigreturn_symbol_info; >+ absl::debugging_internal::VDSOSupport::SymbolInfo vsyscall_symbol_info; >+ if (!vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_2.5", STT_FUNC, >+ &rt_sigreturn_symbol_info) || >+ !vdso.LookupSymbol("__kernel_vsyscall", "LINUX_2.5", STT_FUNC, >+ &vsyscall_symbol_info) || >+ rt_sigreturn_symbol_info.address == nullptr || >+ vsyscall_symbol_info.address == nullptr) { >+ // Unexpected: 32-bit VDSO is present, yet one of the expected >+ // symbols is missing or null. >+ assert(false && "VDSO is present, but doesn't have expected symbols"); >+ num_push_instructions = 0; >+ } else { >+ kernel_rt_sigreturn_address = >+ reinterpret_cast<const unsigned char *>( >+ rt_sigreturn_symbol_info.address); >+ kernel_vsyscall_address = >+ reinterpret_cast<const unsigned char *>( >+ vsyscall_symbol_info.address); >+ num_push_instructions = >+ CountPushInstructions(kernel_vsyscall_address); >+ } >+ } else { >+ num_push_instructions = 0; >+ } >+ } >+ if (num_push_instructions != 0 && kernel_rt_sigreturn_address != nullptr && >+ old_fp[1] == kernel_rt_sigreturn_address) { >+ const ucontext_t *ucv = static_cast<const ucontext_t *>(uc); >+ // This kernel does not use frame pointer in its VDSO code, >+ // and so %ebp is not suitable for unwinding. >+ void **const reg_ebp = >+ reinterpret_cast<void **>(ucv->uc_mcontext.gregs[REG_EBP]); >+ const unsigned char *const reg_eip = >+ reinterpret_cast<unsigned char *>(ucv->uc_mcontext.gregs[REG_EIP]); >+ if (new_fp == reg_ebp && kernel_vsyscall_address <= reg_eip && >+ reg_eip - kernel_vsyscall_address < kMaxBytes) { >+ // We "stepped up" to __kernel_vsyscall, but %ebp is not usable. >+ // Restore from 'ucv' instead. >+ void **const reg_esp = >+ reinterpret_cast<void **>(ucv->uc_mcontext.gregs[REG_ESP]); >+ // Check that alleged %esp is not null and is reasonably aligned. >+ if (reg_esp && >+ ((uintptr_t)reg_esp & (sizeof(reg_esp) - 1)) == 0) { >+ // Check that alleged %esp is actually readable. This is to prevent >+ // "double fault" in case we hit the first fault due to e.g. stack >+ // corruption. >+ void *const reg_esp2 = reg_esp[num_push_instructions - 1]; >+ if (absl::debugging_internal::AddressIsReadable(reg_esp2)) { >+ // Alleged %esp is readable, use it for further unwinding. >+ new_fp = reinterpret_cast<void **>(reg_esp2); >+ } >+ } >+ } >+ } >+ } >+#endif >+ >+ const uintptr_t old_fp_u = reinterpret_cast<uintptr_t>(old_fp); >+ const uintptr_t new_fp_u = reinterpret_cast<uintptr_t>(new_fp); >+ >+ // Check that the transition from frame pointer old_fp to frame >+ // pointer new_fp isn't clearly bogus. Skip the checks if new_fp >+ // matches the signal context, so that we don't skip out early when >+ // using an alternate signal stack. >+ // >+ // TODO(bcmills): The GetFP call should be completely unnecessary when >+ // SHRINK_WRAP_FRAME_POINTER is set (because we should be back in the thread's >+ // stack by this point), but it is empirically still needed (e.g. when the >+ // stack includes a call to abort). unw_get_reg returns UNW_EBADREG for some >+ // frames. Figure out why GetValidFrameAddr and/or libunwind isn't doing what >+ // it's supposed to. >+ if (STRICT_UNWINDING && >+ (!WITH_CONTEXT || uc == nullptr || new_fp_u != GetFP(uc))) { >+ // With the stack growing downwards, older stack frame must be >+ // at a greater address that the current one. >+ if (new_fp_u <= old_fp_u) return nullptr; >+ if (new_fp_u - old_fp_u > kMaxFrameBytes) return nullptr; >+ } else { >+ if (new_fp == nullptr) return nullptr; // skip AddressIsReadable() below >+ // In the non-strict mode, allow discontiguous stack frames. >+ // (alternate-signal-stacks for example). >+ if (new_fp == old_fp) return nullptr; >+ } >+ >+ if (new_fp_u & (sizeof(void *) - 1)) return nullptr; >+#ifdef __i386__ >+ // On 32-bit machines, the stack pointer can be very close to >+ // 0xffffffff, so we explicitly check for a pointer into the >+ // last two pages in the address space >+ if (new_fp_u >= 0xffffe000) return nullptr; >+#endif >+#if !defined(_WIN32) >+ if (!STRICT_UNWINDING) { >+ // Lax sanity checks cause a crash in 32-bit tcmalloc/crash_reason_test >+ // on AMD-based machines with VDSO-enabled kernels. >+ // Make an extra sanity check to insure new_fp is readable. >+ // Note: NextStackFrame<false>() is only called while the program >+ // is already on its last leg, so it's ok to be slow here. >+ >+ if (!absl::debugging_internal::AddressIsReadable(new_fp)) { >+ return nullptr; >+ } >+ } >+#endif >+ return new_fp; >+} >+ >+template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> >+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. >+ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. >+ABSL_ATTRIBUTE_NOINLINE >+static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, >+ const void *ucp, int *min_dropped_frames) { >+ int n = 0; >+ void **fp = reinterpret_cast<void **>(__builtin_frame_address(0)); >+ >+ while (fp && n < max_depth) { >+ if (*(fp + 1) == reinterpret_cast<void *>(0)) { >+ // In 64-bit code, we often see a frame that >+ // points to itself and has a return address of 0. >+ break; >+ } >+ void **next_fp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(fp, ucp); >+ if (skip_count > 0) { >+ skip_count--; >+ } else { >+ result[n] = *(fp + 1); >+ if (IS_STACK_FRAMES) { >+ if (next_fp > fp) { >+ sizes[n] = (uintptr_t)next_fp - (uintptr_t)fp; >+ } else { >+ // A frame-size of 0 is used to indicate unknown frame size. >+ sizes[n] = 0; >+ } >+ } >+ n++; >+ } >+ fp = next_fp; >+ } >+ if (min_dropped_frames != nullptr) { >+ // Implementation detail: we clamp the max of frames we are willing to >+ // count, so as not to spend too much time in the loop below. >+ const int kMaxUnwind = 1000; >+ int j = 0; >+ for (; fp != nullptr && j < kMaxUnwind; j++) { >+ fp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(fp, ucp); >+ } >+ *min_dropped_frames = j; >+ } >+ return n; >+} >+ >+namespace absl { >+namespace debugging_internal { >+bool StackTraceWorksForTest() { >+ return true; >+} >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_X86_INL_INC_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/symbolize.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/symbolize.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8d926fec48aae8c365215535317c85392b305980 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/symbolize.h >@@ -0,0 +1,123 @@ >+// 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 contains internal parts of the Abseil symbolizer. >+// Do not depend on the anything in this file, it may change at anytime. >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ >+#define ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ >+ >+#include <cstddef> >+#include <cstdint> >+#include "absl/base/port.h" // Needed for string vs std::string >+ >+#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE >+#error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set >+#elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) && \ >+ !defined(__asmjs__) && !defined(__wasm__) >+#define ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE 1 >+ >+#include <elf.h> >+#include <link.h> // For ElfW() macro. >+#include <functional> >+#include <string> >+ >+namespace absl { >+namespace debugging_internal { >+ >+// Iterates over all sections, invoking callback on each with the section name >+// and the section header. >+// >+// Returns true on success; otherwise returns false in case of errors. >+// >+// This is not async-signal-safe. >+bool ForEachSection( >+ int fd, const std::function<bool(const std::string& name, const ElfW(Shdr) &)>& >+ callback); >+ >+// Gets the section header for the given name, if it exists. Returns true on >+// success. Otherwise, returns false. >+bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, >+ ElfW(Shdr) *out); >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE >+ >+namespace absl { >+namespace debugging_internal { >+ >+struct SymbolDecoratorArgs { >+ // The program counter we are getting symbolic name for. >+ const void *pc; >+ // 0 for main executable, load address for shared libraries. >+ ptrdiff_t relocation; >+ // Read-only file descriptor for ELF image covering "pc", >+ // or -1 if no such ELF image exists in /proc/self/maps. >+ int fd; >+ // Output buffer, size. >+ // Note: the buffer may not be empty -- default symbolizer may have already >+ // produced some output, and earlier decorators may have adorned it in >+ // some way. You are free to replace or augment the contents (within the >+ // symbol_buf_size limit). >+ char *const symbol_buf; >+ size_t symbol_buf_size; >+ // Temporary scratch space, size. >+ // Use that space in preference to allocating your own stack buffer to >+ // conserve stack. >+ char *const tmp_buf; >+ size_t tmp_buf_size; >+ // User-provided argument >+ void* arg; >+}; >+using SymbolDecorator = void (*)(const SymbolDecoratorArgs *); >+ >+// Installs a function-pointer as a decorator. Returns a value less than zero >+// if the system cannot install the decorator. Otherwise, returns a unique >+// identifier corresponding to the decorator. This identifier can be used to >+// uninstall the decorator - See RemoveSymbolDecorator() below. >+int InstallSymbolDecorator(SymbolDecorator decorator, void* arg); >+ >+// Removes a previously installed function-pointer decorator. Parameter "ticket" >+// is the return-value from calling InstallSymbolDecorator(). >+bool RemoveSymbolDecorator(int ticket); >+ >+// Remove all installed decorators. Returns true if successful, false if >+// symbolization is currently in progress. >+bool RemoveAllSymbolDecorators(void); >+ >+// Registers an address range to a file mapping. >+// >+// Preconditions: >+// start <= end >+// filename != nullptr >+// >+// Returns true if the file was successfully registered. >+bool RegisterFileMappingHint( >+ const void* start, const void* end, uint64_t offset, const char* filename); >+ >+// Looks up the file mapping registered by RegisterFileMappingHint for an >+// address range. If there is one, the file name is stored in *filename and >+// *start and *end are modified to reflect the registered mapping. Returns >+// whether any hint was found. >+bool GetFileMappingHint(const void** start, >+ const void** end, >+ uint64_t * offset, >+ const char** filename); >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e8129e87dca75568108b97fb916e6ed97250b1be >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc >@@ -0,0 +1,192 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Allow dynamic symbol lookup in the kernel VDSO page. >+// >+// VDSOSupport -- a class representing kernel VDSO (if present). >+ >+#include "absl/debugging/internal/vdso_support.h" >+ >+#ifdef ABSL_HAVE_VDSO_SUPPORT // defined in vdso_support.h >+ >+#include <errno.h> >+#include <fcntl.h> >+#include <sys/syscall.h> >+#include <unistd.h> >+ >+#if __GLIBC_PREREQ(2, 16) // GLIBC-2.16 implements getauxval. >+#include <sys/auxv.h> >+#endif >+ >+#include "absl/base/dynamic_annotations.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/port.h" >+ >+#ifndef AT_SYSINFO_EHDR >+#define AT_SYSINFO_EHDR 33 // for crosstoolv10 >+#endif >+ >+namespace absl { >+namespace debugging_internal { >+ >+ABSL_CONST_INIT >+std::atomic<const void *> VDSOSupport::vdso_base_( >+ debugging_internal::ElfMemImage::kInvalidBase); >+ >+std::atomic<VDSOSupport::GetCpuFn> VDSOSupport::getcpu_fn_(&InitAndGetCPU); >+VDSOSupport::VDSOSupport() >+ // If vdso_base_ is still set to kInvalidBase, we got here >+ // before VDSOSupport::Init has been called. Call it now. >+ : image_(vdso_base_.load(std::memory_order_relaxed) == >+ debugging_internal::ElfMemImage::kInvalidBase >+ ? Init() >+ : vdso_base_.load(std::memory_order_relaxed)) {} >+ >+// NOTE: we can't use GoogleOnceInit() below, because we can be >+// called by tcmalloc, and none of the *once* stuff may be functional yet. >+// >+// In addition, we hope that the VDSOSupportHelper constructor >+// causes this code to run before there are any threads, and before >+// InitGoogle() has executed any chroot or setuid calls. >+// >+// Finally, even if there is a race here, it is harmless, because >+// the operation should be idempotent. >+const void *VDSOSupport::Init() { >+ const auto kInvalidBase = debugging_internal::ElfMemImage::kInvalidBase; >+#if __GLIBC_PREREQ(2, 16) >+ if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) { >+ errno = 0; >+ const void *const sysinfo_ehdr = >+ reinterpret_cast<const void *>(getauxval(AT_SYSINFO_EHDR)); >+ if (errno == 0) { >+ vdso_base_.store(sysinfo_ehdr, std::memory_order_relaxed); >+ } >+ } >+#endif // __GLIBC_PREREQ(2, 16) >+ if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) { >+ // Valgrind zaps AT_SYSINFO_EHDR and friends from the auxv[] >+ // on stack, and so glibc works as if VDSO was not present. >+ // But going directly to kernel via /proc/self/auxv below bypasses >+ // Valgrind zapping. So we check for Valgrind separately. >+ if (AbslRunningOnValgrind()) { >+ vdso_base_.store(nullptr, std::memory_order_relaxed); >+ getcpu_fn_.store(&GetCPUViaSyscall, std::memory_order_relaxed); >+ return nullptr; >+ } >+ int fd = open("/proc/self/auxv", O_RDONLY); >+ if (fd == -1) { >+ // Kernel too old to have a VDSO. >+ vdso_base_.store(nullptr, std::memory_order_relaxed); >+ getcpu_fn_.store(&GetCPUViaSyscall, std::memory_order_relaxed); >+ return nullptr; >+ } >+ ElfW(auxv_t) aux; >+ while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) { >+ if (aux.a_type == AT_SYSINFO_EHDR) { >+ vdso_base_.store(reinterpret_cast<void *>(aux.a_un.a_val), >+ std::memory_order_relaxed); >+ break; >+ } >+ } >+ close(fd); >+ if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) { >+ // Didn't find AT_SYSINFO_EHDR in auxv[]. >+ vdso_base_.store(nullptr, std::memory_order_relaxed); >+ } >+ } >+ GetCpuFn fn = &GetCPUViaSyscall; // default if VDSO not present. >+ if (vdso_base_.load(std::memory_order_relaxed)) { >+ VDSOSupport vdso; >+ SymbolInfo info; >+ if (vdso.LookupSymbol("__vdso_getcpu", "LINUX_2.6", STT_FUNC, &info)) { >+ fn = reinterpret_cast<GetCpuFn>(const_cast<void *>(info.address)); >+ } >+ } >+ // Subtle: this code runs outside of any locks; prevent compiler >+ // from assigning to getcpu_fn_ more than once. >+ getcpu_fn_.store(fn, std::memory_order_relaxed); >+ return vdso_base_.load(std::memory_order_relaxed); >+} >+ >+const void *VDSOSupport::SetBase(const void *base) { >+ ABSL_RAW_CHECK(base != debugging_internal::ElfMemImage::kInvalidBase, >+ "internal error"); >+ const void *old_base = vdso_base_.load(std::memory_order_relaxed); >+ vdso_base_.store(base, std::memory_order_relaxed); >+ image_.Init(base); >+ // Also reset getcpu_fn_, so GetCPU could be tested with simulated VDSO. >+ getcpu_fn_.store(&InitAndGetCPU, std::memory_order_relaxed); >+ return old_base; >+} >+ >+bool VDSOSupport::LookupSymbol(const char *name, >+ const char *version, >+ int type, >+ SymbolInfo *info) const { >+ return image_.LookupSymbol(name, version, type, info); >+} >+ >+bool VDSOSupport::LookupSymbolByAddress(const void *address, >+ SymbolInfo *info_out) const { >+ return image_.LookupSymbolByAddress(address, info_out); >+} >+ >+// NOLINT on 'long' because this routine mimics kernel api. >+long VDSOSupport::GetCPUViaSyscall(unsigned *cpu, // NOLINT(runtime/int) >+ void *, void *) { >+#ifdef SYS_getcpu >+ return syscall(SYS_getcpu, cpu, nullptr, nullptr); >+#else >+ // x86_64 never implemented sys_getcpu(), except as a VDSO call. >+ static_cast<void>(cpu); // Avoid an unused argument compiler warning. >+ errno = ENOSYS; >+ return -1; >+#endif >+} >+ >+// Use fast __vdso_getcpu if available. >+long VDSOSupport::InitAndGetCPU(unsigned *cpu, // NOLINT(runtime/int) >+ void *x, void *y) { >+ Init(); >+ GetCpuFn fn = getcpu_fn_.load(std::memory_order_relaxed); >+ ABSL_RAW_CHECK(fn != &InitAndGetCPU, "Init() did not set getcpu_fn_"); >+ return (*fn)(cpu, x, y); >+} >+ >+// This function must be very fast, and may be called from very >+// low level (e.g. tcmalloc). Hence I avoid things like >+// GoogleOnceInit() and ::operator new. >+ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY >+int GetCPU() { >+ unsigned cpu; >+ int ret_code = (*VDSOSupport::getcpu_fn_)(&cpu, nullptr, nullptr); >+ return ret_code == 0 ? cpu : ret_code; >+} >+ >+// We need to make sure VDSOSupport::Init() is called before >+// InitGoogle() does any setuid or chroot calls. If VDSOSupport >+// is used in any global constructor, this will happen, since >+// VDSOSupport's constructor calls Init. But if not, we need to >+// ensure it here, with a global constructor of our own. This >+// is an allowed exception to the normal rule against non-trivial >+// global constructors. >+static class VDSOInitHelper { >+ public: >+ VDSOInitHelper() { VDSOSupport::Init(); } >+} vdso_init_helper; >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_HAVE_VDSO_SUPPORT >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/vdso_support.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/vdso_support.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8002c7405fadd8a1d358b63806beeb348d3a8350 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/internal/vdso_support.h >@@ -0,0 +1,156 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+// Allow dynamic symbol lookup in the kernel VDSO page. >+// >+// VDSO stands for "Virtual Dynamic Shared Object" -- a page of >+// executable code, which looks like a shared library, but doesn't >+// necessarily exist anywhere on disk, and which gets mmap()ed into >+// every process by kernels which support VDSO, such as 2.6.x for 32-bit >+// executables, and 2.6.24 and above for 64-bit executables. >+// >+// More details could be found here: >+// http://www.trilithium.com/johan/2005/08/linux-gate/ >+// >+// VDSOSupport -- a class representing kernel VDSO (if present). >+// >+// Example usage: >+// VDSOSupport vdso; >+// VDSOSupport::SymbolInfo info; >+// typedef (*FN)(unsigned *, void *, void *); >+// FN fn = nullptr; >+// if (vdso.LookupSymbol("__vdso_getcpu", "LINUX_2.6", STT_FUNC, &info)) { >+// fn = reinterpret_cast<FN>(info.address); >+// } >+ >+#ifndef ABSL_DEBUGGING_INTERNAL_VDSO_SUPPORT_H_ >+#define ABSL_DEBUGGING_INTERNAL_VDSO_SUPPORT_H_ >+ >+#include <atomic> >+ >+#include "absl/base/attributes.h" >+#include "absl/debugging/internal/elf_mem_image.h" >+ >+#ifdef ABSL_HAVE_ELF_MEM_IMAGE >+ >+#ifdef ABSL_HAVE_VDSO_SUPPORT >+#error ABSL_HAVE_VDSO_SUPPORT cannot be directly set >+#else >+#define ABSL_HAVE_VDSO_SUPPORT 1 >+#endif >+ >+namespace absl { >+namespace debugging_internal { >+ >+// NOTE: this class may be used from within tcmalloc, and can not >+// use any memory allocation routines. >+class VDSOSupport { >+ public: >+ VDSOSupport(); >+ >+ typedef ElfMemImage::SymbolInfo SymbolInfo; >+ typedef ElfMemImage::SymbolIterator SymbolIterator; >+ >+ // On PowerPC64 VDSO symbols can either be of type STT_FUNC or STT_NOTYPE >+ // depending on how the kernel is built. The kernel is normally built with >+ // STT_NOTYPE type VDSO symbols. Let's make things simpler first by using a >+ // compile-time constant. >+#ifdef __powerpc64__ >+ enum { kVDSOSymbolType = STT_NOTYPE }; >+#else >+ enum { kVDSOSymbolType = STT_FUNC }; >+#endif >+ >+ // Answers whether we have a vdso at all. >+ bool IsPresent() const { return image_.IsPresent(); } >+ >+ // Allow to iterate over all VDSO symbols. >+ SymbolIterator begin() const { return image_.begin(); } >+ SymbolIterator end() const { return image_.end(); } >+ >+ // Look up versioned dynamic symbol in the kernel VDSO. >+ // Returns false if VDSO is not present, or doesn't contain given >+ // symbol/version/type combination. >+ // If info_out != nullptr, additional details are filled in. >+ bool LookupSymbol(const char *name, const char *version, >+ int symbol_type, SymbolInfo *info_out) const; >+ >+ // Find info about symbol (if any) which overlaps given address. >+ // Returns true if symbol was found; false if VDSO isn't present >+ // or doesn't have a symbol overlapping given address. >+ // If info_out != nullptr, additional details are filled in. >+ bool LookupSymbolByAddress(const void *address, SymbolInfo *info_out) const; >+ >+ // Used only for testing. Replace real VDSO base with a mock. >+ // Returns previous value of vdso_base_. After you are done testing, >+ // you are expected to call SetBase() with previous value, in order to >+ // reset state to the way it was. >+ const void *SetBase(const void *s); >+ >+ // Computes vdso_base_ and returns it. Should be called as early as >+ // possible; before any thread creation, chroot or setuid. >+ static const void *Init(); >+ >+ private: >+ // image_ represents VDSO ELF image in memory. >+ // image_.ehdr_ == nullptr implies there is no VDSO. >+ ElfMemImage image_; >+ >+ // Cached value of auxv AT_SYSINFO_EHDR, computed once. >+ // This is a tri-state: >+ // kInvalidBase => value hasn't been determined yet. >+ // 0 => there is no VDSO. >+ // else => vma of VDSO Elf{32,64}_Ehdr. >+ // >+ // When testing with mock VDSO, low bit is set. >+ // The low bit is always available because vdso_base_ is >+ // page-aligned. >+ static std::atomic<const void *> vdso_base_; >+ >+ // NOLINT on 'long' because these routines mimic kernel api. >+ // The 'cache' parameter may be used by some versions of the kernel, >+ // and should be nullptr or point to a static buffer containing at >+ // least two 'long's. >+ static long InitAndGetCPU(unsigned *cpu, void *cache, // NOLINT 'long'. >+ void *unused); >+ static long GetCPUViaSyscall(unsigned *cpu, void *cache, // NOLINT 'long'. >+ void *unused); >+ typedef long (*GetCpuFn)(unsigned *cpu, void *cache, // NOLINT 'long'. >+ void *unused); >+ >+ // This function pointer may point to InitAndGetCPU, >+ // GetCPUViaSyscall, or __vdso_getcpu at different stages of initialization. >+ ABSL_CONST_INIT static std::atomic<GetCpuFn> getcpu_fn_; >+ >+ friend int GetCPU(void); // Needs access to getcpu_fn_. >+ >+ VDSOSupport(const VDSOSupport&) = delete; >+ VDSOSupport& operator=(const VDSOSupport&) = delete; >+}; >+ >+// Same as sched_getcpu() on later glibc versions. >+// Return current CPU, using (fast) __vdso_getcpu@LINUX_2.6 if present, >+// otherwise use syscall(SYS_getcpu,...). >+// May return -1 with errno == ENOSYS if the kernel doesn't >+// support SYS_getcpu. >+int GetCPU(); >+ >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_HAVE_ELF_MEM_IMAGE >+ >+#endif // ABSL_DEBUGGING_INTERNAL_VDSO_SUPPORT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e01e5f8c937ec1ef56eaca37c171f3de91084cca >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check.cc >@@ -0,0 +1,48 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// Wrappers around lsan_interface functions. >+// When lsan is not linked in, these functions are not available, >+// therefore Abseil code which depends on these functions is conditioned on the >+// definition of LEAK_SANITIZER. >+#include "absl/debugging/leak_check.h" >+ >+#ifndef LEAK_SANITIZER >+ >+namespace absl { >+bool HaveLeakSanitizer() { return false; } >+void DoIgnoreLeak(const void*) { } >+void RegisterLivePointers(const void*, size_t) { } >+void UnRegisterLivePointers(const void*, size_t) { } >+LeakCheckDisabler::LeakCheckDisabler() { } >+LeakCheckDisabler::~LeakCheckDisabler() { } >+} // namespace absl >+ >+#else >+ >+#include <sanitizer/lsan_interface.h> >+ >+namespace absl { >+bool HaveLeakSanitizer() { return true; } >+void DoIgnoreLeak(const void* ptr) { __lsan_ignore_object(ptr); } >+void RegisterLivePointers(const void* ptr, size_t size) { >+ __lsan_register_root_region(ptr, size); >+} >+void UnRegisterLivePointers(const void* ptr, size_t size) { >+ __lsan_unregister_root_region(ptr, size); >+} >+LeakCheckDisabler::LeakCheckDisabler() { __lsan_disable(); } >+LeakCheckDisabler::~LeakCheckDisabler() { __lsan_enable(); } >+} // namespace absl >+ >+#endif // LEAK_SANITIZER >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check.h >new file mode 100644 >index 0000000000000000000000000000000000000000..c930684e9598d74868f89ee7efb77d5bada56da6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check.h >@@ -0,0 +1,109 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: leak_check.h >+// ----------------------------------------------------------------------------- >+// >+// This file contains functions that affect leak checking behavior within >+// targets built with the LeakSanitizer (LSan), a memory leak detector that is >+// integrated within the AddressSanitizer (ASan) as an additional component, or >+// which can be used standalone. LSan and ASan are included (or can be provided) >+// as additional components for most compilers such as Clang, gcc and MSVC. >+// Note: this leak checking API is not yet supported in MSVC. >+// Leak checking is enabled by default in all ASan builds. >+// >+// See https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer >+// >+// ----------------------------------------------------------------------------- >+#ifndef ABSL_DEBUGGING_LEAK_CHECK_H_ >+#define ABSL_DEBUGGING_LEAK_CHECK_H_ >+ >+#include <cstddef> >+ >+namespace absl { >+ >+// HaveLeakSanitizer() >+// >+// Returns true if a leak-checking sanitizer (either ASan or standalone LSan) is >+// currently built into this target. >+bool HaveLeakSanitizer(); >+ >+// DoIgnoreLeak() >+// >+// Implements `IgnoreLeak()` below. This function should usually >+// not be called directly; calling `IgnoreLeak()` is preferred. >+void DoIgnoreLeak(const void* ptr); >+ >+// IgnoreLeak() >+// >+// Instruct the leak sanitizer to ignore leak warnings on the object referenced >+// by the passed pointer, as well as all heap objects transitively referenced >+// by it. The passed object pointer can point to either the beginning of the >+// object or anywhere within it. >+// >+// Example: >+// >+// static T* obj = IgnoreLeak(new T(...)); >+// >+// If the passed `ptr` does not point to an actively allocated object at the >+// time `IgnoreLeak()` is called, the call is a no-op; if it is actively >+// allocated, the object must not get deallocated later. >+// >+template <typename T> >+T* IgnoreLeak(T* ptr) { >+ DoIgnoreLeak(ptr); >+ return ptr; >+} >+ >+// LeakCheckDisabler >+// >+// This helper class indicates that any heap allocations done in the code block >+// covered by the scoped object, which should be allocated on the stack, will >+// not be reported as leaks. Leak check disabling will occur within the code >+// block and any nested function calls within the code block. >+// >+// Example: >+// >+// void Foo() { >+// LeakCheckDisabler disabler; >+// ... code that allocates objects whose leaks should be ignored ... >+// } >+// >+// REQUIRES: Destructor runs in same thread as constructor >+class LeakCheckDisabler { >+ public: >+ LeakCheckDisabler(); >+ LeakCheckDisabler(const LeakCheckDisabler&) = delete; >+ LeakCheckDisabler& operator=(const LeakCheckDisabler&) = delete; >+ ~LeakCheckDisabler(); >+}; >+ >+// RegisterLivePointers() >+// >+// Registers `ptr[0,size-1]` as pointers to memory that is still actively being >+// referenced and for which leak checking should be ignored. This function is >+// useful if you store pointers in mapped memory, for memory ranges that we know >+// are correct but for which normal analysis would flag as leaked code. >+void RegisterLivePointers(const void* ptr, size_t size); >+ >+// UnRegisterLivePointers() >+// >+// Deregisters the pointers previously marked as active in >+// `RegisterLivePointers()`, enabling leak checking of those pointers. >+void UnRegisterLivePointers(const void* ptr, size_t size); >+ >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_LEAK_CHECK_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check_disable.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check_disable.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..df22c1cae91d29e3a749f56e9c3b086528c639d8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check_disable.cc >@@ -0,0 +1,20 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Disable LeakSanitizer when this file is linked in. >+// This function overrides __lsan_is_turned_off from sanitizer/lsan_interface.h >+extern "C" int __lsan_is_turned_off(); >+extern "C" int __lsan_is_turned_off() { >+ return 1; >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check_fail_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check_fail_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..bf541fe84153cd1d6882ae9eb042f8ee1e224b1a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check_fail_test.cc >@@ -0,0 +1,41 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <memory> >+#include "gtest/gtest.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/debugging/leak_check.h" >+ >+namespace { >+ >+TEST(LeakCheckTest, LeakMemory) { >+ // This test is expected to cause lsan failures on program exit. Therefore the >+ // test will be run only by leak_check_test.sh, which will verify a >+ // failed exit code. >+ >+ char* foo = strdup("lsan should complain about this leaked string"); >+ ABSL_RAW_LOG(INFO, "Should detect leaked std::string %s", foo); >+} >+ >+TEST(LeakCheckTest, LeakMemoryAfterDisablerScope) { >+ // This test is expected to cause lsan failures on program exit. Therefore the >+ // test will be run only by external_leak_check_test.sh, which will verify a >+ // failed exit code. >+ { absl::LeakCheckDisabler disabler; } >+ char* foo = strdup("lsan should also complain about this leaked string"); >+ ABSL_RAW_LOG(INFO, "Re-enabled leak detection.Should detect leaked std::string %s", >+ foo); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..febd1ee4f928d3d9b85dc7a87ddc7e89b113ea32 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/leak_check_test.cc >@@ -0,0 +1,42 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <string> >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/debugging/leak_check.h" >+ >+namespace { >+ >+TEST(LeakCheckTest, DetectLeakSanitizer) { >+#ifdef ABSL_EXPECT_LEAK_SANITIZER >+ EXPECT_TRUE(absl::HaveLeakSanitizer()); >+#else >+ EXPECT_FALSE(absl::HaveLeakSanitizer()); >+#endif >+} >+ >+TEST(LeakCheckTest, IgnoreLeakSuppressesLeakedMemoryErrors) { >+ auto foo = absl::IgnoreLeak(new std::string("some ignored leaked string")); >+ ABSL_RAW_LOG(INFO, "Ignoring leaked std::string %s", foo->c_str()); >+} >+ >+TEST(LeakCheckTest, LeakCheckDisablerIgnoresLeak) { >+ absl::LeakCheckDisabler disabler; >+ auto foo = new std::string("some std::string leaked while checks are disabled"); >+ ABSL_RAW_LOG(INFO, "Ignoring leaked std::string %s", foo->c_str()); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/stacktrace.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/stacktrace.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..61fee6190f545842adc362c8fcfcec5c0e75658a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/stacktrace.cc >@@ -0,0 +1,133 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Produce stack trace. >+// >+// There are three different ways we can try to get the stack trace: >+// >+// 1) Our hand-coded stack-unwinder. This depends on a certain stack >+// layout, which is used by gcc (and those systems using a >+// gcc-compatible ABI) on x86 systems, at least since gcc 2.95. >+// It uses the frame pointer to do its work. >+// >+// 2) The libunwind library. This is still in development, and as a >+// separate library adds a new dependency, but doesn't need a frame >+// pointer. It also doesn't call malloc. >+// >+// 3) The gdb unwinder -- also the one used by the c++ exception code. >+// It's obviously well-tested, but has a fatal flaw: it can call >+// malloc() from the unwinder. This is a problem because we're >+// trying to use the unwinder to instrument malloc(). >+// >+// Note: if you add a new implementation here, make sure it works >+// correctly when absl::GetStackTrace() is called with max_depth == 0. >+// Some code may do that. >+ >+#include "absl/debugging/stacktrace.h" >+ >+#include <atomic> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/port.h" >+#include "absl/debugging/internal/stacktrace_config.h" >+ >+#if defined(ABSL_STACKTRACE_INL_HEADER) >+#include ABSL_STACKTRACE_INL_HEADER >+#else >+# error Cannot calculate stack trace: will need to write for your environment >+# include "absl/debugging/internal/stacktrace_aarch64-inl.inc" >+# include "absl/debugging/internal/stacktrace_arm-inl.inc" >+# include "absl/debugging/internal/stacktrace_generic-inl.inc" >+# include "absl/debugging/internal/stacktrace_powerpc-inl.inc" >+# include "absl/debugging/internal/stacktrace_unimplemented-inl.inc" >+# include "absl/debugging/internal/stacktrace_win32-inl.inc" >+# include "absl/debugging/internal/stacktrace_x86-inl.inc" >+#endif >+ >+namespace absl { >+namespace { >+ >+typedef int (*Unwinder)(void**, int*, int, int, const void*, int*); >+std::atomic<Unwinder> custom; >+ >+template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> >+ABSL_ATTRIBUTE_ALWAYS_INLINE inline int Unwind(void** result, int* sizes, >+ int max_depth, int skip_count, >+ const void* uc, >+ int* min_dropped_frames) { >+ Unwinder f = &UnwindImpl<IS_STACK_FRAMES, IS_WITH_CONTEXT>; >+ Unwinder g = custom.load(std::memory_order_acquire); >+ if (g != nullptr) f = g; >+ >+ // Add 1 to skip count for the unwinder function itself >+ int size = (*f)(result, sizes, max_depth, skip_count + 1, uc, >+ min_dropped_frames); >+ // To disable tail call to (*f)(...) >+ ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); >+ return size; >+} >+ >+} // anonymous namespace >+ >+int GetStackFrames(void** result, int* sizes, int max_depth, int skip_count) { >+ return Unwind<true, false>(result, sizes, max_depth, skip_count, nullptr, >+ nullptr); >+} >+ >+int GetStackFramesWithContext(void** result, int* sizes, int max_depth, >+ int skip_count, const void* uc, >+ int* min_dropped_frames) { >+ return Unwind<true, true>(result, sizes, max_depth, skip_count, uc, >+ min_dropped_frames); >+} >+ >+int GetStackTrace(void** result, int max_depth, int skip_count) { >+ return Unwind<false, false>(result, nullptr, max_depth, skip_count, nullptr, >+ nullptr); >+} >+ >+int GetStackTraceWithContext(void** result, int max_depth, int skip_count, >+ const void* uc, int* min_dropped_frames) { >+ return Unwind<false, true>(result, nullptr, max_depth, skip_count, uc, >+ min_dropped_frames); >+} >+ >+void SetStackUnwinder(Unwinder w) { >+ custom.store(w, std::memory_order_release); >+} >+ >+int DefaultStackUnwinder(void** pcs, int* sizes, int depth, int skip, >+ const void* uc, int* min_dropped_frames) { >+ skip++; // For this function >+ Unwinder f = nullptr; >+ if (sizes == nullptr) { >+ if (uc == nullptr) { >+ f = &UnwindImpl<false, false>; >+ } else { >+ f = &UnwindImpl<false, true>; >+ } >+ } else { >+ if (uc == nullptr) { >+ f = &UnwindImpl<true, false>; >+ } else { >+ f = &UnwindImpl<true, true>; >+ } >+ } >+ volatile int x = 0; >+ int n = (*f)(pcs, sizes, depth, skip, uc, min_dropped_frames); >+ x = 1; (void) x; // To disable tail call to (*f)(...) >+ return n; >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/stacktrace.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/stacktrace.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8b831e2681558702f454d5dbd3e37e8e293e2a3d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/stacktrace.h >@@ -0,0 +1,225 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: stacktrace.h >+// ----------------------------------------------------------------------------- >+// >+// This file contains routines to extract the current stack trace and associated >+// stack frames. These functions are thread-safe and async-signal-safe. >+// >+// Note that stack trace functionality is platform dependent and requires >+// additional support from the compiler/build system in most cases. (That is, >+// this functionality generally only works on platforms/builds that have been >+// specifically configured to support it.) >+// >+// Note: stack traces in Abseil that do not utilize a symbolizer will result in >+// frames consisting of function addresses rather than human-readable function >+// names. (See symbolize.h for information on symbolizing these values.) >+ >+#ifndef ABSL_DEBUGGING_STACKTRACE_H_ >+#define ABSL_DEBUGGING_STACKTRACE_H_ >+ >+namespace absl { >+ >+// GetStackFrames() >+// >+// Records program counter values for up to `max_depth` frames, skipping the >+// most recent `skip_count` stack frames, and stores their corresponding values >+// and sizes in `results` and `sizes` buffers. (Note that the frame generated >+// for the `absl::GetStackFrames()` routine itself is also skipped.) >+// routine itself. >+// >+// Example: >+// >+// main() { foo(); } >+// foo() { bar(); } >+// bar() { >+// void* result[10]; >+// int sizes[10]; >+// int depth = absl::GetStackFrames(result, sizes, 10, 1); >+// } >+// >+// The current stack frame would consist of three function calls: `bar()`, >+// `foo()`, and then `main()`; however, since the `GetStackFrames()` call sets >+// `skip_count` to `1`, it will skip the frame for `bar()`, the most recently >+// invoked function call. It will therefore return two program counters and will >+// produce values that map to the following function calls: >+// >+// result[0] foo() >+// result[1] main() >+// >+// (Note: in practice, a few more entries after `main()` may be added to account >+// for startup processes.) >+// >+// Corresponding stack frame sizes will also be recorded: >+// >+// sizes[0] 16 >+// sizes[1] 16 >+// >+// (Stack frame sizes of `16` above are just for illustration purposes.) >+// >+// Stack frame sizes of 0 or less indicate that those frame sizes couldn't >+// be identified. >+// >+// This routine may return fewer stack frame entries than are >+// available. Also note that `result` and `sizes` must both be non-null. >+extern int GetStackFrames(void** result, int* sizes, int max_depth, >+ int skip_count); >+ >+// GetStackFramesWithContext() >+// >+// Records program counter values obtained from a signal handler. Records >+// program counter values for up to `max_depth` frames, skipping the most recent >+// `skip_count` stack frames, and stores their corresponding values and sizes in >+// `results` and `sizes` buffers. (Note that the frame generated for the >+// `absl::GetStackFramesWithContext()` routine itself is also skipped.) >+// >+// The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value >+// passed to a signal handler registered via the `sa_sigaction` field of a >+// `sigaction` struct. (See >+// http://man7.org/linux/man-pages/man2/sigaction.2.html.) The `uc` value may >+// help a stack unwinder to provide a better stack trace under certain >+// conditions. `uc` may safely be null. >+// >+// The `min_dropped_frames` output parameter, if non-null, points to the >+// location to note any dropped stack frames, if any, due to buffer limitations >+// or other reasons. (This value will be set to `0` if no frames were dropped.) >+// The number of total stack frames is guaranteed to be >= skip_count + >+// max_depth + *min_dropped_frames. >+extern int GetStackFramesWithContext(void** result, int* sizes, int max_depth, >+ int skip_count, const void* uc, >+ int* min_dropped_frames); >+ >+// GetStackTrace() >+// >+// Records program counter values for up to `max_depth` frames, skipping the >+// most recent `skip_count` stack frames, and stores their corresponding values >+// in `results`. Note that this function is similar to `absl::GetStackFrames()` >+// except that it returns the stack trace only, and not stack frame sizes. >+// >+// Example: >+// >+// main() { foo(); } >+// foo() { bar(); } >+// bar() { >+// void* result[10]; >+// int depth = absl::GetStackTrace(result, 10, 1); >+// } >+// >+// This produces: >+// >+// result[0] foo >+// result[1] main >+// .... ... >+// >+// `result` must not be null. >+extern int GetStackTrace(void** result, int max_depth, int skip_count); >+ >+// GetStackTraceWithContext() >+// >+// Records program counter values obtained from a signal handler. Records >+// program counter values for up to `max_depth` frames, skipping the most recent >+// `skip_count` stack frames, and stores their corresponding values in >+// `results`. (Note that the frame generated for the >+// `absl::GetStackFramesWithContext()` routine itself is also skipped.) >+// >+// The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value >+// passed to a signal handler registered via the `sa_sigaction` field of a >+// `sigaction` struct. (See >+// http://man7.org/linux/man-pages/man2/sigaction.2.html.) The `uc` value may >+// help a stack unwinder to provide a better stack trace under certain >+// conditions. `uc` may safely be null. >+// >+// The `min_dropped_frames` output parameter, if non-null, points to the >+// location to note any dropped stack frames, if any, due to buffer limitations >+// or other reasons. (This value will be set to `0` if no frames were dropped.) >+// The number of total stack frames is guaranteed to be >= skip_count + >+// max_depth + *min_dropped_frames. >+extern int GetStackTraceWithContext(void** result, int max_depth, >+ int skip_count, const void* uc, >+ int* min_dropped_frames); >+ >+// SetStackUnwinder() >+// >+// Provides a custom function for unwinding stack frames that will be used in >+// place of the default stack unwinder when invoking the static >+// GetStack{Frames,Trace}{,WithContext}() functions above. >+// >+// The arguments passed to the unwinder function will match the >+// arguments passed to `absl::GetStackFramesWithContext()` except that sizes >+// will be non-null iff the caller is interested in frame sizes. >+// >+// If unwinder is set to null, we revert to the default stack-tracing behavior. >+// >+// ***************************************************************************** >+// WARNING >+// ***************************************************************************** >+// >+// absl::SetStackUnwinder is not suitable for general purpose use. It is >+// provided for custom runtimes. >+// Some things to watch out for when calling `absl::SetStackUnwinder()`: >+// >+// (a) The unwinder may be called from within signal handlers and >+// therefore must be async-signal-safe. >+// >+// (b) Even after a custom stack unwinder has been unregistered, other >+// threads may still be in the process of using that unwinder. >+// Therefore do not clean up any state that may be needed by an old >+// unwinder. >+// ***************************************************************************** >+extern void SetStackUnwinder(int (*unwinder)(void** pcs, int* sizes, >+ int max_depth, int skip_count, >+ const void* uc, >+ int* min_dropped_frames)); >+ >+// DefaultStackUnwinder() >+// >+// Records program counter values of up to `max_depth` frames, skipping the most >+// recent `skip_count` stack frames, and stores their corresponding values in >+// `pcs`. (Note that the frame generated for this call itself is also skipped.) >+// This function acts as a generic stack-unwinder; prefer usage of the more >+// specific `GetStack{Trace,Frames}{,WithContext}()` functions above. >+// >+// If you have set your own stack unwinder (with the `SetStackUnwinder()` >+// function above, you can still get the default stack unwinder by calling >+// `DefaultStackUnwinder()`, which will ignore any previously set stack unwinder >+// and use the default one instead. >+// >+// Because this function is generic, only `pcs` is guaranteed to be non-null >+// upon return. It is legal for `sizes`, `uc`, and `min_dropped_frames` to all >+// be null when called. >+// >+// The semantics are the same as the corresponding `GetStack*()` function in the >+// case where `absl::SetStackUnwinder()` was never called. Equivalents are: >+// >+// null sizes | non-nullptr sizes >+// |==========================================================| >+// null uc | GetStackTrace() | GetStackFrames() | >+// non-null uc | GetStackTraceWithContext() | GetStackFramesWithContext() | >+// |==========================================================| >+extern int DefaultStackUnwinder(void** pcs, int* sizes, int max_depth, >+ int skip_count, const void* uc, >+ int* min_dropped_frames); >+ >+namespace debugging_internal { >+// Returns true for platforms which are expected to have functioning stack trace >+// implementations. Intended to be used for tests which want to exclude >+// verification of logic known to be broken because stack traces are not >+// working. >+extern bool StackTraceWorksForTest(); >+} // namespace debugging_internal >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_STACKTRACE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..a35e24cc29a4b7851d40e652c387836fb5080225 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize.cc >@@ -0,0 +1,28 @@ >+// 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/debugging/symbolize.h" >+ >+#if defined(ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE) >+#include "absl/debugging/symbolize_elf.inc" >+#elif defined(_WIN32) && defined(_DEBUG) >+// The Windows Symbolizer only works in debug mode. Note that _DEBUG >+// is the macro that defines whether or not MS C-Runtime debug info is >+// available. Note that the PDB files containing the debug info must >+// also be available to the program at runtime for the symbolizer to >+// work. >+#include "absl/debugging/symbolize_win32.inc" >+#else >+#include "absl/debugging/symbolize_unimplemented.inc" >+#endif >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize.h >new file mode 100644 >index 0000000000000000000000000000000000000000..24e6e6471c6580c065b570d8519342d7cb58c85f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize.h >@@ -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. >+// >+// ----------------------------------------------------------------------------- >+// File: symbolize.h >+// ----------------------------------------------------------------------------- >+// >+// This file configures the Abseil symbolizer for use in converting instruction >+// pointer addresses (program counters) into human-readable names (function >+// calls, etc.) within Abseil code. >+// >+// The symbolizer may be invoked from several sources: >+// >+// * Implicitly, through the installation of an Abseil failure signal handler. >+// (See failure_signal_handler.h for more information.) >+// * By calling `Symbolize()` directly on a program counter you obtain through >+// `absl::GetStackTrace()` or `absl::GetStackFrames()`. (See stacktrace.h >+// for more information. >+// * By calling `Symbolize()` directly on a program counter you obtain through >+// other means (which would be platform-dependent). >+// >+// In all of the above cases, the symbolizer must first be initialized before >+// any program counter values can be symbolized. If you are installing a failure >+// signal handler, initialize the symbolizer before you do so. >+// >+// Example: >+// >+// int main(int argc, char** argv) { >+// // Initialize the Symbolizer before installing the failure signal handler >+// absl::InitializeSymbolizer(argv[0]); >+// >+// // Now you may install the failure signal handler >+// absl::FailureSignalHandlerOptions options; >+// absl::InstallFailureSignalHandler(options); >+// >+// // Start running your main program >+// ... >+// return 0; >+// } >+// >+#ifndef ABSL_DEBUGGING_SYMBOLIZE_H_ >+#define ABSL_DEBUGGING_SYMBOLIZE_H_ >+ >+#include "absl/debugging/internal/symbolize.h" >+ >+namespace absl { >+ >+// InitializeSymbolizer() >+// >+// Initializes the program counter symbolizer, given the path of the program >+// (typically obtained through `main()`s `argv[0]`). The Abseil symbolizer >+// allows you to read program counters (instruction pointer values) using their >+// human-readable names within output such as stack traces. >+// >+// Example: >+// >+// int main(int argc, char *argv[]) { >+// absl::InitializeSymbolizer(argv[0]); >+// // Now you can use the symbolizer >+// } >+void InitializeSymbolizer(const char* argv0); >+ >+// Symbolize() >+// >+// Symbolizes a program counter (instruction pointer value) `pc` and, on >+// success, writes the name to `out`. The symbol name is demangled, if possible. >+// Note that the symbolized name may be truncated and will be NUL-terminated. >+// Demangling is supported for symbols generated by GCC 3.x or newer). Returns >+// `false` on failure. >+// >+// Example: >+// >+// // Print a program counter and its symbol name. >+// static void DumpPCAndSymbol(void *pc) { >+// char tmp[1024]; >+// const char *symbol = "(unknown)"; >+// if (absl::Symbolize(pc, tmp, sizeof(tmp))) { >+// symbol = tmp; >+// } >+// absl::PrintF("%*p %s\n", pc, symbol); >+// } >+bool Symbolize(const void *pc, char *out, int out_size); >+ >+} // namespace absl >+ >+#endif // ABSL_DEBUGGING_SYMBOLIZE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..b16a42a62c95f50fdcb4914ef41f278cc410243e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc >@@ -0,0 +1,1473 @@ >+// 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 library provides Symbolize() function that symbolizes program >+// counters to their corresponding symbol names on linux platforms. >+// This library has a minimal implementation of an ELF symbol table >+// reader (i.e. it doesn't depend on libelf, etc.). >+// >+// The algorithm used in Symbolize() is as follows. >+// >+// 1. Go through a list of maps in /proc/self/maps and find the map >+// containing the program counter. >+// >+// 2. Open the mapped file and find a regular symbol table inside. >+// Iterate over symbols in the symbol table and look for the symbol >+// containing the program counter. If such a symbol is found, >+// obtain the symbol name, and demangle the symbol if possible. >+// If the symbol isn't found in the regular symbol table (binary is >+// stripped), try the same thing with a dynamic symbol table. >+// >+// Note that Symbolize() is originally implemented to be used in >+// signal handlers, hence it doesn't use malloc() and other unsafe >+// operations. It should be both thread-safe and async-signal-safe. >+// >+// Implementation note: >+// >+// We don't use heaps but only use stacks. We want to reduce the >+// stack consumption so that the symbolizer can run on small stacks. >+// >+// Here are some numbers collected with GCC 4.1.0 on x86: >+// - sizeof(Elf32_Sym) = 16 >+// - sizeof(Elf32_Shdr) = 40 >+// - sizeof(Elf64_Sym) = 24 >+// - sizeof(Elf64_Shdr) = 64 >+// >+// This implementation is intended to be async-signal-safe but uses some >+// functions which are not guaranteed to be so, such as memchr() and >+// memmove(). We assume they are async-signal-safe. >+ >+#include <dlfcn.h> >+#include <elf.h> >+#include <fcntl.h> >+#include <link.h> // For ElfW() macro. >+#include <sys/stat.h> >+#include <sys/types.h> >+#include <unistd.h> >+ >+#include <algorithm> >+#include <atomic> >+#include <cerrno> >+#include <cinttypes> >+#include <climits> >+#include <cstdint> >+#include <cstdio> >+#include <cstdlib> >+#include <cstring> >+ >+#include "absl/base/casts.h" >+#include "absl/base/dynamic_annotations.h" >+#include "absl/base/internal/low_level_alloc.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/spinlock.h" >+#include "absl/base/port.h" >+#include "absl/debugging/internal/demangle.h" >+#include "absl/debugging/internal/vdso_support.h" >+ >+namespace absl { >+ >+// Value of argv[0]. Used by MaybeInitializeObjFile(). >+static char *argv0_value = nullptr; >+ >+void InitializeSymbolizer(const char *argv0) { >+ if (argv0_value != nullptr) { >+ free(argv0_value); >+ argv0_value = nullptr; >+ } >+ if (argv0 != nullptr && argv0[0] != '\0') { >+ argv0_value = strdup(argv0); >+ } >+} >+ >+namespace debugging_internal { >+namespace { >+ >+// Re-runs fn until it doesn't cause EINTR. >+#define NO_INTR(fn) \ >+ do { \ >+ } while ((fn) < 0 && errno == EINTR) >+ >+// On Linux, ELF_ST_* are defined in <linux/elf.h>. To make this portable >+// we define our own ELF_ST_BIND and ELF_ST_TYPE if not available. >+#ifndef ELF_ST_BIND >+#define ELF_ST_BIND(info) (((unsigned char)(info)) >> 4) >+#endif >+ >+#ifndef ELF_ST_TYPE >+#define ELF_ST_TYPE(info) (((unsigned char)(info)) & 0xF) >+#endif >+ >+// Some platforms use a special .opd section to store function pointers. >+const char kOpdSectionName[] = ".opd"; >+ >+#if (defined(__powerpc__) && !(_CALL_ELF > 1)) || defined(__ia64) >+// Use opd section for function descriptors on these platforms, the function >+// address is the first word of the descriptor. >+enum { kPlatformUsesOPDSections = 1 }; >+#else // not PPC or IA64 >+enum { kPlatformUsesOPDSections = 0 }; >+#endif >+ >+// This works for PowerPC & IA64 only. A function descriptor consist of two >+// pointers and the first one is the function's entry. >+const size_t kFunctionDescriptorSize = sizeof(void *) * 2; >+ >+const int kMaxDecorators = 10; // Seems like a reasonable upper limit. >+ >+struct InstalledSymbolDecorator { >+ SymbolDecorator fn; >+ void *arg; >+ int ticket; >+}; >+ >+int g_num_decorators; >+InstalledSymbolDecorator g_decorators[kMaxDecorators]; >+ >+struct FileMappingHint { >+ const void *start; >+ const void *end; >+ uint64_t offset; >+ const char *filename; >+}; >+ >+// Protects g_decorators. >+// We are using SpinLock and not a Mutex here, because we may be called >+// from inside Mutex::Lock itself, and it prohibits recursive calls. >+// This happens in e.g. base/stacktrace_syscall_unittest. >+// Moreover, we are using only TryLock(), if the decorator list >+// is being modified (is busy), we skip all decorators, and possibly >+// loose some info. Sorry, that's the best we could do. >+base_internal::SpinLock g_decorators_mu(base_internal::kLinkerInitialized); >+ >+const int kMaxFileMappingHints = 8; >+int g_num_file_mapping_hints; >+FileMappingHint g_file_mapping_hints[kMaxFileMappingHints]; >+// Protects g_file_mapping_hints. >+base_internal::SpinLock g_file_mapping_mu(base_internal::kLinkerInitialized); >+ >+// Async-signal-safe function to zero a buffer. >+// memset() is not guaranteed to be async-signal-safe. >+static void SafeMemZero(void* p, size_t size) { >+ unsigned char *c = static_cast<unsigned char *>(p); >+ while (size--) { >+ *c++ = 0; >+ } >+} >+ >+struct ObjFile { >+ ObjFile() >+ : filename(nullptr), >+ start_addr(nullptr), >+ end_addr(nullptr), >+ offset(0), >+ fd(-1), >+ elf_type(-1) { >+ SafeMemZero(&elf_header, sizeof(elf_header)); >+ } >+ >+ char *filename; >+ const void *start_addr; >+ const void *end_addr; >+ uint64_t offset; >+ >+ // The following fields are initialized on the first access to the >+ // object file. >+ int fd; >+ int elf_type; >+ ElfW(Ehdr) elf_header; >+}; >+ >+// Build 4-way associative cache for symbols. Within each cache line, symbols >+// are replaced in LRU order. >+enum { >+ ASSOCIATIVITY = 4, >+}; >+struct SymbolCacheLine { >+ const void *pc[ASSOCIATIVITY]; >+ char *name[ASSOCIATIVITY]; >+ >+ // age[i] is incremented when a line is accessed. it's reset to zero if the >+ // i'th entry is read. >+ uint32_t age[ASSOCIATIVITY]; >+}; >+ >+// --------------------------------------------------------------- >+// An async-signal-safe arena for LowLevelAlloc >+static std::atomic<base_internal::LowLevelAlloc::Arena *> g_sig_safe_arena; >+ >+static base_internal::LowLevelAlloc::Arena *SigSafeArena() { >+ return g_sig_safe_arena.load(std::memory_order_acquire); >+} >+ >+static void InitSigSafeArena() { >+ if (SigSafeArena() == nullptr) { >+ base_internal::LowLevelAlloc::Arena *new_arena = >+ base_internal::LowLevelAlloc::NewArena( >+ base_internal::LowLevelAlloc::kAsyncSignalSafe); >+ base_internal::LowLevelAlloc::Arena *old_value = nullptr; >+ if (!g_sig_safe_arena.compare_exchange_strong(old_value, new_arena, >+ std::memory_order_release, >+ std::memory_order_relaxed)) { >+ // We lost a race to allocate an arena; deallocate. >+ base_internal::LowLevelAlloc::DeleteArena(new_arena); >+ } >+ } >+} >+ >+// --------------------------------------------------------------- >+// An AddrMap is a vector of ObjFile, using SigSafeArena() for allocation. >+ >+class AddrMap { >+ public: >+ AddrMap() : size_(0), allocated_(0), obj_(nullptr) {} >+ ~AddrMap() { base_internal::LowLevelAlloc::Free(obj_); } >+ int Size() const { return size_; } >+ ObjFile *At(int i) { return &obj_[i]; } >+ ObjFile *Add(); >+ void Clear(); >+ >+ private: >+ int size_; // count of valid elements (<= allocated_) >+ int allocated_; // count of allocated elements >+ ObjFile *obj_; // array of allocated_ elements >+ AddrMap(const AddrMap &) = delete; >+ AddrMap &operator=(const AddrMap &) = delete; >+}; >+ >+void AddrMap::Clear() { >+ for (int i = 0; i != size_; i++) { >+ At(i)->~ObjFile(); >+ } >+ size_ = 0; >+} >+ >+ObjFile *AddrMap::Add() { >+ if (size_ == allocated_) { >+ int new_allocated = allocated_ * 2 + 50; >+ ObjFile *new_obj_ = >+ static_cast<ObjFile *>(base_internal::LowLevelAlloc::AllocWithArena( >+ new_allocated * sizeof(*new_obj_), SigSafeArena())); >+ if (obj_) { >+ memcpy(new_obj_, obj_, allocated_ * sizeof(*new_obj_)); >+ base_internal::LowLevelAlloc::Free(obj_); >+ } >+ obj_ = new_obj_; >+ allocated_ = new_allocated; >+ } >+ return new (&obj_[size_++]) ObjFile; >+} >+ >+// --------------------------------------------------------------- >+ >+enum FindSymbolResult { SYMBOL_NOT_FOUND = 1, SYMBOL_TRUNCATED, SYMBOL_FOUND }; >+ >+class Symbolizer { >+ public: >+ Symbolizer(); >+ ~Symbolizer(); >+ const char *GetSymbol(const void *const pc); >+ >+ private: >+ char *CopyString(const char *s) { >+ int len = strlen(s); >+ char *dst = static_cast<char *>( >+ base_internal::LowLevelAlloc::AllocWithArena(len + 1, SigSafeArena())); >+ ABSL_RAW_CHECK(dst != nullptr, "out of memory"); >+ memcpy(dst, s, len + 1); >+ return dst; >+ } >+ ObjFile *FindObjFile(const void *const start, >+ size_t size) ABSL_ATTRIBUTE_NOINLINE; >+ static bool RegisterObjFile(const char *filename, >+ const void *const start_addr, >+ const void *const end_addr, uint64_t offset, >+ void *arg); >+ SymbolCacheLine *GetCacheLine(const void *const pc); >+ const char *FindSymbolInCache(const void *const pc); >+ const char *InsertSymbolInCache(const void *const pc, const char *name); >+ void AgeSymbols(SymbolCacheLine *line); >+ void ClearAddrMap(); >+ FindSymbolResult GetSymbolFromObjectFile(const ObjFile &obj, >+ const void *const pc, >+ const ptrdiff_t relocation, >+ char *out, int out_size, >+ char *tmp_buf, int tmp_buf_size); >+ >+ enum { >+ SYMBOL_BUF_SIZE = 2048, >+ TMP_BUF_SIZE = 1024, >+ SYMBOL_CACHE_LINES = 128, >+ }; >+ >+ AddrMap addr_map_; >+ >+ bool ok_; >+ bool addr_map_read_; >+ >+ char symbol_buf_[SYMBOL_BUF_SIZE]; >+ >+ // tmp_buf_ will be used to store arrays of ElfW(Shdr) and ElfW(Sym) >+ // so we ensure that tmp_buf_ is properly aligned to store either. >+ alignas(16) char tmp_buf_[TMP_BUF_SIZE]; >+ static_assert(alignof(ElfW(Shdr)) <= 16, >+ "alignment of tmp buf too small for Shdr"); >+ static_assert(alignof(ElfW(Sym)) <= 16, >+ "alignment of tmp buf too small for Sym"); >+ >+ SymbolCacheLine symbol_cache_[SYMBOL_CACHE_LINES]; >+}; >+ >+static std::atomic<Symbolizer *> g_cached_symbolizer; >+ >+} // namespace >+ >+static int SymbolizerSize() { >+ int pagesize = getpagesize(); >+ return ((sizeof(Symbolizer) - 1) / pagesize + 1) * pagesize; >+} >+ >+// Return (and set null) g_cached_symbolized_state if it is not null. >+// Otherwise return a new symbolizer. >+static Symbolizer *AllocateSymbolizer() { >+ InitSigSafeArena(); >+ Symbolizer *symbolizer = >+ g_cached_symbolizer.exchange(nullptr, std::memory_order_acquire); >+ if (symbolizer != nullptr) { >+ return symbolizer; >+ } >+ return new (base_internal::LowLevelAlloc::AllocWithArena( >+ SymbolizerSize(), SigSafeArena())) Symbolizer(); >+} >+ >+// Set g_cached_symbolize_state to s if it is null, otherwise >+// delete s. >+static void FreeSymbolizer(Symbolizer *s) { >+ Symbolizer *old_cached_symbolizer = nullptr; >+ if (!g_cached_symbolizer.compare_exchange_strong(old_cached_symbolizer, s, >+ std::memory_order_release, >+ std::memory_order_relaxed)) { >+ s->~Symbolizer(); >+ base_internal::LowLevelAlloc::Free(s); >+ } >+} >+ >+Symbolizer::Symbolizer() : ok_(true), addr_map_read_(false) { >+ for (SymbolCacheLine &symbol_cache_line : symbol_cache_) { >+ for (size_t j = 0; j < ABSL_ARRAYSIZE(symbol_cache_line.name); ++j) { >+ symbol_cache_line.pc[j] = nullptr; >+ symbol_cache_line.name[j] = nullptr; >+ symbol_cache_line.age[j] = 0; >+ } >+ } >+} >+ >+Symbolizer::~Symbolizer() { >+ for (SymbolCacheLine &symbol_cache_line : symbol_cache_) { >+ for (char *s : symbol_cache_line.name) { >+ base_internal::LowLevelAlloc::Free(s); >+ } >+ } >+ ClearAddrMap(); >+} >+ >+// We don't use assert() since it's not guaranteed to be >+// async-signal-safe. Instead we define a minimal assertion >+// macro. So far, we don't need pretty printing for __FILE__, etc. >+#define SAFE_ASSERT(expr) ((expr) ? static_cast<void>(0) : abort()) >+ >+// Read up to "count" bytes from file descriptor "fd" into the buffer >+// starting at "buf" while handling short reads and EINTR. On >+// success, return the number of bytes read. Otherwise, return -1. >+static ssize_t ReadPersistent(int fd, void *buf, size_t count) { >+ SAFE_ASSERT(fd >= 0); >+ SAFE_ASSERT(count <= SSIZE_MAX); >+ char *buf0 = reinterpret_cast<char *>(buf); >+ size_t num_bytes = 0; >+ while (num_bytes < count) { >+ ssize_t len; >+ NO_INTR(len = read(fd, buf0 + num_bytes, count - num_bytes)); >+ if (len < 0) { // There was an error other than EINTR. >+ ABSL_RAW_LOG(WARNING, "read failed: errno=%d", errno); >+ return -1; >+ } >+ if (len == 0) { // Reached EOF. >+ break; >+ } >+ num_bytes += len; >+ } >+ SAFE_ASSERT(num_bytes <= count); >+ return static_cast<ssize_t>(num_bytes); >+} >+ >+// Read up to "count" bytes from "offset" in the file pointed by file >+// descriptor "fd" into the buffer starting at "buf". On success, >+// return the number of bytes read. Otherwise, return -1. >+static ssize_t ReadFromOffset(const int fd, void *buf, const size_t count, >+ const off_t offset) { >+ off_t off = lseek(fd, offset, SEEK_SET); >+ if (off == (off_t)-1) { >+ ABSL_RAW_LOG(WARNING, "lseek(%d, %ju, SEEK_SET) failed: errno=%d", fd, >+ static_cast<uintmax_t>(offset), errno); >+ return -1; >+ } >+ return ReadPersistent(fd, buf, count); >+} >+ >+// Try reading exactly "count" bytes from "offset" bytes in a file >+// pointed by "fd" into the buffer starting at "buf" while handling >+// short reads and EINTR. On success, return true. Otherwise, return >+// false. >+static bool ReadFromOffsetExact(const int fd, void *buf, const size_t count, >+ const off_t offset) { >+ ssize_t len = ReadFromOffset(fd, buf, count, offset); >+ return len >= 0 && static_cast<size_t>(len) == count; >+} >+ >+// Returns elf_header.e_type if the file pointed by fd is an ELF binary. >+static int FileGetElfType(const int fd) { >+ ElfW(Ehdr) elf_header; >+ if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { >+ return -1; >+ } >+ if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) { >+ return -1; >+ } >+ return elf_header.e_type; >+} >+ >+// Read the section headers in the given ELF binary, and if a section >+// of the specified type is found, set the output to this section header >+// and return true. Otherwise, return false. >+// To keep stack consumption low, we would like this function to not get >+// inlined. >+static ABSL_ATTRIBUTE_NOINLINE bool GetSectionHeaderByType( >+ const int fd, ElfW(Half) sh_num, const off_t sh_offset, ElfW(Word) type, >+ ElfW(Shdr) * out, char *tmp_buf, int tmp_buf_size) { >+ ElfW(Shdr) *buf = reinterpret_cast<ElfW(Shdr) *>(tmp_buf); >+ const int buf_entries = tmp_buf_size / sizeof(buf[0]); >+ const int buf_bytes = buf_entries * sizeof(buf[0]); >+ >+ for (int i = 0; i < sh_num;) { >+ const ssize_t num_bytes_left = (sh_num - i) * sizeof(buf[0]); >+ const ssize_t num_bytes_to_read = >+ (buf_bytes > num_bytes_left) ? num_bytes_left : buf_bytes; >+ const off_t offset = sh_offset + i * sizeof(buf[0]); >+ const ssize_t len = ReadFromOffset(fd, buf, num_bytes_to_read, offset); >+ if (len % sizeof(buf[0]) != 0) { >+ ABSL_RAW_LOG( >+ WARNING, >+ "Reading %zd bytes from offset %ju returned %zd which is not a " >+ "multiple of %zu.", >+ num_bytes_to_read, static_cast<uintmax_t>(offset), len, >+ sizeof(buf[0])); >+ return false; >+ } >+ const ssize_t num_headers_in_buf = len / sizeof(buf[0]); >+ SAFE_ASSERT(num_headers_in_buf <= buf_entries); >+ for (int j = 0; j < num_headers_in_buf; ++j) { >+ if (buf[j].sh_type == type) { >+ *out = buf[j]; >+ return true; >+ } >+ } >+ i += num_headers_in_buf; >+ } >+ return false; >+} >+ >+// There is no particular reason to limit section name to 63 characters, >+// but there has (as yet) been no need for anything longer either. >+const int kMaxSectionNameLen = 64; >+ >+bool ForEachSection(int fd, >+ const std::function<bool(const std::string &name, >+ const ElfW(Shdr) &)> &callback) { >+ ElfW(Ehdr) elf_header; >+ if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { >+ return false; >+ } >+ >+ ElfW(Shdr) shstrtab; >+ off_t shstrtab_offset = >+ (elf_header.e_shoff + elf_header.e_shentsize * elf_header.e_shstrndx); >+ if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) { >+ return false; >+ } >+ >+ for (int i = 0; i < elf_header.e_shnum; ++i) { >+ ElfW(Shdr) out; >+ off_t section_header_offset = >+ (elf_header.e_shoff + elf_header.e_shentsize * i); >+ if (!ReadFromOffsetExact(fd, &out, sizeof(out), section_header_offset)) { >+ return false; >+ } >+ off_t name_offset = shstrtab.sh_offset + out.sh_name; >+ char header_name[kMaxSectionNameLen + 1]; >+ ssize_t n_read = >+ ReadFromOffset(fd, &header_name, kMaxSectionNameLen, name_offset); >+ if (n_read == -1) { >+ return false; >+ } else if (n_read > kMaxSectionNameLen) { >+ // Long read? >+ return false; >+ } >+ header_name[n_read] = '\0'; >+ >+ std::string name(header_name); >+ if (!callback(name, out)) { >+ break; >+ } >+ } >+ return true; >+} >+ >+// name_len should include terminating '\0'. >+bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, >+ ElfW(Shdr) * out) { >+ char header_name[kMaxSectionNameLen]; >+ if (sizeof(header_name) < name_len) { >+ ABSL_RAW_LOG(WARNING, >+ "Section name '%s' is too long (%zu); " >+ "section will not be found (even if present).", >+ name, name_len); >+ // No point in even trying. >+ return false; >+ } >+ >+ ElfW(Ehdr) elf_header; >+ if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { >+ return false; >+ } >+ >+ ElfW(Shdr) shstrtab; >+ off_t shstrtab_offset = >+ (elf_header.e_shoff + elf_header.e_shentsize * elf_header.e_shstrndx); >+ if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) { >+ return false; >+ } >+ >+ for (int i = 0; i < elf_header.e_shnum; ++i) { >+ off_t section_header_offset = >+ (elf_header.e_shoff + elf_header.e_shentsize * i); >+ if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) { >+ return false; >+ } >+ off_t name_offset = shstrtab.sh_offset + out->sh_name; >+ ssize_t n_read = ReadFromOffset(fd, &header_name, name_len, name_offset); >+ if (n_read < 0) { >+ return false; >+ } else if (static_cast<size_t>(n_read) != name_len) { >+ // Short read -- name could be at end of file. >+ continue; >+ } >+ if (memcmp(header_name, name, name_len) == 0) { >+ return true; >+ } >+ } >+ return false; >+} >+ >+// Compare symbols at in the same address. >+// Return true if we should pick symbol1. >+static bool ShouldPickFirstSymbol(const ElfW(Sym) & symbol1, >+ const ElfW(Sym) & symbol2) { >+ // If one of the symbols is weak and the other is not, pick the one >+ // this is not a weak symbol. >+ char bind1 = ELF_ST_BIND(symbol1.st_info); >+ char bind2 = ELF_ST_BIND(symbol1.st_info); >+ if (bind1 == STB_WEAK && bind2 != STB_WEAK) return false; >+ if (bind2 == STB_WEAK && bind1 != STB_WEAK) return true; >+ >+ // If one of the symbols has zero size and the other is not, pick the >+ // one that has non-zero size. >+ if (symbol1.st_size != 0 && symbol2.st_size == 0) { >+ return true; >+ } >+ if (symbol1.st_size == 0 && symbol2.st_size != 0) { >+ return false; >+ } >+ >+ // If one of the symbols has no type and the other is not, pick the >+ // one that has a type. >+ char type1 = ELF_ST_TYPE(symbol1.st_info); >+ char type2 = ELF_ST_TYPE(symbol1.st_info); >+ if (type1 != STT_NOTYPE && type2 == STT_NOTYPE) { >+ return true; >+ } >+ if (type1 == STT_NOTYPE && type2 != STT_NOTYPE) { >+ return false; >+ } >+ >+ // Pick the first one, if we still cannot decide. >+ return true; >+} >+ >+// Return true if an address is inside a section. >+static bool InSection(const void *address, const ElfW(Shdr) * section) { >+ const char *start = reinterpret_cast<const char *>(section->sh_addr); >+ size_t size = static_cast<size_t>(section->sh_size); >+ return start <= address && address < (start + size); >+} >+ >+// Read a symbol table and look for the symbol containing the >+// pc. Iterate over symbols in a symbol table and look for the symbol >+// containing "pc". If the symbol is found, and its name fits in >+// out_size, the name is written into out and SYMBOL_FOUND is returned. >+// If the name does not fit, truncated name is written into out, >+// and SYMBOL_TRUNCATED is returned. Out is NUL-terminated. >+// If the symbol is not found, SYMBOL_NOT_FOUND is returned; >+// To keep stack consumption low, we would like this function to not get >+// inlined. >+static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( >+ const void *const pc, const int fd, char *out, int out_size, >+ ptrdiff_t relocation, const ElfW(Shdr) * strtab, const ElfW(Shdr) * symtab, >+ const ElfW(Shdr) * opd, char *tmp_buf, int tmp_buf_size) { >+ if (symtab == nullptr) { >+ return SYMBOL_NOT_FOUND; >+ } >+ >+ // Read multiple symbols at once to save read() calls. >+ ElfW(Sym) *buf = reinterpret_cast<ElfW(Sym) *>(tmp_buf); >+ const int buf_entries = tmp_buf_size / sizeof(buf[0]); >+ >+ const int num_symbols = symtab->sh_size / symtab->sh_entsize; >+ >+ // On platforms using an .opd section (PowerPC & IA64), a function symbol >+ // has the address of a function descriptor, which contains the real >+ // starting address. However, we do not always want to use the real >+ // starting address because we sometimes want to symbolize a function >+ // pointer into the .opd section, e.g. FindSymbol(&foo,...). >+ const bool pc_in_opd = >+ kPlatformUsesOPDSections && opd != nullptr && InSection(pc, opd); >+ const bool deref_function_descriptor_pointer = >+ kPlatformUsesOPDSections && opd != nullptr && !pc_in_opd; >+ >+ ElfW(Sym) best_match; >+ SafeMemZero(&best_match, sizeof(best_match)); >+ bool found_match = false; >+ for (int i = 0; i < num_symbols;) { >+ off_t offset = symtab->sh_offset + i * symtab->sh_entsize; >+ const int num_remaining_symbols = num_symbols - i; >+ const int entries_in_chunk = std::min(num_remaining_symbols, buf_entries); >+ const int bytes_in_chunk = entries_in_chunk * sizeof(buf[0]); >+ const ssize_t len = ReadFromOffset(fd, buf, bytes_in_chunk, offset); >+ SAFE_ASSERT(len % sizeof(buf[0]) == 0); >+ const ssize_t num_symbols_in_buf = len / sizeof(buf[0]); >+ SAFE_ASSERT(num_symbols_in_buf <= entries_in_chunk); >+ for (int j = 0; j < num_symbols_in_buf; ++j) { >+ const ElfW(Sym) &symbol = buf[j]; >+ >+ // For a DSO, a symbol address is relocated by the loading address. >+ // We keep the original address for opd redirection below. >+ const char *const original_start_address = >+ reinterpret_cast<const char *>(symbol.st_value); >+ const char *start_address = original_start_address + relocation; >+ >+ if (deref_function_descriptor_pointer && >+ InSection(original_start_address, opd)) { >+ // The opd section is mapped into memory. Just dereference >+ // start_address to get the first double word, which points to the >+ // function entry. >+ start_address = *reinterpret_cast<const char *const *>(start_address); >+ } >+ >+ // If pc is inside the .opd section, it points to a function descriptor. >+ const size_t size = pc_in_opd ? kFunctionDescriptorSize : symbol.st_size; >+ const void *const end_address = >+ reinterpret_cast<const char *>(start_address) + size; >+ if (symbol.st_value != 0 && // Skip null value symbols. >+ symbol.st_shndx != 0 && // Skip undefined symbols. >+#ifdef STT_TLS >+ ELF_ST_TYPE(symbol.st_info) != STT_TLS && // Skip thread-local data. >+#endif // STT_TLS >+ ((start_address <= pc && pc < end_address) || >+ (start_address == pc && pc == end_address))) { >+ if (!found_match || ShouldPickFirstSymbol(symbol, best_match)) { >+ found_match = true; >+ best_match = symbol; >+ } >+ } >+ } >+ i += num_symbols_in_buf; >+ } >+ >+ if (found_match) { >+ const size_t off = strtab->sh_offset + best_match.st_name; >+ const ssize_t n_read = ReadFromOffset(fd, out, out_size, off); >+ if (n_read <= 0) { >+ // This should never happen. >+ ABSL_RAW_LOG(WARNING, >+ "Unable to read from fd %d at offset %zu: n_read = %zd", fd, >+ off, n_read); >+ return SYMBOL_NOT_FOUND; >+ } >+ ABSL_RAW_CHECK(n_read <= out_size, "ReadFromOffset read too much data."); >+ >+ // strtab->sh_offset points into .strtab-like section that contains >+ // NUL-terminated strings: '\0foo\0barbaz\0...". >+ // >+ // sh_offset+st_name points to the start of symbol name, but we don't know >+ // how long the symbol is, so we try to read as much as we have space for, >+ // and usually over-read (i.e. there is a NUL somewhere before n_read). >+ if (memchr(out, '\0', n_read) == nullptr) { >+ // Either out_size was too small (n_read == out_size and no NUL), or >+ // we tried to read past the EOF (n_read < out_size) and .strtab is >+ // corrupt (missing terminating NUL; should never happen for valid ELF). >+ out[n_read - 1] = '\0'; >+ return SYMBOL_TRUNCATED; >+ } >+ return SYMBOL_FOUND; >+ } >+ >+ return SYMBOL_NOT_FOUND; >+} >+ >+// Get the symbol name of "pc" from the file pointed by "fd". Process >+// both regular and dynamic symbol tables if necessary. >+// See FindSymbol() comment for description of return value. >+FindSymbolResult Symbolizer::GetSymbolFromObjectFile( >+ const ObjFile &obj, const void *const pc, const ptrdiff_t relocation, >+ char *out, int out_size, char *tmp_buf, int tmp_buf_size) { >+ ElfW(Shdr) symtab; >+ ElfW(Shdr) strtab; >+ ElfW(Shdr) opd; >+ ElfW(Shdr) *opd_ptr = nullptr; >+ >+ // On platforms using an .opd sections for function descriptor, read >+ // the section header. The .opd section is in data segment and should be >+ // loaded but we check that it is mapped just to be extra careful. >+ if (kPlatformUsesOPDSections) { >+ if (GetSectionHeaderByName(obj.fd, kOpdSectionName, >+ sizeof(kOpdSectionName) - 1, &opd) && >+ FindObjFile(reinterpret_cast<const char *>(opd.sh_addr) + relocation, >+ opd.sh_size) != nullptr) { >+ opd_ptr = &opd; >+ } else { >+ return SYMBOL_NOT_FOUND; >+ } >+ } >+ >+ // Consult a regular symbol table first. >+ if (!GetSectionHeaderByType(obj.fd, obj.elf_header.e_shnum, >+ obj.elf_header.e_shoff, SHT_SYMTAB, &symtab, >+ tmp_buf, tmp_buf_size)) { >+ return SYMBOL_NOT_FOUND; >+ } >+ if (!ReadFromOffsetExact( >+ obj.fd, &strtab, sizeof(strtab), >+ obj.elf_header.e_shoff + symtab.sh_link * sizeof(symtab))) { >+ return SYMBOL_NOT_FOUND; >+ } >+ const FindSymbolResult rc = >+ FindSymbol(pc, obj.fd, out, out_size, relocation, &strtab, &symtab, >+ opd_ptr, tmp_buf, tmp_buf_size); >+ if (rc != SYMBOL_NOT_FOUND) { >+ return rc; // Found the symbol in a regular symbol table. >+ } >+ >+ // If the symbol is not found, then consult a dynamic symbol table. >+ if (!GetSectionHeaderByType(obj.fd, obj.elf_header.e_shnum, >+ obj.elf_header.e_shoff, SHT_DYNSYM, &symtab, >+ tmp_buf, tmp_buf_size)) { >+ return SYMBOL_NOT_FOUND; >+ } >+ if (!ReadFromOffsetExact( >+ obj.fd, &strtab, sizeof(strtab), >+ obj.elf_header.e_shoff + symtab.sh_link * sizeof(symtab))) { >+ return SYMBOL_NOT_FOUND; >+ } >+ return FindSymbol(pc, obj.fd, out, out_size, relocation, &strtab, &symtab, >+ opd_ptr, tmp_buf, tmp_buf_size); >+} >+ >+namespace { >+// Thin wrapper around a file descriptor so that the file descriptor >+// gets closed for sure. >+class FileDescriptor { >+ public: >+ explicit FileDescriptor(int fd) : fd_(fd) {} >+ FileDescriptor(const FileDescriptor &) = delete; >+ FileDescriptor &operator=(const FileDescriptor &) = delete; >+ >+ ~FileDescriptor() { >+ if (fd_ >= 0) { >+ NO_INTR(close(fd_)); >+ } >+ } >+ >+ int get() const { return fd_; } >+ >+ private: >+ const int fd_; >+}; >+ >+// Helper class for reading lines from file. >+// >+// Note: we don't use ProcMapsIterator since the object is big (it has >+// a 5k array member) and uses async-unsafe functions such as sscanf() >+// and snprintf(). >+class LineReader { >+ public: >+ explicit LineReader(int fd, char *buf, int buf_len) >+ : fd_(fd), >+ buf_len_(buf_len), >+ buf_(buf), >+ bol_(buf), >+ eol_(buf), >+ eod_(buf) {} >+ >+ LineReader(const LineReader &) = delete; >+ LineReader &operator=(const LineReader &) = delete; >+ >+ // Read '\n'-terminated line from file. On success, modify "bol" >+ // and "eol", then return true. Otherwise, return false. >+ // >+ // Note: if the last line doesn't end with '\n', the line will be >+ // dropped. It's an intentional behavior to make the code simple. >+ bool ReadLine(const char **bol, const char **eol) { >+ if (BufferIsEmpty()) { // First time. >+ const ssize_t num_bytes = ReadPersistent(fd_, buf_, buf_len_); >+ if (num_bytes <= 0) { // EOF or error. >+ return false; >+ } >+ eod_ = buf_ + num_bytes; >+ bol_ = buf_; >+ } else { >+ bol_ = eol_ + 1; // Advance to the next line in the buffer. >+ SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_". >+ if (!HasCompleteLine()) { >+ const int incomplete_line_length = eod_ - bol_; >+ // Move the trailing incomplete line to the beginning. >+ memmove(buf_, bol_, incomplete_line_length); >+ // Read text from file and append it. >+ char *const append_pos = buf_ + incomplete_line_length; >+ const int capacity_left = buf_len_ - incomplete_line_length; >+ const ssize_t num_bytes = >+ ReadPersistent(fd_, append_pos, capacity_left); >+ if (num_bytes <= 0) { // EOF or error. >+ return false; >+ } >+ eod_ = append_pos + num_bytes; >+ bol_ = buf_; >+ } >+ } >+ eol_ = FindLineFeed(); >+ if (eol_ == nullptr) { // '\n' not found. Malformed line. >+ return false; >+ } >+ *eol_ = '\0'; // Replace '\n' with '\0'. >+ >+ *bol = bol_; >+ *eol = eol_; >+ return true; >+ } >+ >+ private: >+ char *FindLineFeed() const { >+ return reinterpret_cast<char *>(memchr(bol_, '\n', eod_ - bol_)); >+ } >+ >+ bool BufferIsEmpty() const { return buf_ == eod_; } >+ >+ bool HasCompleteLine() const { >+ return !BufferIsEmpty() && FindLineFeed() != nullptr; >+ } >+ >+ const int fd_; >+ const int buf_len_; >+ char *const buf_; >+ char *bol_; >+ char *eol_; >+ const char *eod_; // End of data in "buf_". >+}; >+} // namespace >+ >+// Place the hex number read from "start" into "*hex". The pointer to >+// the first non-hex character or "end" is returned. >+static const char *GetHex(const char *start, const char *end, >+ uint64_t *const value) { >+ uint64_t hex = 0; >+ const char *p; >+ for (p = start; p < end; ++p) { >+ int ch = *p; >+ if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || >+ (ch >= 'a' && ch <= 'f')) { >+ hex = (hex << 4) | (ch < 'A' ? ch - '0' : (ch & 0xF) + 9); >+ } else { // Encountered the first non-hex character. >+ break; >+ } >+ } >+ SAFE_ASSERT(p <= end); >+ *value = hex; >+ return p; >+} >+ >+static const char *GetHex(const char *start, const char *end, >+ const void **const addr) { >+ uint64_t hex = 0; >+ const char *p = GetHex(start, end, &hex); >+ *addr = reinterpret_cast<void *>(hex); >+ return p; >+} >+ >+// Read /proc/self/maps and run "callback" for each mmapped file found. If >+// "callback" returns false, stop scanning and return true. Else continue >+// scanning /proc/self/maps. Return true if no parse error is found. >+static ABSL_ATTRIBUTE_NOINLINE bool ReadAddrMap( >+ bool (*callback)(const char *filename, const void *const start_addr, >+ const void *const end_addr, uint64_t offset, void *arg), >+ void *arg, void *tmp_buf, int tmp_buf_size) { >+ // Use /proc/self/task/<pid>/maps instead of /proc/self/maps. The latter >+ // requires kernel to stop all threads, and is significantly slower when there >+ // are 1000s of threads. >+ char maps_path[80]; >+ snprintf(maps_path, sizeof(maps_path), "/proc/self/task/%d/maps", getpid()); >+ >+ int maps_fd; >+ NO_INTR(maps_fd = open(maps_path, O_RDONLY)); >+ FileDescriptor wrapped_maps_fd(maps_fd); >+ if (wrapped_maps_fd.get() < 0) { >+ ABSL_RAW_LOG(WARNING, "%s: errno=%d", maps_path, errno); >+ return false; >+ } >+ >+ // Iterate over maps and look for the map containing the pc. Then >+ // look into the symbol tables inside. >+ LineReader reader(wrapped_maps_fd.get(), static_cast<char *>(tmp_buf), >+ tmp_buf_size); >+ while (true) { >+ const char *cursor; >+ const char *eol; >+ if (!reader.ReadLine(&cursor, &eol)) { // EOF or malformed line. >+ break; >+ } >+ >+ const char *line = cursor; >+ const void *start_address; >+ // Start parsing line in /proc/self/maps. Here is an example: >+ // >+ // 08048000-0804c000 r-xp 00000000 08:01 2142121 /bin/cat >+ // >+ // We want start address (08048000), end address (0804c000), flags >+ // (r-xp) and file name (/bin/cat). >+ >+ // Read start address. >+ cursor = GetHex(cursor, eol, &start_address); >+ if (cursor == eol || *cursor != '-') { >+ ABSL_RAW_LOG(WARNING, "Corrupt /proc/self/maps line: %s", line); >+ return false; >+ } >+ ++cursor; // Skip '-'. >+ >+ // Read end address. >+ const void *end_address; >+ cursor = GetHex(cursor, eol, &end_address); >+ if (cursor == eol || *cursor != ' ') { >+ ABSL_RAW_LOG(WARNING, "Corrupt /proc/self/maps line: %s", line); >+ return false; >+ } >+ ++cursor; // Skip ' '. >+ >+ // Read flags. Skip flags until we encounter a space or eol. >+ const char *const flags_start = cursor; >+ while (cursor < eol && *cursor != ' ') { >+ ++cursor; >+ } >+ // We expect at least four letters for flags (ex. "r-xp"). >+ if (cursor == eol || cursor < flags_start + 4) { >+ ABSL_RAW_LOG(WARNING, "Corrupt /proc/self/maps: %s", line); >+ return false; >+ } >+ >+ // Check flags. Normally we are only interested in "r-x" maps. On >+ // the PowerPC, function pointers point to descriptors in the .opd >+ // section. The descriptors themselves are not executable code. So >+ // we need to relax the check below to "r**". >+ if (memcmp(flags_start, "r-x", 3) != 0 && // Not a "r-x" map. >+ !(kPlatformUsesOPDSections && flags_start[0] == 'r')) { >+ continue; // We skip this map. >+ } >+ ++cursor; // Skip ' '. >+ >+ // Read file offset. >+ uint64_t offset; >+ cursor = GetHex(cursor, eol, &offset); >+ ++cursor; // Skip ' '. >+ >+ // Skip to file name. "cursor" now points to dev. We need to skip at least >+ // two spaces for dev and inode. >+ int num_spaces = 0; >+ while (cursor < eol) { >+ if (*cursor == ' ') { >+ ++num_spaces; >+ } else if (num_spaces >= 2) { >+ // The first non-space character after skipping two spaces >+ // is the beginning of the file name. >+ break; >+ } >+ ++cursor; >+ } >+ >+ // Check whether this entry corresponds to our hint table for the true >+ // filename. >+ bool hinted = >+ GetFileMappingHint(&start_address, &end_address, &offset, &cursor); >+ if (!hinted && (cursor == eol || cursor[0] == '[')) { >+ // not an object file, typically [vdso] or [vsyscall] >+ continue; >+ } >+ if (!callback(cursor, start_address, end_address, offset, arg)) break; >+ } >+ return true; >+} >+ >+// Find the objfile mapped in address region containing [addr, addr + len). >+ObjFile *Symbolizer::FindObjFile(const void *const addr, size_t len) { >+ for (int i = 0; i < 2; ++i) { >+ if (!ok_) return nullptr; >+ >+ // Read /proc/self/maps if necessary >+ if (!addr_map_read_) { >+ addr_map_read_ = true; >+ if (!ReadAddrMap(RegisterObjFile, this, tmp_buf_, TMP_BUF_SIZE)) { >+ ok_ = false; >+ return nullptr; >+ } >+ } >+ >+ int lo = 0; >+ int hi = addr_map_.Size(); >+ while (lo < hi) { >+ int mid = (lo + hi) / 2; >+ if (addr < addr_map_.At(mid)->end_addr) { >+ hi = mid; >+ } else { >+ lo = mid + 1; >+ } >+ } >+ if (lo != addr_map_.Size()) { >+ ObjFile *obj = addr_map_.At(lo); >+ SAFE_ASSERT(obj->end_addr > addr); >+ if (addr >= obj->start_addr && >+ reinterpret_cast<const char *>(addr) + len <= obj->end_addr) >+ return obj; >+ } >+ >+ // The address mapping may have changed since it was last read. Retry. >+ ClearAddrMap(); >+ } >+ return nullptr; >+} >+ >+void Symbolizer::ClearAddrMap() { >+ for (int i = 0; i != addr_map_.Size(); i++) { >+ ObjFile *o = addr_map_.At(i); >+ base_internal::LowLevelAlloc::Free(o->filename); >+ if (o->fd >= 0) { >+ NO_INTR(close(o->fd)); >+ } >+ } >+ addr_map_.Clear(); >+ addr_map_read_ = false; >+} >+ >+// Callback for ReadAddrMap to register objfiles in an in-memory table. >+bool Symbolizer::RegisterObjFile(const char *filename, >+ const void *const start_addr, >+ const void *const end_addr, uint64_t offset, >+ void *arg) { >+ Symbolizer *impl = static_cast<Symbolizer *>(arg); >+ >+ // Files are supposed to be added in the increasing address order. Make >+ // sure that's the case. >+ int addr_map_size = impl->addr_map_.Size(); >+ if (addr_map_size != 0) { >+ ObjFile *old = impl->addr_map_.At(addr_map_size - 1); >+ if (old->end_addr > end_addr) { >+ ABSL_RAW_LOG(ERROR, >+ "Unsorted addr map entry: 0x%" PRIxPTR ": %s <-> 0x%" PRIxPTR >+ ": %s", >+ reinterpret_cast<uintptr_t>(end_addr), filename, >+ reinterpret_cast<uintptr_t>(old->end_addr), old->filename); >+ return true; >+ } else if (old->end_addr == end_addr) { >+ // The same entry appears twice. This sometimes happens for [vdso]. >+ if (old->start_addr != start_addr || >+ strcmp(old->filename, filename) != 0) { >+ ABSL_RAW_LOG(ERROR, >+ "Duplicate addr 0x%" PRIxPTR ": %s <-> 0x%" PRIxPTR ": %s", >+ reinterpret_cast<uintptr_t>(end_addr), filename, >+ reinterpret_cast<uintptr_t>(old->end_addr), old->filename); >+ } >+ return true; >+ } >+ } >+ ObjFile *obj = impl->addr_map_.Add(); >+ obj->filename = impl->CopyString(filename); >+ obj->start_addr = start_addr; >+ obj->end_addr = end_addr; >+ obj->offset = offset; >+ obj->elf_type = -1; // filled on demand >+ obj->fd = -1; // opened on demand >+ return true; >+} >+ >+// This function wraps the Demangle function to provide an interface >+// where the input symbol is demangled in-place. >+// To keep stack consumption low, we would like this function to not >+// get inlined. >+static ABSL_ATTRIBUTE_NOINLINE void DemangleInplace(char *out, int out_size, >+ char *tmp_buf, >+ int tmp_buf_size) { >+ if (Demangle(out, tmp_buf, tmp_buf_size)) { >+ // Demangling succeeded. Copy to out if the space allows. >+ int len = strlen(tmp_buf); >+ if (len + 1 <= out_size) { // +1 for '\0'. >+ SAFE_ASSERT(len < tmp_buf_size); >+ memmove(out, tmp_buf, len + 1); >+ } >+ } >+} >+ >+SymbolCacheLine *Symbolizer::GetCacheLine(const void *const pc) { >+ uintptr_t pc0 = reinterpret_cast<uintptr_t>(pc); >+ pc0 >>= 3; // drop the low 3 bits >+ >+ // Shuffle bits. >+ pc0 ^= (pc0 >> 6) ^ (pc0 >> 12) ^ (pc0 >> 18); >+ return &symbol_cache_[pc0 % SYMBOL_CACHE_LINES]; >+} >+ >+void Symbolizer::AgeSymbols(SymbolCacheLine *line) { >+ for (uint32_t &age : line->age) { >+ ++age; >+ } >+} >+ >+const char *Symbolizer::FindSymbolInCache(const void *const pc) { >+ if (pc == nullptr) return nullptr; >+ >+ SymbolCacheLine *line = GetCacheLine(pc); >+ for (size_t i = 0; i < ABSL_ARRAYSIZE(line->pc); ++i) { >+ if (line->pc[i] == pc) { >+ AgeSymbols(line); >+ line->age[i] = 0; >+ return line->name[i]; >+ } >+ } >+ return nullptr; >+} >+ >+const char *Symbolizer::InsertSymbolInCache(const void *const pc, >+ const char *name) { >+ SAFE_ASSERT(pc != nullptr); >+ >+ SymbolCacheLine *line = GetCacheLine(pc); >+ uint32_t max_age = 0; >+ int oldest_index = -1; >+ for (size_t i = 0; i < ABSL_ARRAYSIZE(line->pc); ++i) { >+ if (line->pc[i] == nullptr) { >+ AgeSymbols(line); >+ line->pc[i] = pc; >+ line->name[i] = CopyString(name); >+ line->age[i] = 0; >+ return line->name[i]; >+ } >+ if (line->age[i] >= max_age) { >+ max_age = line->age[i]; >+ oldest_index = i; >+ } >+ } >+ >+ AgeSymbols(line); >+ ABSL_RAW_CHECK(oldest_index >= 0, "Corrupt cache"); >+ base_internal::LowLevelAlloc::Free(line->name[oldest_index]); >+ line->pc[oldest_index] = pc; >+ line->name[oldest_index] = CopyString(name); >+ line->age[oldest_index] = 0; >+ return line->name[oldest_index]; >+} >+ >+static void MaybeOpenFdFromSelfExe(ObjFile *obj) { >+ if (memcmp(obj->start_addr, ELFMAG, SELFMAG) != 0) { >+ return; >+ } >+ int fd = open("/proc/self/exe", O_RDONLY); >+ if (fd == -1) { >+ return; >+ } >+ // Verify that contents of /proc/self/exe matches in-memory image of >+ // the binary. This can fail if the "deleted" binary is in fact not >+ // the main executable, or for binaries that have the first PT_LOAD >+ // segment smaller than 4K. We do it in four steps so that the >+ // buffer is smaller and we don't consume too much stack space. >+ const char *mem = reinterpret_cast<const char *>(obj->start_addr); >+ for (int i = 0; i < 4; ++i) { >+ char buf[1024]; >+ ssize_t n = read(fd, buf, sizeof(buf)); >+ if (n != sizeof(buf) || memcmp(buf, mem, sizeof(buf)) != 0) { >+ close(fd); >+ return; >+ } >+ mem += sizeof(buf); >+ } >+ obj->fd = fd; >+} >+ >+static bool MaybeInitializeObjFile(ObjFile *obj) { >+ if (obj->fd < 0) { >+ obj->fd = open(obj->filename, O_RDONLY); >+ >+ if (obj->fd < 0) { >+ // Getting /proc/self/exe here means that we were hinted. >+ if (strcmp(obj->filename, "/proc/self/exe") == 0) { >+ // /proc/self/exe may be inaccessible (due to setuid, etc.), so try >+ // accessing the binary via argv0. >+ if (argv0_value != nullptr) { >+ obj->fd = open(argv0_value, O_RDONLY); >+ } >+ } else { >+ MaybeOpenFdFromSelfExe(obj); >+ } >+ } >+ >+ if (obj->fd < 0) { >+ ABSL_RAW_LOG(WARNING, "%s: open failed: errno=%d", obj->filename, errno); >+ return false; >+ } >+ obj->elf_type = FileGetElfType(obj->fd); >+ if (obj->elf_type < 0) { >+ ABSL_RAW_LOG(WARNING, "%s: wrong elf type: %d", obj->filename, >+ obj->elf_type); >+ return false; >+ } >+ >+ if (!ReadFromOffsetExact(obj->fd, &obj->elf_header, sizeof(obj->elf_header), >+ 0)) { >+ ABSL_RAW_LOG(WARNING, "%s: failed to read elf header", obj->filename); >+ return false; >+ } >+ } >+ return true; >+} >+ >+// The implementation of our symbolization routine. If it >+// successfully finds the symbol containing "pc" and obtains the >+// symbol name, returns pointer to that symbol. Otherwise, returns nullptr. >+// If any symbol decorators have been installed via InstallSymbolDecorator(), >+// they are called here as well. >+// To keep stack consumption low, we would like this function to not >+// get inlined. >+const char *Symbolizer::GetSymbol(const void *const pc) { >+ const char *entry = FindSymbolInCache(pc); >+ if (entry != nullptr) { >+ return entry; >+ } >+ symbol_buf_[0] = '\0'; >+ >+ ObjFile *const obj = FindObjFile(pc, 1); >+ ptrdiff_t relocation = 0; >+ int fd = -1; >+ if (obj != nullptr) { >+ if (MaybeInitializeObjFile(obj)) { >+ if (obj->elf_type == ET_DYN && >+ reinterpret_cast<uint64_t>(obj->start_addr) >= obj->offset) { >+ // This object was relocated. >+ // >+ // For obj->offset > 0, adjust the relocation since a mapping at offset >+ // X in the file will have a start address of [true relocation]+X. >+ relocation = reinterpret_cast<ptrdiff_t>(obj->start_addr) - obj->offset; >+ } >+ >+ fd = obj->fd; >+ } >+ if (GetSymbolFromObjectFile(*obj, pc, relocation, symbol_buf_, >+ sizeof(symbol_buf_), tmp_buf_, >+ sizeof(tmp_buf_)) == SYMBOL_FOUND) { >+ // Only try to demangle the symbol name if it fit into symbol_buf_. >+ DemangleInplace(symbol_buf_, sizeof(symbol_buf_), tmp_buf_, >+ sizeof(tmp_buf_)); >+ } >+ } else { >+#if ABSL_HAVE_VDSO_SUPPORT >+ VDSOSupport vdso; >+ if (vdso.IsPresent()) { >+ VDSOSupport::SymbolInfo symbol_info; >+ if (vdso.LookupSymbolByAddress(pc, &symbol_info)) { >+ // All VDSO symbols are known to be short. >+ size_t len = strlen(symbol_info.name); >+ ABSL_RAW_CHECK(len + 1 < sizeof(symbol_buf_), >+ "VDSO symbol unexpectedly long"); >+ memcpy(symbol_buf_, symbol_info.name, len + 1); >+ } >+ } >+#endif >+ } >+ >+ if (g_decorators_mu.TryLock()) { >+ if (g_num_decorators > 0) { >+ SymbolDecoratorArgs decorator_args = { >+ pc, relocation, fd, symbol_buf_, sizeof(symbol_buf_), >+ tmp_buf_, sizeof(tmp_buf_), nullptr}; >+ for (int i = 0; i < g_num_decorators; ++i) { >+ decorator_args.arg = g_decorators[i].arg; >+ g_decorators[i].fn(&decorator_args); >+ } >+ } >+ g_decorators_mu.Unlock(); >+ } >+ if (symbol_buf_[0] == '\0') { >+ return nullptr; >+ } >+ symbol_buf_[sizeof(symbol_buf_) - 1] = '\0'; // Paranoia. >+ return InsertSymbolInCache(pc, symbol_buf_); >+} >+ >+bool RemoveAllSymbolDecorators(void) { >+ if (!g_decorators_mu.TryLock()) { >+ // Someone else is using decorators. Get out. >+ return false; >+ } >+ g_num_decorators = 0; >+ g_decorators_mu.Unlock(); >+ return true; >+} >+ >+bool RemoveSymbolDecorator(int ticket) { >+ if (!g_decorators_mu.TryLock()) { >+ // Someone else is using decorators. Get out. >+ return false; >+ } >+ for (int i = 0; i < g_num_decorators; ++i) { >+ if (g_decorators[i].ticket == ticket) { >+ while (i < g_num_decorators - 1) { >+ g_decorators[i] = g_decorators[i + 1]; >+ ++i; >+ } >+ g_num_decorators = i; >+ break; >+ } >+ } >+ g_decorators_mu.Unlock(); >+ return true; // Decorator is known to be removed. >+} >+ >+int InstallSymbolDecorator(SymbolDecorator decorator, void *arg) { >+ static int ticket = 0; >+ >+ if (!g_decorators_mu.TryLock()) { >+ // Someone else is using decorators. Get out. >+ return false; >+ } >+ int ret = ticket; >+ if (g_num_decorators >= kMaxDecorators) { >+ ret = -1; >+ } else { >+ g_decorators[g_num_decorators] = {decorator, arg, ticket++}; >+ ++g_num_decorators; >+ } >+ g_decorators_mu.Unlock(); >+ return ret; >+} >+ >+bool RegisterFileMappingHint(const void *start, const void *end, uint64_t offset, >+ const char *filename) { >+ SAFE_ASSERT(start <= end); >+ SAFE_ASSERT(filename != nullptr); >+ >+ InitSigSafeArena(); >+ >+ if (!g_file_mapping_mu.TryLock()) { >+ return false; >+ } >+ >+ bool ret = true; >+ if (g_num_file_mapping_hints >= kMaxFileMappingHints) { >+ ret = false; >+ } else { >+ // TODO(ckennelly): Move this into a std::string copy routine. >+ int len = strlen(filename); >+ char *dst = static_cast<char *>( >+ base_internal::LowLevelAlloc::AllocWithArena(len + 1, SigSafeArena())); >+ ABSL_RAW_CHECK(dst != nullptr, "out of memory"); >+ memcpy(dst, filename, len + 1); >+ >+ auto &hint = g_file_mapping_hints[g_num_file_mapping_hints++]; >+ hint.start = start; >+ hint.end = end; >+ hint.offset = offset; >+ hint.filename = dst; >+ } >+ >+ g_file_mapping_mu.Unlock(); >+ return ret; >+} >+ >+bool GetFileMappingHint(const void **start, const void **end, uint64_t *offset, >+ const char **filename) { >+ if (!g_file_mapping_mu.TryLock()) { >+ return false; >+ } >+ bool found = false; >+ for (int i = 0; i < g_num_file_mapping_hints; i++) { >+ if (g_file_mapping_hints[i].start <= *start && >+ *end <= g_file_mapping_hints[i].end) { >+ // We assume that the start_address for the mapping is the base >+ // address of the ELF section, but when [start_address,end_address) is >+ // not strictly equal to [hint.start, hint.end), that assumption is >+ // invalid. >+ // >+ // This uses the hint's start address (even though hint.start is not >+ // necessarily equal to start_address) to ensure the correct >+ // relocation is computed later. >+ *start = g_file_mapping_hints[i].start; >+ *end = g_file_mapping_hints[i].end; >+ *offset = g_file_mapping_hints[i].offset; >+ *filename = g_file_mapping_hints[i].filename; >+ found = true; >+ break; >+ } >+ } >+ g_file_mapping_mu.Unlock(); >+ return found; >+} >+ >+} // namespace debugging_internal >+ >+bool Symbolize(const void *pc, char *out, int out_size) { >+ // Symbolization is very slow under tsan. >+ ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN(); >+ SAFE_ASSERT(out_size >= 0); >+ debugging_internal::Symbolizer *s = debugging_internal::AllocateSymbolizer(); >+ const char *name = s->GetSymbol(pc); >+ bool ok = false; >+ if (name != nullptr && out_size > 0) { >+ strncpy(out, name, out_size); >+ ok = true; >+ if (out[out_size - 1] != '\0') { >+ // strncpy() does not '\0' terminate when it truncates. Do so, with >+ // trailing ellipsis. >+ static constexpr char kEllipsis[] = "..."; >+ int ellipsis_size = >+ std::min(implicit_cast<int>(strlen(kEllipsis)), out_size - 1); >+ memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); >+ out[out_size - 1] = '\0'; >+ } >+ } >+ debugging_internal::FreeSymbolizer(s); >+ ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END(); >+ return ok; >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..5f2af47ee45d654b422d0e864fbf060cb5c51075 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_test.cc >@@ -0,0 +1,517 @@ >+// 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/debugging/symbolize.h" >+ >+#ifndef _WIN32 >+#include <fcntl.h> >+#include <sys/mman.h> >+#endif >+ >+#include <cstring> >+#include <iostream> >+#include <memory> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/attributes.h" >+#include "absl/base/casts.h" >+#include "absl/base/internal/per_thread_tls.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/optimization.h" >+#include "absl/debugging/internal/stack_consumption.h" >+#include "absl/memory/memory.h" >+ >+using testing::Contains; >+ >+// Functions to symbolize. Use C linkage to avoid mangled names. >+extern "C" { >+void nonstatic_func() { ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); } >+static void static_func() { ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); } >+} // extern "C" >+ >+struct Foo { >+ static void func(int x); >+}; >+ >+// A C++ method that should have a mangled name. >+void ABSL_ATTRIBUTE_NOINLINE Foo::func(int) { >+ ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); >+} >+ >+// Create functions that will remain in different text sections in the >+// final binary when linker option "-z,keep-text-section-prefix" is used. >+int ABSL_ATTRIBUTE_SECTION_VARIABLE(.text.unlikely) unlikely_func() { >+ return 0; >+} >+ >+int ABSL_ATTRIBUTE_SECTION_VARIABLE(.text.hot) hot_func() { >+ return 0; >+} >+ >+int ABSL_ATTRIBUTE_SECTION_VARIABLE(.text.startup) startup_func() { >+ return 0; >+} >+ >+int ABSL_ATTRIBUTE_SECTION_VARIABLE(.text.exit) exit_func() { >+ return 0; >+} >+ >+int /*ABSL_ATTRIBUTE_SECTION_VARIABLE(.text)*/ regular_func() { >+ return 0; >+} >+ >+// Thread-local data may confuse the symbolizer, ensure that it does not. >+// Variable sizes and order are important. >+#if ABSL_PER_THREAD_TLS >+static ABSL_PER_THREAD_TLS_KEYWORD char symbolize_test_thread_small[1]; >+static ABSL_PER_THREAD_TLS_KEYWORD char >+ symbolize_test_thread_big[2 * 1024 * 1024]; >+#endif >+ >+// Used below to hopefully inhibit some compiler/linker optimizations >+// that may remove kHpageTextPadding, kPadding0, and kPadding1 from >+// the binary. >+static volatile bool volatile_bool = false; >+ >+// Force the binary to be large enough that a THP .text remap will succeed. >+static constexpr size_t kHpageSize = 1 << 21; >+const char kHpageTextPadding[kHpageSize * 4] ABSL_ATTRIBUTE_SECTION_VARIABLE( >+ .text) = ""; >+ >+static char try_symbolize_buffer[4096]; >+ >+// A wrapper function for absl::Symbolize() to make the unit test simple. The >+// limit must be < sizeof(try_symbolize_buffer). Returns null if >+// absl::Symbolize() returns false, otherwise returns try_symbolize_buffer with >+// the result of absl::Symbolize(). >+static const char *TrySymbolizeWithLimit(void *pc, int limit) { >+ ABSL_RAW_CHECK(limit <= sizeof(try_symbolize_buffer), >+ "try_symbolize_buffer is too small"); >+ >+ // Use the heap to facilitate heap and buffer sanitizer tools. >+ auto heap_buffer = absl::make_unique<char[]>(sizeof(try_symbolize_buffer)); >+ bool found = absl::Symbolize(pc, heap_buffer.get(), limit); >+ if (found) { >+ ABSL_RAW_CHECK(strnlen(heap_buffer.get(), limit) < limit, >+ "absl::Symbolize() did not properly terminate the string"); >+ strncpy(try_symbolize_buffer, heap_buffer.get(), >+ sizeof(try_symbolize_buffer)); >+ } >+ >+ return found ? try_symbolize_buffer : nullptr; >+} >+ >+// A wrapper for TrySymbolizeWithLimit(), with a large limit. >+static const char *TrySymbolize(void *pc) { >+ return TrySymbolizeWithLimit(pc, sizeof(try_symbolize_buffer)); >+} >+ >+#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE >+ >+TEST(Symbolize, Cached) { >+ // Compilers should give us pointers to them. >+ EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func))); >+ >+ // The name of an internal linkage symbol is not specified; allow either a >+ // mangled or an unmangled name here. >+ const char *static_func_symbol = TrySymbolize((void *)(&static_func)); >+ EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 || >+ strcmp("static_func()", static_func_symbol) == 0); >+ >+ EXPECT_TRUE(nullptr == TrySymbolize(nullptr)); >+} >+ >+TEST(Symbolize, Truncation) { >+ constexpr char kNonStaticFunc[] = "nonstatic_func"; >+ EXPECT_STREQ("nonstatic_func", >+ TrySymbolizeWithLimit((void *)(&nonstatic_func), >+ strlen(kNonStaticFunc) + 1)); >+ EXPECT_STREQ("nonstatic_...", >+ TrySymbolizeWithLimit((void *)(&nonstatic_func), >+ strlen(kNonStaticFunc) + 0)); >+ EXPECT_STREQ("nonstatic...", >+ TrySymbolizeWithLimit((void *)(&nonstatic_func), >+ strlen(kNonStaticFunc) - 1)); >+ EXPECT_STREQ("n...", TrySymbolizeWithLimit((void *)(&nonstatic_func), 5)); >+ EXPECT_STREQ("...", TrySymbolizeWithLimit((void *)(&nonstatic_func), 4)); >+ EXPECT_STREQ("..", TrySymbolizeWithLimit((void *)(&nonstatic_func), 3)); >+ EXPECT_STREQ(".", TrySymbolizeWithLimit((void *)(&nonstatic_func), 2)); >+ EXPECT_STREQ("", TrySymbolizeWithLimit((void *)(&nonstatic_func), 1)); >+ EXPECT_EQ(nullptr, TrySymbolizeWithLimit((void *)(&nonstatic_func), 0)); >+} >+ >+TEST(Symbolize, SymbolizeWithDemangling) { >+ Foo::func(100); >+ EXPECT_STREQ("Foo::func()", TrySymbolize((void *)(&Foo::func))); >+} >+ >+TEST(Symbolize, SymbolizeSplitTextSections) { >+ EXPECT_STREQ("unlikely_func()", TrySymbolize((void *)(&unlikely_func))); >+ EXPECT_STREQ("hot_func()", TrySymbolize((void *)(&hot_func))); >+ EXPECT_STREQ("startup_func()", TrySymbolize((void *)(&startup_func))); >+ EXPECT_STREQ("exit_func()", TrySymbolize((void *)(&exit_func))); >+ EXPECT_STREQ("regular_func()", TrySymbolize((void *)(®ular_func))); >+} >+ >+// Tests that verify that Symbolize stack footprint is within some limit. >+#ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION >+ >+static void *g_pc_to_symbolize; >+static char g_symbolize_buffer[4096]; >+static char *g_symbolize_result; >+ >+static void SymbolizeSignalHandler(int signo) { >+ if (absl::Symbolize(g_pc_to_symbolize, g_symbolize_buffer, >+ sizeof(g_symbolize_buffer))) { >+ g_symbolize_result = g_symbolize_buffer; >+ } else { >+ g_symbolize_result = nullptr; >+ } >+} >+ >+// Call Symbolize and figure out the stack footprint of this call. >+static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) { >+ g_pc_to_symbolize = pc; >+ *stack_consumed = absl::debugging_internal::GetSignalHandlerStackConsumption( >+ SymbolizeSignalHandler); >+ return g_symbolize_result; >+} >+ >+static int GetStackConsumptionUpperLimit() { >+ // Symbolize stack consumption should be within 2kB. >+ int stack_consumption_upper_limit = 2048; >+#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ >+ defined(THREAD_SANITIZER) >+ // Account for sanitizer instrumentation requiring additional stack space. >+ stack_consumption_upper_limit *= 5; >+#endif >+ return stack_consumption_upper_limit; >+} >+ >+TEST(Symbolize, SymbolizeStackConsumption) { >+ int stack_consumed = 0; >+ >+ const char *symbol = >+ SymbolizeStackConsumption((void *)(&nonstatic_func), &stack_consumed); >+ EXPECT_STREQ("nonstatic_func", symbol); >+ EXPECT_GT(stack_consumed, 0); >+ EXPECT_LT(stack_consumed, GetStackConsumptionUpperLimit()); >+ >+ // The name of an internal linkage symbol is not specified; allow either a >+ // mangled or an unmangled name here. >+ symbol = SymbolizeStackConsumption((void *)(&static_func), &stack_consumed); >+ EXPECT_TRUE(strcmp("static_func", symbol) == 0 || >+ strcmp("static_func()", symbol) == 0); >+ EXPECT_GT(stack_consumed, 0); >+ EXPECT_LT(stack_consumed, GetStackConsumptionUpperLimit()); >+} >+ >+TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) { >+ Foo::func(100); >+ int stack_consumed = 0; >+ >+ const char *symbol = >+ SymbolizeStackConsumption((void *)(&Foo::func), &stack_consumed); >+ >+ EXPECT_STREQ("Foo::func()", symbol); >+ EXPECT_GT(stack_consumed, 0); >+ EXPECT_LT(stack_consumed, GetStackConsumptionUpperLimit()); >+} >+ >+#endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION >+ >+// Use a 64K page size for PPC. >+const size_t kPageSize = 64 << 10; >+// We place a read-only symbols into the .text section and verify that we can >+// symbolize them and other symbols after remapping them. >+const char kPadding0[kPageSize * 4] ABSL_ATTRIBUTE_SECTION_VARIABLE(.text) = >+ ""; >+const char kPadding1[kPageSize * 4] ABSL_ATTRIBUTE_SECTION_VARIABLE(.text) = >+ ""; >+ >+static int FilterElfHeader(struct dl_phdr_info *info, size_t size, void *data) { >+ for (int i = 0; i < info->dlpi_phnum; i++) { >+ if (info->dlpi_phdr[i].p_type == PT_LOAD && >+ info->dlpi_phdr[i].p_flags == (PF_R | PF_X)) { >+ const void *const vaddr = >+ absl::bit_cast<void *>(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr); >+ const auto segsize = info->dlpi_phdr[i].p_memsz; >+ >+ const char *self_exe; >+ if (info->dlpi_name != nullptr && info->dlpi_name[0] != '\0') { >+ self_exe = info->dlpi_name; >+ } else { >+ self_exe = "/proc/self/exe"; >+ } >+ >+ absl::debugging_internal::RegisterFileMappingHint( >+ vaddr, reinterpret_cast<const char *>(vaddr) + segsize, >+ info->dlpi_phdr[i].p_offset, self_exe); >+ >+ return 1; >+ } >+ } >+ >+ return 1; >+} >+ >+TEST(Symbolize, SymbolizeWithMultipleMaps) { >+ // Force kPadding0 and kPadding1 to be linked in. >+ if (volatile_bool) { >+ ABSL_RAW_LOG(INFO, "%s", kPadding0); >+ ABSL_RAW_LOG(INFO, "%s", kPadding1); >+ } >+ >+ // Verify we can symbolize everything. >+ char buf[512]; >+ memset(buf, 0, sizeof(buf)); >+ absl::Symbolize(kPadding0, buf, sizeof(buf)); >+ EXPECT_STREQ("kPadding0", buf); >+ >+ memset(buf, 0, sizeof(buf)); >+ absl::Symbolize(kPadding1, buf, sizeof(buf)); >+ EXPECT_STREQ("kPadding1", buf); >+ >+ // Specify a hint for the executable segment. >+ dl_iterate_phdr(FilterElfHeader, nullptr); >+ >+ // Reload at least one page out of kPadding0, kPadding1 >+ const char *ptrs[] = {kPadding0, kPadding1}; >+ >+ for (const char *ptr : ptrs) { >+ const int kMapFlags = MAP_ANONYMOUS | MAP_PRIVATE; >+ void *addr = mmap(nullptr, kPageSize, PROT_READ, kMapFlags, 0, 0); >+ ASSERT_NE(addr, MAP_FAILED); >+ >+ // kPadding[0-1] is full of zeroes, so we can remap anywhere within it, but >+ // we ensure there is at least a full page of padding. >+ void *remapped = reinterpret_cast<void *>( >+ reinterpret_cast<uintptr_t>(ptr + kPageSize) & ~(kPageSize - 1ULL)); >+ >+ const int kMremapFlags = (MREMAP_MAYMOVE | MREMAP_FIXED); >+ void *ret = mremap(addr, kPageSize, kPageSize, kMremapFlags, remapped); >+ ASSERT_NE(ret, MAP_FAILED); >+ } >+ >+ // Invalidate the symbolization cache so we are forced to rely on the hint. >+ absl::Symbolize(nullptr, buf, sizeof(buf)); >+ >+ // Verify we can still symbolize. >+ const char *expected[] = {"kPadding0", "kPadding1"}; >+ const size_t offsets[] = {0, kPageSize, 2 * kPageSize, 3 * kPageSize}; >+ >+ for (int i = 0; i < 2; i++) { >+ for (size_t offset : offsets) { >+ memset(buf, 0, sizeof(buf)); >+ absl::Symbolize(ptrs[i] + offset, buf, sizeof(buf)); >+ EXPECT_STREQ(expected[i], buf); >+ } >+ } >+} >+ >+// Appends std::string(*args->arg) to args->symbol_buf. >+static void DummySymbolDecorator( >+ const absl::debugging_internal::SymbolDecoratorArgs *args) { >+ std::string *message = static_cast<std::string *>(args->arg); >+ strncat(args->symbol_buf, message->c_str(), >+ args->symbol_buf_size - strlen(args->symbol_buf) - 1); >+} >+ >+TEST(Symbolize, InstallAndRemoveSymbolDecorators) { >+ int ticket_a; >+ std::string a_message("a"); >+ EXPECT_GE(ticket_a = absl::debugging_internal::InstallSymbolDecorator( >+ DummySymbolDecorator, &a_message), >+ 0); >+ >+ int ticket_b; >+ std::string b_message("b"); >+ EXPECT_GE(ticket_b = absl::debugging_internal::InstallSymbolDecorator( >+ DummySymbolDecorator, &b_message), >+ 0); >+ >+ int ticket_c; >+ std::string c_message("c"); >+ EXPECT_GE(ticket_c = absl::debugging_internal::InstallSymbolDecorator( >+ DummySymbolDecorator, &c_message), >+ 0); >+ >+ char *address = reinterpret_cast<char *>(1); >+ EXPECT_STREQ("abc", TrySymbolize(address++)); >+ >+ EXPECT_TRUE(absl::debugging_internal::RemoveSymbolDecorator(ticket_b)); >+ >+ EXPECT_STREQ("ac", TrySymbolize(address++)); >+ >+ // Cleanup: remove all remaining decorators so other stack traces don't >+ // get mystery "ac" decoration. >+ EXPECT_TRUE(absl::debugging_internal::RemoveSymbolDecorator(ticket_a)); >+ EXPECT_TRUE(absl::debugging_internal::RemoveSymbolDecorator(ticket_c)); >+} >+ >+// Some versions of Clang with optimizations enabled seem to be able >+// to optimize away the .data section if no variables live in the >+// section. This variable should get placed in the .data section, and >+// the test below checks for the existence of a .data section. >+static int in_data_section = 1; >+ >+TEST(Symbolize, ForEachSection) { >+ int fd = TEMP_FAILURE_RETRY(open("/proc/self/exe", O_RDONLY)); >+ ASSERT_NE(fd, -1); >+ >+ std::vector<std::string> sections; >+ ASSERT_TRUE(absl::debugging_internal::ForEachSection( >+ fd, [§ions](const std::string &name, const ElfW(Shdr) &) { >+ sections.push_back(name); >+ return true; >+ })); >+ >+ // Check for the presence of common section names. >+ EXPECT_THAT(sections, Contains(".text")); >+ EXPECT_THAT(sections, Contains(".rodata")); >+ EXPECT_THAT(sections, Contains(".bss")); >+ ++in_data_section; >+ EXPECT_THAT(sections, Contains(".data")); >+ >+ close(fd); >+} >+ >+// x86 specific tests. Uses some inline assembler. >+extern "C" { >+inline void *ABSL_ATTRIBUTE_ALWAYS_INLINE inline_func() { >+ void *pc = nullptr; >+#if defined(__i386__) || defined(__x86_64__) >+ __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); >+#endif >+ return pc; >+} >+ >+void *ABSL_ATTRIBUTE_NOINLINE non_inline_func() { >+ void *pc = nullptr; >+#if defined(__i386__) || defined(__x86_64__) >+ __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); >+#endif >+ return pc; >+} >+ >+void ABSL_ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() { >+#if defined(ABSL_HAVE_ATTRIBUTE_NOINLINE) && \ >+ (defined(__i386__) || defined(__x86_64__)) >+ void *pc = non_inline_func(); >+ const char *symbol = TrySymbolize(pc); >+ ABSL_RAW_CHECK(symbol != nullptr, "TestWithPCInsideNonInlineFunction failed"); >+ ABSL_RAW_CHECK(strcmp(symbol, "non_inline_func") == 0, >+ "TestWithPCInsideNonInlineFunction failed"); >+ std::cout << "TestWithPCInsideNonInlineFunction passed" << std::endl; >+#endif >+} >+ >+void ABSL_ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() { >+#if defined(ABSL_HAVE_ATTRIBUTE_ALWAYS_INLINE) && \ >+ (defined(__i386__) || defined(__x86_64__)) >+ void *pc = inline_func(); // Must be inlined. >+ const char *symbol = TrySymbolize(pc); >+ ABSL_RAW_CHECK(symbol != nullptr, "TestWithPCInsideInlineFunction failed"); >+ ABSL_RAW_CHECK(strcmp(symbol, __FUNCTION__) == 0, >+ "TestWithPCInsideInlineFunction failed"); >+ std::cout << "TestWithPCInsideInlineFunction passed" << std::endl; >+#endif >+} >+} >+ >+// Test with a return address. >+void ABSL_ATTRIBUTE_NOINLINE TestWithReturnAddress() { >+#if defined(ABSL_HAVE_ATTRIBUTE_NOINLINE) >+ void *return_address = __builtin_return_address(0); >+ const char *symbol = TrySymbolize(return_address); >+ ABSL_RAW_CHECK(symbol != nullptr, "TestWithReturnAddress failed"); >+ ABSL_RAW_CHECK(strcmp(symbol, "main") == 0, "TestWithReturnAddress failed"); >+ std::cout << "TestWithReturnAddress passed" << std::endl; >+#endif >+} >+ >+#elif defined(_WIN32) && defined(_DEBUG) >+ >+TEST(Symbolize, Basics) { >+ EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func))); >+ >+ // The name of an internal linkage symbol is not specified; allow either a >+ // mangled or an unmangled name here. >+ const char* static_func_symbol = TrySymbolize((void *)(&static_func)); >+ ASSERT_TRUE(static_func_symbol != nullptr); >+ EXPECT_TRUE(strstr(static_func_symbol, "static_func") != nullptr); >+ >+ EXPECT_TRUE(nullptr == TrySymbolize(nullptr)); >+} >+ >+TEST(Symbolize, Truncation) { >+ constexpr char kNonStaticFunc[] = "nonstatic_func"; >+ EXPECT_STREQ("nonstatic_func", >+ TrySymbolizeWithLimit((void *)(&nonstatic_func), >+ strlen(kNonStaticFunc) + 1)); >+ EXPECT_STREQ("nonstatic_...", >+ TrySymbolizeWithLimit((void *)(&nonstatic_func), >+ strlen(kNonStaticFunc) + 0)); >+ EXPECT_STREQ("nonstatic...", >+ TrySymbolizeWithLimit((void *)(&nonstatic_func), >+ strlen(kNonStaticFunc) - 1)); >+ EXPECT_STREQ("n...", TrySymbolizeWithLimit((void *)(&nonstatic_func), 5)); >+ EXPECT_STREQ("...", TrySymbolizeWithLimit((void *)(&nonstatic_func), 4)); >+ EXPECT_STREQ("..", TrySymbolizeWithLimit((void *)(&nonstatic_func), 3)); >+ EXPECT_STREQ(".", TrySymbolizeWithLimit((void *)(&nonstatic_func), 2)); >+ EXPECT_STREQ("", TrySymbolizeWithLimit((void *)(&nonstatic_func), 1)); >+ EXPECT_EQ(nullptr, TrySymbolizeWithLimit((void *)(&nonstatic_func), 0)); >+} >+ >+TEST(Symbolize, SymbolizeWithDemangling) { >+ const char* result = TrySymbolize((void *)(&Foo::func)); >+ ASSERT_TRUE(result != nullptr); >+ EXPECT_TRUE(strstr(result, "Foo::func") != nullptr) << result; >+} >+ >+#else // Symbolizer unimplemented >+ >+TEST(Symbolize, Unimplemented) { >+ char buf[64]; >+ EXPECT_FALSE(absl::Symbolize((void *)(&nonstatic_func), buf, sizeof(buf))); >+ EXPECT_FALSE(absl::Symbolize((void *)(&static_func), buf, sizeof(buf))); >+ EXPECT_FALSE(absl::Symbolize((void *)(&Foo::func), buf, sizeof(buf))); >+} >+ >+#endif >+ >+int main(int argc, char **argv) { >+ // Make sure kHpageTextPadding is linked into the binary. >+ if (volatile_bool) { >+ ABSL_RAW_LOG(INFO, "%s", kHpageTextPadding); >+ } >+ >+#if ABSL_PER_THREAD_TLS >+ // Touch the per-thread variables. >+ symbolize_test_thread_small[0] = 0; >+ symbolize_test_thread_big[0] = 0; >+#endif >+ >+ absl::InitializeSymbolizer(argv[0]); >+ testing::InitGoogleTest(&argc, argv); >+ >+#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE >+ TestWithPCInsideInlineFunction(); >+ TestWithPCInsideNonInlineFunction(); >+ TestWithReturnAddress(); >+#endif >+ >+ return RUN_ALL_TESTS(); >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_unimplemented.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_unimplemented.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..2a3f4acb0e1a2d61d1eb18d4ba5e789593eb62ef >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_unimplemented.inc >@@ -0,0 +1,35 @@ >+// 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 <cstdint> >+ >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+ >+namespace debugging_internal { >+ >+int InstallSymbolDecorator(SymbolDecorator, void*) { return -1; } >+bool RemoveSymbolDecorator(int) { return false; } >+bool RemoveAllSymbolDecorators(void) { return false; } >+bool RegisterFileMappingHint(const void *, const void *, uint64_t, const char *) { >+ return false; >+} >+ >+} // namespace debugging_internal >+ >+void InitializeSymbolizer(const char*) {} >+bool Symbolize(const void *, char *, int) { return false; } >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..e3fff74d493ce35f01aed0bd0f5dadebbb638796 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc >@@ -0,0 +1,74 @@ >+// 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 "Retrieving Symbol Information by Address": >+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680578(v=vs.85).aspx >+ >+#include <windows.h> >+#include <DbgHelp.h> >+#pragma comment(lib, "DbgHelp") >+ >+#include <algorithm> >+#include <cstring> >+ >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+ >+static HANDLE process = NULL; >+ >+void InitializeSymbolizer(const char *argv0) { >+ if (process != nullptr) { >+ return; >+ } >+ process = GetCurrentProcess(); >+ >+ // Symbols are not loaded until a reference is made requiring the >+ // symbols be loaded. This is the fastest, most efficient way to use >+ // the symbol handler. >+ SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME); >+ if (!SymInitialize(process, nullptr, true)) { >+ // GetLastError() returns a Win32 DWORD, but we assign to >+ // unsigned long long to simplify the ABSL_RAW_LOG case below. The uniform >+ // initialization guarantees this is not a narrowing conversion. >+ const unsigned long long error{GetLastError()}; // NOLINT(runtime/int) >+ ABSL_RAW_LOG(FATAL, "SymInitialize() failed: %llu", error); >+ } >+} >+ >+bool Symbolize(const void *pc, char *out, int out_size) { >+ if (out_size <= 0) { >+ return false; >+ } >+ std::aligned_storage<sizeof(SYMBOL_INFO) + MAX_SYM_NAME, >+ alignof(SYMBOL_INFO)>::type buf; >+ SYMBOL_INFO *symbol = reinterpret_cast<SYMBOL_INFO *>(&buf); >+ symbol->SizeOfStruct = sizeof(SYMBOL_INFO); >+ symbol->MaxNameLen = MAX_SYM_NAME; >+ if (!SymFromAddr(process, reinterpret_cast<DWORD64>(pc), nullptr, symbol)) { >+ return false; >+ } >+ strncpy(out, symbol->Name, out_size); >+ if (out[out_size - 1] != '\0') { >+ // strncpy() does not '\0' terminate when it truncates. >+ static constexpr char kEllipsis[] = "..."; >+ int ellipsis_size = >+ std::min<int>(sizeof(kEllipsis) - 1, out_size - 1); >+ memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); >+ out[out_size - 1] = '\0'; >+ } >+ return true; >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..46f47b12bb2adb2f672fb050fb40d77ecf85bc21 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/BUILD.bazel >@@ -0,0 +1,61 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+ "ABSL_EXCEPTIONS_FLAG", >+) >+ >+package(default_visibility = ["//visibility:public"]) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+cc_library( >+ name = "memory", >+ hdrs = ["memory.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/base:core_headers", >+ "//absl/meta:type_traits", >+ ], >+) >+ >+cc_test( >+ name = "memory_test", >+ srcs = ["memory_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":memory", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "memory_exception_safety_test", >+ srcs = [ >+ "memory_exception_safety_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":memory", >+ "//absl/base:exception_safety_testing", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..30224c6a1124023c43eaa41b5496bdd1c337ae9a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/BUILD.gn >@@ -0,0 +1,31 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("memory") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "memory.h", >+ ] >+ deps = [ >+ "../base:core_headers", >+ "../meta:type_traits", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5958f5c52bfb6dacb01f181ab94f64b5ca6cff88 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/CMakeLists.txt >@@ -0,0 +1,71 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+list(APPEND MEMORY_PUBLIC_HEADERS >+ "memory.h" >+) >+ >+ >+absl_header_library( >+ TARGET >+ absl_memory >+ EXPORT_NAME >+ memory >+) >+ >+# >+## TESTS >+# >+ >+# test memory_test >+list(APPEND MEMORY_TEST_SRC >+ "memory_test.cc" >+ ${MEMORY_PUBLIC_HEADERS} >+) >+set(MEMORY_TEST_PUBLIC_LIBRARIES absl::base absl::memory) >+ >+ >+ >+absl_test( >+ TARGET >+ memory_test >+ SOURCES >+ ${MEMORY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${MEMORY_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test memory_exception_safety_test >+set(MEMORY_EXCEPTION_SAFETY_TEST_SRC "memory_exception_safety_test.cc") >+set(MEMORY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES >+ absl::memory >+ absl_base_internal_exception_safety_testing >+) >+ >+absl_test( >+ TARGET >+ memory_exception_safety_test >+ SOURCES >+ ${MEMORY_EXCEPTION_SAFETY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${MEMORY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES} >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+) >+ >+ >+ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/memory.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/memory.h >new file mode 100644 >index 0000000000000000000000000000000000000000..4d9cc0075df61878256aa679dedb6d3ab0ed9124 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/memory.h >@@ -0,0 +1,697 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: memory.h >+// ----------------------------------------------------------------------------- >+// >+// This header file contains utility functions for managing the creation and >+// conversion of smart pointers. This file is an extension to the C++ >+// standard <memory> library header file. >+ >+#ifndef ABSL_MEMORY_MEMORY_H_ >+#define ABSL_MEMORY_MEMORY_H_ >+ >+#include <cstddef> >+#include <limits> >+#include <memory> >+#include <new> >+#include <type_traits> >+#include <utility> >+ >+#include "absl/base/macros.h" >+#include "absl/meta/type_traits.h" >+ >+namespace absl { >+ >+// ----------------------------------------------------------------------------- >+// Function Template: WrapUnique() >+// ----------------------------------------------------------------------------- >+// >+// Adopts ownership from a raw pointer and transfers it to the returned >+// `std::unique_ptr`, whose type is deduced. DO NOT specify the template type T >+// when calling WrapUnique. >+// >+// Example: >+// X* NewX(int, int); >+// auto x = WrapUnique(NewX(1, 2)); // 'x' is std::unique_ptr<X>. >+// >+// `absl::WrapUnique` is useful for capturing the output of a raw pointer >+// factory. However, prefer 'absl::make_unique<T>(args...) over >+// 'absl::WrapUnique(new T(args...))'. >+// >+// auto x = WrapUnique(new X(1, 2)); // works, but nonideal. >+// auto x = make_unique<X>(1, 2); // safer, standard, avoids raw 'new'. >+// >+// Note that `absl::WrapUnique(p)` is valid only if `delete p` is a valid >+// expression. In particular, `absl::WrapUnique()` cannot wrap pointers to >+// arrays, functions or void, and it must not be used to capture pointers >+// obtained from array-new expressions (even though that would compile!). >+template <typename T> >+std::unique_ptr<T> WrapUnique(T* ptr) { >+ static_assert(!std::is_array<T>::value, "array types are unsupported"); >+ static_assert(std::is_object<T>::value, "non-object types are unsupported"); >+ return std::unique_ptr<T>(ptr); >+} >+ >+namespace memory_internal { >+ >+// Traits to select proper overload and return type for `absl::make_unique<>`. >+template <typename T> >+struct MakeUniqueResult { >+ using scalar = std::unique_ptr<T>; >+}; >+template <typename T> >+struct MakeUniqueResult<T[]> { >+ using array = std::unique_ptr<T[]>; >+}; >+template <typename T, size_t N> >+struct MakeUniqueResult<T[N]> { >+ using invalid = void; >+}; >+ >+} // namespace memory_internal >+ >+// gcc 4.8 has __cplusplus at 201301 but doesn't define make_unique. Other >+// supported compilers either just define __cplusplus as 201103 but have >+// make_unique (msvc), or have make_unique whenever __cplusplus > 201103 (clang) >+#if (__cplusplus > 201103L || defined(_MSC_VER)) && \ >+ !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8) >+using std::make_unique; >+#else >+// ----------------------------------------------------------------------------- >+// Function Template: make_unique<T>() >+// ----------------------------------------------------------------------------- >+// >+// Creates a `std::unique_ptr<>`, while avoiding issues creating temporaries >+// during the construction process. `absl::make_unique<>` also avoids redundant >+// type declarations, by avoiding the need to explicitly use the `new` operator. >+// >+// This implementation of `absl::make_unique<>` is designed for C++11 code and >+// will be replaced in C++14 by the equivalent `std::make_unique<>` abstraction. >+// `absl::make_unique<>` is designed to be 100% compatible with >+// `std::make_unique<>` so that the eventual migration will involve a simple >+// rename operation. >+// >+// For more background on why `std::unique_ptr<T>(new T(a,b))` is problematic, >+// see Herb Sutter's explanation on >+// (Exception-Safe Function Calls)[http://herbsutter.com/gotw/_102/]. >+// (In general, reviewers should treat `new T(a,b)` with scrutiny.) >+// >+// Example usage: >+// >+// auto p = make_unique<X>(args...); // 'p' is a std::unique_ptr<X> >+// auto pa = make_unique<X[]>(5); // 'pa' is a std::unique_ptr<X[]> >+// >+// Three overloads of `absl::make_unique` are required: >+// >+// - For non-array T: >+// >+// Allocates a T with `new T(std::forward<Args> args...)`, >+// forwarding all `args` to T's constructor. >+// Returns a `std::unique_ptr<T>` owning that object. >+// >+// - For an array of unknown bounds T[]: >+// >+// `absl::make_unique<>` will allocate an array T of type U[] with >+// `new U[n]()` and return a `std::unique_ptr<U[]>` owning that array. >+// >+// Note that 'U[n]()' is different from 'U[n]', and elements will be >+// value-initialized. Note as well that `std::unique_ptr` will perform its >+// own destruction of the array elements upon leaving scope, even though >+// the array [] does not have a default destructor. >+// >+// NOTE: an array of unknown bounds T[] may still be (and often will be) >+// initialized to have a size, and will still use this overload. E.g: >+// >+// auto my_array = absl::make_unique<int[]>(10); >+// >+// - For an array of known bounds T[N]: >+// >+// `absl::make_unique<>` is deleted (like with `std::make_unique<>`) as >+// this overload is not useful. >+// >+// NOTE: an array of known bounds T[N] is not considered a useful >+// construction, and may cause undefined behavior in templates. E.g: >+// >+// auto my_array = absl::make_unique<int[10]>(); >+// >+// In those cases, of course, you can still use the overload above and >+// simply initialize it to its desired size: >+// >+// auto my_array = absl::make_unique<int[]>(10); >+ >+// `absl::make_unique` overload for non-array types. >+template <typename T, typename... Args> >+typename memory_internal::MakeUniqueResult<T>::scalar make_unique( >+ Args&&... args) { >+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); >+} >+ >+// `absl::make_unique` overload for an array T[] of unknown bounds. >+// The array allocation needs to use the `new T[size]` form and cannot take >+// element constructor arguments. The `std::unique_ptr` will manage destructing >+// these array elements. >+template <typename T> >+typename memory_internal::MakeUniqueResult<T>::array make_unique(size_t n) { >+ return std::unique_ptr<T>(new typename absl::remove_extent_t<T>[n]()); >+} >+ >+// `absl::make_unique` overload for an array T[N] of known bounds. >+// This construction will be rejected. >+template <typename T, typename... Args> >+typename memory_internal::MakeUniqueResult<T>::invalid make_unique( >+ Args&&... /* args */) = delete; >+#endif >+ >+// ----------------------------------------------------------------------------- >+// Function Template: RawPtr() >+// ----------------------------------------------------------------------------- >+// >+// Extracts the raw pointer from a pointer-like value `ptr`. `absl::RawPtr` is >+// useful within templates that need to handle a complement of raw pointers, >+// `std::nullptr_t`, and smart pointers. >+template <typename T> >+auto RawPtr(T&& ptr) -> decltype(std::addressof(*ptr)) { >+ // ptr is a forwarding reference to support Ts with non-const operators. >+ return (ptr != nullptr) ? std::addressof(*ptr) : nullptr; >+} >+inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; } >+ >+// ----------------------------------------------------------------------------- >+// Function Template: ShareUniquePtr() >+// ----------------------------------------------------------------------------- >+// >+// Adopts a `std::unique_ptr` rvalue and returns a `std::shared_ptr` of deduced >+// type. Ownership (if any) of the held value is transferred to the returned >+// shared pointer. >+// >+// Example: >+// >+// auto up = absl::make_unique<int>(10); >+// auto sp = absl::ShareUniquePtr(std::move(up)); // shared_ptr<int> >+// CHECK_EQ(*sp, 10); >+// CHECK(up == nullptr); >+// >+// Note that this conversion is correct even when T is an array type, and more >+// generally it works for *any* deleter of the `unique_ptr` (single-object >+// deleter, array deleter, or any custom deleter), since the deleter is adopted >+// by the shared pointer as well. The deleter is copied (unless it is a >+// reference). >+// >+// Implements the resolution of [LWG 2415](http://wg21.link/lwg2415), by which a >+// null shared pointer does not attempt to call the deleter. >+template <typename T, typename D> >+std::shared_ptr<T> ShareUniquePtr(std::unique_ptr<T, D>&& ptr) { >+ return ptr ? std::shared_ptr<T>(std::move(ptr)) : std::shared_ptr<T>(); >+} >+ >+// ----------------------------------------------------------------------------- >+// Function Template: WeakenPtr() >+// ----------------------------------------------------------------------------- >+// >+// Creates a weak pointer associated with a given shared pointer. The returned >+// value is a `std::weak_ptr` of deduced type. >+// >+// Example: >+// >+// auto sp = std::make_shared<int>(10); >+// auto wp = absl::WeakenPtr(sp); >+// CHECK_EQ(sp.get(), wp.lock().get()); >+// sp.reset(); >+// CHECK(wp.lock() == nullptr); >+// >+template <typename T> >+std::weak_ptr<T> WeakenPtr(const std::shared_ptr<T>& ptr) { >+ return std::weak_ptr<T>(ptr); >+} >+ >+namespace memory_internal { >+ >+// ExtractOr<E, O, D>::type evaluates to E<O> if possible. Otherwise, D. >+template <template <typename> class Extract, typename Obj, typename Default, >+ typename> >+struct ExtractOr { >+ using type = Default; >+}; >+ >+template <template <typename> class Extract, typename Obj, typename Default> >+struct ExtractOr<Extract, Obj, Default, void_t<Extract<Obj>>> { >+ using type = Extract<Obj>; >+}; >+ >+template <template <typename> class Extract, typename Obj, typename Default> >+using ExtractOrT = typename ExtractOr<Extract, Obj, Default, void>::type; >+ >+// Extractors for the features of allocators. >+template <typename T> >+using GetPointer = typename T::pointer; >+ >+template <typename T> >+using GetConstPointer = typename T::const_pointer; >+ >+template <typename T> >+using GetVoidPointer = typename T::void_pointer; >+ >+template <typename T> >+using GetConstVoidPointer = typename T::const_void_pointer; >+ >+template <typename T> >+using GetDifferenceType = typename T::difference_type; >+ >+template <typename T> >+using GetSizeType = typename T::size_type; >+ >+template <typename T> >+using GetPropagateOnContainerCopyAssignment = >+ typename T::propagate_on_container_copy_assignment; >+ >+template <typename T> >+using GetPropagateOnContainerMoveAssignment = >+ typename T::propagate_on_container_move_assignment; >+ >+template <typename T> >+using GetPropagateOnContainerSwap = typename T::propagate_on_container_swap; >+ >+template <typename T> >+using GetIsAlwaysEqual = typename T::is_always_equal; >+ >+template <typename T> >+struct GetFirstArg; >+ >+template <template <typename...> class Class, typename T, typename... Args> >+struct GetFirstArg<Class<T, Args...>> { >+ using type = T; >+}; >+ >+template <typename Ptr, typename = void> >+struct ElementType { >+ using type = typename GetFirstArg<Ptr>::type; >+}; >+ >+template <typename T> >+struct ElementType<T, void_t<typename T::element_type>> { >+ using type = typename T::element_type; >+}; >+ >+template <typename T, typename U> >+struct RebindFirstArg; >+ >+template <template <typename...> class Class, typename T, typename... Args, >+ typename U> >+struct RebindFirstArg<Class<T, Args...>, U> { >+ using type = Class<U, Args...>; >+}; >+ >+template <typename T, typename U, typename = void> >+struct RebindPtr { >+ using type = typename RebindFirstArg<T, U>::type; >+}; >+ >+template <typename T, typename U> >+struct RebindPtr<T, U, void_t<typename T::template rebind<U>>> { >+ using type = typename T::template rebind<U>; >+}; >+ >+template <typename T, typename U> >+constexpr bool HasRebindAlloc(...) { >+ return false; >+} >+ >+template <typename T, typename U> >+constexpr bool HasRebindAlloc(typename T::template rebind<U>::other*) { >+ return true; >+} >+ >+template <typename T, typename U, bool = HasRebindAlloc<T, U>(nullptr)> >+struct RebindAlloc { >+ using type = typename RebindFirstArg<T, U>::type; >+}; >+ >+template <typename T, typename U> >+struct RebindAlloc<T, U, true> { >+ using type = typename T::template rebind<U>::other; >+}; >+ >+} // namespace memory_internal >+ >+// ----------------------------------------------------------------------------- >+// Class Template: pointer_traits >+// ----------------------------------------------------------------------------- >+// >+// An implementation of C++11's std::pointer_traits. >+// >+// Provided for portability on toolchains that have a working C++11 compiler, >+// but the standard library is lacking in C++11 support. For example, some >+// version of the Android NDK. >+// >+ >+template <typename Ptr> >+struct pointer_traits { >+ using pointer = Ptr; >+ >+ // element_type: >+ // Ptr::element_type if present. Otherwise T if Ptr is a template >+ // instantiation Template<T, Args...> >+ using element_type = typename memory_internal::ElementType<Ptr>::type; >+ >+ // difference_type: >+ // Ptr::difference_type if present, otherwise std::ptrdiff_t >+ using difference_type = >+ memory_internal::ExtractOrT<memory_internal::GetDifferenceType, Ptr, >+ std::ptrdiff_t>; >+ >+ // rebind: >+ // Ptr::rebind<U> if exists, otherwise Template<U, Args...> if Ptr is a >+ // template instantiation Template<T, Args...> >+ template <typename U> >+ using rebind = typename memory_internal::RebindPtr<Ptr, U>::type; >+ >+ // pointer_to: >+ // Calls Ptr::pointer_to(r) >+ static pointer pointer_to(element_type& r) { // NOLINT(runtime/references) >+ return Ptr::pointer_to(r); >+ } >+}; >+ >+// Specialization for T*. >+template <typename T> >+struct pointer_traits<T*> { >+ using pointer = T*; >+ using element_type = T; >+ using difference_type = std::ptrdiff_t; >+ >+ template <typename U> >+ using rebind = U*; >+ >+ // pointer_to: >+ // Calls std::addressof(r) >+ static pointer pointer_to( >+ element_type& r) noexcept { // NOLINT(runtime/references) >+ return std::addressof(r); >+ } >+}; >+ >+// ----------------------------------------------------------------------------- >+// Class Template: allocator_traits >+// ----------------------------------------------------------------------------- >+// >+// A C++11 compatible implementation of C++17's std::allocator_traits. >+// >+template <typename Alloc> >+struct allocator_traits { >+ using allocator_type = Alloc; >+ >+ // value_type: >+ // Alloc::value_type >+ using value_type = typename Alloc::value_type; >+ >+ // pointer: >+ // Alloc::pointer if present, otherwise value_type* >+ using pointer = memory_internal::ExtractOrT<memory_internal::GetPointer, >+ Alloc, value_type*>; >+ >+ // const_pointer: >+ // Alloc::const_pointer if present, otherwise >+ // absl::pointer_traits<pointer>::rebind<const value_type> >+ using const_pointer = >+ memory_internal::ExtractOrT<memory_internal::GetConstPointer, Alloc, >+ typename absl::pointer_traits<pointer>:: >+ template rebind<const value_type>>; >+ >+ // void_pointer: >+ // Alloc::void_pointer if present, otherwise >+ // absl::pointer_traits<pointer>::rebind<void> >+ using void_pointer = memory_internal::ExtractOrT< >+ memory_internal::GetVoidPointer, Alloc, >+ typename absl::pointer_traits<pointer>::template rebind<void>>; >+ >+ // const_void_pointer: >+ // Alloc::const_void_pointer if present, otherwise >+ // absl::pointer_traits<pointer>::rebind<const void> >+ using const_void_pointer = memory_internal::ExtractOrT< >+ memory_internal::GetConstVoidPointer, Alloc, >+ typename absl::pointer_traits<pointer>::template rebind<const void>>; >+ >+ // difference_type: >+ // Alloc::difference_type if present, otherwise >+ // absl::pointer_traits<pointer>::difference_type >+ using difference_type = memory_internal::ExtractOrT< >+ memory_internal::GetDifferenceType, Alloc, >+ typename absl::pointer_traits<pointer>::difference_type>; >+ >+ // size_type: >+ // Alloc::size_type if present, otherwise >+ // std::make_unsigned<difference_type>::type >+ using size_type = memory_internal::ExtractOrT< >+ memory_internal::GetSizeType, Alloc, >+ typename std::make_unsigned<difference_type>::type>; >+ >+ // propagate_on_container_copy_assignment: >+ // Alloc::propagate_on_container_copy_assignment if present, otherwise >+ // std::false_type >+ using propagate_on_container_copy_assignment = memory_internal::ExtractOrT< >+ memory_internal::GetPropagateOnContainerCopyAssignment, Alloc, >+ std::false_type>; >+ >+ // propagate_on_container_move_assignment: >+ // Alloc::propagate_on_container_move_assignment if present, otherwise >+ // std::false_type >+ using propagate_on_container_move_assignment = memory_internal::ExtractOrT< >+ memory_internal::GetPropagateOnContainerMoveAssignment, Alloc, >+ std::false_type>; >+ >+ // propagate_on_container_swap: >+ // Alloc::propagate_on_container_swap if present, otherwise std::false_type >+ using propagate_on_container_swap = >+ memory_internal::ExtractOrT<memory_internal::GetPropagateOnContainerSwap, >+ Alloc, std::false_type>; >+ >+ // is_always_equal: >+ // Alloc::is_always_equal if present, otherwise std::is_empty<Alloc>::type >+ using is_always_equal = >+ memory_internal::ExtractOrT<memory_internal::GetIsAlwaysEqual, Alloc, >+ typename std::is_empty<Alloc>::type>; >+ >+ // rebind_alloc: >+ // Alloc::rebind<T>::other if present, otherwise Alloc<T, Args> if this Alloc >+ // is Alloc<U, Args> >+ template <typename T> >+ using rebind_alloc = typename memory_internal::RebindAlloc<Alloc, T>::type; >+ >+ // rebind_traits: >+ // absl::allocator_traits<rebind_alloc<T>> >+ template <typename T> >+ using rebind_traits = absl::allocator_traits<rebind_alloc<T>>; >+ >+ // allocate(Alloc& a, size_type n): >+ // Calls a.allocate(n) >+ static pointer allocate(Alloc& a, // NOLINT(runtime/references) >+ size_type n) { >+ return a.allocate(n); >+ } >+ >+ // allocate(Alloc& a, size_type n, const_void_pointer hint): >+ // Calls a.allocate(n, hint) if possible. >+ // If not possible, calls a.allocate(n) >+ static pointer allocate(Alloc& a, size_type n, // NOLINT(runtime/references) >+ const_void_pointer hint) { >+ return allocate_impl(0, a, n, hint); >+ } >+ >+ // deallocate(Alloc& a, pointer p, size_type n): >+ // Calls a.deallocate(p, n) >+ static void deallocate(Alloc& a, pointer p, // NOLINT(runtime/references) >+ size_type n) { >+ a.deallocate(p, n); >+ } >+ >+ // construct(Alloc& a, T* p, Args&&... args): >+ // Calls a.construct(p, std::forward<Args>(args)...) if possible. >+ // If not possible, calls >+ // ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...) >+ template <typename T, typename... Args> >+ static void construct(Alloc& a, T* p, // NOLINT(runtime/references) >+ Args&&... args) { >+ construct_impl(0, a, p, std::forward<Args>(args)...); >+ } >+ >+ // destroy(Alloc& a, T* p): >+ // Calls a.destroy(p) if possible. If not possible, calls p->~T(). >+ template <typename T> >+ static void destroy(Alloc& a, T* p) { // NOLINT(runtime/references) >+ destroy_impl(0, a, p); >+ } >+ >+ // max_size(const Alloc& a): >+ // Returns a.max_size() if possible. If not possible, returns >+ // std::numeric_limits<size_type>::max() / sizeof(value_type) >+ static size_type max_size(const Alloc& a) { return max_size_impl(0, a); } >+ >+ // select_on_container_copy_construction(const Alloc& a): >+ // Returns a.select_on_container_copy_construction() if possible. >+ // If not possible, returns a. >+ static Alloc select_on_container_copy_construction(const Alloc& a) { >+ return select_on_container_copy_construction_impl(0, a); >+ } >+ >+ private: >+ template <typename A> >+ static auto allocate_impl(int, A& a, // NOLINT(runtime/references) >+ size_type n, const_void_pointer hint) >+ -> decltype(a.allocate(n, hint)) { >+ return a.allocate(n, hint); >+ } >+ static pointer allocate_impl(char, Alloc& a, // NOLINT(runtime/references) >+ size_type n, const_void_pointer) { >+ return a.allocate(n); >+ } >+ >+ template <typename A, typename... Args> >+ static auto construct_impl(int, A& a, // NOLINT(runtime/references) >+ Args&&... args) >+ -> decltype(a.construct(std::forward<Args>(args)...)) { >+ a.construct(std::forward<Args>(args)...); >+ } >+ >+ template <typename T, typename... Args> >+ static void construct_impl(char, Alloc&, T* p, Args&&... args) { >+ ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...); >+ } >+ >+ template <typename A, typename T> >+ static auto destroy_impl(int, A& a, // NOLINT(runtime/references) >+ T* p) -> decltype(a.destroy(p)) { >+ a.destroy(p); >+ } >+ template <typename T> >+ static void destroy_impl(char, Alloc&, T* p) { >+ p->~T(); >+ } >+ >+ template <typename A> >+ static auto max_size_impl(int, const A& a) -> decltype(a.max_size()) { >+ return a.max_size(); >+ } >+ static size_type max_size_impl(char, const Alloc&) { >+ return std::numeric_limits<size_type>::max() / sizeof(value_type); >+ } >+ >+ template <typename A> >+ static auto select_on_container_copy_construction_impl(int, const A& a) >+ -> decltype(a.select_on_container_copy_construction()) { >+ return a.select_on_container_copy_construction(); >+ } >+ static Alloc select_on_container_copy_construction_impl(char, >+ const Alloc& a) { >+ return a; >+ } >+}; >+ >+namespace memory_internal { >+ >+// This template alias transforms Alloc::is_nothrow into a metafunction with >+// Alloc as a parameter so it can be used with ExtractOrT<>. >+template <typename Alloc> >+using GetIsNothrow = typename Alloc::is_nothrow; >+ >+} // namespace memory_internal >+ >+// ABSL_ALLOCATOR_NOTHROW is a build time configuration macro for user to >+// specify whether the default allocation function can throw or never throws. >+// If the allocation function never throws, user should define it to a non-zero >+// value (e.g. via `-DABSL_ALLOCATOR_NOTHROW`). >+// If the allocation function can throw, user should leave it undefined or >+// define it to zero. >+// >+// allocator_is_nothrow<Alloc> is a traits class that derives from >+// Alloc::is_nothrow if present, otherwise std::false_type. It's specialized >+// for Alloc = std::allocator<T> for any type T according to the state of >+// ABSL_ALLOCATOR_NOTHROW. >+// >+// default_allocator_is_nothrow is a class that derives from std::true_type >+// when the default allocator (global operator new) never throws, and >+// std::false_type when it can throw. It is a convenience shorthand for writing >+// allocator_is_nothrow<std::allocator<T>> (T can be any type). >+// NOTE: allocator_is_nothrow<std::allocator<T>> is guaranteed to derive from >+// the same type for all T, because users should specialize neither >+// allocator_is_nothrow nor std::allocator. >+template <typename Alloc> >+struct allocator_is_nothrow >+ : memory_internal::ExtractOrT<memory_internal::GetIsNothrow, Alloc, >+ std::false_type> {}; >+ >+// FIXME: Define ABSL_ALLOCATOR_NOTHROW >+#if 1 >+template <typename T> >+struct allocator_is_nothrow<std::allocator<T>> : std::true_type {}; >+struct default_allocator_is_nothrow : std::true_type {}; >+#else >+struct default_allocator_is_nothrow : std::false_type {}; >+#endif >+ >+namespace memory_internal { >+#ifdef ABSL_HAVE_EXCEPTIONS >+template <typename Allocator, typename StorageElement, typename... Args> >+void ConstructStorage(Allocator* alloc, StorageElement* first, >+ StorageElement* last, const Args&... args) { >+ for (StorageElement* cur = first; cur != last; ++cur) { >+ try { >+ std::allocator_traits<Allocator>::construct(*alloc, cur, args...); >+ } catch (...) { >+ while (cur != first) { >+ --cur; >+ std::allocator_traits<Allocator>::destroy(*alloc, cur); >+ } >+ throw; >+ } >+ } >+} >+template <typename Allocator, typename StorageElement, typename Iterator> >+void CopyToStorageFromRange(Allocator* alloc, StorageElement* destination, >+ Iterator first, Iterator last) { >+ for (StorageElement* cur = destination; first != last; >+ static_cast<void>(++cur), static_cast<void>(++first)) { >+ try { >+ std::allocator_traits<Allocator>::construct(*alloc, cur, *first); >+ } catch (...) { >+ while (cur != destination) { >+ --cur; >+ std::allocator_traits<Allocator>::destroy(*alloc, cur); >+ } >+ throw; >+ } >+ } >+} >+#else // ABSL_HAVE_EXCEPTIONS >+template <typename Allocator, typename StorageElement, typename... Args> >+void ConstructStorage(Allocator* alloc, StorageElement* first, >+ StorageElement* last, const Args&... args) { >+ for (; first != last; ++first) { >+ std::allocator_traits<Allocator>::construct(*alloc, first, args...); >+ } >+} >+template <typename Allocator, typename StorageElement, typename Iterator> >+void CopyToStorageFromRange(Allocator* alloc, StorageElement* destination, >+ Iterator first, Iterator last) { >+ for (; first != last; >+ static_cast<void>(++destination), static_cast<void>(++first)) { >+ std::allocator_traits<Allocator>::construct(*alloc, destination, *first); >+ } >+} >+#endif // ABSL_HAVE_EXCEPTIONS >+} // namespace memory_internal >+} // namespace absl >+ >+#endif // ABSL_MEMORY_MEMORY_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/memory_exception_safety_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/memory_exception_safety_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..d1f6e84f10f8a668ac25fb6d90ccc5a783202219 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/memory_exception_safety_test.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. >+ >+#include "absl/memory/memory.h" >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/exception_safety_testing.h" >+ >+namespace absl { >+namespace { >+ >+constexpr int kLength = 50; >+using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>; >+using ThrowerStorage = >+ absl::aligned_storage_t<sizeof(Thrower), alignof(Thrower)>; >+using ThrowerList = std::array<ThrowerStorage, kLength>; >+ >+TEST(MakeUnique, CheckForLeaks) { >+ constexpr int kValue = 321; >+ auto tester = testing::MakeExceptionSafetyTester() >+ .WithInitialValue(Thrower(kValue)) >+ // Ensures make_unique does not modify the input. The real >+ // test, though, is ConstructorTracker checking for leaks. >+ .WithInvariants(testing::strong_guarantee); >+ >+ EXPECT_TRUE(tester.Test([](Thrower* thrower) { >+ static_cast<void>(absl::make_unique<Thrower>(*thrower)); >+ })); >+ >+ EXPECT_TRUE(tester.Test([](Thrower* thrower) { >+ static_cast<void>(absl::make_unique<Thrower>(std::move(*thrower))); >+ })); >+ >+ // Test T[n] overload >+ EXPECT_TRUE(tester.Test([&](Thrower*) { >+ static_cast<void>(absl::make_unique<Thrower[]>(kLength)); >+ })); >+} >+ >+} // namespace >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/memory_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/memory_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..dee9b486a30d30d255705ac3814f19f781994053 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/memory/memory_test.cc >@@ -0,0 +1,614 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Tests for pointer utilities. >+ >+#include "absl/memory/memory.h" >+ >+#include <sys/types.h> >+#include <cstddef> >+#include <memory> >+#include <string> >+#include <type_traits> >+#include <utility> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+ >+namespace { >+ >+using ::testing::ElementsAre; >+using ::testing::Return; >+ >+// This class creates observable behavior to verify that a destructor has >+// been called, via the instance_count variable. >+class DestructorVerifier { >+ public: >+ DestructorVerifier() { ++instance_count_; } >+ DestructorVerifier(const DestructorVerifier&) = delete; >+ DestructorVerifier& operator=(const DestructorVerifier&) = delete; >+ ~DestructorVerifier() { --instance_count_; } >+ >+ // The number of instances of this class currently active. >+ static int instance_count() { return instance_count_; } >+ >+ private: >+ // The number of instances of this class currently active. >+ static int instance_count_; >+}; >+ >+int DestructorVerifier::instance_count_ = 0; >+ >+TEST(WrapUniqueTest, WrapUnique) { >+ // Test that the unique_ptr is constructed properly by verifying that the >+ // destructor for its payload gets called at the proper time. >+ { >+ auto dv = new DestructorVerifier; >+ EXPECT_EQ(1, DestructorVerifier::instance_count()); >+ std::unique_ptr<DestructorVerifier> ptr = absl::WrapUnique(dv); >+ EXPECT_EQ(1, DestructorVerifier::instance_count()); >+ } >+ EXPECT_EQ(0, DestructorVerifier::instance_count()); >+} >+TEST(MakeUniqueTest, Basic) { >+ std::unique_ptr<std::string> p = absl::make_unique<std::string>(); >+ EXPECT_EQ("", *p); >+ p = absl::make_unique<std::string>("hi"); >+ EXPECT_EQ("hi", *p); >+} >+ >+struct MoveOnly { >+ MoveOnly() = default; >+ explicit MoveOnly(int i1) : ip1{new int{i1}} {} >+ MoveOnly(int i1, int i2) : ip1{new int{i1}}, ip2{new int{i2}} {} >+ std::unique_ptr<int> ip1; >+ std::unique_ptr<int> ip2; >+}; >+ >+struct AcceptMoveOnly { >+ explicit AcceptMoveOnly(MoveOnly m) : m_(std::move(m)) {} >+ MoveOnly m_; >+}; >+ >+TEST(MakeUniqueTest, MoveOnlyTypeAndValue) { >+ using ExpectedType = std::unique_ptr<MoveOnly>; >+ { >+ auto p = absl::make_unique<MoveOnly>(); >+ static_assert(std::is_same<decltype(p), ExpectedType>::value, >+ "unexpected return type"); >+ EXPECT_TRUE(!p->ip1); >+ EXPECT_TRUE(!p->ip2); >+ } >+ { >+ auto p = absl::make_unique<MoveOnly>(1); >+ static_assert(std::is_same<decltype(p), ExpectedType>::value, >+ "unexpected return type"); >+ EXPECT_TRUE(p->ip1 && *p->ip1 == 1); >+ EXPECT_TRUE(!p->ip2); >+ } >+ { >+ auto p = absl::make_unique<MoveOnly>(1, 2); >+ static_assert(std::is_same<decltype(p), ExpectedType>::value, >+ "unexpected return type"); >+ EXPECT_TRUE(p->ip1 && *p->ip1 == 1); >+ EXPECT_TRUE(p->ip2 && *p->ip2 == 2); >+ } >+} >+ >+TEST(MakeUniqueTest, AcceptMoveOnly) { >+ auto p = absl::make_unique<AcceptMoveOnly>(MoveOnly()); >+ p = std::unique_ptr<AcceptMoveOnly>(new AcceptMoveOnly(MoveOnly())); >+} >+ >+struct ArrayWatch { >+ void* operator new[](size_t n) { >+ allocs().push_back(n); >+ return ::operator new[](n); >+ } >+ void operator delete[](void* p) { >+ return ::operator delete[](p); >+ } >+ static std::vector<size_t>& allocs() { >+ static auto& v = *new std::vector<size_t>; >+ return v; >+ } >+}; >+ >+TEST(Make_UniqueTest, Array) { >+ // Ensure state is clean before we start so that these tests >+ // are order-agnostic. >+ ArrayWatch::allocs().clear(); >+ >+ auto p = absl::make_unique<ArrayWatch[]>(5); >+ static_assert(std::is_same<decltype(p), >+ std::unique_ptr<ArrayWatch[]>>::value, >+ "unexpected return type"); >+ EXPECT_THAT(ArrayWatch::allocs(), ElementsAre(5 * sizeof(ArrayWatch))); >+} >+ >+TEST(Make_UniqueTest, NotAmbiguousWithStdMakeUnique) { >+ // Ensure that absl::make_unique is not ambiguous with std::make_unique. >+ // In C++14 mode, the below call to make_unique has both types as candidates. >+ struct TakesStdType { >+ explicit TakesStdType(const std::vector<int> &vec) {} >+ }; >+ using absl::make_unique; >+ make_unique<TakesStdType>(std::vector<int>()); >+} >+ >+#if 0 >+// TODO(billydonahue): Make a proper NC test. >+// These tests shouldn't compile. >+TEST(MakeUniqueTestNC, AcceptMoveOnlyLvalue) { >+ auto m = MoveOnly(); >+ auto p = absl::make_unique<AcceptMoveOnly>(m); >+} >+TEST(MakeUniqueTestNC, KnownBoundArray) { >+ auto p = absl::make_unique<ArrayWatch[5]>(); >+} >+#endif >+ >+TEST(RawPtrTest, RawPointer) { >+ int i = 5; >+ EXPECT_EQ(&i, absl::RawPtr(&i)); >+} >+ >+TEST(RawPtrTest, SmartPointer) { >+ int* o = new int(5); >+ std::unique_ptr<int> p(o); >+ EXPECT_EQ(o, absl::RawPtr(p)); >+} >+ >+class IntPointerNonConstDeref { >+ public: >+ explicit IntPointerNonConstDeref(int* p) : p_(p) {} >+ friend bool operator!=(const IntPointerNonConstDeref& a, std::nullptr_t) { >+ return a.p_ != nullptr; >+ } >+ int& operator*() { return *p_; } >+ >+ private: >+ std::unique_ptr<int> p_; >+}; >+ >+TEST(RawPtrTest, SmartPointerNonConstDereference) { >+ int* o = new int(5); >+ IntPointerNonConstDeref p(o); >+ EXPECT_EQ(o, absl::RawPtr(p)); >+} >+ >+TEST(RawPtrTest, NullValuedRawPointer) { >+ int* p = nullptr; >+ EXPECT_EQ(nullptr, absl::RawPtr(p)); >+} >+ >+TEST(RawPtrTest, NullValuedSmartPointer) { >+ std::unique_ptr<int> p; >+ EXPECT_EQ(nullptr, absl::RawPtr(p)); >+} >+ >+TEST(RawPtrTest, Nullptr) { >+ auto p = absl::RawPtr(nullptr); >+ EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value)); >+ EXPECT_EQ(nullptr, p); >+} >+ >+TEST(RawPtrTest, Null) { >+ auto p = absl::RawPtr(nullptr); >+ EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value)); >+ EXPECT_EQ(nullptr, p); >+} >+ >+TEST(RawPtrTest, Zero) { >+ auto p = absl::RawPtr(nullptr); >+ EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value)); >+ EXPECT_EQ(nullptr, p); >+} >+ >+TEST(ShareUniquePtrTest, Share) { >+ auto up = absl::make_unique<int>(); >+ int* rp = up.get(); >+ auto sp = absl::ShareUniquePtr(std::move(up)); >+ EXPECT_EQ(sp.get(), rp); >+} >+ >+TEST(ShareUniquePtrTest, ShareNull) { >+ struct NeverDie { >+ using pointer = void*; >+ void operator()(pointer) { >+ ASSERT_TRUE(false) << "Deleter should not have been called."; >+ } >+ }; >+ >+ std::unique_ptr<void, NeverDie> up; >+ auto sp = absl::ShareUniquePtr(std::move(up)); >+} >+ >+TEST(WeakenPtrTest, Weak) { >+ auto sp = std::make_shared<int>(); >+ auto wp = absl::WeakenPtr(sp); >+ EXPECT_EQ(sp.get(), wp.lock().get()); >+ sp.reset(); >+ EXPECT_TRUE(wp.expired()); >+} >+ >+// Should not compile. >+/* >+TEST(RawPtrTest, NotAPointer) { >+ absl::RawPtr(1.5); >+} >+*/ >+ >+template <typename T> >+struct SmartPointer { >+ using difference_type = char; >+}; >+ >+struct PointerWith { >+ using element_type = int32_t; >+ using difference_type = int16_t; >+ template <typename U> >+ using rebind = SmartPointer<U>; >+ >+ static PointerWith pointer_to( >+ element_type& r) { // NOLINT(runtime/references) >+ return PointerWith{&r}; >+ } >+ >+ element_type* ptr; >+}; >+ >+template <typename... Args> >+struct PointerWithout {}; >+ >+TEST(PointerTraits, Types) { >+ using TraitsWith = absl::pointer_traits<PointerWith>; >+ EXPECT_TRUE((std::is_same<TraitsWith::pointer, PointerWith>::value)); >+ EXPECT_TRUE((std::is_same<TraitsWith::element_type, int32_t>::value)); >+ EXPECT_TRUE((std::is_same<TraitsWith::difference_type, int16_t>::value)); >+ EXPECT_TRUE(( >+ std::is_same<TraitsWith::rebind<int64_t>, SmartPointer<int64_t>>::value)); >+ >+ using TraitsWithout = absl::pointer_traits<PointerWithout<double, int>>; >+ EXPECT_TRUE((std::is_same<TraitsWithout::pointer, >+ PointerWithout<double, int>>::value)); >+ EXPECT_TRUE((std::is_same<TraitsWithout::element_type, double>::value)); >+ EXPECT_TRUE( >+ (std::is_same<TraitsWithout ::difference_type, std::ptrdiff_t>::value)); >+ EXPECT_TRUE((std::is_same<TraitsWithout::rebind<int64_t>, >+ PointerWithout<int64_t, int>>::value)); >+ >+ using TraitsRawPtr = absl::pointer_traits<char*>; >+ EXPECT_TRUE((std::is_same<TraitsRawPtr::pointer, char*>::value)); >+ EXPECT_TRUE((std::is_same<TraitsRawPtr::element_type, char>::value)); >+ EXPECT_TRUE( >+ (std::is_same<TraitsRawPtr::difference_type, std::ptrdiff_t>::value)); >+ EXPECT_TRUE((std::is_same<TraitsRawPtr::rebind<int64_t>, int64_t*>::value)); >+} >+ >+TEST(PointerTraits, Functions) { >+ int i; >+ EXPECT_EQ(&i, absl::pointer_traits<PointerWith>::pointer_to(i).ptr); >+ EXPECT_EQ(&i, absl::pointer_traits<int*>::pointer_to(i)); >+} >+ >+TEST(AllocatorTraits, Typedefs) { >+ struct A { >+ struct value_type {}; >+ }; >+ EXPECT_TRUE(( >+ std::is_same<A, >+ typename absl::allocator_traits<A>::allocator_type>::value)); >+ EXPECT_TRUE( >+ (std::is_same<A::value_type, >+ typename absl::allocator_traits<A>::value_type>::value)); >+ >+ struct X {}; >+ struct HasPointer { >+ using value_type = X; >+ using pointer = SmartPointer<X>; >+ }; >+ EXPECT_TRUE((std::is_same<SmartPointer<X>, typename absl::allocator_traits< >+ HasPointer>::pointer>::value)); >+ EXPECT_TRUE( >+ (std::is_same<A::value_type*, >+ typename absl::allocator_traits<A>::pointer>::value)); >+ >+ EXPECT_TRUE( >+ (std::is_same< >+ SmartPointer<const X>, >+ typename absl::allocator_traits<HasPointer>::const_pointer>::value)); >+ EXPECT_TRUE( >+ (std::is_same<const A::value_type*, >+ typename absl::allocator_traits<A>::const_pointer>::value)); >+ >+ struct HasVoidPointer { >+ using value_type = X; >+ struct void_pointer {}; >+ }; >+ >+ EXPECT_TRUE((std::is_same<HasVoidPointer::void_pointer, >+ typename absl::allocator_traits< >+ HasVoidPointer>::void_pointer>::value)); >+ EXPECT_TRUE( >+ (std::is_same<SmartPointer<void>, typename absl::allocator_traits< >+ HasPointer>::void_pointer>::value)); >+ >+ struct HasConstVoidPointer { >+ using value_type = X; >+ struct const_void_pointer {}; >+ }; >+ >+ EXPECT_TRUE( >+ (std::is_same<HasConstVoidPointer::const_void_pointer, >+ typename absl::allocator_traits< >+ HasConstVoidPointer>::const_void_pointer>::value)); >+ EXPECT_TRUE((std::is_same<SmartPointer<const void>, >+ typename absl::allocator_traits< >+ HasPointer>::const_void_pointer>::value)); >+ >+ struct HasDifferenceType { >+ using value_type = X; >+ using difference_type = int; >+ }; >+ EXPECT_TRUE( >+ (std::is_same<int, typename absl::allocator_traits< >+ HasDifferenceType>::difference_type>::value)); >+ EXPECT_TRUE((std::is_same<char, typename absl::allocator_traits< >+ HasPointer>::difference_type>::value)); >+ >+ struct HasSizeType { >+ using value_type = X; >+ using size_type = unsigned int; >+ }; >+ EXPECT_TRUE((std::is_same<unsigned int, typename absl::allocator_traits< >+ HasSizeType>::size_type>::value)); >+ EXPECT_TRUE((std::is_same<unsigned char, typename absl::allocator_traits< >+ HasPointer>::size_type>::value)); >+ >+ struct HasPropagateOnCopy { >+ using value_type = X; >+ struct propagate_on_container_copy_assignment {}; >+ }; >+ >+ EXPECT_TRUE( >+ (std::is_same<HasPropagateOnCopy::propagate_on_container_copy_assignment, >+ typename absl::allocator_traits<HasPropagateOnCopy>:: >+ propagate_on_container_copy_assignment>::value)); >+ EXPECT_TRUE( >+ (std::is_same<std::false_type, >+ typename absl::allocator_traits< >+ A>::propagate_on_container_copy_assignment>::value)); >+ >+ struct HasPropagateOnMove { >+ using value_type = X; >+ struct propagate_on_container_move_assignment {}; >+ }; >+ >+ EXPECT_TRUE( >+ (std::is_same<HasPropagateOnMove::propagate_on_container_move_assignment, >+ typename absl::allocator_traits<HasPropagateOnMove>:: >+ propagate_on_container_move_assignment>::value)); >+ EXPECT_TRUE( >+ (std::is_same<std::false_type, >+ typename absl::allocator_traits< >+ A>::propagate_on_container_move_assignment>::value)); >+ >+ struct HasPropagateOnSwap { >+ using value_type = X; >+ struct propagate_on_container_swap {}; >+ }; >+ >+ EXPECT_TRUE( >+ (std::is_same<HasPropagateOnSwap::propagate_on_container_swap, >+ typename absl::allocator_traits<HasPropagateOnSwap>:: >+ propagate_on_container_swap>::value)); >+ EXPECT_TRUE( >+ (std::is_same<std::false_type, typename absl::allocator_traits<A>:: >+ propagate_on_container_swap>::value)); >+ >+ struct HasIsAlwaysEqual { >+ using value_type = X; >+ struct is_always_equal {}; >+ }; >+ >+ EXPECT_TRUE((std::is_same<HasIsAlwaysEqual::is_always_equal, >+ typename absl::allocator_traits< >+ HasIsAlwaysEqual>::is_always_equal>::value)); >+ EXPECT_TRUE((std::is_same<std::true_type, typename absl::allocator_traits< >+ A>::is_always_equal>::value)); >+ struct NonEmpty { >+ using value_type = X; >+ int i; >+ }; >+ EXPECT_TRUE( >+ (std::is_same<std::false_type, >+ absl::allocator_traits<NonEmpty>::is_always_equal>::value)); >+} >+ >+template <typename T> >+struct AllocWithPrivateInheritance : private std::allocator<T> { >+ using value_type = T; >+}; >+ >+TEST(AllocatorTraits, RebindWithPrivateInheritance) { >+ // Regression test for some versions of gcc that do not like the sfinae we >+ // used in combination with private inheritance. >+ EXPECT_TRUE( >+ (std::is_same<AllocWithPrivateInheritance<int>, >+ absl::allocator_traits<AllocWithPrivateInheritance<char>>:: >+ rebind_alloc<int>>::value)); >+} >+ >+template <typename T> >+struct Rebound {}; >+ >+struct AllocWithRebind { >+ using value_type = int; >+ template <typename T> >+ struct rebind { >+ using other = Rebound<T>; >+ }; >+}; >+ >+template <typename T, typename U> >+struct AllocWithoutRebind { >+ using value_type = int; >+}; >+ >+TEST(AllocatorTraits, Rebind) { >+ EXPECT_TRUE( >+ (std::is_same<Rebound<int>, >+ typename absl::allocator_traits< >+ AllocWithRebind>::template rebind_alloc<int>>::value)); >+ EXPECT_TRUE( >+ (std::is_same<absl::allocator_traits<Rebound<int>>, >+ typename absl::allocator_traits< >+ AllocWithRebind>::template rebind_traits<int>>::value)); >+ >+ EXPECT_TRUE( >+ (std::is_same<AllocWithoutRebind<double, char>, >+ typename absl::allocator_traits<AllocWithoutRebind< >+ int, char>>::template rebind_alloc<double>>::value)); >+ EXPECT_TRUE( >+ (std::is_same<absl::allocator_traits<AllocWithoutRebind<double, char>>, >+ typename absl::allocator_traits<AllocWithoutRebind< >+ int, char>>::template rebind_traits<double>>::value)); >+} >+ >+struct TestValue { >+ TestValue() {} >+ explicit TestValue(int* trace) : trace(trace) { ++*trace; } >+ ~TestValue() { >+ if (trace) --*trace; >+ } >+ int* trace = nullptr; >+}; >+ >+struct MinimalMockAllocator { >+ MinimalMockAllocator() : value(0) {} >+ explicit MinimalMockAllocator(int value) : value(value) {} >+ MinimalMockAllocator(const MinimalMockAllocator& other) >+ : value(other.value) {} >+ using value_type = TestValue; >+ MOCK_METHOD1(allocate, value_type*(size_t)); >+ MOCK_METHOD2(deallocate, void(value_type*, size_t)); >+ >+ int value; >+}; >+ >+TEST(AllocatorTraits, FunctionsMinimal) { >+ int trace = 0; >+ int hint; >+ TestValue x(&trace); >+ MinimalMockAllocator mock; >+ using Traits = absl::allocator_traits<MinimalMockAllocator>; >+ EXPECT_CALL(mock, allocate(7)).WillRepeatedly(Return(&x)); >+ EXPECT_CALL(mock, deallocate(&x, 7)); >+ >+ EXPECT_EQ(&x, Traits::allocate(mock, 7)); >+ Traits::allocate(mock, 7, static_cast<const void*>(&hint)); >+ EXPECT_EQ(&x, Traits::allocate(mock, 7, static_cast<const void*>(&hint))); >+ Traits::deallocate(mock, &x, 7); >+ >+ EXPECT_EQ(1, trace); >+ Traits::construct(mock, &x, &trace); >+ EXPECT_EQ(2, trace); >+ Traits::destroy(mock, &x); >+ EXPECT_EQ(1, trace); >+ >+ EXPECT_EQ(std::numeric_limits<size_t>::max() / sizeof(TestValue), >+ Traits::max_size(mock)); >+ >+ EXPECT_EQ(0, mock.value); >+ EXPECT_EQ(0, Traits::select_on_container_copy_construction(mock).value); >+} >+ >+struct FullMockAllocator { >+ FullMockAllocator() : value(0) {} >+ explicit FullMockAllocator(int value) : value(value) {} >+ FullMockAllocator(const FullMockAllocator& other) : value(other.value) {} >+ using value_type = TestValue; >+ MOCK_METHOD1(allocate, value_type*(size_t)); >+ MOCK_METHOD2(allocate, value_type*(size_t, const void*)); >+ MOCK_METHOD2(construct, void(value_type*, int*)); >+ MOCK_METHOD1(destroy, void(value_type*)); >+ MOCK_CONST_METHOD0(max_size, size_t()); >+ MOCK_CONST_METHOD0(select_on_container_copy_construction, >+ FullMockAllocator()); >+ >+ int value; >+}; >+ >+TEST(AllocatorTraits, FunctionsFull) { >+ int trace = 0; >+ int hint; >+ TestValue x(&trace), y; >+ FullMockAllocator mock; >+ using Traits = absl::allocator_traits<FullMockAllocator>; >+ EXPECT_CALL(mock, allocate(7)).WillRepeatedly(Return(&x)); >+ EXPECT_CALL(mock, allocate(13, &hint)).WillRepeatedly(Return(&y)); >+ EXPECT_CALL(mock, construct(&x, &trace)); >+ EXPECT_CALL(mock, destroy(&x)); >+ EXPECT_CALL(mock, max_size()).WillRepeatedly(Return(17)); >+ EXPECT_CALL(mock, select_on_container_copy_construction()) >+ .WillRepeatedly(Return(FullMockAllocator(23))); >+ >+ EXPECT_EQ(&x, Traits::allocate(mock, 7)); >+ EXPECT_EQ(&y, Traits::allocate(mock, 13, static_cast<const void*>(&hint))); >+ >+ EXPECT_EQ(1, trace); >+ Traits::construct(mock, &x, &trace); >+ EXPECT_EQ(1, trace); >+ Traits::destroy(mock, &x); >+ EXPECT_EQ(1, trace); >+ >+ EXPECT_EQ(17, Traits::max_size(mock)); >+ >+ EXPECT_EQ(0, mock.value); >+ EXPECT_EQ(23, Traits::select_on_container_copy_construction(mock).value); >+} >+ >+TEST(AllocatorNoThrowTest, DefaultAllocator) { >+#if ABSL_ALLOCATOR_NOTHROW >+ EXPECT_TRUE(absl::default_allocator_is_nothrow::value); >+#else >+ EXPECT_FALSE(absl::default_allocator_is_nothrow::value); >+#endif >+} >+ >+TEST(AllocatorNoThrowTest, StdAllocator) { >+#if ABSL_ALLOCATOR_NOTHROW >+ EXPECT_TRUE(absl::allocator_is_nothrow<std::allocator<int>>::value); >+#else >+ EXPECT_FALSE(absl::allocator_is_nothrow<std::allocator<int>>::value); >+#endif >+} >+ >+TEST(AllocatorNoThrowTest, CustomAllocator) { >+ struct NoThrowAllocator { >+ using is_nothrow = std::true_type; >+ }; >+ struct CanThrowAllocator { >+ using is_nothrow = std::false_type; >+ }; >+ struct UnspecifiedAllocator { >+ }; >+ EXPECT_TRUE(absl::allocator_is_nothrow<NoThrowAllocator>::value); >+ EXPECT_FALSE(absl::allocator_is_nothrow<CanThrowAllocator>::value); >+ EXPECT_FALSE(absl::allocator_is_nothrow<UnspecifiedAllocator>::value); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..dbc9717ddd33c2fa44a6afb00fbb7dd1a9578b88 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/BUILD.bazel >@@ -0,0 +1,29 @@ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+) >+ >+package(default_visibility = ["//visibility:public"]) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+cc_library( >+ name = "type_traits", >+ hdrs = ["type_traits.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/base:config", >+ ], >+) >+ >+cc_test( >+ name = "type_traits_test", >+ srcs = ["type_traits_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":type_traits", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..6757219c27354994e5da0c5e4613dda88940406d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/BUILD.gn >@@ -0,0 +1,30 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("type_traits") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "type_traits.h", >+ ] >+ deps = [ >+ "../base:config", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..adb0ceb754df527801df576748bf5c2816e954aa >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/CMakeLists.txt >@@ -0,0 +1,52 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+list(APPEND META_PUBLIC_HEADERS >+ "type_traits.h" >+) >+ >+ >+# >+## TESTS >+# >+ >+# test type_traits_test >+list(APPEND TYPE_TRAITS_TEST_SRC >+ "type_traits_test.cc" >+ ${META_PUBLIC_HEADERS} >+) >+ >+absl_header_library( >+ TARGET >+ absl_meta >+ PUBLIC_LIBRARIES >+ absl::base >+ EXPORT_NAME >+ meta >+ ) >+ >+absl_test( >+ TARGET >+ type_traits_test >+ SOURCES >+ ${TYPE_TRAITS_TEST_SRC} >+ PUBLIC_LIBRARIES >+ absl::base >+ absl::meta >+) >+ >+ >+ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/type_traits.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/type_traits.h >new file mode 100644 >index 0000000000000000000000000000000000000000..457b890841a64fb4ed36cde8621d7822190b798d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/type_traits.h >@@ -0,0 +1,419 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// type_traits.h >+// ----------------------------------------------------------------------------- >+// >+// This file contains C++11-compatible versions of standard <type_traits> API >+// functions for determining the characteristics of types. Such traits can >+// support type inference, classification, and transformation, as well as >+// make it easier to write templates based on generic type behavior. >+// >+// See http://en.cppreference.com/w/cpp/header/type_traits >+// >+// WARNING: use of many of the constructs in this header will count as "complex >+// template metaprogramming", so before proceeding, please carefully consider >+// https://google.github.io/styleguide/cppguide.html#Template_metaprogramming >+// >+// WARNING: using template metaprogramming to detect or depend on API >+// features is brittle and not guaranteed. Neither the standard library nor >+// Abseil provides any guarantee that APIs are stable in the face of template >+// metaprogramming. Use with caution. >+#ifndef ABSL_META_TYPE_TRAITS_H_ >+#define ABSL_META_TYPE_TRAITS_H_ >+ >+#include <stddef.h> >+#include <functional> >+#include <type_traits> >+ >+#include "absl/base/config.h" >+ >+namespace absl { >+ >+namespace type_traits_internal { >+ >+template <typename... Ts> >+struct VoidTImpl { >+ using type = void; >+}; >+ >+// This trick to retrieve a default alignment is necessary for our >+// implementation of aligned_storage_t to be consistent with any implementation >+// of std::aligned_storage. >+template <size_t Len, typename T = std::aligned_storage<Len>> >+struct default_alignment_of_aligned_storage; >+ >+template <size_t Len, size_t Align> >+struct default_alignment_of_aligned_storage<Len, >+ std::aligned_storage<Len, Align>> { >+ static constexpr size_t value = Align; >+}; >+ >+//////////////////////////////// >+// Library Fundamentals V2 TS // >+//////////////////////////////// >+ >+// NOTE: The `is_detected` family of templates here differ from the library >+// fundamentals specification in that for library fundamentals, `Op<Args...>` is >+// evaluated as soon as the type `is_detected<Op, Args...>` undergoes >+// substitution, regardless of whether or not the `::value` is accessed. That >+// is inconsistent with all other standard traits and prevents lazy evaluation >+// in larger contexts (such as if the `is_detected` check is a trailing argument >+// of a `conjunction`. This implementation opts to instead be lazy in the same >+// way that the standard traits are (this "defect" of the detection idiom >+// specifications has been reported). >+ >+template <class Enabler, template <class...> class Op, class... Args> >+struct is_detected_impl { >+ using type = std::false_type; >+}; >+ >+template <template <class...> class Op, class... Args> >+struct is_detected_impl<typename VoidTImpl<Op<Args...>>::type, Op, Args...> { >+ using type = std::true_type; >+}; >+ >+template <template <class...> class Op, class... Args> >+struct is_detected : is_detected_impl<void, Op, Args...>::type {}; >+ >+template <class Enabler, class To, template <class...> class Op, class... Args> >+struct is_detected_convertible_impl { >+ using type = std::false_type; >+}; >+ >+template <class To, template <class...> class Op, class... Args> >+struct is_detected_convertible_impl< >+ typename std::enable_if<std::is_convertible<Op<Args...>, To>::value>::type, >+ To, Op, Args...> { >+ using type = std::true_type; >+}; >+ >+template <class To, template <class...> class Op, class... Args> >+struct is_detected_convertible >+ : is_detected_convertible_impl<void, To, Op, Args...>::type {}; >+ >+} // namespace type_traits_internal >+ >+// void_t() >+// >+// Ignores the type of any its arguments and returns `void`. In general, this >+// metafunction allows you to create a general case that maps to `void` while >+// allowing specializations that map to specific types. >+// >+// This metafunction is designed to be a drop-in replacement for the C++17 >+// `std::void_t` metafunction. >+// >+// NOTE: `absl::void_t` does not use the standard-specified implementation so >+// that it can remain compatible with gcc < 5.1. This can introduce slightly >+// different behavior, such as when ordering partial specializations. >+template <typename... Ts> >+using void_t = typename type_traits_internal::VoidTImpl<Ts...>::type; >+ >+// conjunction >+// >+// Performs a compile-time logical AND operation on the passed types (which >+// must have `::value` members convertible to `bool`. Short-circuits if it >+// encounters any `false` members (and does not compare the `::value` members >+// of any remaining arguments). >+// >+// This metafunction is designed to be a drop-in replacement for the C++17 >+// `std::conjunction` metafunction. >+template <typename... Ts> >+struct conjunction; >+ >+template <typename T, typename... Ts> >+struct conjunction<T, Ts...> >+ : std::conditional<T::value, conjunction<Ts...>, T>::type {}; >+ >+template <typename T> >+struct conjunction<T> : T {}; >+ >+template <> >+struct conjunction<> : std::true_type {}; >+ >+// disjunction >+// >+// Performs a compile-time logical OR operation on the passed types (which >+// must have `::value` members convertible to `bool`. Short-circuits if it >+// encounters any `true` members (and does not compare the `::value` members >+// of any remaining arguments). >+// >+// This metafunction is designed to be a drop-in replacement for the C++17 >+// `std::disjunction` metafunction. >+template <typename... Ts> >+struct disjunction; >+ >+template <typename T, typename... Ts> >+struct disjunction<T, Ts...> : >+ std::conditional<T::value, T, disjunction<Ts...>>::type {}; >+ >+template <typename T> >+struct disjunction<T> : T {}; >+ >+template <> >+struct disjunction<> : std::false_type {}; >+ >+// negation >+// >+// Performs a compile-time logical NOT operation on the passed type (which >+// must have `::value` members convertible to `bool`. >+// >+// This metafunction is designed to be a drop-in replacement for the C++17 >+// `std::negation` metafunction. >+template <typename T> >+struct negation : std::integral_constant<bool, !T::value> {}; >+ >+// is_trivially_destructible() >+// >+// Determines whether the passed type `T` is trivially destructable. >+// >+// This metafunction is designed to be a drop-in replacement for the C++11 >+// `std::is_trivially_destructible()` metafunction for platforms that have >+// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do >+// fully support C++11, we check whether this yields the same result as the std >+// implementation. >+// >+// NOTE: the extensions (__has_trivial_xxx) are implemented in gcc (version >= >+// 4.3) and clang. Since we are supporting libstdc++ > 4.7, they should always >+// be present. These extensions are documented at >+// https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits. >+template <typename T> >+struct is_trivially_destructible >+ : std::integral_constant<bool, __has_trivial_destructor(T) && >+ std::is_destructible<T>::value> { >+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE >+ private: >+ static constexpr bool compliant = std::is_trivially_destructible<T>::value == >+ is_trivially_destructible::value; >+ static_assert(compliant || std::is_trivially_destructible<T>::value, >+ "Not compliant with std::is_trivially_destructible; " >+ "Standard: false, Implementation: true"); >+ static_assert(compliant || !std::is_trivially_destructible<T>::value, >+ "Not compliant with std::is_trivially_destructible; " >+ "Standard: true, Implementation: false"); >+#endif // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE >+}; >+ >+// is_trivially_default_constructible() >+// >+// Determines whether the passed type `T` is trivially default constructible. >+// >+// This metafunction is designed to be a drop-in replacement for the C++11 >+// `std::is_trivially_default_constructible()` metafunction for platforms that >+// have incomplete C++11 support (such as libstdc++ 4.x). On any platforms that >+// do fully support C++11, we check whether this yields the same result as the >+// std implementation. >+// >+// NOTE: according to the C++ standard, Section: 20.15.4.3 [meta.unary.prop] >+// "The predicate condition for a template specialization is_constructible<T, >+// Args...> shall be satisfied if and only if the following variable >+// definition would be well-formed for some invented variable t: >+// >+// T t(declval<Args>()...); >+// >+// is_trivially_constructible<T, Args...> additionally requires that the >+// variable definition does not call any operation that is not trivial. >+// For the purposes of this check, the call to std::declval is considered >+// trivial." >+// >+// Notes from http://en.cppreference.com/w/cpp/types/is_constructible: >+// In many implementations, is_nothrow_constructible also checks if the >+// destructor throws because it is effectively noexcept(T(arg)). Same >+// applies to is_trivially_constructible, which, in these implementations, also >+// requires that the destructor is trivial. >+// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 >+// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116. >+// >+// "T obj();" need to be well-formed and not call any nontrivial operation. >+// Nontrivially destructible types will cause the expression to be nontrivial. >+template <typename T> >+struct is_trivially_default_constructible >+ : std::integral_constant<bool, __has_trivial_constructor(T) && >+ std::is_default_constructible<T>::value && >+ is_trivially_destructible<T>::value> { >+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE >+ private: >+ static constexpr bool compliant = >+ std::is_trivially_default_constructible<T>::value == >+ is_trivially_default_constructible::value; >+ static_assert(compliant || std::is_trivially_default_constructible<T>::value, >+ "Not compliant with std::is_trivially_default_constructible; " >+ "Standard: false, Implementation: true"); >+ static_assert(compliant || !std::is_trivially_default_constructible<T>::value, >+ "Not compliant with std::is_trivially_default_constructible; " >+ "Standard: true, Implementation: false"); >+#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE >+}; >+ >+// is_trivially_copy_constructible() >+// >+// Determines whether the passed type `T` is trivially copy constructible. >+// >+// This metafunction is designed to be a drop-in replacement for the C++11 >+// `std::is_trivially_copy_constructible()` metafunction for platforms that have >+// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do >+// fully support C++11, we check whether this yields the same result as the std >+// implementation. >+// >+// NOTE: `T obj(declval<const T&>());` needs to be well-formed and not call any >+// nontrivial operation. Nontrivially destructible types will cause the >+// expression to be nontrivial. >+template <typename T> >+struct is_trivially_copy_constructible >+ : std::integral_constant<bool, __has_trivial_copy(T) && >+ std::is_copy_constructible<T>::value && >+ is_trivially_destructible<T>::value> { >+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE >+ private: >+ static constexpr bool compliant = >+ std::is_trivially_copy_constructible<T>::value == >+ is_trivially_copy_constructible::value; >+ static_assert(compliant || std::is_trivially_copy_constructible<T>::value, >+ "Not compliant with std::is_trivially_copy_constructible; " >+ "Standard: false, Implementation: true"); >+ static_assert(compliant || !std::is_trivially_copy_constructible<T>::value, >+ "Not compliant with std::is_trivially_copy_constructible; " >+ "Standard: true, Implementation: false"); >+#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE >+}; >+ >+// is_trivially_copy_assignable() >+// >+// Determines whether the passed type `T` is trivially copy assignable. >+// >+// This metafunction is designed to be a drop-in replacement for the C++11 >+// `std::is_trivially_copy_assignable()` metafunction for platforms that have >+// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do >+// fully support C++11, we check whether this yields the same result as the std >+// implementation. >+// >+// NOTE: `is_assignable<T, U>::value` is `true` if the expression >+// `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated >+// operand. `is_trivially_assignable<T, U>` requires the assignment to call no >+// operation that is not trivial. `is_trivially_copy_assignable<T>` is simply >+// `is_trivially_assignable<T&, const T&>`. >+template <typename T> >+struct is_trivially_copy_assignable >+ : std::integral_constant< >+ bool, __has_trivial_assign(typename std::remove_reference<T>::type) && >+ std::is_copy_assignable<T>::value> { >+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE >+ private: >+ static constexpr bool compliant = >+ std::is_trivially_copy_assignable<T>::value == >+ is_trivially_copy_assignable::value; >+ static_assert(compliant || std::is_trivially_copy_assignable<T>::value, >+ "Not compliant with std::is_trivially_copy_assignable; " >+ "Standard: false, Implementation: true"); >+ static_assert(compliant || !std::is_trivially_copy_assignable<T>::value, >+ "Not compliant with std::is_trivially_copy_assignable; " >+ "Standard: true, Implementation: false"); >+#endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE >+}; >+ >+// ----------------------------------------------------------------------------- >+// C++14 "_t" trait aliases >+// ----------------------------------------------------------------------------- >+ >+template <typename T> >+using remove_cv_t = typename std::remove_cv<T>::type; >+ >+template <typename T> >+using remove_const_t = typename std::remove_const<T>::type; >+ >+template <typename T> >+using remove_volatile_t = typename std::remove_volatile<T>::type; >+ >+template <typename T> >+using add_cv_t = typename std::add_cv<T>::type; >+ >+template <typename T> >+using add_const_t = typename std::add_const<T>::type; >+ >+template <typename T> >+using add_volatile_t = typename std::add_volatile<T>::type; >+ >+template <typename T> >+using remove_reference_t = typename std::remove_reference<T>::type; >+ >+template <typename T> >+using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type; >+ >+template <typename T> >+using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type; >+ >+template <typename T> >+using remove_pointer_t = typename std::remove_pointer<T>::type; >+ >+template <typename T> >+using add_pointer_t = typename std::add_pointer<T>::type; >+ >+template <typename T> >+using make_signed_t = typename std::make_signed<T>::type; >+ >+template <typename T> >+using make_unsigned_t = typename std::make_unsigned<T>::type; >+ >+template <typename T> >+using remove_extent_t = typename std::remove_extent<T>::type; >+ >+template <typename T> >+using remove_all_extents_t = typename std::remove_all_extents<T>::type; >+ >+template <size_t Len, size_t Align = type_traits_internal:: >+ default_alignment_of_aligned_storage<Len>::value> >+using aligned_storage_t = typename std::aligned_storage<Len, Align>::type; >+ >+template <typename T> >+using decay_t = typename std::decay<T>::type; >+ >+template <bool B, typename T = void> >+using enable_if_t = typename std::enable_if<B, T>::type; >+ >+template <bool B, typename T, typename F> >+using conditional_t = typename std::conditional<B, T, F>::type; >+ >+template <typename... T> >+using common_type_t = typename std::common_type<T...>::type; >+ >+template <typename T> >+using underlying_type_t = typename std::underlying_type<T>::type; >+ >+template <typename T> >+using result_of_t = typename std::result_of<T>::type; >+ >+namespace type_traits_internal { >+template <typename Key, typename = size_t> >+struct IsHashable : std::false_type {}; >+ >+template <typename Key> >+struct IsHashable<Key, >+ decltype(std::declval<std::hash<Key>>()(std::declval<Key>()))> >+ : std::true_type {}; >+ >+template <typename Key> >+struct IsHashEnabled >+ : absl::conjunction<std::is_default_constructible<std::hash<Key>>, >+ std::is_copy_constructible<std::hash<Key>>, >+ std::is_destructible<std::hash<Key>>, >+ std::is_copy_assignable<std::hash<Key>>, >+ IsHashable<Key>> {}; >+} // namespace type_traits_internal >+ >+} // namespace absl >+ >+ >+#endif // ABSL_META_TYPE_TRAITS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/type_traits_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/type_traits_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..81b4bd323977e5e3cd27660c50cced86ab225017 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/meta/type_traits_test.cc >@@ -0,0 +1,880 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/meta/type_traits.h" >+ >+#include <cstdint> >+#include <string> >+#include <type_traits> >+#include <utility> >+#include <vector> >+ >+#include "gtest/gtest.h" >+ >+namespace { >+ >+using ::testing::StaticAssertTypeEq; >+ >+template <class T, class U> >+struct simple_pair { >+ T first; >+ U second; >+}; >+ >+struct Dummy {}; >+ >+struct ReturnType {}; >+struct ConvertibleToReturnType { >+ operator ReturnType() const; // NOLINT >+}; >+ >+// Unique types used as parameter types for testing the detection idiom. >+struct StructA {}; >+struct StructB {}; >+struct StructC {}; >+ >+struct TypeWithBarFunction { >+ template <class T, >+ absl::enable_if_t<std::is_same<T&&, StructA&>::value, int> = 0> >+ ReturnType bar(T&&, const StructB&, StructC&&) &&; // NOLINT >+}; >+ >+struct TypeWithBarFunctionAndConvertibleReturnType { >+ template <class T, >+ absl::enable_if_t<std::is_same<T&&, StructA&>::value, int> = 0> >+ ConvertibleToReturnType bar(T&&, const StructB&, StructC&&) &&; // NOLINT >+}; >+ >+template <class Class, class... Ts> >+using BarIsCallableImpl = >+ decltype(std::declval<Class>().bar(std::declval<Ts>()...)); >+ >+template <class Class, class... T> >+using BarIsCallable = >+ absl::type_traits_internal::is_detected<BarIsCallableImpl, Class, T...>; >+ >+template <class Class, class... T> >+using BarIsCallableConv = absl::type_traits_internal::is_detected_convertible< >+ ReturnType, BarIsCallableImpl, Class, T...>; >+ >+// NOTE: Test of detail type_traits_internal::is_detected. >+TEST(IsDetectedTest, BasicUsage) { >+ EXPECT_TRUE((BarIsCallable<TypeWithBarFunction, StructA&, const StructB&, >+ StructC>::value)); >+ EXPECT_TRUE( >+ (BarIsCallable<TypeWithBarFunction, StructA&, StructB&, StructC>::value)); >+ EXPECT_TRUE( >+ (BarIsCallable<TypeWithBarFunction, StructA&, StructB, StructC>::value)); >+ >+ EXPECT_FALSE((BarIsCallable<int, StructA&, const StructB&, StructC>::value)); >+ EXPECT_FALSE((BarIsCallable<TypeWithBarFunction&, StructA&, const StructB&, >+ StructC>::value)); >+ EXPECT_FALSE((BarIsCallable<TypeWithBarFunction, StructA, const StructB&, >+ StructC>::value)); >+} >+ >+// NOTE: Test of detail type_traits_internal::is_detected_convertible. >+TEST(IsDetectedConvertibleTest, BasicUsage) { >+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunction, StructA&, const StructB&, >+ StructC>::value)); >+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunction, StructA&, StructB&, >+ StructC>::value)); >+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunction, StructA&, StructB, >+ StructC>::value)); >+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType, >+ StructA&, const StructB&, StructC>::value)); >+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType, >+ StructA&, StructB&, StructC>::value)); >+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType, >+ StructA&, StructB, StructC>::value)); >+ >+ EXPECT_FALSE( >+ (BarIsCallableConv<int, StructA&, const StructB&, StructC>::value)); >+ EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunction&, StructA&, >+ const StructB&, StructC>::value)); >+ EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunction, StructA, const StructB&, >+ StructC>::value)); >+ EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType&, >+ StructA&, const StructB&, StructC>::value)); >+ EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType, >+ StructA, const StructB&, StructC>::value)); >+} >+ >+TEST(VoidTTest, BasicUsage) { >+ StaticAssertTypeEq<void, absl::void_t<Dummy>>(); >+ StaticAssertTypeEq<void, absl::void_t<Dummy, Dummy, Dummy>>(); >+} >+ >+TEST(ConjunctionTest, BasicBooleanLogic) { >+ EXPECT_TRUE(absl::conjunction<>::value); >+ EXPECT_TRUE(absl::conjunction<std::true_type>::value); >+ EXPECT_TRUE((absl::conjunction<std::true_type, std::true_type>::value)); >+ EXPECT_FALSE((absl::conjunction<std::true_type, std::false_type>::value)); >+ EXPECT_FALSE((absl::conjunction<std::false_type, std::true_type>::value)); >+ EXPECT_FALSE((absl::conjunction<std::false_type, std::false_type>::value)); >+} >+ >+struct MyTrueType { >+ static constexpr bool value = true; >+}; >+ >+struct MyFalseType { >+ static constexpr bool value = false; >+}; >+ >+TEST(ConjunctionTest, ShortCircuiting) { >+ EXPECT_FALSE( >+ (absl::conjunction<std::true_type, std::false_type, Dummy>::value)); >+ EXPECT_TRUE((std::is_base_of<MyFalseType, >+ absl::conjunction<std::true_type, MyFalseType, >+ std::false_type>>::value)); >+ EXPECT_TRUE( >+ (std::is_base_of<MyTrueType, >+ absl::conjunction<std::true_type, MyTrueType>>::value)); >+} >+ >+TEST(DisjunctionTest, BasicBooleanLogic) { >+ EXPECT_FALSE(absl::disjunction<>::value); >+ EXPECT_FALSE(absl::disjunction<std::false_type>::value); >+ EXPECT_TRUE((absl::disjunction<std::true_type, std::true_type>::value)); >+ EXPECT_TRUE((absl::disjunction<std::true_type, std::false_type>::value)); >+ EXPECT_TRUE((absl::disjunction<std::false_type, std::true_type>::value)); >+ EXPECT_FALSE((absl::disjunction<std::false_type, std::false_type>::value)); >+} >+ >+TEST(DisjunctionTest, ShortCircuiting) { >+ EXPECT_TRUE( >+ (absl::disjunction<std::false_type, std::true_type, Dummy>::value)); >+ EXPECT_TRUE(( >+ std::is_base_of<MyTrueType, absl::disjunction<std::false_type, MyTrueType, >+ std::true_type>>::value)); >+ EXPECT_TRUE(( >+ std::is_base_of<MyFalseType, >+ absl::disjunction<std::false_type, MyFalseType>>::value)); >+} >+ >+TEST(NegationTest, BasicBooleanLogic) { >+ EXPECT_FALSE(absl::negation<std::true_type>::value); >+ EXPECT_FALSE(absl::negation<MyTrueType>::value); >+ EXPECT_TRUE(absl::negation<std::false_type>::value); >+ EXPECT_TRUE(absl::negation<MyFalseType>::value); >+} >+ >+// all member functions are trivial >+class Trivial { >+ int n_; >+}; >+ >+struct TrivialDestructor { >+ ~TrivialDestructor() = default; >+}; >+ >+struct NontrivialDestructor { >+ ~NontrivialDestructor() {} >+}; >+ >+struct DeletedDestructor { >+ ~DeletedDestructor() = delete; >+}; >+ >+class TrivialDefaultCtor { >+ public: >+ TrivialDefaultCtor() = default; >+ explicit TrivialDefaultCtor(int n) : n_(n) {} >+ >+ private: >+ int n_; >+}; >+ >+class NontrivialDefaultCtor { >+ public: >+ NontrivialDefaultCtor() : n_(1) {} >+ >+ private: >+ int n_; >+}; >+ >+class DeletedDefaultCtor { >+ public: >+ DeletedDefaultCtor() = delete; >+ explicit DeletedDefaultCtor(int n) : n_(n) {} >+ >+ private: >+ int n_; >+}; >+ >+class TrivialCopyCtor { >+ public: >+ explicit TrivialCopyCtor(int n) : n_(n) {} >+ TrivialCopyCtor(const TrivialCopyCtor&) = default; >+ TrivialCopyCtor& operator=(const TrivialCopyCtor& t) { >+ n_ = t.n_; >+ return *this; >+ } >+ >+ private: >+ int n_; >+}; >+ >+class NontrivialCopyCtor { >+ public: >+ explicit NontrivialCopyCtor(int n) : n_(n) {} >+ NontrivialCopyCtor(const NontrivialCopyCtor& t) : n_(t.n_) {} >+ NontrivialCopyCtor& operator=(const NontrivialCopyCtor&) = default; >+ >+ private: >+ int n_; >+}; >+ >+class DeletedCopyCtor { >+ public: >+ explicit DeletedCopyCtor(int n) : n_(n) {} >+ DeletedCopyCtor(const DeletedCopyCtor&) = delete; >+ DeletedCopyCtor& operator=(const DeletedCopyCtor&) = default; >+ >+ private: >+ int n_; >+}; >+ >+class TrivialCopyAssign { >+ public: >+ explicit TrivialCopyAssign(int n) : n_(n) {} >+ TrivialCopyAssign(const TrivialCopyAssign& t) : n_(t.n_) {} >+ TrivialCopyAssign& operator=(const TrivialCopyAssign& t) = default; >+ ~TrivialCopyAssign() {} // can have nontrivial destructor >+ private: >+ int n_; >+}; >+ >+class NontrivialCopyAssign { >+ public: >+ explicit NontrivialCopyAssign(int n) : n_(n) {} >+ NontrivialCopyAssign(const NontrivialCopyAssign&) = default; >+ NontrivialCopyAssign& operator=(const NontrivialCopyAssign& t) { >+ n_ = t.n_; >+ return *this; >+ } >+ >+ private: >+ int n_; >+}; >+ >+class DeletedCopyAssign { >+ public: >+ explicit DeletedCopyAssign(int n) : n_(n) {} >+ DeletedCopyAssign(const DeletedCopyAssign&) = default; >+ DeletedCopyAssign& operator=(const DeletedCopyAssign&) = delete; >+ >+ private: >+ int n_; >+}; >+ >+struct NonCopyable { >+ NonCopyable() = default; >+ NonCopyable(const NonCopyable&) = delete; >+ NonCopyable& operator=(const NonCopyable&) = delete; >+}; >+ >+class Base { >+ public: >+ virtual ~Base() {} >+}; >+ >+// In GCC/Clang, std::is_trivially_constructible requires that the destructor is >+// trivial. However, MSVC doesn't require that. This results in different >+// behavior when checking is_trivially_constructible on any type with >+// nontrivial destructor. Since absl::is_trivially_default_constructible and >+// absl::is_trivially_copy_constructible both follows Clang/GCC's interpretation >+// and check is_trivially_destructible, it results in inconsistency with >+// std::is_trivially_xxx_constructible on MSVC. This macro is used to work >+// around this issue in test. In practice, a trivially constructible type >+// should also be trivially destructible. >+// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 >+// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116 >+#ifndef _MSC_VER >+#define ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE 1 >+#endif >+ >+// Old versions of libc++, around Clang 3.5 to 3.6, consider deleted destructors >+// as also being trivial. With the resolution of CWG 1928 and CWG 1734, this >+// is no longer considered true and has thus been amended. >+// Compiler Explorer: https://godbolt.org/g/zT59ZL >+// CWG issue 1734: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1734 >+// CWG issue 1928: http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1928 >+#if !defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 3700 >+#define ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL 1 >+#endif >+ >+// As of the moment, GCC versions >5.1 have a problem compiling for >+// std::is_trivially_default_constructible<NontrivialDestructor[10]>, where >+// NontrivialDestructor is a struct with a custom nontrivial destructor. Note >+// that this problem only occurs for arrays of a known size, so something like >+// std::is_trivially_default_constructible<NontrivialDestructor[]> does not >+// have any problems. >+// Compiler Explorer: https://godbolt.org/g/dXRbdK >+// GCC bug 83689: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83689 >+#if defined(__clang__) || defined(_MSC_VER) || \ >+ (defined(__GNUC__) && __GNUC__ < 5) >+#define ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL 1 >+#endif >+ >+TEST(TypeTraitsTest, TestTrivialDestructor) { >+ // Verify that arithmetic types and pointers have trivial destructors. >+ EXPECT_TRUE(absl::is_trivially_destructible<bool>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<char>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<unsigned char>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<signed char>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<wchar_t>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<int>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<unsigned int>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<int16_t>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<uint16_t>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<int64_t>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<uint64_t>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<float>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<double>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<long double>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<std::string*>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<Trivial*>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<const std::string*>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<const Trivial*>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<std::string**>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<Trivial**>::value); >+ >+ // classes with destructors >+ EXPECT_TRUE(absl::is_trivially_destructible<Trivial>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor>::value); >+ >+ // Verify that types with a nontrivial or deleted destructor >+ // are marked as such. >+ EXPECT_FALSE(absl::is_trivially_destructible<NontrivialDestructor>::value); >+#ifdef ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL >+ EXPECT_FALSE(absl::is_trivially_destructible<DeletedDestructor>::value); >+#endif >+ >+ // simple_pair of such types is trivial >+ EXPECT_TRUE((absl::is_trivially_destructible<simple_pair<int, int>>::value)); >+ EXPECT_TRUE((absl::is_trivially_destructible< >+ simple_pair<Trivial, TrivialDestructor>>::value)); >+ >+ // Verify that types without trivial destructors are correctly marked as such. >+ EXPECT_FALSE(absl::is_trivially_destructible<std::string>::value); >+ EXPECT_FALSE(absl::is_trivially_destructible<std::vector<int>>::value); >+ >+ // Verify that simple_pairs of types without trivial destructors >+ // are not marked as trivial. >+ EXPECT_FALSE((absl::is_trivially_destructible< >+ simple_pair<int, std::string>>::value)); >+ EXPECT_FALSE((absl::is_trivially_destructible< >+ simple_pair<std::string, int>>::value)); >+ >+ // array of such types is trivial >+ using int10 = int[10]; >+ EXPECT_TRUE(absl::is_trivially_destructible<int10>::value); >+ using Trivial10 = Trivial[10]; >+ EXPECT_TRUE(absl::is_trivially_destructible<Trivial10>::value); >+ using TrivialDestructor10 = TrivialDestructor[10]; >+ EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor10>::value); >+ >+ // Conversely, the opposite also holds. >+ using NontrivialDestructor10 = NontrivialDestructor[10]; >+ EXPECT_FALSE(absl::is_trivially_destructible<NontrivialDestructor10>::value); >+} >+ >+TEST(TypeTraitsTest, TestTrivialDefaultCtor) { >+ // arithmetic types and pointers have trivial default constructors. >+ EXPECT_TRUE(absl::is_trivially_default_constructible<bool>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<char>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<unsigned char>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<signed char>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<wchar_t>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<int>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<unsigned int>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<int16_t>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<uint16_t>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<int64_t>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<uint64_t>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<float>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<double>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<long double>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<std::string*>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial*>::value); >+ EXPECT_TRUE( >+ absl::is_trivially_default_constructible<const std::string*>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<const Trivial*>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<std::string**>::value); >+ EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial**>::value); >+ >+ // types with compiler generated default ctors >+ EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial>::value); >+ EXPECT_TRUE( >+ absl::is_trivially_default_constructible<TrivialDefaultCtor>::value); >+ >+ // Verify that types without them are not. >+ EXPECT_FALSE( >+ absl::is_trivially_default_constructible<NontrivialDefaultCtor>::value); >+ EXPECT_FALSE( >+ absl::is_trivially_default_constructible<DeletedDefaultCtor>::value); >+ >+#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE >+ // types with nontrivial destructor are nontrivial >+ EXPECT_FALSE( >+ absl::is_trivially_default_constructible<NontrivialDestructor>::value); >+#endif >+ >+ // types with vtables >+ EXPECT_FALSE(absl::is_trivially_default_constructible<Base>::value); >+ >+ // Verify that simple_pair has trivial constructors where applicable. >+ EXPECT_TRUE((absl::is_trivially_default_constructible< >+ simple_pair<int, char*>>::value)); >+ EXPECT_TRUE((absl::is_trivially_default_constructible< >+ simple_pair<int, Trivial>>::value)); >+ EXPECT_TRUE((absl::is_trivially_default_constructible< >+ simple_pair<int, TrivialDefaultCtor>>::value)); >+ >+ // Verify that types without trivial constructors are >+ // correctly marked as such. >+ EXPECT_FALSE(absl::is_trivially_default_constructible<std::string>::value); >+ EXPECT_FALSE( >+ absl::is_trivially_default_constructible<std::vector<int>>::value); >+ >+ // Verify that simple_pairs of types without trivial constructors >+ // are not marked as trivial. >+ EXPECT_FALSE((absl::is_trivially_default_constructible< >+ simple_pair<int, std::string>>::value)); >+ EXPECT_FALSE((absl::is_trivially_default_constructible< >+ simple_pair<std::string, int>>::value)); >+ >+ // Verify that arrays of such types are trivially default constructible >+ using int10 = int[10]; >+ EXPECT_TRUE(absl::is_trivially_default_constructible<int10>::value); >+ using Trivial10 = Trivial[10]; >+ EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial10>::value); >+ using TrivialDefaultCtor10 = TrivialDefaultCtor[10]; >+ EXPECT_TRUE( >+ absl::is_trivially_default_constructible<TrivialDefaultCtor10>::value); >+ >+ // Conversely, the opposite also holds. >+#ifdef ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL >+ using NontrivialDefaultCtor10 = NontrivialDefaultCtor[10]; >+ EXPECT_FALSE( >+ absl::is_trivially_default_constructible<NontrivialDefaultCtor10>::value); >+#endif >+} >+ >+TEST(TypeTraitsTest, TestTrivialCopyCtor) { >+ // Verify that arithmetic types and pointers have trivial copy >+ // constructors. >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<bool>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<char>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<unsigned char>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<signed char>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<wchar_t>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<int>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<unsigned int>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<int16_t>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<uint16_t>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<int64_t>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<uint64_t>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<float>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<double>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<long double>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string*>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial*>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<const std::string*>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<const Trivial*>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string**>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial**>::value); >+ >+ // types with compiler generated copy ctors >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<TrivialCopyCtor>::value); >+ >+ // Verify that types without them (i.e. nontrivial or deleted) are not. >+ EXPECT_FALSE( >+ absl::is_trivially_copy_constructible<NontrivialCopyCtor>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_constructible<DeletedCopyCtor>::value); >+ EXPECT_FALSE( >+ absl::is_trivially_copy_constructible<NonCopyable>::value); >+ >+#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE >+ // type with nontrivial destructor are nontrivial copy construbtible >+ EXPECT_FALSE( >+ absl::is_trivially_copy_constructible<NontrivialDestructor>::value); >+#endif >+ >+ // types with vtables >+ EXPECT_FALSE(absl::is_trivially_copy_constructible<Base>::value); >+ >+ // Verify that simple_pair of such types is trivially copy constructible >+ EXPECT_TRUE( >+ (absl::is_trivially_copy_constructible<simple_pair<int, char*>>::value)); >+ EXPECT_TRUE(( >+ absl::is_trivially_copy_constructible<simple_pair<int, Trivial>>::value)); >+ EXPECT_TRUE((absl::is_trivially_copy_constructible< >+ simple_pair<int, TrivialCopyCtor>>::value)); >+ >+ // Verify that types without trivial copy constructors are >+ // correctly marked as such. >+ EXPECT_FALSE(absl::is_trivially_copy_constructible<std::string>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_constructible<std::vector<int>>::value); >+ >+ // Verify that simple_pairs of types without trivial copy constructors >+ // are not marked as trivial. >+ EXPECT_FALSE((absl::is_trivially_copy_constructible< >+ simple_pair<int, std::string>>::value)); >+ EXPECT_FALSE((absl::is_trivially_copy_constructible< >+ simple_pair<std::string, int>>::value)); >+ >+ // Verify that arrays are not >+ using int10 = int[10]; >+ EXPECT_FALSE(absl::is_trivially_copy_constructible<int10>::value); >+} >+ >+TEST(TypeTraitsTest, TestTrivialCopyAssign) { >+ // Verify that arithmetic types and pointers have trivial copy >+ // assignment operators. >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<bool>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<char>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<unsigned char>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<signed char>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<wchar_t>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<unsigned int>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<int16_t>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<uint16_t>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<int64_t>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<uint64_t>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<float>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<double>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<long double>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string*>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial*>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<const std::string*>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<const Trivial*>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string**>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial**>::value); >+ >+ // const qualified types are not assignable >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<const int>::value); >+ >+ // types with compiler generated copy assignment >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<TrivialCopyAssign>::value); >+ >+ // Verify that types without them (i.e. nontrivial or deleted) are not. >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<NontrivialCopyAssign>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<DeletedCopyAssign>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<NonCopyable>::value); >+ >+ // types with vtables >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<Base>::value); >+ >+ // Verify that simple_pair is trivially assignable >+ EXPECT_TRUE( >+ (absl::is_trivially_copy_assignable<simple_pair<int, char*>>::value)); >+ EXPECT_TRUE( >+ (absl::is_trivially_copy_assignable<simple_pair<int, Trivial>>::value)); >+ EXPECT_TRUE((absl::is_trivially_copy_assignable< >+ simple_pair<int, TrivialCopyAssign>>::value)); >+ >+ // Verify that types not trivially copy assignable are >+ // correctly marked as such. >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<std::string>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<std::vector<int>>::value); >+ >+ // Verify that simple_pairs of types not trivially copy assignable >+ // are not marked as trivial. >+ EXPECT_FALSE((absl::is_trivially_copy_assignable< >+ simple_pair<int, std::string>>::value)); >+ EXPECT_FALSE((absl::is_trivially_copy_assignable< >+ simple_pair<std::string, int>>::value)); >+ >+ // Verify that arrays are not trivially copy assignable >+ using int10 = int[10]; >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<int10>::value); >+ >+ // Verify that references are handled correctly >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial&&>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial&>::value); >+} >+ >+#define ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(trait_name, ...) \ >+ EXPECT_TRUE((std::is_same<typename std::trait_name<__VA_ARGS__>::type, \ >+ absl::trait_name##_t<__VA_ARGS__>>::value)) >+ >+TEST(TypeTraitsTest, TestRemoveCVAliases) { >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, const int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, const volatile int); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, const int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, const volatile int); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, const int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, const volatile int); >+} >+ >+TEST(TypeTraitsTest, TestAddCVAliases) { >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, const int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, const volatile int); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, const int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, const volatile int); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, const int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, const volatile int); >+} >+ >+TEST(TypeTraitsTest, TestReferenceAliases) { >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int&&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int&&); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int&&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int&&); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int&&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int&&); >+} >+ >+TEST(TypeTraitsTest, TestPointerAliases) { >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_pointer, int*); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_pointer, volatile int*); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_pointer, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_pointer, volatile int); >+} >+ >+TEST(TypeTraitsTest, TestSignednessAliases) { >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, unsigned); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, volatile unsigned); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, unsigned); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, volatile unsigned); >+} >+ >+TEST(TypeTraitsTest, TestExtentAliases) { >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[]); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[1]); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[1][1]); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[][1]); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[]); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[1]); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[1][1]); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[][1]); >+} >+ >+TEST(TypeTraitsTest, TestAlignedStorageAlias) { >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 1); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 2); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 3); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 4); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 5); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 6); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 7); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 8); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 9); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 10); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 11); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 12); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 13); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 14); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 15); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 16); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 17); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 18); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 19); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 20); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 21); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 22); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 23); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 24); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 25); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 26); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 27); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 28); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 29); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 30); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 31); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 32); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 33); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 1, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 2, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 3, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 4, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 5, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 6, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 7, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 8, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 9, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 10, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 11, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 12, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 13, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 14, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 15, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 16, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 17, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 18, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 19, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 20, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 21, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 22, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 23, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 24, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 25, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 26, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 27, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 28, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 29, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 30, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 31, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 32, 128); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 33, 128); >+} >+ >+TEST(TypeTraitsTest, TestDecay) { >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int&); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int&); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[1]); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[1][1]); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[][1]); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int()); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(float)); // NOLINT >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(char, ...)); // NOLINT >+} >+ >+struct TypeA {}; >+struct TypeB {}; >+struct TypeC {}; >+struct TypeD {}; >+ >+template <typename T> >+struct Wrap {}; >+ >+enum class TypeEnum { A, B, C, D }; >+ >+struct GetTypeT { >+ template <typename T, >+ absl::enable_if_t<std::is_same<T, TypeA>::value, int> = 0> >+ TypeEnum operator()(Wrap<T>) const { >+ return TypeEnum::A; >+ } >+ >+ template <typename T, >+ absl::enable_if_t<std::is_same<T, TypeB>::value, int> = 0> >+ TypeEnum operator()(Wrap<T>) const { >+ return TypeEnum::B; >+ } >+ >+ template <typename T, >+ absl::enable_if_t<std::is_same<T, TypeC>::value, int> = 0> >+ TypeEnum operator()(Wrap<T>) const { >+ return TypeEnum::C; >+ } >+ >+ // NOTE: TypeD is intentionally not handled >+} constexpr GetType = {}; >+ >+TEST(TypeTraitsTest, TestEnableIf) { >+ EXPECT_EQ(TypeEnum::A, GetType(Wrap<TypeA>())); >+ EXPECT_EQ(TypeEnum::B, GetType(Wrap<TypeB>())); >+ EXPECT_EQ(TypeEnum::C, GetType(Wrap<TypeC>())); >+} >+ >+TEST(TypeTraitsTest, TestConditional) { >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(conditional, true, int, char); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(conditional, false, int, char); >+} >+ >+// TODO(calabrese) Check with specialized std::common_type >+TEST(TypeTraitsTest, TestCommonType) { >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char, int); >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char&); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char, int&); >+} >+ >+TEST(TypeTraitsTest, TestUnderlyingType) { >+ enum class enum_char : char {}; >+ enum class enum_long_long : long long {}; // NOLINT(runtime/int) >+ >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(underlying_type, enum_char); >+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(underlying_type, enum_long_long); >+} >+ >+struct GetTypeExtT { >+ template <typename T> >+ absl::result_of_t<const GetTypeT&(T)> operator()(T&& arg) const { >+ return GetType(std::forward<T>(arg)); >+ } >+ >+ TypeEnum operator()(Wrap<TypeD>) const { return TypeEnum::D; } >+} constexpr GetTypeExt = {}; >+ >+TEST(TypeTraitsTest, TestResultOf) { >+ EXPECT_EQ(TypeEnum::A, GetTypeExt(Wrap<TypeA>())); >+ EXPECT_EQ(TypeEnum::B, GetTypeExt(Wrap<TypeB>())); >+ EXPECT_EQ(TypeEnum::C, GetTypeExt(Wrap<TypeC>())); >+ EXPECT_EQ(TypeEnum::D, GetTypeExt(Wrap<TypeD>())); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..f49571ebb3e1042434151a2237127a99df1ad301 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/BUILD.bazel >@@ -0,0 +1,67 @@ >+# 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. >+ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+) >+ >+package(default_visibility = ["//visibility:public"]) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+cc_library( >+ name = "int128", >+ srcs = [ >+ "int128.cc", >+ "int128_have_intrinsic.inc", >+ "int128_no_intrinsic.inc", >+ ], >+ hdrs = ["int128.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ ], >+) >+ >+cc_test( >+ name = "int128_test", >+ size = "small", >+ srcs = [ >+ "int128_stream_test.cc", >+ "int128_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":int128", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "//absl/meta:type_traits", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "int128_benchmark", >+ srcs = ["int128_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ deps = [ >+ ":int128", >+ "//absl/base:config", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..fdfa2e271ffffdf33d6c7307fe54e995f4c9789b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/BUILD.gn >@@ -0,0 +1,36 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("int128") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "int128.cc", >+ "int128_have_intrinsic.inc", >+ "int128_no_intrinsic.inc", >+ ] >+ public = [ >+ "int128.h", >+ ] >+ deps = [ >+ "../base:config", >+ "../base:core_headers", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..3360b2ee726e1a198f59c3466f21ce5a3bf08b90 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/CMakeLists.txt >@@ -0,0 +1,62 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+list(APPEND NUMERIC_PUBLIC_HEADERS >+ "int128.h" >+) >+ >+ >+# library 128 >+list(APPEND INT128_SRC >+ "int128.cc" >+ ${NUMERIC_PUBLIC_HEADERS} >+) >+absl_library( >+ TARGET >+ absl_int128 >+ SOURCES >+ ${INT128_SRC} >+ PUBLIC_LIBRARIES >+ ${INT128_PUBLIC_LIBRARIES} >+ EXPORT_NAME >+ int128 >+) >+ >+ >+absl_header_library( >+ TARGET >+ absl_numeric >+ PUBLIC_LIBRARIES >+ absl::int128 >+ EXPORT_NAME >+ numeric >+) >+ >+# test int128_test >+set(INT128_TEST_SRC "int128_test.cc") >+set(INT128_TEST_PUBLIC_LIBRARIES absl::numeric absl::base) >+ >+absl_test( >+ TARGET >+ int128_test >+ SOURCES >+ ${INT128_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${INT128_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..cd79534f3bfd9f650ed158f35b5d86c74f178cd3 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128.cc >@@ -0,0 +1,251 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/numeric/int128.h" >+ >+#include <stddef.h> >+#include <cassert> >+#include <iomanip> >+#include <iostream> // NOLINT(readability/streams) >+#include <sstream> >+#include <string> >+#include <type_traits> >+ >+namespace absl { >+ >+const uint128 kuint128max = MakeUint128(std::numeric_limits<uint64_t>::max(), >+ std::numeric_limits<uint64_t>::max()); >+ >+namespace { >+ >+// Returns the 0-based position of the last set bit (i.e., most significant bit) >+// in the given uint64_t. The argument may not be 0. >+// >+// For example: >+// Given: 5 (decimal) == 101 (binary) >+// Returns: 2 >+#define STEP(T, n, pos, sh) \ >+ do { \ >+ if ((n) >= (static_cast<T>(1) << (sh))) { \ >+ (n) = (n) >> (sh); \ >+ (pos) |= (sh); \ >+ } \ >+ } while (0) >+static inline int Fls64(uint64_t n) { >+ assert(n != 0); >+ int pos = 0; >+ STEP(uint64_t, n, pos, 0x20); >+ uint32_t n32 = static_cast<uint32_t>(n); >+ STEP(uint32_t, n32, pos, 0x10); >+ STEP(uint32_t, n32, pos, 0x08); >+ STEP(uint32_t, n32, pos, 0x04); >+ return pos + ((uint64_t{0x3333333322221100} >> (n32 << 2)) & 0x3); >+} >+#undef STEP >+ >+// Like Fls64() above, but returns the 0-based position of the last set bit >+// (i.e., most significant bit) in the given uint128. The argument may not be 0. >+static inline int Fls128(uint128 n) { >+ if (uint64_t hi = Uint128High64(n)) { >+ return Fls64(hi) + 64; >+ } >+ return Fls64(Uint128Low64(n)); >+} >+ >+// Long division/modulo for uint128 implemented using the shift-subtract >+// division algorithm adapted from: >+// http://stackoverflow.com/questions/5386377/division-without-using >+void DivModImpl(uint128 dividend, uint128 divisor, uint128* quotient_ret, >+ uint128* remainder_ret) { >+ assert(divisor != 0); >+ >+ if (divisor > dividend) { >+ *quotient_ret = 0; >+ *remainder_ret = dividend; >+ return; >+ } >+ >+ if (divisor == dividend) { >+ *quotient_ret = 1; >+ *remainder_ret = 0; >+ return; >+ } >+ >+ uint128 denominator = divisor; >+ uint128 quotient = 0; >+ >+ // Left aligns the MSB of the denominator and the dividend. >+ const int shift = Fls128(dividend) - Fls128(denominator); >+ denominator <<= shift; >+ >+ // Uses shift-subtract algorithm to divide dividend by denominator. The >+ // remainder will be left in dividend. >+ for (int i = 0; i <= shift; ++i) { >+ quotient <<= 1; >+ if (dividend >= denominator) { >+ dividend -= denominator; >+ quotient |= 1; >+ } >+ denominator >>= 1; >+ } >+ >+ *quotient_ret = quotient; >+ *remainder_ret = dividend; >+} >+ >+template <typename T> >+uint128 MakeUint128FromFloat(T v) { >+ static_assert(std::is_floating_point<T>::value, ""); >+ >+ // Rounding behavior is towards zero, same as for built-in types. >+ >+ // Undefined behavior if v is NaN or cannot fit into uint128. >+ assert(std::isfinite(v) && v > -1 && >+ (std::numeric_limits<T>::max_exponent <= 128 || >+ v < std::ldexp(static_cast<T>(1), 128))); >+ >+ if (v >= std::ldexp(static_cast<T>(1), 64)) { >+ uint64_t hi = static_cast<uint64_t>(std::ldexp(v, -64)); >+ uint64_t lo = static_cast<uint64_t>(v - std::ldexp(static_cast<T>(hi), 64)); >+ return MakeUint128(hi, lo); >+ } >+ >+ return MakeUint128(0, static_cast<uint64_t>(v)); >+} >+} // namespace >+ >+uint128::uint128(float v) : uint128(MakeUint128FromFloat(v)) {} >+uint128::uint128(double v) : uint128(MakeUint128FromFloat(v)) {} >+uint128::uint128(long double v) : uint128(MakeUint128FromFloat(v)) {} >+ >+uint128 operator/(uint128 lhs, uint128 rhs) { >+#if defined(ABSL_HAVE_INTRINSIC_INT128) >+ return static_cast<unsigned __int128>(lhs) / >+ static_cast<unsigned __int128>(rhs); >+#else // ABSL_HAVE_INTRINSIC_INT128 >+ uint128 quotient = 0; >+ uint128 remainder = 0; >+ DivModImpl(lhs, rhs, "ient, &remainder); >+ return quotient; >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+} >+uint128 operator%(uint128 lhs, uint128 rhs) { >+#if defined(ABSL_HAVE_INTRINSIC_INT128) >+ return static_cast<unsigned __int128>(lhs) % >+ static_cast<unsigned __int128>(rhs); >+#else // ABSL_HAVE_INTRINSIC_INT128 >+ uint128 quotient = 0; >+ uint128 remainder = 0; >+ DivModImpl(lhs, rhs, "ient, &remainder); >+ return remainder; >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+} >+ >+namespace { >+ >+std::string Uint128ToFormattedString(uint128 v, std::ios_base::fmtflags flags) { >+ // Select a divisor which is the largest power of the base < 2^64. >+ uint128 div; >+ int div_base_log; >+ switch (flags & std::ios::basefield) { >+ case std::ios::hex: >+ div = 0x1000000000000000; // 16^15 >+ div_base_log = 15; >+ break; >+ case std::ios::oct: >+ div = 01000000000000000000000; // 8^21 >+ div_base_log = 21; >+ break; >+ default: // std::ios::dec >+ div = 10000000000000000000u; // 10^19 >+ div_base_log = 19; >+ break; >+ } >+ >+ // Now piece together the uint128 representation from three chunks of the >+ // original value, each less than "div" and therefore representable as a >+ // uint64_t. >+ std::ostringstream os; >+ std::ios_base::fmtflags copy_mask = >+ std::ios::basefield | std::ios::showbase | std::ios::uppercase; >+ os.setf(flags & copy_mask, copy_mask); >+ uint128 high = v; >+ uint128 low; >+ DivModImpl(high, div, &high, &low); >+ uint128 mid; >+ DivModImpl(high, div, &high, &mid); >+ if (Uint128Low64(high) != 0) { >+ os << Uint128Low64(high); >+ os << std::noshowbase << std::setfill('0') << std::setw(div_base_log); >+ os << Uint128Low64(mid); >+ os << std::setw(div_base_log); >+ } else if (Uint128Low64(mid) != 0) { >+ os << Uint128Low64(mid); >+ os << std::noshowbase << std::setfill('0') << std::setw(div_base_log); >+ } >+ os << Uint128Low64(low); >+ return os.str(); >+} >+ >+} // namespace >+ >+std::ostream& operator<<(std::ostream& os, uint128 v) { >+ std::ios_base::fmtflags flags = os.flags(); >+ std::string rep = Uint128ToFormattedString(v, flags); >+ >+ // Add the requisite padding. >+ std::streamsize width = os.width(0); >+ if (static_cast<size_t>(width) > rep.size()) { >+ std::ios::fmtflags adjustfield = flags & std::ios::adjustfield; >+ if (adjustfield == std::ios::left) { >+ rep.append(width - rep.size(), os.fill()); >+ } else if (adjustfield == std::ios::internal && >+ (flags & std::ios::showbase) && >+ (flags & std::ios::basefield) == std::ios::hex && v != 0) { >+ rep.insert(2, width - rep.size(), os.fill()); >+ } else { >+ rep.insert(0, width - rep.size(), os.fill()); >+ } >+ } >+ >+ return os << rep; >+} >+ >+} // namespace absl >+ >+namespace std { >+constexpr bool numeric_limits<absl::uint128>::is_specialized; >+constexpr bool numeric_limits<absl::uint128>::is_signed; >+constexpr bool numeric_limits<absl::uint128>::is_integer; >+constexpr bool numeric_limits<absl::uint128>::is_exact; >+constexpr bool numeric_limits<absl::uint128>::has_infinity; >+constexpr bool numeric_limits<absl::uint128>::has_quiet_NaN; >+constexpr bool numeric_limits<absl::uint128>::has_signaling_NaN; >+constexpr float_denorm_style numeric_limits<absl::uint128>::has_denorm; >+constexpr bool numeric_limits<absl::uint128>::has_denorm_loss; >+constexpr float_round_style numeric_limits<absl::uint128>::round_style; >+constexpr bool numeric_limits<absl::uint128>::is_iec559; >+constexpr bool numeric_limits<absl::uint128>::is_bounded; >+constexpr bool numeric_limits<absl::uint128>::is_modulo; >+constexpr int numeric_limits<absl::uint128>::digits; >+constexpr int numeric_limits<absl::uint128>::digits10; >+constexpr int numeric_limits<absl::uint128>::max_digits10; >+constexpr int numeric_limits<absl::uint128>::radix; >+constexpr int numeric_limits<absl::uint128>::min_exponent; >+constexpr int numeric_limits<absl::uint128>::min_exponent10; >+constexpr int numeric_limits<absl::uint128>::max_exponent; >+constexpr int numeric_limits<absl::uint128>::max_exponent10; >+constexpr bool numeric_limits<absl::uint128>::traps; >+constexpr bool numeric_limits<absl::uint128>::tinyness_before; >+} // namespace std >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128.h >new file mode 100644 >index 0000000000000000000000000000000000000000..2d131b8bda1c348d91743e7c42d38a57968c330b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128.h >@@ -0,0 +1,705 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: int128.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines 128-bit integer types. >+// >+// Currently, this file defines `uint128`, an unsigned 128-bit integer; a signed >+// 128-bit integer is forthcoming. >+ >+#ifndef ABSL_NUMERIC_INT128_H_ >+#define ABSL_NUMERIC_INT128_H_ >+ >+#include <cassert> >+#include <cmath> >+#include <cstdint> >+#include <cstring> >+#include <iosfwd> >+#include <limits> >+#include <utility> >+ >+#include "absl/base/config.h" >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+ >+namespace absl { >+ >+ >+// uint128 >+// >+// An unsigned 128-bit integer type. The API is meant to mimic an intrinsic type >+// as closely as is practical, including exhibiting undefined behavior in >+// analogous cases (e.g. division by zero). This type is intended to be a >+// drop-in replacement once C++ supports an intrinsic `uint128_t` type; when >+// that occurs, existing well-behaved uses of `uint128` will continue to work >+// using that new type. >+// >+// Note: code written with this type will continue to compile once `uint128_t` >+// is introduced, provided the replacement helper functions >+// `Uint128(Low|High)64()` and `MakeUint128()` are made. >+// >+// A `uint128` supports the following: >+// >+// * Implicit construction from integral types >+// * Explicit conversion to integral types >+// >+// Additionally, if your compiler supports `__int128`, `uint128` is >+// interoperable with that type. (Abseil checks for this compatibility through >+// the `ABSL_HAVE_INTRINSIC_INT128` macro.) >+// >+// However, a `uint128` differs from intrinsic integral types in the following >+// ways: >+// >+// * Errors on implicit conversions that do not preserve value (such as >+// loss of precision when converting to float values). >+// * Requires explicit construction from and conversion to floating point >+// types. >+// * Conversion to integral types requires an explicit static_cast() to >+// mimic use of the `-Wnarrowing` compiler flag. >+// * The alignment requirement of `uint128` may differ from that of an >+// intrinsic 128-bit integer type depending on platform and build >+// configuration. >+// >+// Example: >+// >+// float y = absl::Uint128Max(); // Error. uint128 cannot be implicitly >+// // converted to float. >+// >+// absl::uint128 v; >+// uint64_t i = v; // Error >+// uint64_t i = static_cast<uint64_t>(v); // OK >+// >+class >+#if defined(ABSL_HAVE_INTRINSIC_INT128) >+ alignas(unsigned __int128) >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ uint128 { >+ public: >+ uint128() = default; >+ >+ // Constructors from arithmetic types >+ constexpr uint128(int v); // NOLINT(runtime/explicit) >+ constexpr uint128(unsigned int v); // NOLINT(runtime/explicit) >+ constexpr uint128(long v); // NOLINT(runtime/int) >+ constexpr uint128(unsigned long v); // NOLINT(runtime/int) >+ constexpr uint128(long long v); // NOLINT(runtime/int) >+ constexpr uint128(unsigned long long v); // NOLINT(runtime/int) >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+ constexpr uint128(__int128 v); // NOLINT(runtime/explicit) >+ constexpr uint128(unsigned __int128 v); // NOLINT(runtime/explicit) >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ explicit uint128(float v); >+ explicit uint128(double v); >+ explicit uint128(long double v); >+ >+ // Assignment operators from arithmetic types >+ uint128& operator=(int v); >+ uint128& operator=(unsigned int v); >+ uint128& operator=(long v); // NOLINT(runtime/int) >+ uint128& operator=(unsigned long v); // NOLINT(runtime/int) >+ uint128& operator=(long long v); // NOLINT(runtime/int) >+ uint128& operator=(unsigned long long v); // NOLINT(runtime/int) >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+ uint128& operator=(__int128 v); >+ uint128& operator=(unsigned __int128 v); >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ >+ // Conversion operators to other arithmetic types >+ constexpr explicit operator bool() const; >+ constexpr explicit operator char() const; >+ constexpr explicit operator signed char() const; >+ constexpr explicit operator unsigned char() const; >+ constexpr explicit operator char16_t() const; >+ constexpr explicit operator char32_t() const; >+ constexpr explicit operator wchar_t() const; >+ constexpr explicit operator short() const; // NOLINT(runtime/int) >+ // NOLINTNEXTLINE(runtime/int) >+ constexpr explicit operator unsigned short() const; >+ constexpr explicit operator int() const; >+ constexpr explicit operator unsigned int() const; >+ constexpr explicit operator long() const; // NOLINT(runtime/int) >+ // NOLINTNEXTLINE(runtime/int) >+ constexpr explicit operator unsigned long() const; >+ // NOLINTNEXTLINE(runtime/int) >+ constexpr explicit operator long long() const; >+ // NOLINTNEXTLINE(runtime/int) >+ constexpr explicit operator unsigned long long() const; >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+ constexpr explicit operator __int128() const; >+ constexpr explicit operator unsigned __int128() const; >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ explicit operator float() const; >+ explicit operator double() const; >+ explicit operator long double() const; >+ >+ // Trivial copy constructor, assignment operator and destructor. >+ >+ // Arithmetic operators. >+ uint128& operator+=(uint128 other); >+ uint128& operator-=(uint128 other); >+ uint128& operator*=(uint128 other); >+ // Long division/modulo for uint128. >+ uint128& operator/=(uint128 other); >+ uint128& operator%=(uint128 other); >+ uint128 operator++(int); >+ uint128 operator--(int); >+ uint128& operator<<=(int); >+ uint128& operator>>=(int); >+ uint128& operator&=(uint128 other); >+ uint128& operator|=(uint128 other); >+ uint128& operator^=(uint128 other); >+ uint128& operator++(); >+ uint128& operator--(); >+ >+ // Uint128Low64() >+ // >+ // Returns the lower 64-bit value of a `uint128` value. >+ friend constexpr uint64_t Uint128Low64(uint128 v); >+ >+ // Uint128High64() >+ // >+ // Returns the higher 64-bit value of a `uint128` value. >+ friend constexpr uint64_t Uint128High64(uint128 v); >+ >+ // MakeUInt128() >+ // >+ // Constructs a `uint128` numeric value from two 64-bit unsigned integers. >+ // Note that this factory function is the only way to construct a `uint128` >+ // from integer values greater than 2^64. >+ // >+ // Example: >+ // >+ // absl::uint128 big = absl::MakeUint128(1, 0); >+ friend constexpr uint128 MakeUint128(uint64_t high, uint64_t low); >+ >+ // Uint128Max() >+ // >+ // Returns the highest value for a 128-bit unsigned integer. >+ friend constexpr uint128 Uint128Max(); >+ >+ private: >+ constexpr uint128(uint64_t high, uint64_t low); >+ >+ // TODO(strel) Update implementation to use __int128 once all users of >+ // uint128 are fixed to not depend on alignof(uint128) == 8. Also add >+ // alignas(16) to class definition to keep alignment consistent across >+ // platforms. >+#if defined(ABSL_IS_LITTLE_ENDIAN) >+ uint64_t lo_; >+ uint64_t hi_; >+#elif defined(ABSL_IS_BIG_ENDIAN) >+ uint64_t hi_; >+ uint64_t lo_; >+#else // byte order >+#error "Unsupported byte order: must be little-endian or big-endian." >+#endif // byte order >+}; >+ >+// Prefer to use the constexpr `Uint128Max()`. >+// >+// TODO(absl-team) deprecate kuint128max once migration tool is released. >+extern const uint128 kuint128max; >+ >+// allow uint128 to be logged >+std::ostream& operator<<(std::ostream& os, uint128 v); >+ >+// TODO(strel) add operator>>(std::istream&, uint128) >+ >+constexpr uint128 Uint128Max() { >+ return uint128(std::numeric_limits<uint64_t>::max(), >+ std::numeric_limits<uint64_t>::max()); >+} >+ >+} // namespace absl >+ >+// Specialized numeric_limits for uint128. >+namespace std { >+template <> >+class numeric_limits<absl::uint128> { >+ public: >+ static constexpr bool is_specialized = true; >+ static constexpr bool is_signed = false; >+ static constexpr bool is_integer = true; >+ static constexpr bool is_exact = true; >+ static constexpr bool has_infinity = false; >+ static constexpr bool has_quiet_NaN = false; >+ static constexpr bool has_signaling_NaN = false; >+ static constexpr float_denorm_style has_denorm = denorm_absent; >+ static constexpr bool has_denorm_loss = false; >+ static constexpr float_round_style round_style = round_toward_zero; >+ static constexpr bool is_iec559 = false; >+ static constexpr bool is_bounded = true; >+ static constexpr bool is_modulo = true; >+ static constexpr int digits = 128; >+ static constexpr int digits10 = 38; >+ static constexpr int max_digits10 = 0; >+ static constexpr int radix = 2; >+ static constexpr int min_exponent = 0; >+ static constexpr int min_exponent10 = 0; >+ static constexpr int max_exponent = 0; >+ static constexpr int max_exponent10 = 0; >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+ static constexpr bool traps = numeric_limits<unsigned __int128>::traps; >+#else // ABSL_HAVE_INTRINSIC_INT128 >+ static constexpr bool traps = numeric_limits<uint64_t>::traps; >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ static constexpr bool tinyness_before = false; >+ >+ static constexpr absl::uint128 min() { return 0; } >+ static constexpr absl::uint128 lowest() { return 0; } >+ static constexpr absl::uint128 max() { return absl::Uint128Max(); } >+ static constexpr absl::uint128 epsilon() { return 0; } >+ static constexpr absl::uint128 round_error() { return 0; } >+ static constexpr absl::uint128 infinity() { return 0; } >+ static constexpr absl::uint128 quiet_NaN() { return 0; } >+ static constexpr absl::uint128 signaling_NaN() { return 0; } >+ static constexpr absl::uint128 denorm_min() { return 0; } >+}; >+} // namespace std >+ >+// TODO(absl-team): Implement signed 128-bit type >+ >+// -------------------------------------------------------------------------- >+// Implementation details follow >+// -------------------------------------------------------------------------- >+namespace absl { >+ >+constexpr uint128 MakeUint128(uint64_t high, uint64_t low) { >+ return uint128(high, low); >+} >+ >+// Assignment from integer types. >+ >+inline uint128& uint128::operator=(int v) { return *this = uint128(v); } >+ >+inline uint128& uint128::operator=(unsigned int v) { >+ return *this = uint128(v); >+} >+ >+inline uint128& uint128::operator=(long v) { // NOLINT(runtime/int) >+ return *this = uint128(v); >+} >+ >+// NOLINTNEXTLINE(runtime/int) >+inline uint128& uint128::operator=(unsigned long v) { >+ return *this = uint128(v); >+} >+ >+// NOLINTNEXTLINE(runtime/int) >+inline uint128& uint128::operator=(long long v) { >+ return *this = uint128(v); >+} >+ >+// NOLINTNEXTLINE(runtime/int) >+inline uint128& uint128::operator=(unsigned long long v) { >+ return *this = uint128(v); >+} >+ >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+inline uint128& uint128::operator=(__int128 v) { >+ return *this = uint128(v); >+} >+ >+inline uint128& uint128::operator=(unsigned __int128 v) { >+ return *this = uint128(v); >+} >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ >+// Arithmetic operators. >+ >+uint128 operator<<(uint128 lhs, int amount); >+uint128 operator>>(uint128 lhs, int amount); >+uint128 operator+(uint128 lhs, uint128 rhs); >+uint128 operator-(uint128 lhs, uint128 rhs); >+uint128 operator*(uint128 lhs, uint128 rhs); >+uint128 operator/(uint128 lhs, uint128 rhs); >+uint128 operator%(uint128 lhs, uint128 rhs); >+ >+inline uint128& uint128::operator<<=(int amount) { >+ *this = *this << amount; >+ return *this; >+} >+ >+inline uint128& uint128::operator>>=(int amount) { >+ *this = *this >> amount; >+ return *this; >+} >+ >+inline uint128& uint128::operator+=(uint128 other) { >+ *this = *this + other; >+ return *this; >+} >+ >+inline uint128& uint128::operator-=(uint128 other) { >+ *this = *this - other; >+ return *this; >+} >+ >+inline uint128& uint128::operator*=(uint128 other) { >+ *this = *this * other; >+ return *this; >+} >+ >+inline uint128& uint128::operator/=(uint128 other) { >+ *this = *this / other; >+ return *this; >+} >+ >+inline uint128& uint128::operator%=(uint128 other) { >+ *this = *this % other; >+ return *this; >+} >+ >+constexpr uint64_t Uint128Low64(uint128 v) { return v.lo_; } >+ >+constexpr uint64_t Uint128High64(uint128 v) { return v.hi_; } >+ >+// Constructors from integer types. >+ >+#if defined(ABSL_IS_LITTLE_ENDIAN) >+ >+constexpr uint128::uint128(uint64_t high, uint64_t low) >+ : lo_{low}, hi_{high} {} >+ >+constexpr uint128::uint128(int v) >+ : lo_{static_cast<uint64_t>(v)}, >+ hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0} {} >+constexpr uint128::uint128(long v) // NOLINT(runtime/int) >+ : lo_{static_cast<uint64_t>(v)}, >+ hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0} {} >+constexpr uint128::uint128(long long v) // NOLINT(runtime/int) >+ : lo_{static_cast<uint64_t>(v)}, >+ hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0} {} >+ >+constexpr uint128::uint128(unsigned int v) : lo_{v}, hi_{0} {} >+// NOLINTNEXTLINE(runtime/int) >+constexpr uint128::uint128(unsigned long v) : lo_{v}, hi_{0} {} >+// NOLINTNEXTLINE(runtime/int) >+constexpr uint128::uint128(unsigned long long v) : lo_{v}, hi_{0} {} >+ >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+constexpr uint128::uint128(__int128 v) >+ : lo_{static_cast<uint64_t>(v & ~uint64_t{0})}, >+ hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)} {} >+constexpr uint128::uint128(unsigned __int128 v) >+ : lo_{static_cast<uint64_t>(v & ~uint64_t{0})}, >+ hi_{static_cast<uint64_t>(v >> 64)} {} >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ >+#elif defined(ABSL_IS_BIG_ENDIAN) >+ >+constexpr uint128::uint128(uint64_t high, uint64_t low) >+ : hi_{high}, lo_{low} {} >+ >+constexpr uint128::uint128(int v) >+ : hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0}, >+ lo_{static_cast<uint64_t>(v)} {} >+constexpr uint128::uint128(long v) // NOLINT(runtime/int) >+ : hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0}, >+ lo_{static_cast<uint64_t>(v)} {} >+constexpr uint128::uint128(long long v) // NOLINT(runtime/int) >+ : hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0}, >+ lo_{static_cast<uint64_t>(v)} {} >+ >+constexpr uint128::uint128(unsigned int v) : hi_{0}, lo_{v} {} >+// NOLINTNEXTLINE(runtime/int) >+constexpr uint128::uint128(unsigned long v) : hi_{0}, lo_{v} {} >+// NOLINTNEXTLINE(runtime/int) >+constexpr uint128::uint128(unsigned long long v) : hi_{0}, lo_{v} {} >+ >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+constexpr uint128::uint128(__int128 v) >+ : hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)}, >+ lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {} >+constexpr uint128::uint128(unsigned __int128 v) >+ : hi_{static_cast<uint64_t>(v >> 64)}, >+ lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {} >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ >+#else // byte order >+#error "Unsupported byte order: must be little-endian or big-endian." >+#endif // byte order >+ >+// Conversion operators to integer types. >+ >+constexpr uint128::operator bool() const { return lo_ || hi_; } >+ >+constexpr uint128::operator char() const { return static_cast<char>(lo_); } >+ >+constexpr uint128::operator signed char() const { >+ return static_cast<signed char>(lo_); >+} >+ >+constexpr uint128::operator unsigned char() const { >+ return static_cast<unsigned char>(lo_); >+} >+ >+constexpr uint128::operator char16_t() const { >+ return static_cast<char16_t>(lo_); >+} >+ >+constexpr uint128::operator char32_t() const { >+ return static_cast<char32_t>(lo_); >+} >+ >+constexpr uint128::operator wchar_t() const { >+ return static_cast<wchar_t>(lo_); >+} >+ >+// NOLINTNEXTLINE(runtime/int) >+constexpr uint128::operator short() const { return static_cast<short>(lo_); } >+ >+constexpr uint128::operator unsigned short() const { // NOLINT(runtime/int) >+ return static_cast<unsigned short>(lo_); // NOLINT(runtime/int) >+} >+ >+constexpr uint128::operator int() const { return static_cast<int>(lo_); } >+ >+constexpr uint128::operator unsigned int() const { >+ return static_cast<unsigned int>(lo_); >+} >+ >+// NOLINTNEXTLINE(runtime/int) >+constexpr uint128::operator long() const { return static_cast<long>(lo_); } >+ >+constexpr uint128::operator unsigned long() const { // NOLINT(runtime/int) >+ return static_cast<unsigned long>(lo_); // NOLINT(runtime/int) >+} >+ >+constexpr uint128::operator long long() const { // NOLINT(runtime/int) >+ return static_cast<long long>(lo_); // NOLINT(runtime/int) >+} >+ >+constexpr uint128::operator unsigned long long() const { // NOLINT(runtime/int) >+ return static_cast<unsigned long long>(lo_); // NOLINT(runtime/int) >+} >+ >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+constexpr uint128::operator __int128() const { >+ return (static_cast<__int128>(hi_) << 64) + lo_; >+} >+ >+constexpr uint128::operator unsigned __int128() const { >+ return (static_cast<unsigned __int128>(hi_) << 64) + lo_; >+} >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ >+// Conversion operators to floating point types. >+ >+inline uint128::operator float() const { >+ return static_cast<float>(lo_) + std::ldexp(static_cast<float>(hi_), 64); >+} >+ >+inline uint128::operator double() const { >+ return static_cast<double>(lo_) + std::ldexp(static_cast<double>(hi_), 64); >+} >+ >+inline uint128::operator long double() const { >+ return static_cast<long double>(lo_) + >+ std::ldexp(static_cast<long double>(hi_), 64); >+} >+ >+// Comparison operators. >+ >+inline bool operator==(uint128 lhs, uint128 rhs) { >+ return (Uint128Low64(lhs) == Uint128Low64(rhs) && >+ Uint128High64(lhs) == Uint128High64(rhs)); >+} >+ >+inline bool operator!=(uint128 lhs, uint128 rhs) { >+ return !(lhs == rhs); >+} >+ >+inline bool operator<(uint128 lhs, uint128 rhs) { >+ return (Uint128High64(lhs) == Uint128High64(rhs)) >+ ? (Uint128Low64(lhs) < Uint128Low64(rhs)) >+ : (Uint128High64(lhs) < Uint128High64(rhs)); >+} >+ >+inline bool operator>(uint128 lhs, uint128 rhs) { >+ return (Uint128High64(lhs) == Uint128High64(rhs)) >+ ? (Uint128Low64(lhs) > Uint128Low64(rhs)) >+ : (Uint128High64(lhs) > Uint128High64(rhs)); >+} >+ >+inline bool operator<=(uint128 lhs, uint128 rhs) { >+ return (Uint128High64(lhs) == Uint128High64(rhs)) >+ ? (Uint128Low64(lhs) <= Uint128Low64(rhs)) >+ : (Uint128High64(lhs) <= Uint128High64(rhs)); >+} >+ >+inline bool operator>=(uint128 lhs, uint128 rhs) { >+ return (Uint128High64(lhs) == Uint128High64(rhs)) >+ ? (Uint128Low64(lhs) >= Uint128Low64(rhs)) >+ : (Uint128High64(lhs) >= Uint128High64(rhs)); >+} >+ >+// Unary operators. >+ >+inline uint128 operator-(uint128 val) { >+ uint64_t hi = ~Uint128High64(val); >+ uint64_t lo = ~Uint128Low64(val) + 1; >+ if (lo == 0) ++hi; // carry >+ return MakeUint128(hi, lo); >+} >+ >+inline bool operator!(uint128 val) { >+ return !Uint128High64(val) && !Uint128Low64(val); >+} >+ >+// Logical operators. >+ >+inline uint128 operator~(uint128 val) { >+ return MakeUint128(~Uint128High64(val), ~Uint128Low64(val)); >+} >+ >+inline uint128 operator|(uint128 lhs, uint128 rhs) { >+ return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs), >+ Uint128Low64(lhs) | Uint128Low64(rhs)); >+} >+ >+inline uint128 operator&(uint128 lhs, uint128 rhs) { >+ return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs), >+ Uint128Low64(lhs) & Uint128Low64(rhs)); >+} >+ >+inline uint128 operator^(uint128 lhs, uint128 rhs) { >+ return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs), >+ Uint128Low64(lhs) ^ Uint128Low64(rhs)); >+} >+ >+inline uint128& uint128::operator|=(uint128 other) { >+ hi_ |= other.hi_; >+ lo_ |= other.lo_; >+ return *this; >+} >+ >+inline uint128& uint128::operator&=(uint128 other) { >+ hi_ &= other.hi_; >+ lo_ &= other.lo_; >+ return *this; >+} >+ >+inline uint128& uint128::operator^=(uint128 other) { >+ hi_ ^= other.hi_; >+ lo_ ^= other.lo_; >+ return *this; >+} >+ >+// Arithmetic operators. >+ >+inline uint128 operator<<(uint128 lhs, int amount) { >+ // uint64_t shifts of >= 64 are undefined, so we will need some >+ // special-casing. >+ if (amount < 64) { >+ if (amount != 0) { >+ return MakeUint128( >+ (Uint128High64(lhs) << amount) | (Uint128Low64(lhs) >> (64 - amount)), >+ Uint128Low64(lhs) << amount); >+ } >+ return lhs; >+ } >+ return MakeUint128(Uint128Low64(lhs) << (amount - 64), 0); >+} >+ >+inline uint128 operator>>(uint128 lhs, int amount) { >+ // uint64_t shifts of >= 64 are undefined, so we will need some >+ // special-casing. >+ if (amount < 64) { >+ if (amount != 0) { >+ return MakeUint128(Uint128High64(lhs) >> amount, >+ (Uint128Low64(lhs) >> amount) | >+ (Uint128High64(lhs) << (64 - amount))); >+ } >+ return lhs; >+ } >+ return MakeUint128(0, Uint128High64(lhs) >> (amount - 64)); >+} >+ >+inline uint128 operator+(uint128 lhs, uint128 rhs) { >+ uint128 result = MakeUint128(Uint128High64(lhs) + Uint128High64(rhs), >+ Uint128Low64(lhs) + Uint128Low64(rhs)); >+ if (Uint128Low64(result) < Uint128Low64(lhs)) { // check for carry >+ return MakeUint128(Uint128High64(result) + 1, Uint128Low64(result)); >+ } >+ return result; >+} >+ >+inline uint128 operator-(uint128 lhs, uint128 rhs) { >+ uint128 result = MakeUint128(Uint128High64(lhs) - Uint128High64(rhs), >+ Uint128Low64(lhs) - Uint128Low64(rhs)); >+ if (Uint128Low64(lhs) < Uint128Low64(rhs)) { // check for carry >+ return MakeUint128(Uint128High64(result) - 1, Uint128Low64(result)); >+ } >+ return result; >+} >+ >+inline uint128 operator*(uint128 lhs, uint128 rhs) { >+#if defined(ABSL_HAVE_INTRINSIC_INT128) >+ // TODO(strel) Remove once alignment issues are resolved and unsigned __int128 >+ // can be used for uint128 storage. >+ return static_cast<unsigned __int128>(lhs) * >+ static_cast<unsigned __int128>(rhs); >+#else // ABSL_HAVE_INTRINSIC128 >+ uint64_t a32 = Uint128Low64(lhs) >> 32; >+ uint64_t a00 = Uint128Low64(lhs) & 0xffffffff; >+ uint64_t b32 = Uint128Low64(rhs) >> 32; >+ uint64_t b00 = Uint128Low64(rhs) & 0xffffffff; >+ uint128 result = >+ MakeUint128(Uint128High64(lhs) * Uint128Low64(rhs) + >+ Uint128Low64(lhs) * Uint128High64(rhs) + a32 * b32, >+ a00 * b00); >+ result += uint128(a32 * b00) << 32; >+ result += uint128(a00 * b32) << 32; >+ return result; >+#endif // ABSL_HAVE_INTRINSIC128 >+} >+ >+// Increment/decrement operators. >+ >+inline uint128 uint128::operator++(int) { >+ uint128 tmp(*this); >+ *this += 1; >+ return tmp; >+} >+ >+inline uint128 uint128::operator--(int) { >+ uint128 tmp(*this); >+ *this -= 1; >+ return tmp; >+} >+ >+inline uint128& uint128::operator++() { >+ *this += 1; >+ return *this; >+} >+ >+inline uint128& uint128::operator--() { >+ *this -= 1; >+ return *this; >+} >+ >+#if defined(ABSL_HAVE_INTRINSIC_INT128) >+#include "absl/numeric/int128_have_intrinsic.inc" >+#else // ABSL_HAVE_INTRINSIC_INT128 >+#include "absl/numeric/int128_no_intrinsic.inc" >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ >+} // namespace absl >+ >+#endif // ABSL_NUMERIC_INT128_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..1cb7d0ed87e0ca17deb5dfea0d718a10d75892fc >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_benchmark.cc >@@ -0,0 +1,221 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/numeric/int128.h" >+ >+#include <algorithm> >+#include <cstdint> >+#include <random> >+#include <vector> >+ >+#include "benchmark/benchmark.h" >+#include "absl/base/config.h" >+ >+namespace { >+ >+constexpr size_t kSampleSize = 1000000; >+ >+std::mt19937 MakeRandomEngine() { >+ std::random_device r; >+ std::seed_seq seed({r(), r(), r(), r(), r(), r(), r(), r()}); >+ return std::mt19937(seed); >+} >+ >+std::vector<std::pair<absl::uint128, absl::uint128>> >+GetRandomClass128SampleUniformDivisor() { >+ std::vector<std::pair<absl::uint128, absl::uint128>> values; >+ std::mt19937 random = MakeRandomEngine(); >+ std::uniform_int_distribution<uint64_t> uniform_uint64; >+ values.reserve(kSampleSize); >+ for (size_t i = 0; i < kSampleSize; ++i) { >+ absl::uint128 a = >+ absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)); >+ absl::uint128 b = >+ absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)); >+ values.emplace_back(std::max(a, b), >+ std::max(absl::uint128(2), std::min(a, b))); >+ } >+ return values; >+} >+ >+void BM_DivideClass128UniformDivisor(benchmark::State& state) { >+ auto values = GetRandomClass128SampleUniformDivisor(); >+ while (state.KeepRunningBatch(values.size())) { >+ for (const auto& pair : values) { >+ benchmark::DoNotOptimize(pair.first / pair.second); >+ } >+ } >+} >+BENCHMARK(BM_DivideClass128UniformDivisor); >+ >+std::vector<std::pair<absl::uint128, uint64_t>> >+GetRandomClass128SampleSmallDivisor() { >+ std::vector<std::pair<absl::uint128, uint64_t>> values; >+ std::mt19937 random = MakeRandomEngine(); >+ std::uniform_int_distribution<uint64_t> uniform_uint64; >+ values.reserve(kSampleSize); >+ for (size_t i = 0; i < kSampleSize; ++i) { >+ absl::uint128 a = >+ absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)); >+ uint64_t b = std::max(uint64_t{2}, uniform_uint64(random)); >+ values.emplace_back(std::max(a, absl::uint128(b)), b); >+ } >+ return values; >+} >+ >+void BM_DivideClass128SmallDivisor(benchmark::State& state) { >+ auto values = GetRandomClass128SampleSmallDivisor(); >+ while (state.KeepRunningBatch(values.size())) { >+ for (const auto& pair : values) { >+ benchmark::DoNotOptimize(pair.first / pair.second); >+ } >+ } >+} >+BENCHMARK(BM_DivideClass128SmallDivisor); >+ >+std::vector<std::pair<absl::uint128, absl::uint128>> GetRandomClass128Sample() { >+ std::vector<std::pair<absl::uint128, absl::uint128>> values; >+ std::mt19937 random = MakeRandomEngine(); >+ std::uniform_int_distribution<uint64_t> uniform_uint64; >+ values.reserve(kSampleSize); >+ for (size_t i = 0; i < kSampleSize; ++i) { >+ values.emplace_back( >+ absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)), >+ absl::MakeUint128(uniform_uint64(random), uniform_uint64(random))); >+ } >+ return values; >+} >+ >+void BM_MultiplyClass128(benchmark::State& state) { >+ auto values = GetRandomClass128Sample(); >+ while (state.KeepRunningBatch(values.size())) { >+ for (const auto& pair : values) { >+ benchmark::DoNotOptimize(pair.first * pair.second); >+ } >+ } >+} >+BENCHMARK(BM_MultiplyClass128); >+ >+void BM_AddClass128(benchmark::State& state) { >+ auto values = GetRandomClass128Sample(); >+ while (state.KeepRunningBatch(values.size())) { >+ for (const auto& pair : values) { >+ benchmark::DoNotOptimize(pair.first + pair.second); >+ } >+ } >+} >+BENCHMARK(BM_AddClass128); >+ >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+ >+// Some implementations of <random> do not support __int128 when it is >+// available, so we make our own uniform_int_distribution-like type. >+class UniformIntDistribution128 { >+ public: >+ // NOLINTNEXTLINE: mimicking std::uniform_int_distribution API >+ unsigned __int128 operator()(std::mt19937& generator) { >+ return (static_cast<unsigned __int128>(dist64_(generator)) << 64) | >+ dist64_(generator); >+ } >+ >+ private: >+ std::uniform_int_distribution<uint64_t> dist64_; >+}; >+ >+std::vector<std::pair<unsigned __int128, unsigned __int128>> >+GetRandomIntrinsic128SampleUniformDivisor() { >+ std::vector<std::pair<unsigned __int128, unsigned __int128>> values; >+ std::mt19937 random = MakeRandomEngine(); >+ UniformIntDistribution128 uniform_uint128; >+ values.reserve(kSampleSize); >+ for (size_t i = 0; i < kSampleSize; ++i) { >+ unsigned __int128 a = uniform_uint128(random); >+ unsigned __int128 b = uniform_uint128(random); >+ values.emplace_back( >+ std::max(a, b), >+ std::max(static_cast<unsigned __int128>(2), std::min(a, b))); >+ } >+ return values; >+} >+ >+void BM_DivideIntrinsic128UniformDivisor(benchmark::State& state) { >+ auto values = GetRandomIntrinsic128SampleUniformDivisor(); >+ while (state.KeepRunningBatch(values.size())) { >+ for (const auto& pair : values) { >+ benchmark::DoNotOptimize(pair.first / pair.second); >+ } >+ } >+} >+BENCHMARK(BM_DivideIntrinsic128UniformDivisor); >+ >+std::vector<std::pair<unsigned __int128, uint64_t>> >+GetRandomIntrinsic128SampleSmallDivisor() { >+ std::vector<std::pair<unsigned __int128, uint64_t>> values; >+ std::mt19937 random = MakeRandomEngine(); >+ UniformIntDistribution128 uniform_uint128; >+ std::uniform_int_distribution<uint64_t> uniform_uint64; >+ values.reserve(kSampleSize); >+ for (size_t i = 0; i < kSampleSize; ++i) { >+ unsigned __int128 a = uniform_uint128(random); >+ uint64_t b = std::max(uint64_t{2}, uniform_uint64(random)); >+ values.emplace_back(std::max(a, static_cast<unsigned __int128>(b)), b); >+ } >+ return values; >+} >+ >+void BM_DivideIntrinsic128SmallDivisor(benchmark::State& state) { >+ auto values = GetRandomIntrinsic128SampleSmallDivisor(); >+ while (state.KeepRunningBatch(values.size())) { >+ for (const auto& pair : values) { >+ benchmark::DoNotOptimize(pair.first / pair.second); >+ } >+ } >+} >+BENCHMARK(BM_DivideIntrinsic128SmallDivisor); >+ >+std::vector<std::pair<unsigned __int128, unsigned __int128>> >+ GetRandomIntrinsic128Sample() { >+ std::vector<std::pair<unsigned __int128, unsigned __int128>> values; >+ std::mt19937 random = MakeRandomEngine(); >+ UniformIntDistribution128 uniform_uint128; >+ values.reserve(kSampleSize); >+ for (size_t i = 0; i < kSampleSize; ++i) { >+ values.emplace_back(uniform_uint128(random), uniform_uint128(random)); >+ } >+ return values; >+} >+ >+void BM_MultiplyIntrinsic128(benchmark::State& state) { >+ auto values = GetRandomIntrinsic128Sample(); >+ while (state.KeepRunningBatch(values.size())) { >+ for (const auto& pair : values) { >+ benchmark::DoNotOptimize(pair.first * pair.second); >+ } >+ } >+} >+BENCHMARK(BM_MultiplyIntrinsic128); >+ >+void BM_AddIntrinsic128(benchmark::State& state) { >+ auto values = GetRandomIntrinsic128Sample(); >+ while (state.KeepRunningBatch(values.size())) { >+ for (const auto& pair : values) { >+ benchmark::DoNotOptimize(pair.first + pair.second); >+ } >+ } >+} >+BENCHMARK(BM_AddIntrinsic128); >+ >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..ee2a093018d955315f95282057029cb2fd590276 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc >@@ -0,0 +1,18 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// This file contains :int128 implementation details that depend on internal >+// representation when ABSL_HAVE_INTRINSIC_INT128 is defined. This file is >+// included by int128.h. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..0d0b3cfdeb125a4291d5a3dc5f3c50552b1a40c9 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc >@@ -0,0 +1,18 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// This file contains :int128 implementation details that depend on internal >+// representation when ABSL_HAVE_INTRINSIC_INT128 is *not* defined. This file >+// is included by int128.h. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_stream_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_stream_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..09efaad4e7fbad2dd7849ebce492ae7d0dcc270a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_stream_test.cc >@@ -0,0 +1,666 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/numeric/int128.h" >+ >+#include <sstream> >+#include <string> >+ >+#include "gtest/gtest.h" >+ >+namespace { >+ >+struct Uint128TestCase { >+ absl::uint128 value; >+ std::ios_base::fmtflags flags; >+ std::streamsize width; >+ const char* expected; >+}; >+ >+constexpr char kFill = '_'; >+ >+std::string StreamFormatToString(std::ios_base::fmtflags flags, >+ std::streamsize width) { >+ std::vector<const char*> flagstr; >+ switch (flags & std::ios::basefield) { >+ case std::ios::dec: >+ flagstr.push_back("std::ios::dec"); >+ break; >+ case std::ios::oct: >+ flagstr.push_back("std::ios::oct"); >+ break; >+ case std::ios::hex: >+ flagstr.push_back("std::ios::hex"); >+ break; >+ default: // basefield not specified >+ break; >+ } >+ switch (flags & std::ios::adjustfield) { >+ case std::ios::left: >+ flagstr.push_back("std::ios::left"); >+ break; >+ case std::ios::internal: >+ flagstr.push_back("std::ios::internal"); >+ break; >+ case std::ios::right: >+ flagstr.push_back("std::ios::right"); >+ break; >+ default: // adjustfield not specified >+ break; >+ } >+ if (flags & std::ios::uppercase) flagstr.push_back("std::ios::uppercase"); >+ if (flags & std::ios::showbase) flagstr.push_back("std::ios::showbase"); >+ if (flags & std::ios::showpos) flagstr.push_back("std::ios::showpos"); >+ >+ std::ostringstream msg; >+ msg << "\n StreamFormatToString(test_case.flags, test_case.width)\n " >+ "flags: "; >+ if (!flagstr.empty()) { >+ for (size_t i = 0; i < flagstr.size() - 1; ++i) msg << flagstr[i] << " | "; >+ msg << flagstr.back(); >+ } else { >+ msg << "(default)"; >+ } >+ msg << "\n width: " << width << "\n fill: '" << kFill << "'"; >+ return msg.str(); >+} >+ >+void CheckUint128Case(const Uint128TestCase& test_case) { >+ std::ostringstream os; >+ os.flags(test_case.flags); >+ os.width(test_case.width); >+ os.fill(kFill); >+ os << test_case.value; >+ SCOPED_TRACE(StreamFormatToString(test_case.flags, test_case.width)); >+ EXPECT_EQ(test_case.expected, os.str()); >+} >+ >+constexpr std::ios::fmtflags kDec = std::ios::dec; >+constexpr std::ios::fmtflags kOct = std::ios::oct; >+constexpr std::ios::fmtflags kHex = std::ios::hex; >+constexpr std::ios::fmtflags kLeft = std::ios::left; >+constexpr std::ios::fmtflags kInt = std::ios::internal; >+constexpr std::ios::fmtflags kRight = std::ios::right; >+constexpr std::ios::fmtflags kUpper = std::ios::uppercase; >+constexpr std::ios::fmtflags kBase = std::ios::showbase; >+constexpr std::ios::fmtflags kPos = std::ios::showpos; >+ >+TEST(Uint128, OStreamValueTest) { >+ CheckUint128Case({1, kDec, /*width = */ 0, "1"}); >+ CheckUint128Case({1, kOct, /*width = */ 0, "1"}); >+ CheckUint128Case({1, kHex, /*width = */ 0, "1"}); >+ CheckUint128Case({9, kDec, /*width = */ 0, "9"}); >+ CheckUint128Case({9, kOct, /*width = */ 0, "11"}); >+ CheckUint128Case({9, kHex, /*width = */ 0, "9"}); >+ CheckUint128Case({12345, kDec, /*width = */ 0, "12345"}); >+ CheckUint128Case({12345, kOct, /*width = */ 0, "30071"}); >+ CheckUint128Case({12345, kHex, /*width = */ 0, "3039"}); >+ CheckUint128Case( >+ {0x8000000000000000, kDec, /*width = */ 0, "9223372036854775808"}); >+ CheckUint128Case( >+ {0x8000000000000000, kOct, /*width = */ 0, "1000000000000000000000"}); >+ CheckUint128Case( >+ {0x8000000000000000, kHex, /*width = */ 0, "8000000000000000"}); >+ CheckUint128Case({std::numeric_limits<uint64_t>::max(), kDec, >+ /*width = */ 0, "18446744073709551615"}); >+ CheckUint128Case({std::numeric_limits<uint64_t>::max(), kOct, >+ /*width = */ 0, "1777777777777777777777"}); >+ CheckUint128Case({std::numeric_limits<uint64_t>::max(), kHex, >+ /*width = */ 0, "ffffffffffffffff"}); >+ CheckUint128Case( >+ {absl::MakeUint128(1, 0), kDec, /*width = */ 0, "18446744073709551616"}); >+ CheckUint128Case({absl::MakeUint128(1, 0), kOct, /*width = */ 0, >+ "2000000000000000000000"}); >+ CheckUint128Case( >+ {absl::MakeUint128(1, 0), kHex, /*width = */ 0, "10000000000000000"}); >+ CheckUint128Case({absl::MakeUint128(0x8000000000000000, 0), kDec, >+ /*width = */ 0, "170141183460469231731687303715884105728"}); >+ CheckUint128Case({absl::MakeUint128(0x8000000000000000, 0), kOct, >+ /*width = */ 0, >+ "2000000000000000000000000000000000000000000"}); >+ CheckUint128Case({absl::MakeUint128(0x8000000000000000, 0), kHex, >+ /*width = */ 0, "80000000000000000000000000000000"}); >+ CheckUint128Case({absl::kuint128max, kDec, /*width = */ 0, >+ "340282366920938463463374607431768211455"}); >+ CheckUint128Case({absl::kuint128max, kOct, /*width = */ 0, >+ "3777777777777777777777777777777777777777777"}); >+ CheckUint128Case({absl::kuint128max, kHex, /*width = */ 0, >+ "ffffffffffffffffffffffffffffffff"}); >+} >+ >+std::vector<Uint128TestCase> GetUint128FormatCases(); >+ >+TEST(Uint128, OStreamFormatTest) { >+ for (const Uint128TestCase& test_case : GetUint128FormatCases()) { >+ CheckUint128Case(test_case); >+ } >+} >+ >+std::vector<Uint128TestCase> GetUint128FormatCases() { >+ return { >+ {0, std::ios_base::fmtflags(), /*width = */ 0, "0"}, >+ {0, std::ios_base::fmtflags(), /*width = */ 6, "_____0"}, >+ {0, kPos, /*width = */ 0, "0"}, >+ {0, kPos, /*width = */ 6, "_____0"}, >+ {0, kBase, /*width = */ 0, "0"}, >+ {0, kBase, /*width = */ 6, "_____0"}, >+ {0, kBase | kPos, /*width = */ 0, "0"}, >+ {0, kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kUpper, /*width = */ 0, "0"}, >+ {0, kUpper, /*width = */ 6, "_____0"}, >+ {0, kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kLeft, /*width = */ 0, "0"}, >+ {0, kLeft, /*width = */ 6, "0_____"}, >+ {0, kLeft | kPos, /*width = */ 0, "0"}, >+ {0, kLeft | kPos, /*width = */ 6, "0_____"}, >+ {0, kLeft | kBase, /*width = */ 0, "0"}, >+ {0, kLeft | kBase, /*width = */ 6, "0_____"}, >+ {0, kLeft | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kLeft | kBase | kPos, /*width = */ 6, "0_____"}, >+ {0, kLeft | kUpper, /*width = */ 0, "0"}, >+ {0, kLeft | kUpper, /*width = */ 6, "0_____"}, >+ {0, kLeft | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kLeft | kUpper | kPos, /*width = */ 6, "0_____"}, >+ {0, kLeft | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kLeft | kUpper | kBase, /*width = */ 6, "0_____"}, >+ {0, kLeft | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kLeft | kUpper | kBase | kPos, /*width = */ 6, "0_____"}, >+ {0, kInt, /*width = */ 0, "0"}, >+ {0, kInt, /*width = */ 6, "_____0"}, >+ {0, kInt | kPos, /*width = */ 0, "0"}, >+ {0, kInt | kPos, /*width = */ 6, "_____0"}, >+ {0, kInt | kBase, /*width = */ 0, "0"}, >+ {0, kInt | kBase, /*width = */ 6, "_____0"}, >+ {0, kInt | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kInt | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kInt | kUpper, /*width = */ 0, "0"}, >+ {0, kInt | kUpper, /*width = */ 6, "_____0"}, >+ {0, kInt | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kInt | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kInt | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kInt | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kInt | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kInt | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kRight, /*width = */ 0, "0"}, >+ {0, kRight, /*width = */ 6, "_____0"}, >+ {0, kRight | kPos, /*width = */ 0, "0"}, >+ {0, kRight | kPos, /*width = */ 6, "_____0"}, >+ {0, kRight | kBase, /*width = */ 0, "0"}, >+ {0, kRight | kBase, /*width = */ 6, "_____0"}, >+ {0, kRight | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kRight | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kRight | kUpper, /*width = */ 0, "0"}, >+ {0, kRight | kUpper, /*width = */ 6, "_____0"}, >+ {0, kRight | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kRight | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kRight | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kRight | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kRight | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kRight | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec, /*width = */ 0, "0"}, >+ {0, kDec, /*width = */ 6, "_____0"}, >+ {0, kDec | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kBase, /*width = */ 0, "0"}, >+ {0, kDec | kBase, /*width = */ 6, "_____0"}, >+ {0, kDec | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kUpper, /*width = */ 0, "0"}, >+ {0, kDec | kUpper, /*width = */ 6, "_____0"}, >+ {0, kDec | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kDec | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kDec | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kLeft, /*width = */ 0, "0"}, >+ {0, kDec | kLeft, /*width = */ 6, "0_____"}, >+ {0, kDec | kLeft | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kLeft | kPos, /*width = */ 6, "0_____"}, >+ {0, kDec | kLeft | kBase, /*width = */ 0, "0"}, >+ {0, kDec | kLeft | kBase, /*width = */ 6, "0_____"}, >+ {0, kDec | kLeft | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kLeft | kBase | kPos, /*width = */ 6, "0_____"}, >+ {0, kDec | kLeft | kUpper, /*width = */ 0, "0"}, >+ {0, kDec | kLeft | kUpper, /*width = */ 6, "0_____"}, >+ {0, kDec | kLeft | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kLeft | kUpper | kPos, /*width = */ 6, "0_____"}, >+ {0, kDec | kLeft | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kDec | kLeft | kUpper | kBase, /*width = */ 6, "0_____"}, >+ {0, kDec | kLeft | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kLeft | kUpper | kBase | kPos, /*width = */ 6, "0_____"}, >+ {0, kDec | kInt, /*width = */ 0, "0"}, >+ {0, kDec | kInt, /*width = */ 6, "_____0"}, >+ {0, kDec | kInt | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kInt | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kInt | kBase, /*width = */ 0, "0"}, >+ {0, kDec | kInt | kBase, /*width = */ 6, "_____0"}, >+ {0, kDec | kInt | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kInt | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kInt | kUpper, /*width = */ 0, "0"}, >+ {0, kDec | kInt | kUpper, /*width = */ 6, "_____0"}, >+ {0, kDec | kInt | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kInt | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kInt | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kDec | kInt | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kDec | kInt | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kInt | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kRight, /*width = */ 0, "0"}, >+ {0, kDec | kRight, /*width = */ 6, "_____0"}, >+ {0, kDec | kRight | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kRight | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kRight | kBase, /*width = */ 0, "0"}, >+ {0, kDec | kRight | kBase, /*width = */ 6, "_____0"}, >+ {0, kDec | kRight | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kRight | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kRight | kUpper, /*width = */ 0, "0"}, >+ {0, kDec | kRight | kUpper, /*width = */ 6, "_____0"}, >+ {0, kDec | kRight | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kRight | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kDec | kRight | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kDec | kRight | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kDec | kRight | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kDec | kRight | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct, /*width = */ 0, "0"}, >+ {0, kOct, /*width = */ 6, "_____0"}, >+ {0, kOct | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kBase, /*width = */ 0, "0"}, >+ {0, kOct | kBase, /*width = */ 6, "_____0"}, >+ {0, kOct | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kUpper, /*width = */ 0, "0"}, >+ {0, kOct | kUpper, /*width = */ 6, "_____0"}, >+ {0, kOct | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kOct | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kOct | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kLeft, /*width = */ 0, "0"}, >+ {0, kOct | kLeft, /*width = */ 6, "0_____"}, >+ {0, kOct | kLeft | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kLeft | kPos, /*width = */ 6, "0_____"}, >+ {0, kOct | kLeft | kBase, /*width = */ 0, "0"}, >+ {0, kOct | kLeft | kBase, /*width = */ 6, "0_____"}, >+ {0, kOct | kLeft | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kLeft | kBase | kPos, /*width = */ 6, "0_____"}, >+ {0, kOct | kLeft | kUpper, /*width = */ 0, "0"}, >+ {0, kOct | kLeft | kUpper, /*width = */ 6, "0_____"}, >+ {0, kOct | kLeft | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kLeft | kUpper | kPos, /*width = */ 6, "0_____"}, >+ {0, kOct | kLeft | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kOct | kLeft | kUpper | kBase, /*width = */ 6, "0_____"}, >+ {0, kOct | kLeft | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kLeft | kUpper | kBase | kPos, /*width = */ 6, "0_____"}, >+ {0, kOct | kInt, /*width = */ 0, "0"}, >+ {0, kOct | kInt, /*width = */ 6, "_____0"}, >+ {0, kOct | kInt | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kInt | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kInt | kBase, /*width = */ 0, "0"}, >+ {0, kOct | kInt | kBase, /*width = */ 6, "_____0"}, >+ {0, kOct | kInt | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kInt | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kInt | kUpper, /*width = */ 0, "0"}, >+ {0, kOct | kInt | kUpper, /*width = */ 6, "_____0"}, >+ {0, kOct | kInt | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kInt | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kInt | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kOct | kInt | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kOct | kInt | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kInt | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kRight, /*width = */ 0, "0"}, >+ {0, kOct | kRight, /*width = */ 6, "_____0"}, >+ {0, kOct | kRight | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kRight | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kRight | kBase, /*width = */ 0, "0"}, >+ {0, kOct | kRight | kBase, /*width = */ 6, "_____0"}, >+ {0, kOct | kRight | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kRight | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kRight | kUpper, /*width = */ 0, "0"}, >+ {0, kOct | kRight | kUpper, /*width = */ 6, "_____0"}, >+ {0, kOct | kRight | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kRight | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kOct | kRight | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kOct | kRight | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kOct | kRight | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kOct | kRight | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex, /*width = */ 0, "0"}, >+ {0, kHex, /*width = */ 6, "_____0"}, >+ {0, kHex | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kBase, /*width = */ 0, "0"}, >+ {0, kHex | kBase, /*width = */ 6, "_____0"}, >+ {0, kHex | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kUpper, /*width = */ 0, "0"}, >+ {0, kHex | kUpper, /*width = */ 6, "_____0"}, >+ {0, kHex | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kHex | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kHex | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kLeft, /*width = */ 0, "0"}, >+ {0, kHex | kLeft, /*width = */ 6, "0_____"}, >+ {0, kHex | kLeft | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kLeft | kPos, /*width = */ 6, "0_____"}, >+ {0, kHex | kLeft | kBase, /*width = */ 0, "0"}, >+ {0, kHex | kLeft | kBase, /*width = */ 6, "0_____"}, >+ {0, kHex | kLeft | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kLeft | kBase | kPos, /*width = */ 6, "0_____"}, >+ {0, kHex | kLeft | kUpper, /*width = */ 0, "0"}, >+ {0, kHex | kLeft | kUpper, /*width = */ 6, "0_____"}, >+ {0, kHex | kLeft | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kLeft | kUpper | kPos, /*width = */ 6, "0_____"}, >+ {0, kHex | kLeft | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kHex | kLeft | kUpper | kBase, /*width = */ 6, "0_____"}, >+ {0, kHex | kLeft | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kLeft | kUpper | kBase | kPos, /*width = */ 6, "0_____"}, >+ {0, kHex | kInt, /*width = */ 0, "0"}, >+ {0, kHex | kInt, /*width = */ 6, "_____0"}, >+ {0, kHex | kInt | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kInt | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kInt | kBase, /*width = */ 0, "0"}, >+ {0, kHex | kInt | kBase, /*width = */ 6, "_____0"}, >+ {0, kHex | kInt | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kInt | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kInt | kUpper, /*width = */ 0, "0"}, >+ {0, kHex | kInt | kUpper, /*width = */ 6, "_____0"}, >+ {0, kHex | kInt | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kInt | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kInt | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kHex | kInt | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kHex | kInt | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kInt | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kRight, /*width = */ 0, "0"}, >+ {0, kHex | kRight, /*width = */ 6, "_____0"}, >+ {0, kHex | kRight | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kRight | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kRight | kBase, /*width = */ 0, "0"}, >+ {0, kHex | kRight | kBase, /*width = */ 6, "_____0"}, >+ {0, kHex | kRight | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kRight | kBase | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kRight | kUpper, /*width = */ 0, "0"}, >+ {0, kHex | kRight | kUpper, /*width = */ 6, "_____0"}, >+ {0, kHex | kRight | kUpper | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kRight | kUpper | kPos, /*width = */ 6, "_____0"}, >+ {0, kHex | kRight | kUpper | kBase, /*width = */ 0, "0"}, >+ {0, kHex | kRight | kUpper | kBase, /*width = */ 6, "_____0"}, >+ {0, kHex | kRight | kUpper | kBase | kPos, /*width = */ 0, "0"}, >+ {0, kHex | kRight | kUpper | kBase | kPos, /*width = */ 6, "_____0"}, >+ {37, std::ios_base::fmtflags(), /*width = */ 0, "37"}, >+ {37, std::ios_base::fmtflags(), /*width = */ 6, "____37"}, >+ {37, kPos, /*width = */ 0, "37"}, >+ {37, kPos, /*width = */ 6, "____37"}, >+ {37, kBase, /*width = */ 0, "37"}, >+ {37, kBase, /*width = */ 6, "____37"}, >+ {37, kBase | kPos, /*width = */ 0, "37"}, >+ {37, kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kUpper, /*width = */ 0, "37"}, >+ {37, kUpper, /*width = */ 6, "____37"}, >+ {37, kUpper | kPos, /*width = */ 0, "37"}, >+ {37, kUpper | kPos, /*width = */ 6, "____37"}, >+ {37, kUpper | kBase, /*width = */ 0, "37"}, >+ {37, kUpper | kBase, /*width = */ 6, "____37"}, >+ {37, kUpper | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kUpper | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kLeft, /*width = */ 0, "37"}, >+ {37, kLeft, /*width = */ 6, "37____"}, >+ {37, kLeft | kPos, /*width = */ 0, "37"}, >+ {37, kLeft | kPos, /*width = */ 6, "37____"}, >+ {37, kLeft | kBase, /*width = */ 0, "37"}, >+ {37, kLeft | kBase, /*width = */ 6, "37____"}, >+ {37, kLeft | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kLeft | kBase | kPos, /*width = */ 6, "37____"}, >+ {37, kLeft | kUpper, /*width = */ 0, "37"}, >+ {37, kLeft | kUpper, /*width = */ 6, "37____"}, >+ {37, kLeft | kUpper | kPos, /*width = */ 0, "37"}, >+ {37, kLeft | kUpper | kPos, /*width = */ 6, "37____"}, >+ {37, kLeft | kUpper | kBase, /*width = */ 0, "37"}, >+ {37, kLeft | kUpper | kBase, /*width = */ 6, "37____"}, >+ {37, kLeft | kUpper | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kLeft | kUpper | kBase | kPos, /*width = */ 6, "37____"}, >+ {37, kInt, /*width = */ 0, "37"}, >+ {37, kInt, /*width = */ 6, "____37"}, >+ {37, kInt | kPos, /*width = */ 0, "37"}, >+ {37, kInt | kPos, /*width = */ 6, "____37"}, >+ {37, kInt | kBase, /*width = */ 0, "37"}, >+ {37, kInt | kBase, /*width = */ 6, "____37"}, >+ {37, kInt | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kInt | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kInt | kUpper, /*width = */ 0, "37"}, >+ {37, kInt | kUpper, /*width = */ 6, "____37"}, >+ {37, kInt | kUpper | kPos, /*width = */ 0, "37"}, >+ {37, kInt | kUpper | kPos, /*width = */ 6, "____37"}, >+ {37, kInt | kUpper | kBase, /*width = */ 0, "37"}, >+ {37, kInt | kUpper | kBase, /*width = */ 6, "____37"}, >+ {37, kInt | kUpper | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kInt | kUpper | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kRight, /*width = */ 0, "37"}, >+ {37, kRight, /*width = */ 6, "____37"}, >+ {37, kRight | kPos, /*width = */ 0, "37"}, >+ {37, kRight | kPos, /*width = */ 6, "____37"}, >+ {37, kRight | kBase, /*width = */ 0, "37"}, >+ {37, kRight | kBase, /*width = */ 6, "____37"}, >+ {37, kRight | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kRight | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kRight | kUpper, /*width = */ 0, "37"}, >+ {37, kRight | kUpper, /*width = */ 6, "____37"}, >+ {37, kRight | kUpper | kPos, /*width = */ 0, "37"}, >+ {37, kRight | kUpper | kPos, /*width = */ 6, "____37"}, >+ {37, kRight | kUpper | kBase, /*width = */ 0, "37"}, >+ {37, kRight | kUpper | kBase, /*width = */ 6, "____37"}, >+ {37, kRight | kUpper | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kRight | kUpper | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kDec, /*width = */ 0, "37"}, >+ {37, kDec, /*width = */ 6, "____37"}, >+ {37, kDec | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kBase, /*width = */ 0, "37"}, >+ {37, kDec | kBase, /*width = */ 6, "____37"}, >+ {37, kDec | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kUpper, /*width = */ 0, "37"}, >+ {37, kDec | kUpper, /*width = */ 6, "____37"}, >+ {37, kDec | kUpper | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kUpper | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kUpper | kBase, /*width = */ 0, "37"}, >+ {37, kDec | kUpper | kBase, /*width = */ 6, "____37"}, >+ {37, kDec | kUpper | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kUpper | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kLeft, /*width = */ 0, "37"}, >+ {37, kDec | kLeft, /*width = */ 6, "37____"}, >+ {37, kDec | kLeft | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kLeft | kPos, /*width = */ 6, "37____"}, >+ {37, kDec | kLeft | kBase, /*width = */ 0, "37"}, >+ {37, kDec | kLeft | kBase, /*width = */ 6, "37____"}, >+ {37, kDec | kLeft | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kLeft | kBase | kPos, /*width = */ 6, "37____"}, >+ {37, kDec | kLeft | kUpper, /*width = */ 0, "37"}, >+ {37, kDec | kLeft | kUpper, /*width = */ 6, "37____"}, >+ {37, kDec | kLeft | kUpper | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kLeft | kUpper | kPos, /*width = */ 6, "37____"}, >+ {37, kDec | kLeft | kUpper | kBase, /*width = */ 0, "37"}, >+ {37, kDec | kLeft | kUpper | kBase, /*width = */ 6, "37____"}, >+ {37, kDec | kLeft | kUpper | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kLeft | kUpper | kBase | kPos, /*width = */ 6, "37____"}, >+ {37, kDec | kInt, /*width = */ 0, "37"}, >+ {37, kDec | kInt, /*width = */ 6, "____37"}, >+ {37, kDec | kInt | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kInt | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kInt | kBase, /*width = */ 0, "37"}, >+ {37, kDec | kInt | kBase, /*width = */ 6, "____37"}, >+ {37, kDec | kInt | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kInt | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kInt | kUpper, /*width = */ 0, "37"}, >+ {37, kDec | kInt | kUpper, /*width = */ 6, "____37"}, >+ {37, kDec | kInt | kUpper | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kInt | kUpper | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kInt | kUpper | kBase, /*width = */ 0, "37"}, >+ {37, kDec | kInt | kUpper | kBase, /*width = */ 6, "____37"}, >+ {37, kDec | kInt | kUpper | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kInt | kUpper | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kRight, /*width = */ 0, "37"}, >+ {37, kDec | kRight, /*width = */ 6, "____37"}, >+ {37, kDec | kRight | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kRight | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kRight | kBase, /*width = */ 0, "37"}, >+ {37, kDec | kRight | kBase, /*width = */ 6, "____37"}, >+ {37, kDec | kRight | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kRight | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kRight | kUpper, /*width = */ 0, "37"}, >+ {37, kDec | kRight | kUpper, /*width = */ 6, "____37"}, >+ {37, kDec | kRight | kUpper | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kRight | kUpper | kPos, /*width = */ 6, "____37"}, >+ {37, kDec | kRight | kUpper | kBase, /*width = */ 0, "37"}, >+ {37, kDec | kRight | kUpper | kBase, /*width = */ 6, "____37"}, >+ {37, kDec | kRight | kUpper | kBase | kPos, /*width = */ 0, "37"}, >+ {37, kDec | kRight | kUpper | kBase | kPos, /*width = */ 6, "____37"}, >+ {37, kOct, /*width = */ 0, "45"}, >+ {37, kOct, /*width = */ 6, "____45"}, >+ {37, kOct | kPos, /*width = */ 0, "45"}, >+ {37, kOct | kPos, /*width = */ 6, "____45"}, >+ {37, kOct | kBase, /*width = */ 0, "045"}, >+ {37, kOct | kBase, /*width = */ 6, "___045"}, >+ {37, kOct | kBase | kPos, /*width = */ 0, "045"}, >+ {37, kOct | kBase | kPos, /*width = */ 6, "___045"}, >+ {37, kOct | kUpper, /*width = */ 0, "45"}, >+ {37, kOct | kUpper, /*width = */ 6, "____45"}, >+ {37, kOct | kUpper | kPos, /*width = */ 0, "45"}, >+ {37, kOct | kUpper | kPos, /*width = */ 6, "____45"}, >+ {37, kOct | kUpper | kBase, /*width = */ 0, "045"}, >+ {37, kOct | kUpper | kBase, /*width = */ 6, "___045"}, >+ {37, kOct | kUpper | kBase | kPos, /*width = */ 0, "045"}, >+ {37, kOct | kUpper | kBase | kPos, /*width = */ 6, "___045"}, >+ {37, kOct | kLeft, /*width = */ 0, "45"}, >+ {37, kOct | kLeft, /*width = */ 6, "45____"}, >+ {37, kOct | kLeft | kPos, /*width = */ 0, "45"}, >+ {37, kOct | kLeft | kPos, /*width = */ 6, "45____"}, >+ {37, kOct | kLeft | kBase, /*width = */ 0, "045"}, >+ {37, kOct | kLeft | kBase, /*width = */ 6, "045___"}, >+ {37, kOct | kLeft | kBase | kPos, /*width = */ 0, "045"}, >+ {37, kOct | kLeft | kBase | kPos, /*width = */ 6, "045___"}, >+ {37, kOct | kLeft | kUpper, /*width = */ 0, "45"}, >+ {37, kOct | kLeft | kUpper, /*width = */ 6, "45____"}, >+ {37, kOct | kLeft | kUpper | kPos, /*width = */ 0, "45"}, >+ {37, kOct | kLeft | kUpper | kPos, /*width = */ 6, "45____"}, >+ {37, kOct | kLeft | kUpper | kBase, /*width = */ 0, "045"}, >+ {37, kOct | kLeft | kUpper | kBase, /*width = */ 6, "045___"}, >+ {37, kOct | kLeft | kUpper | kBase | kPos, /*width = */ 0, "045"}, >+ {37, kOct | kLeft | kUpper | kBase | kPos, /*width = */ 6, "045___"}, >+ {37, kOct | kInt, /*width = */ 0, "45"}, >+ {37, kOct | kInt, /*width = */ 6, "____45"}, >+ {37, kOct | kInt | kPos, /*width = */ 0, "45"}, >+ {37, kOct | kInt | kPos, /*width = */ 6, "____45"}, >+ {37, kOct | kInt | kBase, /*width = */ 0, "045"}, >+ {37, kOct | kInt | kBase, /*width = */ 6, "___045"}, >+ {37, kOct | kInt | kBase | kPos, /*width = */ 0, "045"}, >+ {37, kOct | kInt | kBase | kPos, /*width = */ 6, "___045"}, >+ {37, kOct | kInt | kUpper, /*width = */ 0, "45"}, >+ {37, kOct | kInt | kUpper, /*width = */ 6, "____45"}, >+ {37, kOct | kInt | kUpper | kPos, /*width = */ 0, "45"}, >+ {37, kOct | kInt | kUpper | kPos, /*width = */ 6, "____45"}, >+ {37, kOct | kInt | kUpper | kBase, /*width = */ 0, "045"}, >+ {37, kOct | kInt | kUpper | kBase, /*width = */ 6, "___045"}, >+ {37, kOct | kInt | kUpper | kBase | kPos, /*width = */ 0, "045"}, >+ {37, kOct | kInt | kUpper | kBase | kPos, /*width = */ 6, "___045"}, >+ {37, kOct | kRight, /*width = */ 0, "45"}, >+ {37, kOct | kRight, /*width = */ 6, "____45"}, >+ {37, kOct | kRight | kPos, /*width = */ 0, "45"}, >+ {37, kOct | kRight | kPos, /*width = */ 6, "____45"}, >+ {37, kOct | kRight | kBase, /*width = */ 0, "045"}, >+ {37, kOct | kRight | kBase, /*width = */ 6, "___045"}, >+ {37, kOct | kRight | kBase | kPos, /*width = */ 0, "045"}, >+ {37, kOct | kRight | kBase | kPos, /*width = */ 6, "___045"}, >+ {37, kOct | kRight | kUpper, /*width = */ 0, "45"}, >+ {37, kOct | kRight | kUpper, /*width = */ 6, "____45"}, >+ {37, kOct | kRight | kUpper | kPos, /*width = */ 0, "45"}, >+ {37, kOct | kRight | kUpper | kPos, /*width = */ 6, "____45"}, >+ {37, kOct | kRight | kUpper | kBase, /*width = */ 0, "045"}, >+ {37, kOct | kRight | kUpper | kBase, /*width = */ 6, "___045"}, >+ {37, kOct | kRight | kUpper | kBase | kPos, /*width = */ 0, "045"}, >+ {37, kOct | kRight | kUpper | kBase | kPos, /*width = */ 6, "___045"}, >+ {37, kHex, /*width = */ 0, "25"}, >+ {37, kHex, /*width = */ 6, "____25"}, >+ {37, kHex | kPos, /*width = */ 0, "25"}, >+ {37, kHex | kPos, /*width = */ 6, "____25"}, >+ {37, kHex | kBase, /*width = */ 0, "0x25"}, >+ {37, kHex | kBase, /*width = */ 6, "__0x25"}, >+ {37, kHex | kBase | kPos, /*width = */ 0, "0x25"}, >+ {37, kHex | kBase | kPos, /*width = */ 6, "__0x25"}, >+ {37, kHex | kUpper, /*width = */ 0, "25"}, >+ {37, kHex | kUpper, /*width = */ 6, "____25"}, >+ {37, kHex | kUpper | kPos, /*width = */ 0, "25"}, >+ {37, kHex | kUpper | kPos, /*width = */ 6, "____25"}, >+ {37, kHex | kUpper | kBase, /*width = */ 0, "0X25"}, >+ {37, kHex | kUpper | kBase, /*width = */ 6, "__0X25"}, >+ {37, kHex | kUpper | kBase | kPos, /*width = */ 0, "0X25"}, >+ {37, kHex | kUpper | kBase | kPos, /*width = */ 6, "__0X25"}, >+ {37, kHex | kLeft, /*width = */ 0, "25"}, >+ {37, kHex | kLeft, /*width = */ 6, "25____"}, >+ {37, kHex | kLeft | kPos, /*width = */ 0, "25"}, >+ {37, kHex | kLeft | kPos, /*width = */ 6, "25____"}, >+ {37, kHex | kLeft | kBase, /*width = */ 0, "0x25"}, >+ {37, kHex | kLeft | kBase, /*width = */ 6, "0x25__"}, >+ {37, kHex | kLeft | kBase | kPos, /*width = */ 0, "0x25"}, >+ {37, kHex | kLeft | kBase | kPos, /*width = */ 6, "0x25__"}, >+ {37, kHex | kLeft | kUpper, /*width = */ 0, "25"}, >+ {37, kHex | kLeft | kUpper, /*width = */ 6, "25____"}, >+ {37, kHex | kLeft | kUpper | kPos, /*width = */ 0, "25"}, >+ {37, kHex | kLeft | kUpper | kPos, /*width = */ 6, "25____"}, >+ {37, kHex | kLeft | kUpper | kBase, /*width = */ 0, "0X25"}, >+ {37, kHex | kLeft | kUpper | kBase, /*width = */ 6, "0X25__"}, >+ {37, kHex | kLeft | kUpper | kBase | kPos, /*width = */ 0, "0X25"}, >+ {37, kHex | kLeft | kUpper | kBase | kPos, /*width = */ 6, "0X25__"}, >+ {37, kHex | kInt, /*width = */ 0, "25"}, >+ {37, kHex | kInt, /*width = */ 6, "____25"}, >+ {37, kHex | kInt | kPos, /*width = */ 0, "25"}, >+ {37, kHex | kInt | kPos, /*width = */ 6, "____25"}, >+ {37, kHex | kInt | kBase, /*width = */ 0, "0x25"}, >+ {37, kHex | kInt | kBase, /*width = */ 6, "0x__25"}, >+ {37, kHex | kInt | kBase | kPos, /*width = */ 0, "0x25"}, >+ {37, kHex | kInt | kBase | kPos, /*width = */ 6, "0x__25"}, >+ {37, kHex | kInt | kUpper, /*width = */ 0, "25"}, >+ {37, kHex | kInt | kUpper, /*width = */ 6, "____25"}, >+ {37, kHex | kInt | kUpper | kPos, /*width = */ 0, "25"}, >+ {37, kHex | kInt | kUpper | kPos, /*width = */ 6, "____25"}, >+ {37, kHex | kInt | kUpper | kBase, /*width = */ 0, "0X25"}, >+ {37, kHex | kInt | kUpper | kBase, /*width = */ 6, "0X__25"}, >+ {37, kHex | kInt | kUpper | kBase | kPos, /*width = */ 0, "0X25"}, >+ {37, kHex | kInt | kUpper | kBase | kPos, /*width = */ 6, "0X__25"}, >+ {37, kHex | kRight, /*width = */ 0, "25"}, >+ {37, kHex | kRight, /*width = */ 6, "____25"}, >+ {37, kHex | kRight | kPos, /*width = */ 0, "25"}, >+ {37, kHex | kRight | kPos, /*width = */ 6, "____25"}, >+ {37, kHex | kRight | kBase, /*width = */ 0, "0x25"}, >+ {37, kHex | kRight | kBase, /*width = */ 6, "__0x25"}, >+ {37, kHex | kRight | kBase | kPos, /*width = */ 0, "0x25"}, >+ {37, kHex | kRight | kBase | kPos, /*width = */ 6, "__0x25"}, >+ {37, kHex | kRight | kUpper, /*width = */ 0, "25"}, >+ {37, kHex | kRight | kUpper, /*width = */ 6, "____25"}, >+ {37, kHex | kRight | kUpper | kPos, /*width = */ 0, "25"}, >+ {37, kHex | kRight | kUpper | kPos, /*width = */ 6, "____25"}, >+ {37, kHex | kRight | kUpper | kBase, /*width = */ 0, "0X25"}, >+ {37, kHex | kRight | kUpper | kBase, /*width = */ 6, "__0X25"}, >+ {37, kHex | kRight | kUpper | kBase | kPos, /*width = */ 0, "0X25"}, >+ {37, kHex | kRight | kUpper | kBase | kPos, /*width = */ 6, "__0X25"}}; >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..1eb3e0ec8961c1c6c88756ef1f201f0203aee0a2 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/numeric/int128_test.cc >@@ -0,0 +1,442 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/numeric/int128.h" >+ >+#include <algorithm> >+#include <limits> >+#include <random> >+#include <type_traits> >+#include <utility> >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/cycleclock.h" >+#include "absl/meta/type_traits.h" >+ >+#if defined(_MSC_VER) && _MSC_VER == 1900 >+// Disable "unary minus operator applied to unsigned type" warnings in Microsoft >+// Visual C++ 14 (2015). >+#pragma warning(disable:4146) >+#endif >+ >+namespace { >+ >+template <typename T> >+class Uint128IntegerTraitsTest : public ::testing::Test {}; >+typedef ::testing::Types<bool, char, signed char, unsigned char, char16_t, >+ char32_t, wchar_t, >+ short, // NOLINT(runtime/int) >+ unsigned short, // NOLINT(runtime/int) >+ int, unsigned int, >+ long, // NOLINT(runtime/int) >+ unsigned long, // NOLINT(runtime/int) >+ long long, // NOLINT(runtime/int) >+ unsigned long long> // NOLINT(runtime/int) >+ IntegerTypes; >+ >+template <typename T> >+class Uint128FloatTraitsTest : public ::testing::Test {}; >+typedef ::testing::Types<float, double, long double> FloatingPointTypes; >+ >+TYPED_TEST_CASE(Uint128IntegerTraitsTest, IntegerTypes); >+ >+TYPED_TEST(Uint128IntegerTraitsTest, ConstructAssignTest) { >+ static_assert(std::is_constructible<absl::uint128, TypeParam>::value, >+ "absl::uint128 must be constructible from TypeParam"); >+ static_assert(std::is_assignable<absl::uint128&, TypeParam>::value, >+ "absl::uint128 must be assignable from TypeParam"); >+ static_assert(!std::is_assignable<TypeParam&, absl::uint128>::value, >+ "TypeParam must not be assignable from absl::uint128"); >+} >+ >+TYPED_TEST_CASE(Uint128FloatTraitsTest, FloatingPointTypes); >+ >+TYPED_TEST(Uint128FloatTraitsTest, ConstructAssignTest) { >+ static_assert(std::is_constructible<absl::uint128, TypeParam>::value, >+ "absl::uint128 must be constructible from TypeParam"); >+ static_assert(!std::is_assignable<absl::uint128&, TypeParam>::value, >+ "absl::uint128 must not be assignable from TypeParam"); >+ static_assert(!std::is_assignable<TypeParam&, absl::uint128>::value, >+ "TypeParam must not be assignable from absl::uint128"); >+} >+ >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+// These type traits done separately as TYPED_TEST requires typeinfo, and not >+// all platforms have this for __int128 even though they define the type. >+TEST(Uint128, IntrinsicTypeTraitsTest) { >+ static_assert(std::is_constructible<absl::uint128, __int128>::value, >+ "absl::uint128 must be constructible from __int128"); >+ static_assert(std::is_assignable<absl::uint128&, __int128>::value, >+ "absl::uint128 must be assignable from __int128"); >+ static_assert(!std::is_assignable<__int128&, absl::uint128>::value, >+ "__int128 must not be assignable from absl::uint128"); >+ >+ static_assert(std::is_constructible<absl::uint128, unsigned __int128>::value, >+ "absl::uint128 must be constructible from unsigned __int128"); >+ static_assert(std::is_assignable<absl::uint128&, unsigned __int128>::value, >+ "absl::uint128 must be assignable from unsigned __int128"); >+ static_assert(!std::is_assignable<unsigned __int128&, absl::uint128>::value, >+ "unsigned __int128 must not be assignable from absl::uint128"); >+} >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ >+TEST(Uint128, TrivialTraitsTest) { >+ static_assert(absl::is_trivially_default_constructible<absl::uint128>::value, >+ ""); >+ static_assert(absl::is_trivially_copy_constructible<absl::uint128>::value, >+ ""); >+ static_assert(absl::is_trivially_copy_assignable<absl::uint128>::value, ""); >+ static_assert(std::is_trivially_destructible<absl::uint128>::value, ""); >+} >+ >+TEST(Uint128, AllTests) { >+ absl::uint128 zero = 0; >+ absl::uint128 one = 1; >+ absl::uint128 one_2arg = absl::MakeUint128(0, 1); >+ absl::uint128 two = 2; >+ absl::uint128 three = 3; >+ absl::uint128 big = absl::MakeUint128(2000, 2); >+ absl::uint128 big_minus_one = absl::MakeUint128(2000, 1); >+ absl::uint128 bigger = absl::MakeUint128(2001, 1); >+ absl::uint128 biggest = absl::Uint128Max(); >+ absl::uint128 high_low = absl::MakeUint128(1, 0); >+ absl::uint128 low_high = >+ absl::MakeUint128(0, std::numeric_limits<uint64_t>::max()); >+ EXPECT_LT(one, two); >+ EXPECT_GT(two, one); >+ EXPECT_LT(one, big); >+ EXPECT_LT(one, big); >+ EXPECT_EQ(one, one_2arg); >+ EXPECT_NE(one, two); >+ EXPECT_GT(big, one); >+ EXPECT_GE(big, two); >+ EXPECT_GE(big, big_minus_one); >+ EXPECT_GT(big, big_minus_one); >+ EXPECT_LT(big_minus_one, big); >+ EXPECT_LE(big_minus_one, big); >+ EXPECT_NE(big_minus_one, big); >+ EXPECT_LT(big, biggest); >+ EXPECT_LE(big, biggest); >+ EXPECT_GT(biggest, big); >+ EXPECT_GE(biggest, big); >+ EXPECT_EQ(big, ~~big); >+ EXPECT_EQ(one, one | one); >+ EXPECT_EQ(big, big | big); >+ EXPECT_EQ(one, one | zero); >+ EXPECT_EQ(one, one & one); >+ EXPECT_EQ(big, big & big); >+ EXPECT_EQ(zero, one & zero); >+ EXPECT_EQ(zero, big & ~big); >+ EXPECT_EQ(zero, one ^ one); >+ EXPECT_EQ(zero, big ^ big); >+ EXPECT_EQ(one, one ^ zero); >+ >+ // Shift operators. >+ EXPECT_EQ(big, big << 0); >+ EXPECT_EQ(big, big >> 0); >+ EXPECT_GT(big << 1, big); >+ EXPECT_LT(big >> 1, big); >+ EXPECT_EQ(big, (big << 10) >> 10); >+ EXPECT_EQ(big, (big >> 1) << 1); >+ EXPECT_EQ(one, (one << 80) >> 80); >+ EXPECT_EQ(zero, (one >> 80) << 80); >+ >+ // Shift assignments. >+ absl::uint128 big_copy = big; >+ EXPECT_EQ(big << 0, big_copy <<= 0); >+ big_copy = big; >+ EXPECT_EQ(big >> 0, big_copy >>= 0); >+ big_copy = big; >+ EXPECT_EQ(big << 1, big_copy <<= 1); >+ big_copy = big; >+ EXPECT_EQ(big >> 1, big_copy >>= 1); >+ big_copy = big; >+ EXPECT_EQ(big << 10, big_copy <<= 10); >+ big_copy = big; >+ EXPECT_EQ(big >> 10, big_copy >>= 10); >+ big_copy = big; >+ EXPECT_EQ(big << 64, big_copy <<= 64); >+ big_copy = big; >+ EXPECT_EQ(big >> 64, big_copy >>= 64); >+ big_copy = big; >+ EXPECT_EQ(big << 73, big_copy <<= 73); >+ big_copy = big; >+ EXPECT_EQ(big >> 73, big_copy >>= 73); >+ >+ EXPECT_EQ(absl::Uint128High64(biggest), std::numeric_limits<uint64_t>::max()); >+ EXPECT_EQ(absl::Uint128Low64(biggest), std::numeric_limits<uint64_t>::max()); >+ EXPECT_EQ(zero + one, one); >+ EXPECT_EQ(one + one, two); >+ EXPECT_EQ(big_minus_one + one, big); >+ EXPECT_EQ(one - one, zero); >+ EXPECT_EQ(one - zero, one); >+ EXPECT_EQ(zero - one, biggest); >+ EXPECT_EQ(big - big, zero); >+ EXPECT_EQ(big - one, big_minus_one); >+ EXPECT_EQ(big + std::numeric_limits<uint64_t>::max(), bigger); >+ EXPECT_EQ(biggest + 1, zero); >+ EXPECT_EQ(zero - 1, biggest); >+ EXPECT_EQ(high_low - one, low_high); >+ EXPECT_EQ(low_high + one, high_low); >+ EXPECT_EQ(absl::Uint128High64((absl::uint128(1) << 64) - 1), 0); >+ EXPECT_EQ(absl::Uint128Low64((absl::uint128(1) << 64) - 1), >+ std::numeric_limits<uint64_t>::max()); >+ EXPECT_TRUE(!!one); >+ EXPECT_TRUE(!!high_low); >+ EXPECT_FALSE(!!zero); >+ EXPECT_FALSE(!one); >+ EXPECT_FALSE(!high_low); >+ EXPECT_TRUE(!zero); >+ EXPECT_TRUE(zero == 0); // NOLINT(readability/check) >+ EXPECT_FALSE(zero != 0); // NOLINT(readability/check) >+ EXPECT_FALSE(one == 0); // NOLINT(readability/check) >+ EXPECT_TRUE(one != 0); // NOLINT(readability/check) >+ EXPECT_FALSE(high_low == 0); // NOLINT(readability/check) >+ EXPECT_TRUE(high_low != 0); // NOLINT(readability/check) >+ >+ absl::uint128 test = zero; >+ EXPECT_EQ(++test, one); >+ EXPECT_EQ(test, one); >+ EXPECT_EQ(test++, one); >+ EXPECT_EQ(test, two); >+ EXPECT_EQ(test -= 2, zero); >+ EXPECT_EQ(test, zero); >+ EXPECT_EQ(test += 2, two); >+ EXPECT_EQ(test, two); >+ EXPECT_EQ(--test, one); >+ EXPECT_EQ(test, one); >+ EXPECT_EQ(test--, one); >+ EXPECT_EQ(test, zero); >+ EXPECT_EQ(test |= three, three); >+ EXPECT_EQ(test &= one, one); >+ EXPECT_EQ(test ^= three, two); >+ EXPECT_EQ(test >>= 1, one); >+ EXPECT_EQ(test <<= 1, two); >+ >+ EXPECT_EQ(big, -(-big)); >+ EXPECT_EQ(two, -((-one) - 1)); >+ EXPECT_EQ(absl::Uint128Max(), -one); >+ EXPECT_EQ(zero, -zero); >+ >+ EXPECT_EQ(absl::Uint128Max(), absl::kuint128max); >+} >+ >+TEST(Uint128, ConversionTests) { >+ EXPECT_TRUE(absl::MakeUint128(1, 0)); >+ >+#ifdef ABSL_HAVE_INTRINSIC_INT128 >+ unsigned __int128 intrinsic = >+ (static_cast<unsigned __int128>(0x3a5b76c209de76f6) << 64) + >+ 0x1f25e1d63a2b46c5; >+ absl::uint128 custom = >+ absl::MakeUint128(0x3a5b76c209de76f6, 0x1f25e1d63a2b46c5); >+ >+ EXPECT_EQ(custom, absl::uint128(intrinsic)); >+ EXPECT_EQ(custom, absl::uint128(static_cast<__int128>(intrinsic))); >+ EXPECT_EQ(intrinsic, static_cast<unsigned __int128>(custom)); >+ EXPECT_EQ(intrinsic, static_cast<__int128>(custom)); >+#endif // ABSL_HAVE_INTRINSIC_INT128 >+ >+ // verify that an integer greater than 2**64 that can be stored precisely >+ // inside a double is converted to a absl::uint128 without loss of >+ // information. >+ double precise_double = 0x530e * std::pow(2.0, 64.0) + 0xda74000000000000; >+ absl::uint128 from_precise_double(precise_double); >+ absl::uint128 from_precise_ints = >+ absl::MakeUint128(0x530e, 0xda74000000000000); >+ EXPECT_EQ(from_precise_double, from_precise_ints); >+ EXPECT_DOUBLE_EQ(static_cast<double>(from_precise_ints), precise_double); >+ >+ double approx_double = 0xffffeeeeddddcccc * std::pow(2.0, 64.0) + >+ 0xbbbbaaaa99998888; >+ absl::uint128 from_approx_double(approx_double); >+ EXPECT_DOUBLE_EQ(static_cast<double>(from_approx_double), approx_double); >+ >+ double round_to_zero = 0.7; >+ double round_to_five = 5.8; >+ double round_to_nine = 9.3; >+ EXPECT_EQ(static_cast<absl::uint128>(round_to_zero), 0); >+ EXPECT_EQ(static_cast<absl::uint128>(round_to_five), 5); >+ EXPECT_EQ(static_cast<absl::uint128>(round_to_nine), 9); >+} >+ >+TEST(Uint128, OperatorAssignReturnRef) { >+ absl::uint128 v(1); >+ (v += 4) -= 3; >+ EXPECT_EQ(2, v); >+} >+ >+TEST(Uint128, Multiply) { >+ absl::uint128 a, b, c; >+ >+ // Zero test. >+ a = 0; >+ b = 0; >+ c = a * b; >+ EXPECT_EQ(0, c); >+ >+ // Max carries. >+ a = absl::uint128(0) - 1; >+ b = absl::uint128(0) - 1; >+ c = a * b; >+ EXPECT_EQ(1, c); >+ >+ // Self-operation with max carries. >+ c = absl::uint128(0) - 1; >+ c *= c; >+ EXPECT_EQ(1, c); >+ >+ // 1-bit x 1-bit. >+ for (int i = 0; i < 64; ++i) { >+ for (int j = 0; j < 64; ++j) { >+ a = absl::uint128(1) << i; >+ b = absl::uint128(1) << j; >+ c = a * b; >+ EXPECT_EQ(absl::uint128(1) << (i + j), c); >+ } >+ } >+ >+ // Verified with dc. >+ a = absl::MakeUint128(0xffffeeeeddddcccc, 0xbbbbaaaa99998888); >+ b = absl::MakeUint128(0x7777666655554444, 0x3333222211110000); >+ c = a * b; >+ EXPECT_EQ(absl::MakeUint128(0x530EDA741C71D4C3, 0xBF25975319080000), c); >+ EXPECT_EQ(0, c - b * a); >+ EXPECT_EQ(a*a - b*b, (a+b) * (a-b)); >+ >+ // Verified with dc. >+ a = absl::MakeUint128(0x0123456789abcdef, 0xfedcba9876543210); >+ b = absl::MakeUint128(0x02468ace13579bdf, 0xfdb97531eca86420); >+ c = a * b; >+ EXPECT_EQ(absl::MakeUint128(0x97a87f4f261ba3f2, 0x342d0bbf48948200), c); >+ EXPECT_EQ(0, c - b * a); >+ EXPECT_EQ(a*a - b*b, (a+b) * (a-b)); >+} >+ >+TEST(Uint128, AliasTests) { >+ absl::uint128 x1 = absl::MakeUint128(1, 2); >+ absl::uint128 x2 = absl::MakeUint128(2, 4); >+ x1 += x1; >+ EXPECT_EQ(x2, x1); >+ >+ absl::uint128 x3 = absl::MakeUint128(1, static_cast<uint64_t>(1) << 63); >+ absl::uint128 x4 = absl::MakeUint128(3, 0); >+ x3 += x3; >+ EXPECT_EQ(x4, x3); >+} >+ >+TEST(Uint128, DivideAndMod) { >+ using std::swap; >+ >+ // a := q * b + r >+ absl::uint128 a, b, q, r; >+ >+ // Zero test. >+ a = 0; >+ b = 123; >+ q = a / b; >+ r = a % b; >+ EXPECT_EQ(0, q); >+ EXPECT_EQ(0, r); >+ >+ a = absl::MakeUint128(0x530eda741c71d4c3, 0xbf25975319080000); >+ q = absl::MakeUint128(0x4de2cab081, 0x14c34ab4676e4bab); >+ b = absl::uint128(0x1110001); >+ r = absl::uint128(0x3eb455); >+ ASSERT_EQ(a, q * b + r); // Sanity-check. >+ >+ absl::uint128 result_q, result_r; >+ result_q = a / b; >+ result_r = a % b; >+ EXPECT_EQ(q, result_q); >+ EXPECT_EQ(r, result_r); >+ >+ // Try the other way around. >+ swap(q, b); >+ result_q = a / b; >+ result_r = a % b; >+ EXPECT_EQ(q, result_q); >+ EXPECT_EQ(r, result_r); >+ // Restore. >+ swap(b, q); >+ >+ // Dividend < divisor; result should be q:0 r:<dividend>. >+ swap(a, b); >+ result_q = a / b; >+ result_r = a % b; >+ EXPECT_EQ(0, result_q); >+ EXPECT_EQ(a, result_r); >+ // Try the other way around. >+ swap(a, q); >+ result_q = a / b; >+ result_r = a % b; >+ EXPECT_EQ(0, result_q); >+ EXPECT_EQ(a, result_r); >+ // Restore. >+ swap(q, a); >+ swap(b, a); >+ >+ // Try a large remainder. >+ b = a / 2 + 1; >+ absl::uint128 expected_r = >+ absl::MakeUint128(0x29876d3a0e38ea61, 0xdf92cba98c83ffff); >+ // Sanity checks. >+ ASSERT_EQ(a / 2 - 1, expected_r); >+ ASSERT_EQ(a, b + expected_r); >+ result_q = a / b; >+ result_r = a % b; >+ EXPECT_EQ(1, result_q); >+ EXPECT_EQ(expected_r, result_r); >+} >+ >+TEST(Uint128, DivideAndModRandomInputs) { >+ const int kNumIters = 1 << 18; >+ std::minstd_rand random(testing::UnitTest::GetInstance()->random_seed()); >+ std::uniform_int_distribution<uint64_t> uniform_uint64; >+ for (int i = 0; i < kNumIters; ++i) { >+ const absl::uint128 a = >+ absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)); >+ const absl::uint128 b = >+ absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)); >+ if (b == 0) { >+ continue; // Avoid a div-by-zero. >+ } >+ const absl::uint128 q = a / b; >+ const absl::uint128 r = a % b; >+ ASSERT_EQ(a, b * q + r); >+ } >+} >+ >+TEST(Uint128, ConstexprTest) { >+ constexpr absl::uint128 zero = absl::uint128(); >+ constexpr absl::uint128 one = 1; >+ constexpr absl::uint128 minus_two = -2; >+ EXPECT_EQ(zero, absl::uint128(0)); >+ EXPECT_EQ(one, absl::uint128(1)); >+ EXPECT_EQ(minus_two, absl::MakeUint128(-1, -2)); >+} >+ >+TEST(Uint128, NumericLimitsTest) { >+ static_assert(std::numeric_limits<absl::uint128>::is_specialized, ""); >+ static_assert(!std::numeric_limits<absl::uint128>::is_signed, ""); >+ static_assert(std::numeric_limits<absl::uint128>::is_integer, ""); >+ EXPECT_EQ(static_cast<int>(128 * std::log10(2)), >+ std::numeric_limits<absl::uint128>::digits10); >+ EXPECT_EQ(0, std::numeric_limits<absl::uint128>::min()); >+ EXPECT_EQ(0, std::numeric_limits<absl::uint128>::lowest()); >+ EXPECT_EQ(absl::Uint128Max(), std::numeric_limits<absl::uint128>::max()); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..3a5f1332cda0e1f7040ef0dbdae557b018213854 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/BUILD.bazel >@@ -0,0 +1,661 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+ "ABSL_EXCEPTIONS_FLAG", >+) >+ >+package( >+ default_visibility = ["//visibility:public"], >+ features = ["parse_headers"], >+) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+cc_library( >+ name = "strings", >+ srcs = [ >+ "ascii.cc", >+ "charconv.cc", >+ "escaping.cc", >+ "internal/charconv_bigint.cc", >+ "internal/charconv_bigint.h", >+ "internal/charconv_parse.cc", >+ "internal/charconv_parse.h", >+ "internal/memutil.cc", >+ "internal/memutil.h", >+ "internal/stl_type_traits.h", >+ "internal/str_join_internal.h", >+ "internal/str_split_internal.h", >+ "match.cc", >+ "numbers.cc", >+ "str_cat.cc", >+ "str_replace.cc", >+ "str_split.cc", >+ "string_view.cc", >+ "substitute.cc", >+ ], >+ hdrs = [ >+ "ascii.h", >+ "charconv.h", >+ "escaping.h", >+ "match.h", >+ "numbers.h", >+ "str_cat.h", >+ "str_join.h", >+ "str_replace.h", >+ "str_split.h", >+ "string_view.h", >+ "strip.h", >+ "substitute.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":internal", >+ "//absl/base", >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ "//absl/base:endian", >+ "//absl/base:throw_delegate", >+ "//absl/memory", >+ "//absl/meta:type_traits", >+ "//absl/numeric:int128", >+ ], >+) >+ >+cc_library( >+ name = "internal", >+ srcs = [ >+ "internal/ostringstream.cc", >+ "internal/utf8.cc", >+ ], >+ hdrs = [ >+ "internal/bits.h", >+ "internal/char_map.h", >+ "internal/ostringstream.h", >+ "internal/resize_uninitialized.h", >+ "internal/utf8.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/base:core_headers", >+ "//absl/base:endian", >+ "//absl/meta:type_traits", >+ ], >+) >+ >+cc_test( >+ name = "match_test", >+ size = "small", >+ srcs = ["match_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "escaping_test", >+ size = "small", >+ srcs = [ >+ "escaping_test.cc", >+ "internal/escaping_test_common.h", >+ ], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base:core_headers", >+ "//absl/container:fixed_array", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "escaping_benchmark", >+ srcs = [ >+ "escaping_benchmark.cc", >+ "internal/escaping_test_common.h", >+ ], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "ascii_test", >+ size = "small", >+ srcs = ["ascii_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "ascii_benchmark", >+ srcs = ["ascii_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "memutil_benchmark", >+ srcs = [ >+ "internal/memutil.h", >+ "internal/memutil_benchmark.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base:core_headers", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "memutil_test", >+ size = "small", >+ srcs = [ >+ "internal/memutil.h", >+ "internal/memutil_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "utf8_test", >+ size = "small", >+ srcs = [ >+ "internal/utf8_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":internal", >+ ":strings", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "string_view_benchmark", >+ srcs = ["string_view_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "string_view_test", >+ size = "small", >+ srcs = ["string_view_test.cc"], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ "//absl/base:dynamic_annotations", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "substitute_test", >+ size = "small", >+ srcs = ["substitute_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_replace_benchmark", >+ srcs = ["str_replace_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "str_replace_test", >+ size = "small", >+ srcs = ["str_replace_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_split_test", >+ srcs = ["str_split_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base:core_headers", >+ "//absl/base:dynamic_annotations", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_split_benchmark", >+ srcs = ["str_split_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "ostringstream_test", >+ size = "small", >+ srcs = ["internal/ostringstream_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":internal", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "ostringstream_benchmark", >+ srcs = ["internal/ostringstream_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":internal", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "resize_uninitialized_test", >+ size = "small", >+ srcs = [ >+ "internal/resize_uninitialized.h", >+ "internal/resize_uninitialized_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ "//absl/base:core_headers", >+ "//absl/meta:type_traits", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_join_test", >+ size = "small", >+ srcs = ["str_join_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base:core_headers", >+ "//absl/memory", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_join_benchmark", >+ srcs = ["str_join_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/memory", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "str_cat_test", >+ size = "small", >+ srcs = ["str_cat_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_cat_benchmark", >+ srcs = ["str_cat_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "numbers_test", >+ size = "small", >+ srcs = [ >+ "internal/numbers_test_common.h", >+ "numbers_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "numbers_benchmark", >+ srcs = ["numbers_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "strip_test", >+ size = "small", >+ srcs = ["strip_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "char_map_test", >+ srcs = ["internal/char_map_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":internal", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "char_map_benchmark", >+ srcs = ["internal/char_map_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ deps = [ >+ ":internal", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "charconv_test", >+ srcs = ["charconv_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":strings", >+ "//absl/base", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "charconv_parse_test", >+ srcs = [ >+ "internal/charconv_parse.h", >+ "internal/charconv_parse_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":strings", >+ "//absl/base", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "charconv_bigint_test", >+ srcs = [ >+ "internal/charconv_bigint.h", >+ "internal/charconv_bigint_test.cc", >+ "internal/charconv_parse.h", >+ ], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":strings", >+ "//absl/base", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "charconv_benchmark", >+ srcs = [ >+ "charconv_benchmark.cc", >+ ], >+ tags = [ >+ "benchmark", >+ ], >+ deps = [ >+ ":strings", >+ "//absl/base", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_library( >+ name = "str_format", >+ hdrs = [ >+ "str_format.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":str_format_internal", >+ ], >+) >+ >+cc_library( >+ name = "str_format_internal", >+ srcs = [ >+ "internal/str_format/arg.cc", >+ "internal/str_format/bind.cc", >+ "internal/str_format/extension.cc", >+ "internal/str_format/float_conversion.cc", >+ "internal/str_format/output.cc", >+ "internal/str_format/parser.cc", >+ ], >+ hdrs = [ >+ "internal/str_format/arg.h", >+ "internal/str_format/bind.h", >+ "internal/str_format/checker.h", >+ "internal/str_format/extension.h", >+ "internal/str_format/float_conversion.h", >+ "internal/str_format/output.h", >+ "internal/str_format/parser.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":strings", >+ "//absl/base:core_headers", >+ "//absl/container:inlined_vector", >+ "//absl/meta:type_traits", >+ "//absl/numeric:int128", >+ "//absl/types:span", >+ ], >+) >+ >+cc_test( >+ name = "str_format_test", >+ srcs = ["str_format_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":str_format", >+ ":strings", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_format_extension_test", >+ srcs = [ >+ "internal/str_format/extension_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":str_format", >+ ":str_format_internal", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_format_arg_test", >+ srcs = ["internal/str_format/arg_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":str_format", >+ ":str_format_internal", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_format_bind_test", >+ srcs = ["internal/str_format/bind_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":str_format_internal", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_format_checker_test", >+ srcs = ["internal/str_format/checker_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":str_format", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_format_convert_test", >+ size = "small", >+ srcs = ["internal/str_format/convert_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":str_format_internal", >+ "//absl/numeric:int128", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_format_output_test", >+ srcs = ["internal/str_format/output_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":str_format_internal", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "str_format_parser_test", >+ srcs = ["internal/str_format/parser_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":str_format_internal", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..9a8a10d0e7108e79e42c9c5b36355cf879016b95 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/BUILD.gn >@@ -0,0 +1,146 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("strings") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "ascii.cc", >+ "charconv.cc", >+ "escaping.cc", >+ "internal/charconv_bigint.cc", >+ "internal/charconv_bigint.h", >+ "internal/charconv_parse.cc", >+ "internal/charconv_parse.h", >+ "internal/memutil.cc", >+ "internal/memutil.h", >+ "internal/stl_type_traits.h", >+ "internal/str_join_internal.h", >+ "internal/str_split_internal.h", >+ "match.cc", >+ "numbers.cc", >+ "str_cat.cc", >+ "str_replace.cc", >+ "str_split.cc", >+ "string_view.cc", >+ "substitute.cc", >+ ] >+ public = [ >+ "ascii.h", >+ "charconv.h", >+ "escaping.h", >+ "match.h", >+ "numbers.h", >+ "str_cat.h", >+ "str_join.h", >+ "str_replace.h", >+ "str_split.h", >+ "string_view.h", >+ "strip.h", >+ "substitute.h", >+ ] >+ deps = [ >+ ":internal", >+ "../base", >+ "../base:config", >+ "../base:core_headers", >+ "../base:endian", >+ "../base:throw_delegate", >+ "../memory", >+ "../meta:type_traits", >+ "../numeric:int128", >+ ] >+} >+ >+source_set("internal") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/ostringstream.cc", >+ "internal/utf8.cc", >+ ] >+ public = [ >+ "internal/bits.h", >+ "internal/char_map.h", >+ "internal/ostringstream.h", >+ "internal/resize_uninitialized.h", >+ "internal/utf8.h", >+ ] >+ deps = [ >+ "../base:core_headers", >+ "../base:endian", >+ "../meta:type_traits", >+ ] >+} >+ >+source_set("str_format") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "str_format.h", >+ ] >+ deps = [ >+ ":str_format_internal", >+ ] >+} >+ >+source_set("str_format_internal") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/str_format/arg.cc", >+ "internal/str_format/bind.cc", >+ "internal/str_format/extension.cc", >+ "internal/str_format/float_conversion.cc", >+ "internal/str_format/output.cc", >+ "internal/str_format/parser.cc", >+ ] >+ public = [ >+ "internal/str_format/arg.h", >+ "internal/str_format/bind.h", >+ "internal/str_format/checker.h", >+ "internal/str_format/extension.h", >+ "internal/str_format/float_conversion.h", >+ "internal/str_format/output.h", >+ "internal/str_format/parser.h", >+ ] >+ visibility = [] >+ visibility += [ ":*" ] >+ deps = [ >+ ":strings", >+ "../base:core_headers", >+ "../container:inlined_vector", >+ "../meta:type_traits", >+ "../numeric:int128", >+ "../types:span", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..cd122134729fa686e98610269f18acb18f8d3007 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/CMakeLists.txt >@@ -0,0 +1,464 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+ >+list(APPEND STRINGS_PUBLIC_HEADERS >+ "ascii.h" >+ "charconv.h" >+ "escaping.h" >+ "match.h" >+ "numbers.h" >+ "str_cat.h" >+ "string_view.h" >+ "strip.h" >+ "str_join.h" >+ "str_replace.h" >+ "str_split.h" >+ "substitute.h" >+) >+ >+ >+list(APPEND STRINGS_INTERNAL_HEADERS >+ "internal/bits.h" >+ "internal/char_map.h" >+ "internal/charconv_bigint.h" >+ "internal/charconv_parse.h" >+ "internal/memutil.h" >+ "internal/ostringstream.h" >+ "internal/resize_uninitialized.h" >+ "internal/stl_type_traits.h" >+ "internal/str_join_internal.h" >+ "internal/str_split_internal.h" >+ "internal/utf8.h" >+) >+ >+ >+ >+# add string library >+list(APPEND STRINGS_SRC >+ "ascii.cc" >+ "charconv.cc" >+ "escaping.cc" >+ "internal/charconv_bigint.cc" >+ "internal/charconv_parse.cc" >+ "internal/memutil.cc" >+ "internal/memutil.h" >+ "internal/utf8.cc" >+ "internal/ostringstream.cc" >+ "match.cc" >+ "numbers.cc" >+ "str_cat.cc" >+ "str_replace.cc" >+ "str_split.cc" >+ "string_view.cc" >+ "substitute.cc" >+ ${STRINGS_PUBLIC_HEADERS} >+ ${STRINGS_INTERNAL_HEADERS} >+) >+set(STRINGS_PUBLIC_LIBRARIES absl::base absl_throw_delegate) >+ >+absl_library( >+ TARGET >+ absl_strings >+ SOURCES >+ ${STRINGS_SRC} >+ PUBLIC_LIBRARIES >+ ${STRINGS_PUBLIC_LIBRARIES} >+ EXPORT_NAME >+ strings >+) >+ >+# add str_format library >+absl_header_library( >+ TARGET >+ absl_str_format >+ PUBLIC_LIBRARIES >+ str_format_internal >+ EXPORT_NAME >+ str_format >+) >+ >+# str_format_internal >+absl_library( >+ TARGET >+ str_format_internal >+ SOURCES >+ "internal/str_format/arg.cc" >+ "internal/str_format/bind.cc" >+ "internal/str_format/extension.cc" >+ "internal/str_format/float_conversion.cc" >+ "internal/str_format/output.cc" >+ "internal/str_format/parser.cc" >+ "internal/str_format/arg.h" >+ "internal/str_format/bind.h" >+ "internal/str_format/checker.h" >+ "internal/str_format/extension.h" >+ "internal/str_format/float_conversion.h" >+ "internal/str_format/output.h" >+ "internal/str_format/parser.h" >+ PUBLIC_LIBRARIES >+ str_format_extension_internal >+ absl::strings >+ absl::base >+ absl::numeric >+ absl::container >+ absl::span >+) >+ >+# str_format_extension_internal >+absl_library( >+ TARGET >+ str_format_extension_internal >+ SOURCES >+ "internal/str_format/extension.cc" >+ "internal/str_format/extension.h" >+ "internal/str_format/output.cc" >+ "internal/str_format/output.h" >+ PUBLIC_LIBRARIES >+ absl::base >+ absl::strings >+) >+ >+# >+## TESTS >+# >+ >+# test match_test >+set(MATCH_TEST_SRC "match_test.cc") >+set(MATCH_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ match_test >+ SOURCES >+ ${MATCH_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${MATCH_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test escaping_test >+set(ESCAPING_TEST_SRC "escaping_test.cc") >+set(ESCAPING_TEST_PUBLIC_LIBRARIES absl::strings absl::base) >+ >+absl_test( >+ TARGET >+ escaping_test >+ SOURCES >+ ${ESCAPING_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${ESCAPING_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test ascii_test >+set(ASCII_TEST_SRC "ascii_test.cc") >+set(ASCII_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ ascii_test >+ SOURCES >+ ${ASCII_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${ASCII_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test memutil_test >+set(MEMUTIL_TEST_SRC "internal/memutil_test.cc") >+set(MEMUTIL_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ memutil_test >+ SOURCES >+ ${MEMUTIL_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${MEMUTIL_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test utf8_test >+set(UTF8_TEST_SRC "internal/utf8_test.cc") >+set(UTF8_TEST_PUBLIC_LIBRARIES absl::strings absl::base) >+ >+absl_test( >+ TARGET >+ utf8_test >+ SOURCES >+ ${UTF8_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${UTF8_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test string_view_test >+set(STRING_VIEW_TEST_SRC "string_view_test.cc") >+set(STRING_VIEW_TEST_PUBLIC_LIBRARIES absl::strings absl_throw_delegate absl::base) >+ >+absl_test( >+ TARGET >+ string_view_test >+ SOURCES >+ ${STRING_VIEW_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${STRING_VIEW_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test substitute_test >+set(SUBSTITUTE_TEST_SRC "substitute_test.cc") >+set(SUBSTITUTE_TEST_PUBLIC_LIBRARIES absl::strings absl::base) >+ >+absl_test( >+ TARGET >+ substitute_test >+ SOURCES >+ ${SUBSTITUTE_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${SUBSTITUTE_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test str_replace_test >+set(STR_REPLACE_TEST_SRC "str_replace_test.cc") >+set(STR_REPLACE_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) >+ >+absl_test( >+ TARGET >+ str_replace_test >+ SOURCES >+ ${STR_REPLACE_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${STR_REPLACE_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test str_split_test >+set(STR_SPLIT_TEST_SRC "str_split_test.cc") >+set(STR_SPLIT_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) >+ >+absl_test( >+ TARGET >+ str_split_test >+ SOURCES >+ ${STR_SPLIT_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${STR_SPLIT_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test ostringstream_test >+set(OSTRINGSTREAM_TEST_SRC "internal/ostringstream_test.cc") >+set(OSTRINGSTREAM_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ ostringstream_test >+ SOURCES >+ ${OSTRINGSTREAM_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${OSTRINGSTREAM_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test resize_uninitialized_test >+set(RESIZE_UNINITIALIZED_TEST_SRC "internal/resize_uninitialized_test.cc") >+ >+absl_test( >+ TARGET >+ resize_uninitialized_test >+ SOURCES >+ ${RESIZE_UNINITIALIZED_TEST_SRC} >+) >+ >+ >+# test str_join_test >+set(STR_JOIN_TEST_SRC "str_join_test.cc") >+set(STR_JOIN_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ str_join_test >+ SOURCES >+ ${STR_JOIN_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${STR_JOIN_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test str_cat_test >+set(STR_CAT_TEST_SRC "str_cat_test.cc") >+set(STR_CAT_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ str_cat_test >+ SOURCES >+ ${STR_CAT_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${STR_CAT_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test numbers_test >+set(NUMBERS_TEST_SRC "numbers_test.cc") >+set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ numbers_test >+ SOURCES >+ ${NUMBERS_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${NUMBERS_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test strip_test >+set(STRIP_TEST_SRC "strip_test.cc") >+set(STRIP_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ strip_test >+ SOURCES >+ ${STRIP_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${STRIP_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test char_map_test >+set(CHAR_MAP_TEST_SRC "internal/char_map_test.cc") >+set(CHAR_MAP_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ char_map_test >+ SOURCES >+ ${CHAR_MAP_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${CHAR_MAP_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test charconv_test >+set(CHARCONV_TEST_SRC "charconv_test.cc") >+set(CHARCONV_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ charconv_test >+ SOURCES >+ ${CHARCONV_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${CHARCONV_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test charconv_parse_test >+set(CHARCONV_PARSE_TEST_SRC "internal/charconv_parse_test.cc") >+set(CHARCONV_PARSE_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ charconv_parse_test >+ SOURCES >+ ${CHARCONV_PARSE_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${CHARCONV_PARSE_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test charconv_bigint_test >+set(CHARCONV_BIGINT_TEST_SRC "internal/charconv_bigint_test.cc") >+set(CHARCONV_BIGINT_TEST_PUBLIC_LIBRARIES absl::strings) >+ >+absl_test( >+ TARGET >+ charconv_bigint_test >+ SOURCES >+ ${CHARCONV_BIGINT_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${CHARCONV_BIGINT_TEST_PUBLIC_LIBRARIES} >+) >+# test str_format_test >+absl_test( >+ TARGET >+ str_format_test >+ SOURCES >+ "str_format_test.cc" >+ PUBLIC_LIBRARIES >+ absl::base >+ absl::str_format >+ absl::strings >+) >+ >+# test str_format_bind_test >+absl_test( >+ TARGET >+ str_format_bind_test >+ SOURCES >+ "internal/str_format/bind_test.cc" >+ PUBLIC_LIBRARIES >+ str_format_internal >+) >+ >+# test str_format_checker_test >+absl_test( >+ TARGET >+ str_format_checker_test >+ SOURCES >+ "internal/str_format/checker_test.cc" >+ PUBLIC_LIBRARIES >+ absl::str_format >+) >+ >+# test str_format_convert_test >+absl_test( >+ TARGET >+ str_format_convert_test >+ SOURCES >+ "internal/str_format/convert_test.cc" >+ PUBLIC_LIBRARIES >+ str_format_internal >+ absl::numeric >+) >+ >+# test str_format_output_test >+absl_test( >+ TARGET >+ str_format_output_test >+ SOURCES >+ "internal/str_format/output_test.cc" >+ PUBLIC_LIBRARIES >+ str_format_extension_internal >+) >+ >+# test str_format_parser_test >+absl_test( >+ TARGET >+ str_format_parser_test >+ SOURCES >+ "internal/str_format/parser_test.cc" >+ PUBLIC_LIBRARIES >+ str_format_internal >+ absl::base >+) >+ >+ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..c9481e886542b3fbc95efc0fe65739c198a2eec5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii.cc >@@ -0,0 +1,198 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/ascii.h" >+ >+namespace absl { >+namespace ascii_internal { >+ >+// # Table generated by this Python code (bit 0x02 is currently unused): >+// TODO(mbar) Move Python code for generation of table to BUILD and link here. >+ >+// NOTE: The kAsciiPropertyBits table used within this code was generated by >+// Python code of the following form. (Bit 0x02 is currently unused and >+// available.) >+// >+// def Hex2(n): >+// return '0x' + hex(n/16)[2:] + hex(n%16)[2:] >+// def IsPunct(ch): >+// return (ord(ch) >= 32 and ord(ch) < 127 and >+// not ch.isspace() and not ch.isalnum()) >+// def IsBlank(ch): >+// return ch in ' \t' >+// def IsCntrl(ch): >+// return ord(ch) < 32 or ord(ch) == 127 >+// def IsXDigit(ch): >+// return ch.isdigit() or ch.lower() in 'abcdef' >+// for i in range(128): >+// ch = chr(i) >+// mask = ((ch.isalpha() and 0x01 or 0) | >+// (ch.isalnum() and 0x04 or 0) | >+// (ch.isspace() and 0x08 or 0) | >+// (IsPunct(ch) and 0x10 or 0) | >+// (IsBlank(ch) and 0x20 or 0) | >+// (IsCntrl(ch) and 0x40 or 0) | >+// (IsXDigit(ch) and 0x80 or 0)) >+// print Hex2(mask) + ',', >+// if i % 16 == 7: >+// print ' //', Hex2(i & 0x78) >+// elif i % 16 == 15: >+// print >+ >+// clang-format off >+// Array of bitfields holding character information. Each bit value corresponds >+// to a particular character feature. For readability, and because the value >+// of these bits is tightly coupled to this implementation, the individual bits >+// are not named. Note that bitfields for all characters above ASCII 127 are >+// zero-initialized. >+const unsigned char kPropertyBits[256] = { >+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x00 >+ 0x40, 0x68, 0x48, 0x48, 0x48, 0x48, 0x40, 0x40, >+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x10 >+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, >+ 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 0x20 >+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, >+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, // 0x30 >+ 0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, >+ 0x10, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x05, // 0x40 >+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, >+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x50 >+ 0x05, 0x05, 0x05, 0x10, 0x10, 0x10, 0x10, 0x10, >+ 0x10, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x05, // 0x60 >+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, >+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x70 >+ 0x05, 0x05, 0x05, 0x10, 0x10, 0x10, 0x10, 0x40, >+}; >+ >+// Array of characters for the ascii_tolower() function. For values 'A' >+// through 'Z', return the lower-case character; otherwise, return the >+// identity of the passed character. >+const char kToLower[256] = { >+ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', >+ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', >+ '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', >+ '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', >+ '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', >+ '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f', >+ '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', >+ '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f', >+ '\x40', 'a', 'b', 'c', 'd', 'e', 'f', 'g', >+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', >+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', >+ 'x', 'y', 'z', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f', >+ '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', >+ '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', >+ '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', >+ '\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f', >+ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', >+ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', >+ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', >+ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', >+ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', >+ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', >+ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', >+ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', >+ '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', >+ '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', >+ '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7', >+ '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', >+ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', >+ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', >+ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7', >+ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff', >+}; >+ >+// Array of characters for the ascii_toupper() function. For values 'a' >+// through 'z', return the upper-case character; otherwise, return the >+// identity of the passed character. >+const char kToUpper[256] = { >+ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', >+ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', >+ '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', >+ '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', >+ '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', >+ '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f', >+ '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', >+ '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f', >+ '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', >+ '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f', >+ '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', >+ '\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f', >+ '\x60', 'A', 'B', 'C', 'D', 'E', 'F', 'G', >+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', >+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', >+ 'X', 'Y', 'Z', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f', >+ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', >+ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', >+ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', >+ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', >+ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', >+ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', >+ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', >+ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', >+ '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', >+ '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', >+ '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7', >+ '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', >+ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', >+ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', >+ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7', >+ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff', >+}; >+// clang-format on >+ >+} // namespace ascii_internal >+ >+void AsciiStrToLower(std::string* s) { >+ for (auto& ch : *s) { >+ ch = absl::ascii_tolower(ch); >+ } >+} >+ >+void AsciiStrToUpper(std::string* s) { >+ for (auto& ch : *s) { >+ ch = absl::ascii_toupper(ch); >+ } >+} >+ >+void RemoveExtraAsciiWhitespace(std::string* str) { >+ auto stripped = StripAsciiWhitespace(*str); >+ >+ if (stripped.empty()) { >+ str->clear(); >+ return; >+ } >+ >+ auto input_it = stripped.begin(); >+ auto input_end = stripped.end(); >+ auto output_it = &(*str)[0]; >+ bool is_ws = false; >+ >+ for (; input_it < input_end; ++input_it) { >+ if (is_ws) { >+ // Consecutive whitespace? Keep only the last. >+ is_ws = absl::ascii_isspace(*input_it); >+ if (is_ws) --output_it; >+ } else { >+ is_ws = absl::ascii_isspace(*input_it); >+ } >+ >+ *output_it = *input_it; >+ ++output_it; >+ } >+ >+ str->erase(output_it - &(*str)[0]); >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii.h >new file mode 100644 >index 0000000000000000000000000000000000000000..96a64541c321a710d29efc8d9263862f1b9960e7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii.h >@@ -0,0 +1,239 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: ascii.h >+// ----------------------------------------------------------------------------- >+// >+// This package contains functions operating on characters and strings >+// restricted to standard ASCII. These include character classification >+// functions analogous to those found in the ANSI C Standard Library <ctype.h> >+// header file. >+// >+// C++ implementations provide <ctype.h> functionality based on their >+// C environment locale. In general, reliance on such a locale is not ideal, as >+// the locale standard is problematic (and may not return invariant information >+// for the same character set, for example). These `ascii_*()` functions are >+// hard-wired for standard ASCII, much faster, and guaranteed to behave >+// consistently. They will never be overloaded, nor will their function >+// signature change. >+// >+// `ascii_isalnum()`, `ascii_isalpha()`, `ascii_isascii()`, `ascii_isblank()`, >+// `ascii_iscntrl()`, `ascii_isdigit()`, `ascii_isgraph()`, `ascii_islower()`, >+// `ascii_isprint()`, `ascii_ispunct()`, `ascii_isspace()`, `ascii_isupper()`, >+// `ascii_isxdigit()` >+// Analogous to the <ctype.h> functions with similar names, these >+// functions take an unsigned char and return a bool, based on whether the >+// character matches the condition specified. >+// >+// If the input character has a numerical value greater than 127, these >+// functions return `false`. >+// >+// `ascii_tolower()`, `ascii_toupper()` >+// Analogous to the <ctype.h> functions with similar names, these functions >+// take an unsigned char and return a char. >+// >+// If the input character is not an ASCII {lower,upper}-case letter (including >+// numerical values greater than 127) then the functions return the same value >+// as the input character. >+ >+#ifndef ABSL_STRINGS_ASCII_H_ >+#define ABSL_STRINGS_ASCII_H_ >+ >+#include <algorithm> >+#include <string> >+ >+#include "absl/base/attributes.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+namespace ascii_internal { >+ >+// Declaration for an array of bitfields holding character information. >+extern const unsigned char kPropertyBits[256]; >+ >+// Declaration for the array of characters to upper-case characters. >+extern const char kToUpper[256]; >+ >+// Declaration for the array of characters to lower-case characters. >+extern const char kToLower[256]; >+ >+} // namespace ascii_internal >+ >+// ascii_isalpha() >+// >+// Determines whether the given character is an alphabetic character. >+inline bool ascii_isalpha(unsigned char c) { >+ return (ascii_internal::kPropertyBits[c] & 0x01) != 0; >+} >+ >+// ascii_isalnum() >+// >+// Determines whether the given character is an alphanumeric character. >+inline bool ascii_isalnum(unsigned char c) { >+ return (ascii_internal::kPropertyBits[c] & 0x04) != 0; >+} >+ >+// ascii_isspace() >+// >+// Determines whether the given character is a whitespace character (space, >+// tab, vertical tab, formfeed, linefeed, or carriage return). >+inline bool ascii_isspace(unsigned char c) { >+ return (ascii_internal::kPropertyBits[c] & 0x08) != 0; >+} >+ >+// ascii_ispunct() >+// >+// Determines whether the given character is a punctuation character. >+inline bool ascii_ispunct(unsigned char c) { >+ return (ascii_internal::kPropertyBits[c] & 0x10) != 0; >+} >+ >+// ascii_isblank() >+// >+// Determines whether the given character is a blank character (tab or space). >+inline bool ascii_isblank(unsigned char c) { >+ return (ascii_internal::kPropertyBits[c] & 0x20) != 0; >+} >+ >+// ascii_iscntrl() >+// >+// Determines whether the given character is a control character. >+inline bool ascii_iscntrl(unsigned char c) { >+ return (ascii_internal::kPropertyBits[c] & 0x40) != 0; >+} >+ >+// ascii_isxdigit() >+// >+// Determines whether the given character can be represented as a hexadecimal >+// digit character (i.e. {0-9} or {A-F}). >+inline bool ascii_isxdigit(unsigned char c) { >+ return (ascii_internal::kPropertyBits[c] & 0x80) != 0; >+} >+ >+// ascii_isdigit() >+// >+// Determines whether the given character can be represented as a decimal >+// digit character (i.e. {0-9}). >+inline bool ascii_isdigit(unsigned char c) { return c >= '0' && c <= '9'; } >+ >+// ascii_isprint() >+// >+// Determines whether the given character is printable, including whitespace. >+inline bool ascii_isprint(unsigned char c) { return c >= 32 && c < 127; } >+ >+// ascii_isgraph() >+// >+// Determines whether the given character has a graphical representation. >+inline bool ascii_isgraph(unsigned char c) { return c > 32 && c < 127; } >+ >+// ascii_isupper() >+// >+// Determines whether the given character is uppercase. >+inline bool ascii_isupper(unsigned char c) { return c >= 'A' && c <= 'Z'; } >+ >+// ascii_islower() >+// >+// Determines whether the given character is lowercase. >+inline bool ascii_islower(unsigned char c) { return c >= 'a' && c <= 'z'; } >+ >+// ascii_isascii() >+// >+// Determines whether the given character is ASCII. >+inline bool ascii_isascii(unsigned char c) { return c < 128; } >+ >+// ascii_tolower() >+// >+// Returns an ASCII character, converting to lowercase if uppercase is >+// passed. Note that character values > 127 are simply returned. >+inline char ascii_tolower(unsigned char c) { >+ return ascii_internal::kToLower[c]; >+} >+ >+// Converts the characters in `s` to lowercase, changing the contents of `s`. >+void AsciiStrToLower(std::string* s); >+ >+// Creates a lowercase std::string from a given absl::string_view. >+ABSL_MUST_USE_RESULT inline std::string AsciiStrToLower(absl::string_view s) { >+ std::string result(s); >+ absl::AsciiStrToLower(&result); >+ return result; >+} >+ >+// ascii_toupper() >+// >+// Returns the ASCII character, converting to upper-case if lower-case is >+// passed. Note that characters values > 127 are simply returned. >+inline char ascii_toupper(unsigned char c) { >+ return ascii_internal::kToUpper[c]; >+} >+ >+// Converts the characters in `s` to uppercase, changing the contents of `s`. >+void AsciiStrToUpper(std::string* s); >+ >+// Creates an uppercase std::string from a given absl::string_view. >+ABSL_MUST_USE_RESULT inline std::string AsciiStrToUpper(absl::string_view s) { >+ std::string result(s); >+ absl::AsciiStrToUpper(&result); >+ return result; >+} >+ >+// Returns absl::string_view with whitespace stripped from the beginning of the >+// given string_view. >+ABSL_MUST_USE_RESULT inline absl::string_view StripLeadingAsciiWhitespace( >+ absl::string_view str) { >+ auto it = std::find_if_not(str.begin(), str.end(), absl::ascii_isspace); >+ return absl::string_view(it, str.end() - it); >+} >+ >+// Strips in place whitespace from the beginning of the given std::string. >+inline void StripLeadingAsciiWhitespace(std::string* str) { >+ auto it = std::find_if_not(str->begin(), str->end(), absl::ascii_isspace); >+ str->erase(str->begin(), it); >+} >+ >+// Returns absl::string_view with whitespace stripped from the end of the given >+// string_view. >+ABSL_MUST_USE_RESULT inline absl::string_view StripTrailingAsciiWhitespace( >+ absl::string_view str) { >+ auto it = std::find_if_not(str.rbegin(), str.rend(), absl::ascii_isspace); >+ return absl::string_view(str.begin(), str.rend() - it); >+} >+ >+// Strips in place whitespace from the end of the given std::string >+inline void StripTrailingAsciiWhitespace(std::string* str) { >+ auto it = std::find_if_not(str->rbegin(), str->rend(), absl::ascii_isspace); >+ str->erase(str->rend() - it); >+} >+ >+// Returns absl::string_view with whitespace stripped from both ends of the >+// given string_view. >+ABSL_MUST_USE_RESULT inline absl::string_view StripAsciiWhitespace( >+ absl::string_view str) { >+ return StripTrailingAsciiWhitespace(StripLeadingAsciiWhitespace(str)); >+} >+ >+// Strips in place whitespace from both ends of the given std::string >+inline void StripAsciiWhitespace(std::string* str) { >+ StripTrailingAsciiWhitespace(str); >+ StripLeadingAsciiWhitespace(str); >+} >+ >+// Removes leading, trailing, and consecutive internal whitespace. >+void RemoveExtraAsciiWhitespace(std::string*); >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_ASCII_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..8dea4b8cfbf930758e220262606220d83fbfe0c2 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii_benchmark.cc >@@ -0,0 +1,120 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/ascii.h" >+ >+#include <cctype> >+#include <string> >+#include <array> >+#include <random> >+ >+#include "benchmark/benchmark.h" >+ >+namespace { >+ >+std::array<unsigned char, 256> MakeShuffledBytes() { >+ std::array<unsigned char, 256> bytes; >+ for (size_t i = 0; i < 256; ++i) bytes[i] = static_cast<unsigned char>(i); >+ std::random_device rd; >+ std::seed_seq seed({rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()}); >+ std::mt19937 g(seed); >+ std::shuffle(bytes.begin(), bytes.end(), g); >+ return bytes; >+} >+ >+template <typename Function> >+void AsciiBenchmark(benchmark::State& state, Function f) { >+ std::array<unsigned char, 256> bytes = MakeShuffledBytes(); >+ size_t sum = 0; >+ for (auto _ : state) { >+ for (unsigned char b : bytes) sum += f(b) ? 1 : 0; >+ } >+ // Make a copy of `sum` before calling `DoNotOptimize` to make sure that `sum` >+ // can be put in a CPU register and not degrade performance in the loop above. >+ size_t sum2 = sum; >+ benchmark::DoNotOptimize(sum2); >+ state.SetBytesProcessed(state.iterations() * bytes.size()); >+} >+ >+using StdAsciiFunction = int (*)(int); >+template <StdAsciiFunction f> >+void BM_Ascii(benchmark::State& state) { >+ AsciiBenchmark(state, f); >+} >+ >+using AbslAsciiIsFunction = bool (*)(unsigned char); >+template <AbslAsciiIsFunction f> >+void BM_Ascii(benchmark::State& state) { >+ AsciiBenchmark(state, f); >+} >+ >+using AbslAsciiToFunction = char (*)(unsigned char); >+template <AbslAsciiToFunction f> >+void BM_Ascii(benchmark::State& state) { >+ AsciiBenchmark(state, f); >+} >+ >+inline char Noop(unsigned char b) { return static_cast<char>(b); } >+ >+BENCHMARK_TEMPLATE(BM_Ascii, Noop); >+BENCHMARK_TEMPLATE(BM_Ascii, std::isalpha); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isalpha); >+BENCHMARK_TEMPLATE(BM_Ascii, std::isdigit); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isdigit); >+BENCHMARK_TEMPLATE(BM_Ascii, std::isalnum); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isalnum); >+BENCHMARK_TEMPLATE(BM_Ascii, std::isspace); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isspace); >+BENCHMARK_TEMPLATE(BM_Ascii, std::ispunct); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_ispunct); >+BENCHMARK_TEMPLATE(BM_Ascii, std::isblank); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isblank); >+BENCHMARK_TEMPLATE(BM_Ascii, std::iscntrl); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_iscntrl); >+BENCHMARK_TEMPLATE(BM_Ascii, std::isxdigit); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isxdigit); >+BENCHMARK_TEMPLATE(BM_Ascii, std::isprint); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isprint); >+BENCHMARK_TEMPLATE(BM_Ascii, std::isgraph); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isgraph); >+BENCHMARK_TEMPLATE(BM_Ascii, std::isupper); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isupper); >+BENCHMARK_TEMPLATE(BM_Ascii, std::islower); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_islower); >+BENCHMARK_TEMPLATE(BM_Ascii, isascii); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isascii); >+BENCHMARK_TEMPLATE(BM_Ascii, std::tolower); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_tolower); >+BENCHMARK_TEMPLATE(BM_Ascii, std::toupper); >+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_toupper); >+ >+static void BM_StrToLower(benchmark::State& state) { >+ const int size = state.range(0); >+ std::string s(size, 'X'); >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(absl::AsciiStrToLower(s)); >+ } >+} >+BENCHMARK(BM_StrToLower)->Range(1, 1 << 20); >+ >+static void BM_StrToUpper(benchmark::State& state) { >+ const int size = state.range(0); >+ std::string s(size, 'x'); >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(absl::AsciiStrToUpper(s)); >+ } >+} >+BENCHMARK(BM_StrToUpper)->Range(1, 1 << 20); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..9903b0496b7719df703fc11bd70514c5c74ddd95 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/ascii_test.cc >@@ -0,0 +1,361 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/ascii.h" >+ >+#include <cctype> >+#include <clocale> >+#include <cstring> >+#include <string> >+ >+#include "gtest/gtest.h" >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+ >+namespace { >+ >+TEST(AsciiIsFoo, All) { >+ for (int i = 0; i < 256; i++) { >+ if ((i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z')) >+ EXPECT_TRUE(absl::ascii_isalpha(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_isalpha(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if ((i >= '0' && i <= '9')) >+ EXPECT_TRUE(absl::ascii_isdigit(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_isdigit(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if (absl::ascii_isalpha(i) || absl::ascii_isdigit(i)) >+ EXPECT_TRUE(absl::ascii_isalnum(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_isalnum(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if (i != '\0' && strchr(" \r\n\t\v\f", i)) >+ EXPECT_TRUE(absl::ascii_isspace(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_isspace(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if (i >= 32 && i < 127) >+ EXPECT_TRUE(absl::ascii_isprint(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_isprint(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if (absl::ascii_isprint(i) && !absl::ascii_isspace(i) && >+ !absl::ascii_isalnum(i)) >+ EXPECT_TRUE(absl::ascii_ispunct(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_ispunct(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if (i == ' ' || i == '\t') >+ EXPECT_TRUE(absl::ascii_isblank(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_isblank(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if (i < 32 || i == 127) >+ EXPECT_TRUE(absl::ascii_iscntrl(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_iscntrl(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if (absl::ascii_isdigit(i) || (i >= 'A' && i <= 'F') || >+ (i >= 'a' && i <= 'f')) >+ EXPECT_TRUE(absl::ascii_isxdigit(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_isxdigit(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if (i > 32 && i < 127) >+ EXPECT_TRUE(absl::ascii_isgraph(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_isgraph(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if (i >= 'A' && i <= 'Z') >+ EXPECT_TRUE(absl::ascii_isupper(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_isupper(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 256; i++) { >+ if (i >= 'a' && i <= 'z') >+ EXPECT_TRUE(absl::ascii_islower(i)) << ": failed on " << i; >+ else >+ EXPECT_TRUE(!absl::ascii_islower(i)) << ": failed on " << i; >+ } >+ for (int i = 0; i < 128; i++) { >+ EXPECT_TRUE(absl::ascii_isascii(i)) << ": failed on " << i; >+ } >+ for (int i = 128; i < 256; i++) { >+ EXPECT_TRUE(!absl::ascii_isascii(i)) << ": failed on " << i; >+ } >+ >+ // The official is* functions don't accept negative signed chars, but >+ // our absl::ascii_is* functions do. >+ for (int i = 0; i < 256; i++) { >+ signed char sc = static_cast<signed char>(static_cast<unsigned char>(i)); >+ EXPECT_EQ(absl::ascii_isalpha(i), absl::ascii_isalpha(sc)) << i; >+ EXPECT_EQ(absl::ascii_isdigit(i), absl::ascii_isdigit(sc)) << i; >+ EXPECT_EQ(absl::ascii_isalnum(i), absl::ascii_isalnum(sc)) << i; >+ EXPECT_EQ(absl::ascii_isspace(i), absl::ascii_isspace(sc)) << i; >+ EXPECT_EQ(absl::ascii_ispunct(i), absl::ascii_ispunct(sc)) << i; >+ EXPECT_EQ(absl::ascii_isblank(i), absl::ascii_isblank(sc)) << i; >+ EXPECT_EQ(absl::ascii_iscntrl(i), absl::ascii_iscntrl(sc)) << i; >+ EXPECT_EQ(absl::ascii_isxdigit(i), absl::ascii_isxdigit(sc)) << i; >+ EXPECT_EQ(absl::ascii_isprint(i), absl::ascii_isprint(sc)) << i; >+ EXPECT_EQ(absl::ascii_isgraph(i), absl::ascii_isgraph(sc)) << i; >+ EXPECT_EQ(absl::ascii_isupper(i), absl::ascii_isupper(sc)) << i; >+ EXPECT_EQ(absl::ascii_islower(i), absl::ascii_islower(sc)) << i; >+ EXPECT_EQ(absl::ascii_isascii(i), absl::ascii_isascii(sc)) << i; >+ } >+} >+ >+// Checks that absl::ascii_isfoo returns the same value as isfoo in the C >+// locale. >+TEST(AsciiIsFoo, SameAsIsFoo) { >+#ifndef __ANDROID__ >+ // temporarily change locale to C. It should already be C, but just for safety >+ const char* old_locale = setlocale(LC_CTYPE, "C"); >+ ASSERT_TRUE(old_locale != nullptr); >+#endif >+ >+ for (int i = 0; i < 256; i++) { >+ EXPECT_EQ(isalpha(i) != 0, absl::ascii_isalpha(i)) << i; >+ EXPECT_EQ(isdigit(i) != 0, absl::ascii_isdigit(i)) << i; >+ EXPECT_EQ(isalnum(i) != 0, absl::ascii_isalnum(i)) << i; >+ EXPECT_EQ(isspace(i) != 0, absl::ascii_isspace(i)) << i; >+ EXPECT_EQ(ispunct(i) != 0, absl::ascii_ispunct(i)) << i; >+ EXPECT_EQ(isblank(i) != 0, absl::ascii_isblank(i)) << i; >+ EXPECT_EQ(iscntrl(i) != 0, absl::ascii_iscntrl(i)) << i; >+ EXPECT_EQ(isxdigit(i) != 0, absl::ascii_isxdigit(i)) << i; >+ EXPECT_EQ(isprint(i) != 0, absl::ascii_isprint(i)) << i; >+ EXPECT_EQ(isgraph(i) != 0, absl::ascii_isgraph(i)) << i; >+ EXPECT_EQ(isupper(i) != 0, absl::ascii_isupper(i)) << i; >+ EXPECT_EQ(islower(i) != 0, absl::ascii_islower(i)) << i; >+ EXPECT_EQ(isascii(i) != 0, absl::ascii_isascii(i)) << i; >+ } >+ >+#ifndef __ANDROID__ >+ // restore the old locale. >+ ASSERT_TRUE(setlocale(LC_CTYPE, old_locale)); >+#endif >+} >+ >+TEST(AsciiToFoo, All) { >+#ifndef __ANDROID__ >+ // temporarily change locale to C. It should already be C, but just for safety >+ const char* old_locale = setlocale(LC_CTYPE, "C"); >+ ASSERT_TRUE(old_locale != nullptr); >+#endif >+ >+ for (int i = 0; i < 256; i++) { >+ if (absl::ascii_islower(i)) >+ EXPECT_EQ(absl::ascii_toupper(i), 'A' + (i - 'a')) << i; >+ else >+ EXPECT_EQ(absl::ascii_toupper(i), static_cast<char>(i)) << i; >+ >+ if (absl::ascii_isupper(i)) >+ EXPECT_EQ(absl::ascii_tolower(i), 'a' + (i - 'A')) << i; >+ else >+ EXPECT_EQ(absl::ascii_tolower(i), static_cast<char>(i)) << i; >+ >+ // These CHECKs only hold in a C locale. >+ EXPECT_EQ(static_cast<char>(tolower(i)), absl::ascii_tolower(i)) << i; >+ EXPECT_EQ(static_cast<char>(toupper(i)), absl::ascii_toupper(i)) << i; >+ >+ // The official to* functions don't accept negative signed chars, but >+ // our absl::ascii_to* functions do. >+ signed char sc = static_cast<signed char>(static_cast<unsigned char>(i)); >+ EXPECT_EQ(absl::ascii_tolower(i), absl::ascii_tolower(sc)) << i; >+ EXPECT_EQ(absl::ascii_toupper(i), absl::ascii_toupper(sc)) << i; >+ } >+#ifndef __ANDROID__ >+ // restore the old locale. >+ ASSERT_TRUE(setlocale(LC_CTYPE, old_locale)); >+#endif >+} >+ >+TEST(AsciiStrTo, Lower) { >+ const char buf[] = "ABCDEF"; >+ const std::string str("GHIJKL"); >+ const std::string str2("MNOPQR"); >+ const absl::string_view sp(str2); >+ >+ EXPECT_EQ("abcdef", absl::AsciiStrToLower(buf)); >+ EXPECT_EQ("ghijkl", absl::AsciiStrToLower(str)); >+ EXPECT_EQ("mnopqr", absl::AsciiStrToLower(sp)); >+ >+ char mutable_buf[] = "Mutable"; >+ std::transform(mutable_buf, mutable_buf + strlen(mutable_buf), >+ mutable_buf, absl::ascii_tolower); >+ EXPECT_STREQ("mutable", mutable_buf); >+} >+ >+TEST(AsciiStrTo, Upper) { >+ const char buf[] = "abcdef"; >+ const std::string str("ghijkl"); >+ const std::string str2("mnopqr"); >+ const absl::string_view sp(str2); >+ >+ EXPECT_EQ("ABCDEF", absl::AsciiStrToUpper(buf)); >+ EXPECT_EQ("GHIJKL", absl::AsciiStrToUpper(str)); >+ EXPECT_EQ("MNOPQR", absl::AsciiStrToUpper(sp)); >+ >+ char mutable_buf[] = "Mutable"; >+ std::transform(mutable_buf, mutable_buf + strlen(mutable_buf), >+ mutable_buf, absl::ascii_toupper); >+ EXPECT_STREQ("MUTABLE", mutable_buf); >+} >+ >+TEST(StripLeadingAsciiWhitespace, FromStringView) { >+ EXPECT_EQ(absl::string_view{}, >+ absl::StripLeadingAsciiWhitespace(absl::string_view{})); >+ EXPECT_EQ("foo", absl::StripLeadingAsciiWhitespace({"foo"})); >+ EXPECT_EQ("foo", absl::StripLeadingAsciiWhitespace({"\t \n\f\r\n\vfoo"})); >+ EXPECT_EQ("foo foo\n ", >+ absl::StripLeadingAsciiWhitespace({"\t \n\f\r\n\vfoo foo\n "})); >+ EXPECT_EQ(absl::string_view{}, absl::StripLeadingAsciiWhitespace( >+ {"\t \n\f\r\v\n\t \n\f\r\v\n"})); >+} >+ >+TEST(StripLeadingAsciiWhitespace, InPlace) { >+ std::string str; >+ >+ absl::StripLeadingAsciiWhitespace(&str); >+ EXPECT_EQ("", str); >+ >+ str = "foo"; >+ absl::StripLeadingAsciiWhitespace(&str); >+ EXPECT_EQ("foo", str); >+ >+ str = "\t \n\f\r\n\vfoo"; >+ absl::StripLeadingAsciiWhitespace(&str); >+ EXPECT_EQ("foo", str); >+ >+ str = "\t \n\f\r\n\vfoo foo\n "; >+ absl::StripLeadingAsciiWhitespace(&str); >+ EXPECT_EQ("foo foo\n ", str); >+ >+ str = "\t \n\f\r\v\n\t \n\f\r\v\n"; >+ absl::StripLeadingAsciiWhitespace(&str); >+ EXPECT_EQ(absl::string_view{}, str); >+} >+ >+TEST(StripTrailingAsciiWhitespace, FromStringView) { >+ EXPECT_EQ(absl::string_view{}, >+ absl::StripTrailingAsciiWhitespace(absl::string_view{})); >+ EXPECT_EQ("foo", absl::StripTrailingAsciiWhitespace({"foo"})); >+ EXPECT_EQ("foo", absl::StripTrailingAsciiWhitespace({"foo\t \n\f\r\n\v"})); >+ EXPECT_EQ(" \nfoo foo", >+ absl::StripTrailingAsciiWhitespace({" \nfoo foo\t \n\f\r\n\v"})); >+ EXPECT_EQ(absl::string_view{}, absl::StripTrailingAsciiWhitespace( >+ {"\t \n\f\r\v\n\t \n\f\r\v\n"})); >+} >+ >+TEST(StripTrailingAsciiWhitespace, InPlace) { >+ std::string str; >+ >+ absl::StripTrailingAsciiWhitespace(&str); >+ EXPECT_EQ("", str); >+ >+ str = "foo"; >+ absl::StripTrailingAsciiWhitespace(&str); >+ EXPECT_EQ("foo", str); >+ >+ str = "foo\t \n\f\r\n\v"; >+ absl::StripTrailingAsciiWhitespace(&str); >+ EXPECT_EQ("foo", str); >+ >+ str = " \nfoo foo\t \n\f\r\n\v"; >+ absl::StripTrailingAsciiWhitespace(&str); >+ EXPECT_EQ(" \nfoo foo", str); >+ >+ str = "\t \n\f\r\v\n\t \n\f\r\v\n"; >+ absl::StripTrailingAsciiWhitespace(&str); >+ EXPECT_EQ(absl::string_view{}, str); >+} >+ >+TEST(StripAsciiWhitespace, FromStringView) { >+ EXPECT_EQ(absl::string_view{}, >+ absl::StripAsciiWhitespace(absl::string_view{})); >+ EXPECT_EQ("foo", absl::StripAsciiWhitespace({"foo"})); >+ EXPECT_EQ("foo", >+ absl::StripAsciiWhitespace({"\t \n\f\r\n\vfoo\t \n\f\r\n\v"})); >+ EXPECT_EQ("foo foo", absl::StripAsciiWhitespace( >+ {"\t \n\f\r\n\vfoo foo\t \n\f\r\n\v"})); >+ EXPECT_EQ(absl::string_view{}, >+ absl::StripAsciiWhitespace({"\t \n\f\r\v\n\t \n\f\r\v\n"})); >+} >+ >+TEST(StripAsciiWhitespace, InPlace) { >+ std::string str; >+ >+ absl::StripAsciiWhitespace(&str); >+ EXPECT_EQ("", str); >+ >+ str = "foo"; >+ absl::StripAsciiWhitespace(&str); >+ EXPECT_EQ("foo", str); >+ >+ str = "\t \n\f\r\n\vfoo\t \n\f\r\n\v"; >+ absl::StripAsciiWhitespace(&str); >+ EXPECT_EQ("foo", str); >+ >+ str = "\t \n\f\r\n\vfoo foo\t \n\f\r\n\v"; >+ absl::StripAsciiWhitespace(&str); >+ EXPECT_EQ("foo foo", str); >+ >+ str = "\t \n\f\r\v\n\t \n\f\r\v\n"; >+ absl::StripAsciiWhitespace(&str); >+ EXPECT_EQ(absl::string_view{}, str); >+} >+ >+TEST(RemoveExtraAsciiWhitespace, InPlace) { >+ const char* inputs[] = {"No extra space", >+ " Leading whitespace", >+ "Trailing whitespace ", >+ " Leading and trailing ", >+ " Whitespace \t in\v middle ", >+ "'Eeeeep! \n Newlines!\n", >+ "nospaces", >+ "", >+ "\n\t a\t\n\nb \t\n"}; >+ >+ const char* outputs[] = { >+ "No extra space", >+ "Leading whitespace", >+ "Trailing whitespace", >+ "Leading and trailing", >+ "Whitespace in middle", >+ "'Eeeeep! Newlines!", >+ "nospaces", >+ "", >+ "a\nb", >+ }; >+ const int NUM_TESTS = ABSL_ARRAYSIZE(inputs); >+ >+ for (int i = 0; i < NUM_TESTS; i++) { >+ std::string s(inputs[i]); >+ absl::RemoveExtraAsciiWhitespace(&s); >+ EXPECT_EQ(outputs[i], s); >+ } >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..08c3947eccd475dee33310d247bf8740039980c8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv.cc >@@ -0,0 +1,982 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/charconv.h" >+ >+#include <algorithm> >+#include <cassert> >+#include <cmath> >+#include <cstring> >+ >+#include "absl/base/casts.h" >+#include "absl/numeric/int128.h" >+#include "absl/strings/internal/bits.h" >+#include "absl/strings/internal/charconv_bigint.h" >+#include "absl/strings/internal/charconv_parse.h" >+ >+// The macro ABSL_BIT_PACK_FLOATS is defined on x86-64, where IEEE floating >+// point numbers have the same endianness in memory as a bitfield struct >+// containing the corresponding parts. >+// >+// When set, we replace calls to ldexp() with manual bit packing, which is >+// faster and is unaffected by floating point environment. >+#ifdef ABSL_BIT_PACK_FLOATS >+#error ABSL_BIT_PACK_FLOATS cannot be directly set >+#elif defined(__x86_64__) || defined(_M_X64) >+#define ABSL_BIT_PACK_FLOATS 1 >+#endif >+ >+// A note about subnormals: >+// >+// The code below talks about "normals" and "subnormals". A normal IEEE float >+// has a fixed-width mantissa and power of two exponent. For example, a normal >+// `double` has a 53-bit mantissa. Because the high bit is always 1, it is not >+// stored in the representation. The implicit bit buys an extra bit of >+// resolution in the datatype. >+// >+// The downside of this scheme is that there is a large gap between DBL_MIN and >+// zero. (Large, at least, relative to the different between DBL_MIN and the >+// next representable number). This gap is softened by the "subnormal" numbers, >+// which have the same power-of-two exponent as DBL_MIN, but no implicit 53rd >+// bit. An all-bits-zero exponent in the encoding represents subnormals. (Zero >+// is represented as a subnormal with an all-bits-zero mantissa.) >+// >+// The code below, in calculations, represents the mantissa as a uint64_t. The >+// end result normally has the 53rd bit set. It represents subnormals by using >+// narrower mantissas. >+ >+namespace absl { >+namespace { >+ >+template <typename FloatType> >+struct FloatTraits; >+ >+template <> >+struct FloatTraits<double> { >+ // The number of mantissa bits in the given float type. This includes the >+ // implied high bit. >+ static constexpr int kTargetMantissaBits = 53; >+ >+ // The largest supported IEEE exponent, in our integral mantissa >+ // representation. >+ // >+ // If `m` is the largest possible int kTargetMantissaBits bits wide, then >+ // m * 2**kMaxExponent is exactly equal to DBL_MAX. >+ static constexpr int kMaxExponent = 971; >+ >+ // The smallest supported IEEE normal exponent, in our integral mantissa >+ // representation. >+ // >+ // If `m` is the smallest possible int kTargetMantissaBits bits wide, then >+ // m * 2**kMinNormalExponent is exactly equal to DBL_MIN. >+ static constexpr int kMinNormalExponent = -1074; >+ >+ static double MakeNan(const char* tagp) { >+ // Support nan no matter which namespace it's in. Some platforms >+ // incorrectly don't put it in namespace std. >+ using namespace std; // NOLINT >+ return nan(tagp); >+ } >+ >+ // Builds a nonzero floating point number out of the provided parts. >+ // >+ // This is intended to do the same operation as ldexp(mantissa, exponent), >+ // but using purely integer math, to avoid -ffastmath and floating >+ // point environment issues. Using type punning is also faster. We fall back >+ // to ldexp on a per-platform basis for portability. >+ // >+ // `exponent` must be between kMinNormalExponent and kMaxExponent. >+ // >+ // `mantissa` must either be exactly kTargetMantissaBits wide, in which case >+ // a normal value is made, or it must be less narrow than that, in which case >+ // `exponent` must be exactly kMinNormalExponent, and a subnormal value is >+ // made. >+ static double Make(uint64_t mantissa, int exponent, bool sign) { >+#ifndef ABSL_BIT_PACK_FLOATS >+ // Support ldexp no matter which namespace it's in. Some platforms >+ // incorrectly don't put it in namespace std. >+ using namespace std; // NOLINT >+ return sign ? -ldexp(mantissa, exponent) : ldexp(mantissa, exponent); >+#else >+ constexpr uint64_t kMantissaMask = >+ (uint64_t(1) << (kTargetMantissaBits - 1)) - 1; >+ uint64_t dbl = static_cast<uint64_t>(sign) << 63; >+ if (mantissa > kMantissaMask) { >+ // Normal value. >+ // Adjust by 1023 for the exponent representation bias, and an additional >+ // 52 due to the implied decimal point in the IEEE mantissa represenation. >+ dbl += uint64_t{exponent + 1023u + kTargetMantissaBits - 1} << 52; >+ mantissa &= kMantissaMask; >+ } else { >+ // subnormal value >+ assert(exponent == kMinNormalExponent); >+ } >+ dbl += mantissa; >+ return absl::bit_cast<double>(dbl); >+#endif // ABSL_BIT_PACK_FLOATS >+ } >+}; >+ >+// Specialization of floating point traits for the `float` type. See the >+// FloatTraits<double> specialization above for meaning of each of the following >+// members and methods. >+template <> >+struct FloatTraits<float> { >+ static constexpr int kTargetMantissaBits = 24; >+ static constexpr int kMaxExponent = 104; >+ static constexpr int kMinNormalExponent = -149; >+ static float MakeNan(const char* tagp) { >+ // Support nanf no matter which namespace it's in. Some platforms >+ // incorrectly don't put it in namespace std. >+ using namespace std; // NOLINT >+ return nanf(tagp); >+ } >+ static float Make(uint32_t mantissa, int exponent, bool sign) { >+#ifndef ABSL_BIT_PACK_FLOATS >+ // Support ldexpf no matter which namespace it's in. Some platforms >+ // incorrectly don't put it in namespace std. >+ using namespace std; // NOLINT >+ return sign ? -ldexpf(mantissa, exponent) : ldexpf(mantissa, exponent); >+#else >+ constexpr uint32_t kMantissaMask = >+ (uint32_t(1) << (kTargetMantissaBits - 1)) - 1; >+ uint32_t flt = static_cast<uint32_t>(sign) << 31; >+ if (mantissa > kMantissaMask) { >+ // Normal value. >+ // Adjust by 127 for the exponent representation bias, and an additional >+ // 23 due to the implied decimal point in the IEEE mantissa represenation. >+ flt += uint32_t{exponent + 127u + kTargetMantissaBits - 1} << 23; >+ mantissa &= kMantissaMask; >+ } else { >+ // subnormal value >+ assert(exponent == kMinNormalExponent); >+ } >+ flt += mantissa; >+ return absl::bit_cast<float>(flt); >+#endif // ABSL_BIT_PACK_FLOATS >+ } >+}; >+ >+// Decimal-to-binary conversions require coercing powers of 10 into a mantissa >+// and a power of 2. The two helper functions Power10Mantissa(n) and >+// Power10Exponent(n) perform this task. Together, these represent a hand- >+// rolled floating point value which is equal to or just less than 10**n. >+// >+// The return values satisfy two range guarantees: >+// >+// Power10Mantissa(n) * 2**Power10Exponent(n) <= 10**n >+// < (Power10Mantissa(n) + 1) * 2**Power10Exponent(n) >+// >+// 2**63 <= Power10Mantissa(n) < 2**64. >+// >+// Lookups into the power-of-10 table must first check the Power10Overflow() and >+// Power10Underflow() functions, to avoid out-of-bounds table access. >+// >+// Indexes into these tables are biased by -kPower10TableMin, and the table has >+// values in the range [kPower10TableMin, kPower10TableMax]. >+extern const uint64_t kPower10MantissaTable[]; >+extern const int16_t kPower10ExponentTable[]; >+ >+// The smallest allowed value for use with the Power10Mantissa() and >+// Power10Exponent() functions below. (If a smaller exponent is needed in >+// calculations, the end result is guaranteed to underflow.) >+constexpr int kPower10TableMin = -342; >+ >+// The largest allowed value for use with the Power10Mantissa() and >+// Power10Exponent() functions below. (If a smaller exponent is needed in >+// calculations, the end result is guaranteed to overflow.) >+constexpr int kPower10TableMax = 308; >+ >+uint64_t Power10Mantissa(int n) { >+ return kPower10MantissaTable[n - kPower10TableMin]; >+} >+ >+int Power10Exponent(int n) { >+ return kPower10ExponentTable[n - kPower10TableMin]; >+} >+ >+// Returns true if n is large enough that 10**n always results in an IEEE >+// overflow. >+bool Power10Overflow(int n) { return n > kPower10TableMax; } >+ >+// Returns true if n is small enough that 10**n times a ParsedFloat mantissa >+// always results in an IEEE underflow. >+bool Power10Underflow(int n) { return n < kPower10TableMin; } >+ >+// Returns true if Power10Mantissa(n) * 2**Power10Exponent(n) is exactly equal >+// to 10**n numerically. Put another way, this returns true if there is no >+// truncation error in Power10Mantissa(n). >+bool Power10Exact(int n) { return n >= 0 && n <= 27; } >+ >+// Sentinel exponent values for representing numbers too large or too close to >+// zero to represent in a double. >+constexpr int kOverflow = 99999; >+constexpr int kUnderflow = -99999; >+ >+// Struct representing the calculated conversion result of a positive (nonzero) >+// floating point number. >+// >+// The calculated number is mantissa * 2**exponent (mantissa is treated as an >+// integer.) `mantissa` is chosen to be the correct width for the IEEE float >+// representation being calculated. (`mantissa` will always have the same bit >+// width for normal values, and narrower bit widths for subnormals.) >+// >+// If the result of conversion was an underflow or overflow, exponent is set >+// to kUnderflow or kOverflow. >+struct CalculatedFloat { >+ uint64_t mantissa = 0; >+ int exponent = 0; >+}; >+ >+// Returns the bit width of the given uint128. (Equivalently, returns 128 >+// minus the number of leading zero bits.) >+int BitWidth(uint128 value) { >+ if (Uint128High64(value) == 0) { >+ return 64 - strings_internal::CountLeadingZeros64(Uint128Low64(value)); >+ } >+ return 128 - strings_internal::CountLeadingZeros64(Uint128High64(value)); >+} >+ >+// Calculates how far to the right a mantissa needs to be shifted to create a >+// properly adjusted mantissa for an IEEE floating point number. >+// >+// `mantissa_width` is the bit width of the mantissa to be shifted, and >+// `binary_exponent` is the exponent of the number before the shift. >+// >+// This accounts for subnormal values, and will return a larger-than-normal >+// shift if binary_exponent would otherwise be too low. >+template <typename FloatType> >+int NormalizedShiftSize(int mantissa_width, int binary_exponent) { >+ const int normal_shift = >+ mantissa_width - FloatTraits<FloatType>::kTargetMantissaBits; >+ const int minimum_shift = >+ FloatTraits<FloatType>::kMinNormalExponent - binary_exponent; >+ return std::max(normal_shift, minimum_shift); >+} >+ >+// Right shifts a uint128 so that it has the requested bit width. (The >+// resulting value will have 128 - bit_width leading zeroes.) The initial >+// `value` must be wider than the requested bit width. >+// >+// Returns the number of bits shifted. >+int TruncateToBitWidth(int bit_width, uint128* value) { >+ const int current_bit_width = BitWidth(*value); >+ const int shift = current_bit_width - bit_width; >+ *value >>= shift; >+ return shift; >+} >+ >+// Checks if the given ParsedFloat represents one of the edge cases that are >+// not dependent on number base: zero, infinity, or NaN. If so, sets *value >+// the appropriate double, and returns true. >+template <typename FloatType> >+bool HandleEdgeCase(const strings_internal::ParsedFloat& input, bool negative, >+ FloatType* value) { >+ if (input.type == strings_internal::FloatType::kNan) { >+ // A bug in both clang and gcc would cause the compiler to optimize away the >+ // buffer we are building below. Declaring the buffer volatile avoids the >+ // issue, and has no measurable performance impact in microbenchmarks. >+ // >+ // https://bugs.llvm.org/show_bug.cgi?id=37778 >+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86113 >+ constexpr ptrdiff_t kNanBufferSize = 128; >+ volatile char n_char_sequence[kNanBufferSize]; >+ if (input.subrange_begin == nullptr) { >+ n_char_sequence[0] = '\0'; >+ } else { >+ ptrdiff_t nan_size = input.subrange_end - input.subrange_begin; >+ nan_size = std::min(nan_size, kNanBufferSize - 1); >+ std::copy_n(input.subrange_begin, nan_size, n_char_sequence); >+ n_char_sequence[nan_size] = '\0'; >+ } >+ char* nan_argument = const_cast<char*>(n_char_sequence); >+ *value = negative ? -FloatTraits<FloatType>::MakeNan(nan_argument) >+ : FloatTraits<FloatType>::MakeNan(nan_argument); >+ return true; >+ } >+ if (input.type == strings_internal::FloatType::kInfinity) { >+ *value = negative ? -std::numeric_limits<FloatType>::infinity() >+ : std::numeric_limits<FloatType>::infinity(); >+ return true; >+ } >+ if (input.mantissa == 0) { >+ *value = negative ? -0.0 : 0.0; >+ return true; >+ } >+ return false; >+} >+ >+// Given a CalculatedFloat result of a from_chars conversion, generate the >+// correct output values. >+// >+// CalculatedFloat can represent an underflow or overflow, in which case the >+// error code in *result is set. Otherwise, the calculated floating point >+// number is stored in *value. >+template <typename FloatType> >+void EncodeResult(const CalculatedFloat& calculated, bool negative, >+ absl::from_chars_result* result, FloatType* value) { >+ if (calculated.exponent == kOverflow) { >+ result->ec = std::errc::result_out_of_range; >+ *value = negative ? -std::numeric_limits<FloatType>::max() >+ : std::numeric_limits<FloatType>::max(); >+ return; >+ } else if (calculated.mantissa == 0 || calculated.exponent == kUnderflow) { >+ result->ec = std::errc::result_out_of_range; >+ *value = negative ? -0.0 : 0.0; >+ return; >+ } >+ *value = FloatTraits<FloatType>::Make(calculated.mantissa, >+ calculated.exponent, negative); >+} >+ >+// Returns the given uint128 shifted to the right by `shift` bits, and rounds >+// the remaining bits using round_to_nearest logic. The value is returned as a >+// uint64_t, since this is the type used by this library for storing calculated >+// floating point mantissas. >+// >+// It is expected that the width of the input value shifted by `shift` will >+// be the correct bit-width for the target mantissa, which is strictly narrower >+// than a uint64_t. >+// >+// If `input_exact` is false, then a nonzero error epsilon is assumed. For >+// rounding purposes, the true value being rounded is strictly greater than the >+// input value. The error may represent a single lost carry bit. >+// >+// When input_exact, shifted bits of the form 1000000... represent a tie, which >+// is broken by rounding to even -- the rounding direction is chosen so the low >+// bit of the returned value is 0. >+// >+// When !input_exact, shifted bits of the form 10000000... represent a value >+// strictly greater than one half (due to the error epsilon), and so ties are >+// always broken by rounding up. >+// >+// When !input_exact, shifted bits of the form 01111111... are uncertain; >+// the true value may or may not be greater than 10000000..., due to the >+// possible lost carry bit. The correct rounding direction is unknown. In this >+// case, the result is rounded down, and `output_exact` is set to false. >+// >+// Zero and negative values of `shift` are accepted, in which case the word is >+// shifted left, as necessary. >+uint64_t ShiftRightAndRound(uint128 value, int shift, bool input_exact, >+ bool* output_exact) { >+ if (shift <= 0) { >+ *output_exact = input_exact; >+ return static_cast<uint64_t>(value << -shift); >+ } >+ if (shift >= 128) { >+ // Exponent is so small that we are shifting away all significant bits. >+ // Answer will not be representable, even as a subnormal, so return a zero >+ // mantissa (which represents underflow). >+ *output_exact = true; >+ return 0; >+ } >+ >+ *output_exact = true; >+ const uint128 shift_mask = (uint128(1) << shift) - 1; >+ const uint128 halfway_point = uint128(1) << (shift - 1); >+ >+ const uint128 shifted_bits = value & shift_mask; >+ value >>= shift; >+ if (shifted_bits > halfway_point) { >+ // Shifted bits greater than 10000... require rounding up. >+ return static_cast<uint64_t>(value + 1); >+ } >+ if (shifted_bits == halfway_point) { >+ // In exact mode, shifted bits of 10000... mean we're exactly halfway >+ // between two numbers, and we must round to even. So only round up if >+ // the low bit of `value` is set. >+ // >+ // In inexact mode, the nonzero error means the actual value is greater >+ // than the halfway point and we must alway round up. >+ if ((value & 1) == 1 || !input_exact) { >+ ++value; >+ } >+ return static_cast<uint64_t>(value); >+ } >+ if (!input_exact && shifted_bits == halfway_point - 1) { >+ // Rounding direction is unclear, due to error. >+ *output_exact = false; >+ } >+ // Otherwise, round down. >+ return static_cast<uint64_t>(value); >+} >+ >+// Checks if a floating point guess needs to be rounded up, using high precision >+// math. >+// >+// `guess_mantissa` and `guess_exponent` represent a candidate guess for the >+// number represented by `parsed_decimal`. >+// >+// The exact number represented by `parsed_decimal` must lie between the two >+// numbers: >+// A = `guess_mantissa * 2**guess_exponent` >+// B = `(guess_mantissa + 1) * 2**guess_exponent` >+// >+// This function returns false if `A` is the better guess, and true if `B` is >+// the better guess, with rounding ties broken by rounding to even. >+bool MustRoundUp(uint64_t guess_mantissa, int guess_exponent, >+ const strings_internal::ParsedFloat& parsed_decimal) { >+ // 768 is the number of digits needed in the worst case. We could determine a >+ // better limit dynamically based on the value of parsed_decimal.exponent. >+ // This would optimize pathological input cases only. (Sane inputs won't have >+ // hundreds of digits of mantissa.) >+ absl::strings_internal::BigUnsigned<84> exact_mantissa; >+ int exact_exponent = exact_mantissa.ReadFloatMantissa(parsed_decimal, 768); >+ >+ // Adjust the `guess` arguments to be halfway between A and B. >+ guess_mantissa = guess_mantissa * 2 + 1; >+ guess_exponent -= 1; >+ >+ // In our comparison: >+ // lhs = exact = exact_mantissa * 10**exact_exponent >+ // = exact_mantissa * 5**exact_exponent * 2**exact_exponent >+ // rhs = guess = guess_mantissa * 2**guess_exponent >+ // >+ // Because we are doing integer math, we can't directly deal with negative >+ // exponents. We instead move these to the other side of the inequality. >+ absl::strings_internal::BigUnsigned<84>& lhs = exact_mantissa; >+ int comparison; >+ if (exact_exponent >= 0) { >+ lhs.MultiplyByFiveToTheNth(exact_exponent); >+ absl::strings_internal::BigUnsigned<84> rhs(guess_mantissa); >+ // There are powers of 2 on both sides of the inequality; reduce this to >+ // a single bit-shift. >+ if (exact_exponent > guess_exponent) { >+ lhs.ShiftLeft(exact_exponent - guess_exponent); >+ } else { >+ rhs.ShiftLeft(guess_exponent - exact_exponent); >+ } >+ comparison = Compare(lhs, rhs); >+ } else { >+ // Move the power of 5 to the other side of the equation, giving us: >+ // lhs = exact_mantissa * 2**exact_exponent >+ // rhs = guess_mantissa * 5**(-exact_exponent) * 2**guess_exponent >+ absl::strings_internal::BigUnsigned<84> rhs = >+ absl::strings_internal::BigUnsigned<84>::FiveToTheNth(-exact_exponent); >+ rhs.MultiplyBy(guess_mantissa); >+ if (exact_exponent > guess_exponent) { >+ lhs.ShiftLeft(exact_exponent - guess_exponent); >+ } else { >+ rhs.ShiftLeft(guess_exponent - exact_exponent); >+ } >+ comparison = Compare(lhs, rhs); >+ } >+ if (comparison < 0) { >+ return false; >+ } else if (comparison > 0) { >+ return true; >+ } else { >+ // When lhs == rhs, the decimal input is exactly between A and B. >+ // Round towards even -- round up only if the low bit of the initial >+ // `guess_mantissa` was a 1. We shifted guess_mantissa left 1 bit at >+ // the beginning of this function, so test the 2nd bit here. >+ return (guess_mantissa & 2) == 2; >+ } >+} >+ >+// Constructs a CalculatedFloat from a given mantissa and exponent, but >+// with the following normalizations applied: >+// >+// If rounding has caused mantissa to increase just past the allowed bit >+// width, shift and adjust exponent. >+// >+// If exponent is too high, sets kOverflow. >+// >+// If mantissa is zero (representing a non-zero value not representable, even >+// as a subnormal), sets kUnderflow. >+template <typename FloatType> >+CalculatedFloat CalculatedFloatFromRawValues(uint64_t mantissa, int exponent) { >+ CalculatedFloat result; >+ if (mantissa == uint64_t(1) << FloatTraits<FloatType>::kTargetMantissaBits) { >+ mantissa >>= 1; >+ exponent += 1; >+ } >+ if (exponent > FloatTraits<FloatType>::kMaxExponent) { >+ result.exponent = kOverflow; >+ } else if (mantissa == 0) { >+ result.exponent = kUnderflow; >+ } else { >+ result.exponent = exponent; >+ result.mantissa = mantissa; >+ } >+ return result; >+} >+ >+template <typename FloatType> >+CalculatedFloat CalculateFromParsedHexadecimal( >+ const strings_internal::ParsedFloat& parsed_hex) { >+ uint64_t mantissa = parsed_hex.mantissa; >+ int exponent = parsed_hex.exponent; >+ int mantissa_width = 64 - strings_internal::CountLeadingZeros64(mantissa); >+ const int shift = NormalizedShiftSize<FloatType>(mantissa_width, exponent); >+ bool result_exact; >+ exponent += shift; >+ mantissa = ShiftRightAndRound(mantissa, shift, >+ /* input exact= */ true, &result_exact); >+ // ParseFloat handles rounding in the hexadecimal case, so we don't have to >+ // check `result_exact` here. >+ return CalculatedFloatFromRawValues<FloatType>(mantissa, exponent); >+} >+ >+template <typename FloatType> >+CalculatedFloat CalculateFromParsedDecimal( >+ const strings_internal::ParsedFloat& parsed_decimal) { >+ CalculatedFloat result; >+ >+ // Large or small enough decimal exponents will always result in overflow >+ // or underflow. >+ if (Power10Underflow(parsed_decimal.exponent)) { >+ result.exponent = kUnderflow; >+ return result; >+ } else if (Power10Overflow(parsed_decimal.exponent)) { >+ result.exponent = kOverflow; >+ return result; >+ } >+ >+ // Otherwise convert our power of 10 into a power of 2 times an integer >+ // mantissa, and multiply this by our parsed decimal mantissa. >+ uint128 wide_binary_mantissa = parsed_decimal.mantissa; >+ wide_binary_mantissa *= Power10Mantissa(parsed_decimal.exponent); >+ int binary_exponent = Power10Exponent(parsed_decimal.exponent); >+ >+ // Discard bits that are inaccurate due to truncation error. The magic >+ // `mantissa_width` constants below are justified in charconv_algorithm.md. >+ // They represent the number of bits in `wide_binary_mantissa` that are >+ // guaranteed to be unaffected by error propagation. >+ bool mantissa_exact; >+ int mantissa_width; >+ if (parsed_decimal.subrange_begin) { >+ // Truncated mantissa >+ mantissa_width = 58; >+ mantissa_exact = false; >+ binary_exponent += >+ TruncateToBitWidth(mantissa_width, &wide_binary_mantissa); >+ } else if (!Power10Exact(parsed_decimal.exponent)) { >+ // Exact mantissa, truncated power of ten >+ mantissa_width = 63; >+ mantissa_exact = false; >+ binary_exponent += >+ TruncateToBitWidth(mantissa_width, &wide_binary_mantissa); >+ } else { >+ // Product is exact >+ mantissa_width = BitWidth(wide_binary_mantissa); >+ mantissa_exact = true; >+ } >+ >+ // Shift into an FloatType-sized mantissa, and round to nearest. >+ const int shift = >+ NormalizedShiftSize<FloatType>(mantissa_width, binary_exponent); >+ bool result_exact; >+ binary_exponent += shift; >+ uint64_t binary_mantissa = ShiftRightAndRound(wide_binary_mantissa, shift, >+ mantissa_exact, &result_exact); >+ if (!result_exact) { >+ // We could not determine the rounding direction using int128 math. Use >+ // full resolution math instead. >+ if (MustRoundUp(binary_mantissa, binary_exponent, parsed_decimal)) { >+ binary_mantissa += 1; >+ } >+ } >+ >+ return CalculatedFloatFromRawValues<FloatType>(binary_mantissa, >+ binary_exponent); >+} >+ >+template <typename FloatType> >+from_chars_result FromCharsImpl(const char* first, const char* last, >+ FloatType& value, chars_format fmt_flags) { >+ from_chars_result result; >+ result.ptr = first; // overwritten on successful parse >+ result.ec = std::errc(); >+ >+ bool negative = false; >+ if (first != last && *first == '-') { >+ ++first; >+ negative = true; >+ } >+ // If the `hex` flag is *not* set, then we will accept a 0x prefix and try >+ // to parse a hexadecimal float. >+ if ((fmt_flags & chars_format::hex) == chars_format{} && last - first >= 2 && >+ *first == '0' && (first[1] == 'x' || first[1] == 'X')) { >+ const char* hex_first = first + 2; >+ strings_internal::ParsedFloat hex_parse = >+ strings_internal::ParseFloat<16>(hex_first, last, fmt_flags); >+ if (hex_parse.end == nullptr || >+ hex_parse.type != strings_internal::FloatType::kNumber) { >+ // Either we failed to parse a hex float after the "0x", or we read >+ // "0xinf" or "0xnan" which we don't want to match. >+ // >+ // However, a std::string that begins with "0x" also begins with "0", which >+ // is normally a valid match for the number zero. So we want these >+ // strings to match zero unless fmt_flags is `scientific`. (This flag >+ // means an exponent is required, which the std::string "0" does not have.) >+ if (fmt_flags == chars_format::scientific) { >+ result.ec = std::errc::invalid_argument; >+ } else { >+ result.ptr = first + 1; >+ value = negative ? -0.0 : 0.0; >+ } >+ return result; >+ } >+ // We matched a value. >+ result.ptr = hex_parse.end; >+ if (HandleEdgeCase(hex_parse, negative, &value)) { >+ return result; >+ } >+ CalculatedFloat calculated = >+ CalculateFromParsedHexadecimal<FloatType>(hex_parse); >+ EncodeResult(calculated, negative, &result, &value); >+ return result; >+ } >+ // Otherwise, we choose the number base based on the flags. >+ if ((fmt_flags & chars_format::hex) == chars_format::hex) { >+ strings_internal::ParsedFloat hex_parse = >+ strings_internal::ParseFloat<16>(first, last, fmt_flags); >+ if (hex_parse.end == nullptr) { >+ result.ec = std::errc::invalid_argument; >+ return result; >+ } >+ result.ptr = hex_parse.end; >+ if (HandleEdgeCase(hex_parse, negative, &value)) { >+ return result; >+ } >+ CalculatedFloat calculated = >+ CalculateFromParsedHexadecimal<FloatType>(hex_parse); >+ EncodeResult(calculated, negative, &result, &value); >+ return result; >+ } else { >+ strings_internal::ParsedFloat decimal_parse = >+ strings_internal::ParseFloat<10>(first, last, fmt_flags); >+ if (decimal_parse.end == nullptr) { >+ result.ec = std::errc::invalid_argument; >+ return result; >+ } >+ result.ptr = decimal_parse.end; >+ if (HandleEdgeCase(decimal_parse, negative, &value)) { >+ return result; >+ } >+ CalculatedFloat calculated = >+ CalculateFromParsedDecimal<FloatType>(decimal_parse); >+ EncodeResult(calculated, negative, &result, &value); >+ return result; >+ } >+ return result; >+} >+} // namespace >+ >+from_chars_result from_chars(const char* first, const char* last, double& value, >+ chars_format fmt) { >+ return FromCharsImpl(first, last, value, fmt); >+} >+ >+from_chars_result from_chars(const char* first, const char* last, float& value, >+ chars_format fmt) { >+ return FromCharsImpl(first, last, value, fmt); >+} >+ >+namespace { >+ >+// Table of powers of 10, from kPower10TableMin to kPower10TableMax. >+// >+// kPower10MantissaTable[i - kPower10TableMin] stores the 64-bit mantissa (high >+// bit always on), and kPower10ExponentTable[i - kPower10TableMin] stores the >+// power-of-two exponent. For a given number i, this gives the unique mantissa >+// and exponent such that mantissa * 2**exponent <= 10**i < (mantissa + 1) * >+// 2**exponent. >+ >+const uint64_t kPower10MantissaTable[] = { >+ 0xeef453d6923bd65aU, 0x9558b4661b6565f8U, 0xbaaee17fa23ebf76U, >+ 0xe95a99df8ace6f53U, 0x91d8a02bb6c10594U, 0xb64ec836a47146f9U, >+ 0xe3e27a444d8d98b7U, 0x8e6d8c6ab0787f72U, 0xb208ef855c969f4fU, >+ 0xde8b2b66b3bc4723U, 0x8b16fb203055ac76U, 0xaddcb9e83c6b1793U, >+ 0xd953e8624b85dd78U, 0x87d4713d6f33aa6bU, 0xa9c98d8ccb009506U, >+ 0xd43bf0effdc0ba48U, 0x84a57695fe98746dU, 0xa5ced43b7e3e9188U, >+ 0xcf42894a5dce35eaU, 0x818995ce7aa0e1b2U, 0xa1ebfb4219491a1fU, >+ 0xca66fa129f9b60a6U, 0xfd00b897478238d0U, 0x9e20735e8cb16382U, >+ 0xc5a890362fddbc62U, 0xf712b443bbd52b7bU, 0x9a6bb0aa55653b2dU, >+ 0xc1069cd4eabe89f8U, 0xf148440a256e2c76U, 0x96cd2a865764dbcaU, >+ 0xbc807527ed3e12bcU, 0xeba09271e88d976bU, 0x93445b8731587ea3U, >+ 0xb8157268fdae9e4cU, 0xe61acf033d1a45dfU, 0x8fd0c16206306babU, >+ 0xb3c4f1ba87bc8696U, 0xe0b62e2929aba83cU, 0x8c71dcd9ba0b4925U, >+ 0xaf8e5410288e1b6fU, 0xdb71e91432b1a24aU, 0x892731ac9faf056eU, >+ 0xab70fe17c79ac6caU, 0xd64d3d9db981787dU, 0x85f0468293f0eb4eU, >+ 0xa76c582338ed2621U, 0xd1476e2c07286faaU, 0x82cca4db847945caU, >+ 0xa37fce126597973cU, 0xcc5fc196fefd7d0cU, 0xff77b1fcbebcdc4fU, >+ 0x9faacf3df73609b1U, 0xc795830d75038c1dU, 0xf97ae3d0d2446f25U, >+ 0x9becce62836ac577U, 0xc2e801fb244576d5U, 0xf3a20279ed56d48aU, >+ 0x9845418c345644d6U, 0xbe5691ef416bd60cU, 0xedec366b11c6cb8fU, >+ 0x94b3a202eb1c3f39U, 0xb9e08a83a5e34f07U, 0xe858ad248f5c22c9U, >+ 0x91376c36d99995beU, 0xb58547448ffffb2dU, 0xe2e69915b3fff9f9U, >+ 0x8dd01fad907ffc3bU, 0xb1442798f49ffb4aU, 0xdd95317f31c7fa1dU, >+ 0x8a7d3eef7f1cfc52U, 0xad1c8eab5ee43b66U, 0xd863b256369d4a40U, >+ 0x873e4f75e2224e68U, 0xa90de3535aaae202U, 0xd3515c2831559a83U, >+ 0x8412d9991ed58091U, 0xa5178fff668ae0b6U, 0xce5d73ff402d98e3U, >+ 0x80fa687f881c7f8eU, 0xa139029f6a239f72U, 0xc987434744ac874eU, >+ 0xfbe9141915d7a922U, 0x9d71ac8fada6c9b5U, 0xc4ce17b399107c22U, >+ 0xf6019da07f549b2bU, 0x99c102844f94e0fbU, 0xc0314325637a1939U, >+ 0xf03d93eebc589f88U, 0x96267c7535b763b5U, 0xbbb01b9283253ca2U, >+ 0xea9c227723ee8bcbU, 0x92a1958a7675175fU, 0xb749faed14125d36U, >+ 0xe51c79a85916f484U, 0x8f31cc0937ae58d2U, 0xb2fe3f0b8599ef07U, >+ 0xdfbdcece67006ac9U, 0x8bd6a141006042bdU, 0xaecc49914078536dU, >+ 0xda7f5bf590966848U, 0x888f99797a5e012dU, 0xaab37fd7d8f58178U, >+ 0xd5605fcdcf32e1d6U, 0x855c3be0a17fcd26U, 0xa6b34ad8c9dfc06fU, >+ 0xd0601d8efc57b08bU, 0x823c12795db6ce57U, 0xa2cb1717b52481edU, >+ 0xcb7ddcdda26da268U, 0xfe5d54150b090b02U, 0x9efa548d26e5a6e1U, >+ 0xc6b8e9b0709f109aU, 0xf867241c8cc6d4c0U, 0x9b407691d7fc44f8U, >+ 0xc21094364dfb5636U, 0xf294b943e17a2bc4U, 0x979cf3ca6cec5b5aU, >+ 0xbd8430bd08277231U, 0xece53cec4a314ebdU, 0x940f4613ae5ed136U, >+ 0xb913179899f68584U, 0xe757dd7ec07426e5U, 0x9096ea6f3848984fU, >+ 0xb4bca50b065abe63U, 0xe1ebce4dc7f16dfbU, 0x8d3360f09cf6e4bdU, >+ 0xb080392cc4349decU, 0xdca04777f541c567U, 0x89e42caaf9491b60U, >+ 0xac5d37d5b79b6239U, 0xd77485cb25823ac7U, 0x86a8d39ef77164bcU, >+ 0xa8530886b54dbdebU, 0xd267caa862a12d66U, 0x8380dea93da4bc60U, >+ 0xa46116538d0deb78U, 0xcd795be870516656U, 0x806bd9714632dff6U, >+ 0xa086cfcd97bf97f3U, 0xc8a883c0fdaf7df0U, 0xfad2a4b13d1b5d6cU, >+ 0x9cc3a6eec6311a63U, 0xc3f490aa77bd60fcU, 0xf4f1b4d515acb93bU, >+ 0x991711052d8bf3c5U, 0xbf5cd54678eef0b6U, 0xef340a98172aace4U, >+ 0x9580869f0e7aac0eU, 0xbae0a846d2195712U, 0xe998d258869facd7U, >+ 0x91ff83775423cc06U, 0xb67f6455292cbf08U, 0xe41f3d6a7377eecaU, >+ 0x8e938662882af53eU, 0xb23867fb2a35b28dU, 0xdec681f9f4c31f31U, >+ 0x8b3c113c38f9f37eU, 0xae0b158b4738705eU, 0xd98ddaee19068c76U, >+ 0x87f8a8d4cfa417c9U, 0xa9f6d30a038d1dbcU, 0xd47487cc8470652bU, >+ 0x84c8d4dfd2c63f3bU, 0xa5fb0a17c777cf09U, 0xcf79cc9db955c2ccU, >+ 0x81ac1fe293d599bfU, 0xa21727db38cb002fU, 0xca9cf1d206fdc03bU, >+ 0xfd442e4688bd304aU, 0x9e4a9cec15763e2eU, 0xc5dd44271ad3cdbaU, >+ 0xf7549530e188c128U, 0x9a94dd3e8cf578b9U, 0xc13a148e3032d6e7U, >+ 0xf18899b1bc3f8ca1U, 0x96f5600f15a7b7e5U, 0xbcb2b812db11a5deU, >+ 0xebdf661791d60f56U, 0x936b9fcebb25c995U, 0xb84687c269ef3bfbU, >+ 0xe65829b3046b0afaU, 0x8ff71a0fe2c2e6dcU, 0xb3f4e093db73a093U, >+ 0xe0f218b8d25088b8U, 0x8c974f7383725573U, 0xafbd2350644eeacfU, >+ 0xdbac6c247d62a583U, 0x894bc396ce5da772U, 0xab9eb47c81f5114fU, >+ 0xd686619ba27255a2U, 0x8613fd0145877585U, 0xa798fc4196e952e7U, >+ 0xd17f3b51fca3a7a0U, 0x82ef85133de648c4U, 0xa3ab66580d5fdaf5U, >+ 0xcc963fee10b7d1b3U, 0xffbbcfe994e5c61fU, 0x9fd561f1fd0f9bd3U, >+ 0xc7caba6e7c5382c8U, 0xf9bd690a1b68637bU, 0x9c1661a651213e2dU, >+ 0xc31bfa0fe5698db8U, 0xf3e2f893dec3f126U, 0x986ddb5c6b3a76b7U, >+ 0xbe89523386091465U, 0xee2ba6c0678b597fU, 0x94db483840b717efU, >+ 0xba121a4650e4ddebU, 0xe896a0d7e51e1566U, 0x915e2486ef32cd60U, >+ 0xb5b5ada8aaff80b8U, 0xe3231912d5bf60e6U, 0x8df5efabc5979c8fU, >+ 0xb1736b96b6fd83b3U, 0xddd0467c64bce4a0U, 0x8aa22c0dbef60ee4U, >+ 0xad4ab7112eb3929dU, 0xd89d64d57a607744U, 0x87625f056c7c4a8bU, >+ 0xa93af6c6c79b5d2dU, 0xd389b47879823479U, 0x843610cb4bf160cbU, >+ 0xa54394fe1eedb8feU, 0xce947a3da6a9273eU, 0x811ccc668829b887U, >+ 0xa163ff802a3426a8U, 0xc9bcff6034c13052U, 0xfc2c3f3841f17c67U, >+ 0x9d9ba7832936edc0U, 0xc5029163f384a931U, 0xf64335bcf065d37dU, >+ 0x99ea0196163fa42eU, 0xc06481fb9bcf8d39U, 0xf07da27a82c37088U, >+ 0x964e858c91ba2655U, 0xbbe226efb628afeaU, 0xeadab0aba3b2dbe5U, >+ 0x92c8ae6b464fc96fU, 0xb77ada0617e3bbcbU, 0xe55990879ddcaabdU, >+ 0x8f57fa54c2a9eab6U, 0xb32df8e9f3546564U, 0xdff9772470297ebdU, >+ 0x8bfbea76c619ef36U, 0xaefae51477a06b03U, 0xdab99e59958885c4U, >+ 0x88b402f7fd75539bU, 0xaae103b5fcd2a881U, 0xd59944a37c0752a2U, >+ 0x857fcae62d8493a5U, 0xa6dfbd9fb8e5b88eU, 0xd097ad07a71f26b2U, >+ 0x825ecc24c873782fU, 0xa2f67f2dfa90563bU, 0xcbb41ef979346bcaU, >+ 0xfea126b7d78186bcU, 0x9f24b832e6b0f436U, 0xc6ede63fa05d3143U, >+ 0xf8a95fcf88747d94U, 0x9b69dbe1b548ce7cU, 0xc24452da229b021bU, >+ 0xf2d56790ab41c2a2U, 0x97c560ba6b0919a5U, 0xbdb6b8e905cb600fU, >+ 0xed246723473e3813U, 0x9436c0760c86e30bU, 0xb94470938fa89bceU, >+ 0xe7958cb87392c2c2U, 0x90bd77f3483bb9b9U, 0xb4ecd5f01a4aa828U, >+ 0xe2280b6c20dd5232U, 0x8d590723948a535fU, 0xb0af48ec79ace837U, >+ 0xdcdb1b2798182244U, 0x8a08f0f8bf0f156bU, 0xac8b2d36eed2dac5U, >+ 0xd7adf884aa879177U, 0x86ccbb52ea94baeaU, 0xa87fea27a539e9a5U, >+ 0xd29fe4b18e88640eU, 0x83a3eeeef9153e89U, 0xa48ceaaab75a8e2bU, >+ 0xcdb02555653131b6U, 0x808e17555f3ebf11U, 0xa0b19d2ab70e6ed6U, >+ 0xc8de047564d20a8bU, 0xfb158592be068d2eU, 0x9ced737bb6c4183dU, >+ 0xc428d05aa4751e4cU, 0xf53304714d9265dfU, 0x993fe2c6d07b7fabU, >+ 0xbf8fdb78849a5f96U, 0xef73d256a5c0f77cU, 0x95a8637627989aadU, >+ 0xbb127c53b17ec159U, 0xe9d71b689dde71afU, 0x9226712162ab070dU, >+ 0xb6b00d69bb55c8d1U, 0xe45c10c42a2b3b05U, 0x8eb98a7a9a5b04e3U, >+ 0xb267ed1940f1c61cU, 0xdf01e85f912e37a3U, 0x8b61313bbabce2c6U, >+ 0xae397d8aa96c1b77U, 0xd9c7dced53c72255U, 0x881cea14545c7575U, >+ 0xaa242499697392d2U, 0xd4ad2dbfc3d07787U, 0x84ec3c97da624ab4U, >+ 0xa6274bbdd0fadd61U, 0xcfb11ead453994baU, 0x81ceb32c4b43fcf4U, >+ 0xa2425ff75e14fc31U, 0xcad2f7f5359a3b3eU, 0xfd87b5f28300ca0dU, >+ 0x9e74d1b791e07e48U, 0xc612062576589ddaU, 0xf79687aed3eec551U, >+ 0x9abe14cd44753b52U, 0xc16d9a0095928a27U, 0xf1c90080baf72cb1U, >+ 0x971da05074da7beeU, 0xbce5086492111aeaU, 0xec1e4a7db69561a5U, >+ 0x9392ee8e921d5d07U, 0xb877aa3236a4b449U, 0xe69594bec44de15bU, >+ 0x901d7cf73ab0acd9U, 0xb424dc35095cd80fU, 0xe12e13424bb40e13U, >+ 0x8cbccc096f5088cbU, 0xafebff0bcb24aafeU, 0xdbe6fecebdedd5beU, >+ 0x89705f4136b4a597U, 0xabcc77118461cefcU, 0xd6bf94d5e57a42bcU, >+ 0x8637bd05af6c69b5U, 0xa7c5ac471b478423U, 0xd1b71758e219652bU, >+ 0x83126e978d4fdf3bU, 0xa3d70a3d70a3d70aU, 0xccccccccccccccccU, >+ 0x8000000000000000U, 0xa000000000000000U, 0xc800000000000000U, >+ 0xfa00000000000000U, 0x9c40000000000000U, 0xc350000000000000U, >+ 0xf424000000000000U, 0x9896800000000000U, 0xbebc200000000000U, >+ 0xee6b280000000000U, 0x9502f90000000000U, 0xba43b74000000000U, >+ 0xe8d4a51000000000U, 0x9184e72a00000000U, 0xb5e620f480000000U, >+ 0xe35fa931a0000000U, 0x8e1bc9bf04000000U, 0xb1a2bc2ec5000000U, >+ 0xde0b6b3a76400000U, 0x8ac7230489e80000U, 0xad78ebc5ac620000U, >+ 0xd8d726b7177a8000U, 0x878678326eac9000U, 0xa968163f0a57b400U, >+ 0xd3c21bcecceda100U, 0x84595161401484a0U, 0xa56fa5b99019a5c8U, >+ 0xcecb8f27f4200f3aU, 0x813f3978f8940984U, 0xa18f07d736b90be5U, >+ 0xc9f2c9cd04674edeU, 0xfc6f7c4045812296U, 0x9dc5ada82b70b59dU, >+ 0xc5371912364ce305U, 0xf684df56c3e01bc6U, 0x9a130b963a6c115cU, >+ 0xc097ce7bc90715b3U, 0xf0bdc21abb48db20U, 0x96769950b50d88f4U, >+ 0xbc143fa4e250eb31U, 0xeb194f8e1ae525fdU, 0x92efd1b8d0cf37beU, >+ 0xb7abc627050305adU, 0xe596b7b0c643c719U, 0x8f7e32ce7bea5c6fU, >+ 0xb35dbf821ae4f38bU, 0xe0352f62a19e306eU, 0x8c213d9da502de45U, >+ 0xaf298d050e4395d6U, 0xdaf3f04651d47b4cU, 0x88d8762bf324cd0fU, >+ 0xab0e93b6efee0053U, 0xd5d238a4abe98068U, 0x85a36366eb71f041U, >+ 0xa70c3c40a64e6c51U, 0xd0cf4b50cfe20765U, 0x82818f1281ed449fU, >+ 0xa321f2d7226895c7U, 0xcbea6f8ceb02bb39U, 0xfee50b7025c36a08U, >+ 0x9f4f2726179a2245U, 0xc722f0ef9d80aad6U, 0xf8ebad2b84e0d58bU, >+ 0x9b934c3b330c8577U, 0xc2781f49ffcfa6d5U, 0xf316271c7fc3908aU, >+ 0x97edd871cfda3a56U, 0xbde94e8e43d0c8ecU, 0xed63a231d4c4fb27U, >+ 0x945e455f24fb1cf8U, 0xb975d6b6ee39e436U, 0xe7d34c64a9c85d44U, >+ 0x90e40fbeea1d3a4aU, 0xb51d13aea4a488ddU, 0xe264589a4dcdab14U, >+ 0x8d7eb76070a08aecU, 0xb0de65388cc8ada8U, 0xdd15fe86affad912U, >+ 0x8a2dbf142dfcc7abU, 0xacb92ed9397bf996U, 0xd7e77a8f87daf7fbU, >+ 0x86f0ac99b4e8dafdU, 0xa8acd7c0222311bcU, 0xd2d80db02aabd62bU, >+ 0x83c7088e1aab65dbU, 0xa4b8cab1a1563f52U, 0xcde6fd5e09abcf26U, >+ 0x80b05e5ac60b6178U, 0xa0dc75f1778e39d6U, 0xc913936dd571c84cU, >+ 0xfb5878494ace3a5fU, 0x9d174b2dcec0e47bU, 0xc45d1df942711d9aU, >+ 0xf5746577930d6500U, 0x9968bf6abbe85f20U, 0xbfc2ef456ae276e8U, >+ 0xefb3ab16c59b14a2U, 0x95d04aee3b80ece5U, 0xbb445da9ca61281fU, >+ 0xea1575143cf97226U, 0x924d692ca61be758U, 0xb6e0c377cfa2e12eU, >+ 0xe498f455c38b997aU, 0x8edf98b59a373fecU, 0xb2977ee300c50fe7U, >+ 0xdf3d5e9bc0f653e1U, 0x8b865b215899f46cU, 0xae67f1e9aec07187U, >+ 0xda01ee641a708de9U, 0x884134fe908658b2U, 0xaa51823e34a7eedeU, >+ 0xd4e5e2cdc1d1ea96U, 0x850fadc09923329eU, 0xa6539930bf6bff45U, >+ 0xcfe87f7cef46ff16U, 0x81f14fae158c5f6eU, 0xa26da3999aef7749U, >+ 0xcb090c8001ab551cU, 0xfdcb4fa002162a63U, 0x9e9f11c4014dda7eU, >+ 0xc646d63501a1511dU, 0xf7d88bc24209a565U, 0x9ae757596946075fU, >+ 0xc1a12d2fc3978937U, 0xf209787bb47d6b84U, 0x9745eb4d50ce6332U, >+ 0xbd176620a501fbffU, 0xec5d3fa8ce427affU, 0x93ba47c980e98cdfU, >+ 0xb8a8d9bbe123f017U, 0xe6d3102ad96cec1dU, 0x9043ea1ac7e41392U, >+ 0xb454e4a179dd1877U, 0xe16a1dc9d8545e94U, 0x8ce2529e2734bb1dU, >+ 0xb01ae745b101e9e4U, 0xdc21a1171d42645dU, 0x899504ae72497ebaU, >+ 0xabfa45da0edbde69U, 0xd6f8d7509292d603U, 0x865b86925b9bc5c2U, >+ 0xa7f26836f282b732U, 0xd1ef0244af2364ffU, 0x8335616aed761f1fU, >+ 0xa402b9c5a8d3a6e7U, 0xcd036837130890a1U, 0x802221226be55a64U, >+ 0xa02aa96b06deb0fdU, 0xc83553c5c8965d3dU, 0xfa42a8b73abbf48cU, >+ 0x9c69a97284b578d7U, 0xc38413cf25e2d70dU, 0xf46518c2ef5b8cd1U, >+ 0x98bf2f79d5993802U, 0xbeeefb584aff8603U, 0xeeaaba2e5dbf6784U, >+ 0x952ab45cfa97a0b2U, 0xba756174393d88dfU, 0xe912b9d1478ceb17U, >+ 0x91abb422ccb812eeU, 0xb616a12b7fe617aaU, 0xe39c49765fdf9d94U, >+ 0x8e41ade9fbebc27dU, 0xb1d219647ae6b31cU, 0xde469fbd99a05fe3U, >+ 0x8aec23d680043beeU, 0xada72ccc20054ae9U, 0xd910f7ff28069da4U, >+ 0x87aa9aff79042286U, 0xa99541bf57452b28U, 0xd3fa922f2d1675f2U, >+ 0x847c9b5d7c2e09b7U, 0xa59bc234db398c25U, 0xcf02b2c21207ef2eU, >+ 0x8161afb94b44f57dU, 0xa1ba1ba79e1632dcU, 0xca28a291859bbf93U, >+ 0xfcb2cb35e702af78U, 0x9defbf01b061adabU, 0xc56baec21c7a1916U, >+ 0xf6c69a72a3989f5bU, 0x9a3c2087a63f6399U, 0xc0cb28a98fcf3c7fU, >+ 0xf0fdf2d3f3c30b9fU, 0x969eb7c47859e743U, 0xbc4665b596706114U, >+ 0xeb57ff22fc0c7959U, 0x9316ff75dd87cbd8U, 0xb7dcbf5354e9beceU, >+ 0xe5d3ef282a242e81U, 0x8fa475791a569d10U, 0xb38d92d760ec4455U, >+ 0xe070f78d3927556aU, 0x8c469ab843b89562U, 0xaf58416654a6babbU, >+ 0xdb2e51bfe9d0696aU, 0x88fcf317f22241e2U, 0xab3c2fddeeaad25aU, >+ 0xd60b3bd56a5586f1U, 0x85c7056562757456U, 0xa738c6bebb12d16cU, >+ 0xd106f86e69d785c7U, 0x82a45b450226b39cU, 0xa34d721642b06084U, >+ 0xcc20ce9bd35c78a5U, 0xff290242c83396ceU, 0x9f79a169bd203e41U, >+ 0xc75809c42c684dd1U, 0xf92e0c3537826145U, 0x9bbcc7a142b17ccbU, >+ 0xc2abf989935ddbfeU, 0xf356f7ebf83552feU, 0x98165af37b2153deU, >+ 0xbe1bf1b059e9a8d6U, 0xeda2ee1c7064130cU, 0x9485d4d1c63e8be7U, >+ 0xb9a74a0637ce2ee1U, 0xe8111c87c5c1ba99U, 0x910ab1d4db9914a0U, >+ 0xb54d5e4a127f59c8U, 0xe2a0b5dc971f303aU, 0x8da471a9de737e24U, >+ 0xb10d8e1456105dadU, 0xdd50f1996b947518U, 0x8a5296ffe33cc92fU, >+ 0xace73cbfdc0bfb7bU, 0xd8210befd30efa5aU, 0x8714a775e3e95c78U, >+ 0xa8d9d1535ce3b396U, 0xd31045a8341ca07cU, 0x83ea2b892091e44dU, >+ 0xa4e4b66b68b65d60U, 0xce1de40642e3f4b9U, 0x80d2ae83e9ce78f3U, >+ 0xa1075a24e4421730U, 0xc94930ae1d529cfcU, 0xfb9b7cd9a4a7443cU, >+ 0x9d412e0806e88aa5U, 0xc491798a08a2ad4eU, 0xf5b5d7ec8acb58a2U, >+ 0x9991a6f3d6bf1765U, 0xbff610b0cc6edd3fU, 0xeff394dcff8a948eU, >+ 0x95f83d0a1fb69cd9U, 0xbb764c4ca7a4440fU, 0xea53df5fd18d5513U, >+ 0x92746b9be2f8552cU, 0xb7118682dbb66a77U, 0xe4d5e82392a40515U, >+ 0x8f05b1163ba6832dU, 0xb2c71d5bca9023f8U, 0xdf78e4b2bd342cf6U, >+ 0x8bab8eefb6409c1aU, 0xae9672aba3d0c320U, 0xda3c0f568cc4f3e8U, >+ 0x8865899617fb1871U, 0xaa7eebfb9df9de8dU, 0xd51ea6fa85785631U, >+ 0x8533285c936b35deU, 0xa67ff273b8460356U, 0xd01fef10a657842cU, >+ 0x8213f56a67f6b29bU, 0xa298f2c501f45f42U, 0xcb3f2f7642717713U, >+ 0xfe0efb53d30dd4d7U, 0x9ec95d1463e8a506U, 0xc67bb4597ce2ce48U, >+ 0xf81aa16fdc1b81daU, 0x9b10a4e5e9913128U, 0xc1d4ce1f63f57d72U, >+ 0xf24a01a73cf2dccfU, 0x976e41088617ca01U, 0xbd49d14aa79dbc82U, >+ 0xec9c459d51852ba2U, 0x93e1ab8252f33b45U, 0xb8da1662e7b00a17U, >+ 0xe7109bfba19c0c9dU, 0x906a617d450187e2U, 0xb484f9dc9641e9daU, >+ 0xe1a63853bbd26451U, 0x8d07e33455637eb2U, 0xb049dc016abc5e5fU, >+ 0xdc5c5301c56b75f7U, 0x89b9b3e11b6329baU, 0xac2820d9623bf429U, >+ 0xd732290fbacaf133U, 0x867f59a9d4bed6c0U, 0xa81f301449ee8c70U, >+ 0xd226fc195c6a2f8cU, 0x83585d8fd9c25db7U, 0xa42e74f3d032f525U, >+ 0xcd3a1230c43fb26fU, 0x80444b5e7aa7cf85U, 0xa0555e361951c366U, >+ 0xc86ab5c39fa63440U, 0xfa856334878fc150U, 0x9c935e00d4b9d8d2U, >+ 0xc3b8358109e84f07U, 0xf4a642e14c6262c8U, 0x98e7e9cccfbd7dbdU, >+ 0xbf21e44003acdd2cU, 0xeeea5d5004981478U, 0x95527a5202df0ccbU, >+ 0xbaa718e68396cffdU, 0xe950df20247c83fdU, 0x91d28b7416cdd27eU, >+ 0xb6472e511c81471dU, 0xe3d8f9e563a198e5U, 0x8e679c2f5e44ff8fU, >+}; >+ >+const int16_t kPower10ExponentTable[] = { >+ -1200, -1196, -1193, -1190, -1186, -1183, -1180, -1176, -1173, -1170, -1166, >+ -1163, -1160, -1156, -1153, -1150, -1146, -1143, -1140, -1136, -1133, -1130, >+ -1127, -1123, -1120, -1117, -1113, -1110, -1107, -1103, -1100, -1097, -1093, >+ -1090, -1087, -1083, -1080, -1077, -1073, -1070, -1067, -1063, -1060, -1057, >+ -1053, -1050, -1047, -1043, -1040, -1037, -1034, -1030, -1027, -1024, -1020, >+ -1017, -1014, -1010, -1007, -1004, -1000, -997, -994, -990, -987, -984, >+ -980, -977, -974, -970, -967, -964, -960, -957, -954, -950, -947, >+ -944, -940, -937, -934, -931, -927, -924, -921, -917, -914, -911, >+ -907, -904, -901, -897, -894, -891, -887, -884, -881, -877, -874, >+ -871, -867, -864, -861, -857, -854, -851, -847, -844, -841, -838, >+ -834, -831, -828, -824, -821, -818, -814, -811, -808, -804, -801, >+ -798, -794, -791, -788, -784, -781, -778, -774, -771, -768, -764, >+ -761, -758, -754, -751, -748, -744, -741, -738, -735, -731, -728, >+ -725, -721, -718, -715, -711, -708, -705, -701, -698, -695, -691, >+ -688, -685, -681, -678, -675, -671, -668, -665, -661, -658, -655, >+ -651, -648, -645, -642, -638, -635, -632, -628, -625, -622, -618, >+ -615, -612, -608, -605, -602, -598, -595, -592, -588, -585, -582, >+ -578, -575, -572, -568, -565, -562, -558, -555, -552, -549, -545, >+ -542, -539, -535, -532, -529, -525, -522, -519, -515, -512, -509, >+ -505, -502, -499, -495, -492, -489, -485, -482, -479, -475, -472, >+ -469, -465, -462, -459, -455, -452, -449, -446, -442, -439, -436, >+ -432, -429, -426, -422, -419, -416, -412, -409, -406, -402, -399, >+ -396, -392, -389, -386, -382, -379, -376, -372, -369, -366, -362, >+ -359, -356, -353, -349, -346, -343, -339, -336, -333, -329, -326, >+ -323, -319, -316, -313, -309, -306, -303, -299, -296, -293, -289, >+ -286, -283, -279, -276, -273, -269, -266, -263, -259, -256, -253, >+ -250, -246, -243, -240, -236, -233, -230, -226, -223, -220, -216, >+ -213, -210, -206, -203, -200, -196, -193, -190, -186, -183, -180, >+ -176, -173, -170, -166, -163, -160, -157, -153, -150, -147, -143, >+ -140, -137, -133, -130, -127, -123, -120, -117, -113, -110, -107, >+ -103, -100, -97, -93, -90, -87, -83, -80, -77, -73, -70, >+ -67, -63, -60, -57, -54, -50, -47, -44, -40, -37, -34, >+ -30, -27, -24, -20, -17, -14, -10, -7, -4, 0, 3, >+ 6, 10, 13, 16, 20, 23, 26, 30, 33, 36, 39, >+ 43, 46, 49, 53, 56, 59, 63, 66, 69, 73, 76, >+ 79, 83, 86, 89, 93, 96, 99, 103, 106, 109, 113, >+ 116, 119, 123, 126, 129, 132, 136, 139, 142, 146, 149, >+ 152, 156, 159, 162, 166, 169, 172, 176, 179, 182, 186, >+ 189, 192, 196, 199, 202, 206, 209, 212, 216, 219, 222, >+ 226, 229, 232, 235, 239, 242, 245, 249, 252, 255, 259, >+ 262, 265, 269, 272, 275, 279, 282, 285, 289, 292, 295, >+ 299, 302, 305, 309, 312, 315, 319, 322, 325, 328, 332, >+ 335, 338, 342, 345, 348, 352, 355, 358, 362, 365, 368, >+ 372, 375, 378, 382, 385, 388, 392, 395, 398, 402, 405, >+ 408, 412, 415, 418, 422, 425, 428, 431, 435, 438, 441, >+ 445, 448, 451, 455, 458, 461, 465, 468, 471, 475, 478, >+ 481, 485, 488, 491, 495, 498, 501, 505, 508, 511, 515, >+ 518, 521, 524, 528, 531, 534, 538, 541, 544, 548, 551, >+ 554, 558, 561, 564, 568, 571, 574, 578, 581, 584, 588, >+ 591, 594, 598, 601, 604, 608, 611, 614, 617, 621, 624, >+ 627, 631, 634, 637, 641, 644, 647, 651, 654, 657, 661, >+ 664, 667, 671, 674, 677, 681, 684, 687, 691, 694, 697, >+ 701, 704, 707, 711, 714, 717, 720, 724, 727, 730, 734, >+ 737, 740, 744, 747, 750, 754, 757, 760, 764, 767, 770, >+ 774, 777, 780, 784, 787, 790, 794, 797, 800, 804, 807, >+ 810, 813, 817, 820, 823, 827, 830, 833, 837, 840, 843, >+ 847, 850, 853, 857, 860, 863, 867, 870, 873, 877, 880, >+ 883, 887, 890, 893, 897, 900, 903, 907, 910, 913, 916, >+ 920, 923, 926, 930, 933, 936, 940, 943, 946, 950, 953, >+ 956, 960, >+}; >+ >+} // namespace >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv.h >new file mode 100644 >index 0000000000000000000000000000000000000000..3e313679c9618aa88dc9e8b55e88e96a0f7f696b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv.h >@@ -0,0 +1,115 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_STRINGS_CHARCONV_H_ >+#define ABSL_STRINGS_CHARCONV_H_ >+ >+#include <system_error> // NOLINT(build/c++11) >+ >+namespace absl { >+ >+// Workalike compatibilty version of std::chars_format from C++17. >+// >+// This is an bitfield enumerator which can be passed to absl::from_chars to >+// configure the std::string-to-float conversion. >+enum class chars_format { >+ scientific = 1, >+ fixed = 2, >+ hex = 4, >+ general = fixed | scientific, >+}; >+ >+// The return result of a std::string-to-number conversion. >+// >+// `ec` will be set to `invalid_argument` if a well-formed number was not found >+// at the start of the input range, `result_out_of_range` if a well-formed >+// number was found, but it was out of the representable range of the requested >+// type, or to std::errc() otherwise. >+// >+// If a well-formed number was found, `ptr` is set to one past the sequence of >+// characters that were successfully parsed. If none was found, `ptr` is set >+// to the `first` argument to from_chars. >+struct from_chars_result { >+ const char* ptr; >+ std::errc ec; >+}; >+ >+// Workalike compatibilty version of std::from_chars from C++17. Currently >+// this only supports the `double` and `float` types. >+// >+// This interface incorporates the proposed resolutions for library issues >+// DR 3800 and DR 3801. If these are adopted with different wording, >+// Abseil's behavior will change to match the standard. (The behavior most >+// likely to change is for DR 3801, which says what `value` will be set to in >+// the case of overflow and underflow. Code that wants to avoid possible >+// breaking changes in this area should not depend on `value` when the returned >+// from_chars_result indicates a range error.) >+// >+// Searches the range [first, last) for the longest matching pattern beginning >+// at `first` that represents a floating point number. If one is found, store >+// the result in `value`. >+// >+// The matching pattern format is almost the same as that of strtod(), except >+// that C locale is not respected, and an initial '+' character in the input >+// range will never be matched. >+// >+// If `fmt` is set, it must be one of the enumerator values of the chars_format. >+// (This is despite the fact that chars_format is a bitmask type.) If set to >+// `scientific`, a matching number must contain an exponent. If set to `fixed`, >+// then an exponent will never match. (For example, the std::string "1e5" will be >+// parsed as "1".) If set to `hex`, then a hexadecimal float is parsed in the >+// format that strtod() accepts, except that a "0x" prefix is NOT matched. >+// (In particular, in `hex` mode, the input "0xff" results in the largest >+// matching pattern "0".) >+absl::from_chars_result from_chars(const char* first, const char* last, >+ double& value, // NOLINT >+ chars_format fmt = chars_format::general); >+ >+absl::from_chars_result from_chars(const char* first, const char* last, >+ float& value, // NOLINT >+ chars_format fmt = chars_format::general); >+ >+// std::chars_format is specified as a bitmask type, which means the following >+// operations must be provided: >+inline constexpr chars_format operator&(chars_format lhs, chars_format rhs) { >+ return static_cast<chars_format>(static_cast<int>(lhs) & >+ static_cast<int>(rhs)); >+} >+inline constexpr chars_format operator|(chars_format lhs, chars_format rhs) { >+ return static_cast<chars_format>(static_cast<int>(lhs) | >+ static_cast<int>(rhs)); >+} >+inline constexpr chars_format operator^(chars_format lhs, chars_format rhs) { >+ return static_cast<chars_format>(static_cast<int>(lhs) ^ >+ static_cast<int>(rhs)); >+} >+inline constexpr chars_format operator~(chars_format arg) { >+ return static_cast<chars_format>(~static_cast<int>(arg)); >+} >+inline chars_format& operator&=(chars_format& lhs, chars_format rhs) { >+ lhs = lhs & rhs; >+ return lhs; >+} >+inline chars_format& operator|=(chars_format& lhs, chars_format rhs) { >+ lhs = lhs | rhs; >+ return lhs; >+} >+inline chars_format& operator^=(chars_format& lhs, chars_format rhs) { >+ lhs = lhs ^ rhs; >+ return lhs; >+} >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_CHARCONV_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..fd83f44e3d09ceb944125bdd19f7282c39f62ee6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv_benchmark.cc >@@ -0,0 +1,204 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/charconv.h" >+ >+#include <cstdlib> >+#include <cstring> >+#include <string> >+ >+#include "benchmark/benchmark.h" >+ >+namespace { >+ >+void BM_Strtod_Pi(benchmark::State& state) { >+ const char* pi = "3.14159"; >+ for (auto s : state) { >+ benchmark::DoNotOptimize(pi); >+ benchmark::DoNotOptimize(strtod(pi, nullptr)); >+ } >+} >+BENCHMARK(BM_Strtod_Pi); >+ >+void BM_Absl_Pi(benchmark::State& state) { >+ const char* pi = "3.14159"; >+ const char* pi_end = pi + strlen(pi); >+ for (auto s : state) { >+ benchmark::DoNotOptimize(pi); >+ double v; >+ absl::from_chars(pi, pi_end, v); >+ benchmark::DoNotOptimize(v); >+ } >+} >+BENCHMARK(BM_Absl_Pi); >+ >+void BM_Strtod_Pi_float(benchmark::State& state) { >+ const char* pi = "3.14159"; >+ for (auto s : state) { >+ benchmark::DoNotOptimize(pi); >+ benchmark::DoNotOptimize(strtof(pi, nullptr)); >+ } >+} >+BENCHMARK(BM_Strtod_Pi_float); >+ >+void BM_Absl_Pi_float(benchmark::State& state) { >+ const char* pi = "3.14159"; >+ const char* pi_end = pi + strlen(pi); >+ for (auto s : state) { >+ benchmark::DoNotOptimize(pi); >+ float v; >+ absl::from_chars(pi, pi_end, v); >+ benchmark::DoNotOptimize(v); >+ } >+} >+BENCHMARK(BM_Absl_Pi_float); >+ >+void BM_Strtod_HardLarge(benchmark::State& state) { >+ const char* num = "272104041512242479.e200"; >+ for (auto s : state) { >+ benchmark::DoNotOptimize(num); >+ benchmark::DoNotOptimize(strtod(num, nullptr)); >+ } >+} >+BENCHMARK(BM_Strtod_HardLarge); >+ >+void BM_Absl_HardLarge(benchmark::State& state) { >+ const char* numstr = "272104041512242479.e200"; >+ const char* numstr_end = numstr + strlen(numstr); >+ for (auto s : state) { >+ benchmark::DoNotOptimize(numstr); >+ double v; >+ absl::from_chars(numstr, numstr_end, v); >+ benchmark::DoNotOptimize(v); >+ } >+} >+BENCHMARK(BM_Absl_HardLarge); >+ >+void BM_Strtod_HardSmall(benchmark::State& state) { >+ const char* num = "94080055902682397.e-242"; >+ for (auto s : state) { >+ benchmark::DoNotOptimize(num); >+ benchmark::DoNotOptimize(strtod(num, nullptr)); >+ } >+} >+BENCHMARK(BM_Strtod_HardSmall); >+ >+void BM_Absl_HardSmall(benchmark::State& state) { >+ const char* numstr = "94080055902682397.e-242"; >+ const char* numstr_end = numstr + strlen(numstr); >+ for (auto s : state) { >+ benchmark::DoNotOptimize(numstr); >+ double v; >+ absl::from_chars(numstr, numstr_end, v); >+ benchmark::DoNotOptimize(v); >+ } >+} >+BENCHMARK(BM_Absl_HardSmall); >+ >+void BM_Strtod_HugeMantissa(benchmark::State& state) { >+ std::string huge(200, '3'); >+ const char* num = huge.c_str(); >+ for (auto s : state) { >+ benchmark::DoNotOptimize(num); >+ benchmark::DoNotOptimize(strtod(num, nullptr)); >+ } >+} >+BENCHMARK(BM_Strtod_HugeMantissa); >+ >+void BM_Absl_HugeMantissa(benchmark::State& state) { >+ std::string huge(200, '3'); >+ const char* num = huge.c_str(); >+ const char* num_end = num + 200; >+ for (auto s : state) { >+ benchmark::DoNotOptimize(num); >+ double v; >+ absl::from_chars(num, num_end, v); >+ benchmark::DoNotOptimize(v); >+ } >+} >+BENCHMARK(BM_Absl_HugeMantissa); >+ >+std::string MakeHardCase(int length) { >+ // The number 1.1521...e-297 is exactly halfway between 12345 * 2**-1000 and >+ // the next larger representable number. The digits of this number are in >+ // the std::string below. >+ const std::string digits = >+ "1." >+ "152113937042223790993097181572444900347587985074226836242307364987727724" >+ "831384300183638649152607195040591791364113930628852279348613864894524591" >+ "272746490313676832900762939595690019745859128071117417798540258114233761" >+ "012939937017879509401007964861774960297319002612457273148497158989073482" >+ "171377406078223015359818300988676687994537274548940612510414856761641652" >+ "513434981938564294004070500716200446656421722229202383105446378511678258" >+ "370570631774499359748259931676320916632111681001853983492795053244971606" >+ "922718923011680846577744433974087653954904214152517799883551075537146316" >+ "168973685866425605046988661997658648354773076621610279716804960009043764" >+ "038392994055171112475093876476783502487512538082706095923790634572014823" >+ "78877699375152587890625" + >+ std::string(5000, '0'); >+ // generate the hard cases on either side for the given length. >+ // Lengths between 3 and 1000 are reasonable. >+ return digits.substr(0, length) + "1e-297"; >+} >+ >+void BM_Strtod_Big_And_Difficult(benchmark::State& state) { >+ std::string testcase = MakeHardCase(state.range(0)); >+ const char* begin = testcase.c_str(); >+ for (auto s : state) { >+ benchmark::DoNotOptimize(begin); >+ benchmark::DoNotOptimize(strtod(begin, nullptr)); >+ } >+} >+BENCHMARK(BM_Strtod_Big_And_Difficult)->Range(3, 5000); >+ >+void BM_Absl_Big_And_Difficult(benchmark::State& state) { >+ std::string testcase = MakeHardCase(state.range(0)); >+ const char* begin = testcase.c_str(); >+ const char* end = begin + testcase.size(); >+ for (auto s : state) { >+ benchmark::DoNotOptimize(begin); >+ double v; >+ absl::from_chars(begin, end, v); >+ benchmark::DoNotOptimize(v); >+ } >+} >+BENCHMARK(BM_Absl_Big_And_Difficult)->Range(3, 5000); >+ >+} // namespace >+ >+// ------------------------------------------------------------------------ >+// Benchmark Time CPU Iterations >+// ------------------------------------------------------------------------ >+// BM_Strtod_Pi 96 ns 96 ns 6337454 >+// BM_Absl_Pi 35 ns 35 ns 20031996 >+// BM_Strtod_Pi_float 91 ns 91 ns 7745851 >+// BM_Absl_Pi_float 35 ns 35 ns 20430298 >+// BM_Strtod_HardLarge 133 ns 133 ns 5288341 >+// BM_Absl_HardLarge 181 ns 181 ns 3855615 >+// BM_Strtod_HardSmall 279 ns 279 ns 2517243 >+// BM_Absl_HardSmall 287 ns 287 ns 2458744 >+// BM_Strtod_HugeMantissa 433 ns 433 ns 1604293 >+// BM_Absl_HugeMantissa 160 ns 160 ns 4403671 >+// BM_Strtod_Big_And_Difficult/3 236 ns 236 ns 2942496 >+// BM_Strtod_Big_And_Difficult/8 232 ns 232 ns 2983796 >+// BM_Strtod_Big_And_Difficult/64 437 ns 437 ns 1591951 >+// BM_Strtod_Big_And_Difficult/512 1738 ns 1738 ns 402519 >+// BM_Strtod_Big_And_Difficult/4096 3943 ns 3943 ns 176128 >+// BM_Strtod_Big_And_Difficult/5000 4397 ns 4397 ns 157878 >+// BM_Absl_Big_And_Difficult/3 39 ns 39 ns 17799583 >+// BM_Absl_Big_And_Difficult/8 43 ns 43 ns 16096859 >+// BM_Absl_Big_And_Difficult/64 550 ns 550 ns 1259717 >+// BM_Absl_Big_And_Difficult/512 4167 ns 4167 ns 171414 >+// BM_Absl_Big_And_Difficult/4096 9160 ns 9159 ns 76297 >+// BM_Absl_Big_And_Difficult/5000 9738 ns 9738 ns 70140 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..f8d71cc6c448c7a3e7f0caf98098fc7b4d2d5642 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/charconv_test.cc >@@ -0,0 +1,766 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/charconv.h" >+ >+#include <cstdlib> >+#include <string> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/strings/str_cat.h" >+ >+#ifdef _MSC_FULL_VER >+#define ABSL_COMPILER_DOES_EXACT_ROUNDING 0 >+#define ABSL_STRTOD_HANDLES_NAN_CORRECTLY 0 >+#else >+#define ABSL_COMPILER_DOES_EXACT_ROUNDING 1 >+#define ABSL_STRTOD_HANDLES_NAN_CORRECTLY 1 >+#endif >+ >+namespace { >+ >+#if ABSL_COMPILER_DOES_EXACT_ROUNDING >+ >+// Tests that the given std::string is accepted by absl::from_chars, and that it >+// converts exactly equal to the given number. >+void TestDoubleParse(absl::string_view str, double expected_number) { >+ SCOPED_TRACE(str); >+ double actual_number = 0.0; >+ absl::from_chars_result result = >+ absl::from_chars(str.data(), str.data() + str.length(), actual_number); >+ EXPECT_EQ(result.ec, std::errc()); >+ EXPECT_EQ(result.ptr, str.data() + str.length()); >+ EXPECT_EQ(actual_number, expected_number); >+} >+ >+void TestFloatParse(absl::string_view str, float expected_number) { >+ SCOPED_TRACE(str); >+ float actual_number = 0.0; >+ absl::from_chars_result result = >+ absl::from_chars(str.data(), str.data() + str.length(), actual_number); >+ EXPECT_EQ(result.ec, std::errc()); >+ EXPECT_EQ(result.ptr, str.data() + str.length()); >+ EXPECT_EQ(actual_number, expected_number); >+} >+ >+// Tests that the given double or single precision floating point literal is >+// parsed correctly by absl::from_chars. >+// >+// These convenience macros assume that the C++ compiler being used also does >+// fully correct decimal-to-binary conversions. >+#define FROM_CHARS_TEST_DOUBLE(number) \ >+ { \ >+ TestDoubleParse(#number, number); \ >+ TestDoubleParse("-" #number, -number); \ >+ } >+ >+#define FROM_CHARS_TEST_FLOAT(number) \ >+ { \ >+ TestFloatParse(#number, number##f); \ >+ TestFloatParse("-" #number, -number##f); \ >+ } >+ >+TEST(FromChars, NearRoundingCases) { >+ // Cases from "A Program for Testing IEEE Decimal-Binary Conversion" >+ // by Vern Paxson. >+ >+ // Forms that should round towards zero. (These are the hardest cases for >+ // each decimal mantissa size.) >+ FROM_CHARS_TEST_DOUBLE(5.e125); >+ FROM_CHARS_TEST_DOUBLE(69.e267); >+ FROM_CHARS_TEST_DOUBLE(999.e-026); >+ FROM_CHARS_TEST_DOUBLE(7861.e-034); >+ FROM_CHARS_TEST_DOUBLE(75569.e-254); >+ FROM_CHARS_TEST_DOUBLE(928609.e-261); >+ FROM_CHARS_TEST_DOUBLE(9210917.e080); >+ FROM_CHARS_TEST_DOUBLE(84863171.e114); >+ FROM_CHARS_TEST_DOUBLE(653777767.e273); >+ FROM_CHARS_TEST_DOUBLE(5232604057.e-298); >+ FROM_CHARS_TEST_DOUBLE(27235667517.e-109); >+ FROM_CHARS_TEST_DOUBLE(653532977297.e-123); >+ FROM_CHARS_TEST_DOUBLE(3142213164987.e-294); >+ FROM_CHARS_TEST_DOUBLE(46202199371337.e-072); >+ FROM_CHARS_TEST_DOUBLE(231010996856685.e-073); >+ FROM_CHARS_TEST_DOUBLE(9324754620109615.e212); >+ FROM_CHARS_TEST_DOUBLE(78459735791271921.e049); >+ FROM_CHARS_TEST_DOUBLE(272104041512242479.e200); >+ FROM_CHARS_TEST_DOUBLE(6802601037806061975.e198); >+ FROM_CHARS_TEST_DOUBLE(20505426358836677347.e-221); >+ FROM_CHARS_TEST_DOUBLE(836168422905420598437.e-234); >+ FROM_CHARS_TEST_DOUBLE(4891559871276714924261.e222); >+ FROM_CHARS_TEST_FLOAT(5.e-20); >+ FROM_CHARS_TEST_FLOAT(67.e14); >+ FROM_CHARS_TEST_FLOAT(985.e15); >+ FROM_CHARS_TEST_FLOAT(7693.e-42); >+ FROM_CHARS_TEST_FLOAT(55895.e-16); >+ FROM_CHARS_TEST_FLOAT(996622.e-44); >+ FROM_CHARS_TEST_FLOAT(7038531.e-32); >+ FROM_CHARS_TEST_FLOAT(60419369.e-46); >+ FROM_CHARS_TEST_FLOAT(702990899.e-20); >+ FROM_CHARS_TEST_FLOAT(6930161142.e-48); >+ FROM_CHARS_TEST_FLOAT(25933168707.e-13); >+ FROM_CHARS_TEST_FLOAT(596428896559.e20); >+ >+ // Similarly, forms that should round away from zero. >+ FROM_CHARS_TEST_DOUBLE(9.e-265); >+ FROM_CHARS_TEST_DOUBLE(85.e-037); >+ FROM_CHARS_TEST_DOUBLE(623.e100); >+ FROM_CHARS_TEST_DOUBLE(3571.e263); >+ FROM_CHARS_TEST_DOUBLE(81661.e153); >+ FROM_CHARS_TEST_DOUBLE(920657.e-023); >+ FROM_CHARS_TEST_DOUBLE(4603285.e-024); >+ FROM_CHARS_TEST_DOUBLE(87575437.e-309); >+ FROM_CHARS_TEST_DOUBLE(245540327.e122); >+ FROM_CHARS_TEST_DOUBLE(6138508175.e120); >+ FROM_CHARS_TEST_DOUBLE(83356057653.e193); >+ FROM_CHARS_TEST_DOUBLE(619534293513.e124); >+ FROM_CHARS_TEST_DOUBLE(2335141086879.e218); >+ FROM_CHARS_TEST_DOUBLE(36167929443327.e-159); >+ FROM_CHARS_TEST_DOUBLE(609610927149051.e-255); >+ FROM_CHARS_TEST_DOUBLE(3743626360493413.e-165); >+ FROM_CHARS_TEST_DOUBLE(94080055902682397.e-242); >+ FROM_CHARS_TEST_DOUBLE(899810892172646163.e283); >+ FROM_CHARS_TEST_DOUBLE(7120190517612959703.e120); >+ FROM_CHARS_TEST_DOUBLE(25188282901709339043.e-252); >+ FROM_CHARS_TEST_DOUBLE(308984926168550152811.e-052); >+ FROM_CHARS_TEST_DOUBLE(6372891218502368041059.e064); >+ FROM_CHARS_TEST_FLOAT(3.e-23); >+ FROM_CHARS_TEST_FLOAT(57.e18); >+ FROM_CHARS_TEST_FLOAT(789.e-35); >+ FROM_CHARS_TEST_FLOAT(2539.e-18); >+ FROM_CHARS_TEST_FLOAT(76173.e28); >+ FROM_CHARS_TEST_FLOAT(887745.e-11); >+ FROM_CHARS_TEST_FLOAT(5382571.e-37); >+ FROM_CHARS_TEST_FLOAT(82381273.e-35); >+ FROM_CHARS_TEST_FLOAT(750486563.e-38); >+ FROM_CHARS_TEST_FLOAT(3752432815.e-39); >+ FROM_CHARS_TEST_FLOAT(75224575729.e-45); >+ FROM_CHARS_TEST_FLOAT(459926601011.e15); >+} >+ >+#undef FROM_CHARS_TEST_DOUBLE >+#undef FROM_CHARS_TEST_FLOAT >+#endif >+ >+float ToFloat(absl::string_view s) { >+ float f; >+ absl::from_chars(s.data(), s.data() + s.size(), f); >+ return f; >+} >+ >+double ToDouble(absl::string_view s) { >+ double d; >+ absl::from_chars(s.data(), s.data() + s.size(), d); >+ return d; >+} >+ >+// A duplication of the test cases in "NearRoundingCases" above, but with >+// expected values expressed with integers, using ldexp/ldexpf. These test >+// cases will work even on compilers that do not accurately round floating point >+// literals. >+TEST(FromChars, NearRoundingCasesExplicit) { >+ EXPECT_EQ(ToDouble("5.e125"), ldexp(6653062250012735, 365)); >+ EXPECT_EQ(ToDouble("69.e267"), ldexp(4705683757438170, 841)); >+ EXPECT_EQ(ToDouble("999.e-026"), ldexp(6798841691080350, -129)); >+ EXPECT_EQ(ToDouble("7861.e-034"), ldexp(8975675289889240, -153)); >+ EXPECT_EQ(ToDouble("75569.e-254"), ldexp(6091718967192243, -880)); >+ EXPECT_EQ(ToDouble("928609.e-261"), ldexp(7849264900213743, -900)); >+ EXPECT_EQ(ToDouble("9210917.e080"), ldexp(8341110837370930, 236)); >+ EXPECT_EQ(ToDouble("84863171.e114"), ldexp(4625202867375927, 353)); >+ EXPECT_EQ(ToDouble("653777767.e273"), ldexp(5068902999763073, 884)); >+ EXPECT_EQ(ToDouble("5232604057.e-298"), ldexp(5741343011915040, -1010)); >+ EXPECT_EQ(ToDouble("27235667517.e-109"), ldexp(6707124626673586, -380)); >+ EXPECT_EQ(ToDouble("653532977297.e-123"), ldexp(7078246407265384, -422)); >+ EXPECT_EQ(ToDouble("3142213164987.e-294"), ldexp(8219991337640559, -988)); >+ EXPECT_EQ(ToDouble("46202199371337.e-072"), ldexp(5224462102115359, -246)); >+ EXPECT_EQ(ToDouble("231010996856685.e-073"), ldexp(5224462102115359, -247)); >+ EXPECT_EQ(ToDouble("9324754620109615.e212"), ldexp(5539753864394442, 705)); >+ EXPECT_EQ(ToDouble("78459735791271921.e049"), ldexp(8388176519442766, 166)); >+ EXPECT_EQ(ToDouble("272104041512242479.e200"), ldexp(5554409530847367, 670)); >+ EXPECT_EQ(ToDouble("6802601037806061975.e198"), ldexp(5554409530847367, 668)); >+ EXPECT_EQ(ToDouble("20505426358836677347.e-221"), >+ ldexp(4524032052079546, -722)); >+ EXPECT_EQ(ToDouble("836168422905420598437.e-234"), >+ ldexp(5070963299887562, -760)); >+ EXPECT_EQ(ToDouble("4891559871276714924261.e222"), >+ ldexp(6452687840519111, 757)); >+ EXPECT_EQ(ToFloat("5.e-20"), ldexpf(15474250, -88)); >+ EXPECT_EQ(ToFloat("67.e14"), ldexpf(12479722, 29)); >+ EXPECT_EQ(ToFloat("985.e15"), ldexpf(14333636, 36)); >+ EXPECT_EQ(ToFloat("7693.e-42"), ldexpf(10979816, -150)); >+ EXPECT_EQ(ToFloat("55895.e-16"), ldexpf(12888509, -61)); >+ EXPECT_EQ(ToFloat("996622.e-44"), ldexpf(14224264, -150)); >+ EXPECT_EQ(ToFloat("7038531.e-32"), ldexpf(11420669, -107)); >+ EXPECT_EQ(ToFloat("60419369.e-46"), ldexpf(8623340, -150)); >+ EXPECT_EQ(ToFloat("702990899.e-20"), ldexpf(16209866, -61)); >+ EXPECT_EQ(ToFloat("6930161142.e-48"), ldexpf(9891056, -150)); >+ EXPECT_EQ(ToFloat("25933168707.e-13"), ldexpf(11138211, -32)); >+ EXPECT_EQ(ToFloat("596428896559.e20"), ldexpf(12333860, 82)); >+ >+ >+ EXPECT_EQ(ToDouble("9.e-265"), ldexp(8168427841980010, -930)); >+ EXPECT_EQ(ToDouble("85.e-037"), ldexp(6360455125664090, -169)); >+ EXPECT_EQ(ToDouble("623.e100"), ldexp(6263531988747231, 289)); >+ EXPECT_EQ(ToDouble("3571.e263"), ldexp(6234526311072170, 833)); >+ EXPECT_EQ(ToDouble("81661.e153"), ldexp(6696636728760206, 472)); >+ EXPECT_EQ(ToDouble("920657.e-023"), ldexp(5975405561110124, -109)); >+ EXPECT_EQ(ToDouble("4603285.e-024"), ldexp(5975405561110124, -110)); >+ EXPECT_EQ(ToDouble("87575437.e-309"), ldexp(8452160731874668, -1053)); >+ EXPECT_EQ(ToDouble("245540327.e122"), ldexp(4985336549131723, 381)); >+ EXPECT_EQ(ToDouble("6138508175.e120"), ldexp(4985336549131723, 379)); >+ EXPECT_EQ(ToDouble("83356057653.e193"), ldexp(5986732817132056, 625)); >+ EXPECT_EQ(ToDouble("619534293513.e124"), ldexp(4798406992060657, 399)); >+ EXPECT_EQ(ToDouble("2335141086879.e218"), ldexp(5419088166961646, 713)); >+ EXPECT_EQ(ToDouble("36167929443327.e-159"), ldexp(8135819834632444, -536)); >+ EXPECT_EQ(ToDouble("609610927149051.e-255"), ldexp(4576664294594737, -850)); >+ EXPECT_EQ(ToDouble("3743626360493413.e-165"), ldexp(6898586531774201, -549)); >+ EXPECT_EQ(ToDouble("94080055902682397.e-242"), ldexp(6273271706052298, -800)); >+ EXPECT_EQ(ToDouble("899810892172646163.e283"), ldexp(7563892574477827, 947)); >+ EXPECT_EQ(ToDouble("7120190517612959703.e120"), ldexp(5385467232557565, 409)); >+ EXPECT_EQ(ToDouble("25188282901709339043.e-252"), >+ ldexp(5635662608542340, -825)); >+ EXPECT_EQ(ToDouble("308984926168550152811.e-052"), >+ ldexp(5644774693823803, -157)); >+ EXPECT_EQ(ToDouble("6372891218502368041059.e064"), >+ ldexp(4616868614322430, 233)); >+ >+ EXPECT_EQ(ToFloat("3.e-23"), ldexpf(9507380, -98)); >+ EXPECT_EQ(ToFloat("57.e18"), ldexpf(12960300, 42)); >+ EXPECT_EQ(ToFloat("789.e-35"), ldexpf(10739312, -130)); >+ EXPECT_EQ(ToFloat("2539.e-18"), ldexpf(11990089, -72)); >+ EXPECT_EQ(ToFloat("76173.e28"), ldexpf(9845130, 86)); >+ EXPECT_EQ(ToFloat("887745.e-11"), ldexpf(9760860, -40)); >+ EXPECT_EQ(ToFloat("5382571.e-37"), ldexpf(11447463, -124)); >+ EXPECT_EQ(ToFloat("82381273.e-35"), ldexpf(8554961, -113)); >+ EXPECT_EQ(ToFloat("750486563.e-38"), ldexpf(9975678, -120)); >+ EXPECT_EQ(ToFloat("3752432815.e-39"), ldexpf(9975678, -121)); >+ EXPECT_EQ(ToFloat("75224575729.e-45"), ldexpf(13105970, -137)); >+ EXPECT_EQ(ToFloat("459926601011.e15"), ldexpf(12466336, 65)); >+} >+ >+// Common test logic for converting a std::string which lies exactly halfway between >+// two target floats. >+// >+// mantissa and exponent represent the precise value between two floating point >+// numbers, `expected_low` and `expected_high`. The floating point >+// representation to parse in `StrCat(mantissa, "e", exponent)`. >+// >+// This function checks that an input just slightly less than the exact value >+// is rounded down to `expected_low`, and an input just slightly greater than >+// the exact value is rounded up to `expected_high`. >+// >+// The exact value should round to `expected_half`, which must be either >+// `expected_low` or `expected_high`. >+template <typename FloatType> >+void TestHalfwayValue(const std::string& mantissa, int exponent, >+ FloatType expected_low, FloatType expected_high, >+ FloatType expected_half) { >+ std::string low_rep = mantissa; >+ low_rep[low_rep.size() - 1] -= 1; >+ absl::StrAppend(&low_rep, std::string(1000, '9'), "e", exponent); >+ >+ FloatType actual_low = 0; >+ absl::from_chars(low_rep.data(), low_rep.data() + low_rep.size(), actual_low); >+ EXPECT_EQ(expected_low, actual_low); >+ >+ std::string high_rep = absl::StrCat(mantissa, std::string(1000, '0'), "1e", exponent); >+ FloatType actual_high = 0; >+ absl::from_chars(high_rep.data(), high_rep.data() + high_rep.size(), >+ actual_high); >+ EXPECT_EQ(expected_high, actual_high); >+ >+ std::string halfway_rep = absl::StrCat(mantissa, "e", exponent); >+ FloatType actual_half = 0; >+ absl::from_chars(halfway_rep.data(), halfway_rep.data() + halfway_rep.size(), >+ actual_half); >+ EXPECT_EQ(expected_half, actual_half); >+} >+ >+TEST(FromChars, DoubleRounding) { >+ const double zero = 0.0; >+ const double first_subnormal = nextafter(zero, 1.0); >+ const double second_subnormal = nextafter(first_subnormal, 1.0); >+ >+ const double first_normal = DBL_MIN; >+ const double last_subnormal = nextafter(first_normal, 0.0); >+ const double second_normal = nextafter(first_normal, 1.0); >+ >+ const double last_normal = DBL_MAX; >+ const double penultimate_normal = nextafter(last_normal, 0.0); >+ >+ // Various test cases for numbers between two representable floats. Each >+ // call to TestHalfwayValue tests a number just below and just above the >+ // halfway point, as well as the number exactly between them. >+ >+ // Test between zero and first_subnormal. Round-to-even tie rounds down. >+ TestHalfwayValue( >+ "2." >+ "470328229206232720882843964341106861825299013071623822127928412503377536" >+ "351043759326499181808179961898982823477228588654633283551779698981993873" >+ "980053909390631503565951557022639229085839244910518443593180284993653615" >+ "250031937045767824921936562366986365848075700158576926990370631192827955" >+ "855133292783433840935197801553124659726357957462276646527282722005637400" >+ "648549997709659947045402082816622623785739345073633900796776193057750674" >+ "017632467360096895134053553745851666113422376667860416215968046191446729" >+ "184030053005753084904876539171138659164623952491262365388187963623937328" >+ "042389101867234849766823508986338858792562830275599565752445550725518931" >+ "369083625477918694866799496832404970582102851318545139621383772282614543" >+ "7693412532098591327667236328125", >+ -324, zero, first_subnormal, zero); >+ >+ // first_subnormal and second_subnormal. Round-to-even tie rounds up. >+ TestHalfwayValue( >+ "7." >+ "410984687618698162648531893023320585475897039214871466383785237510132609" >+ "053131277979497545424539885696948470431685765963899850655339096945981621" >+ "940161728171894510697854671067917687257517734731555330779540854980960845" >+ "750095811137303474765809687100959097544227100475730780971111893578483867" >+ "565399878350301522805593404659373979179073872386829939581848166016912201" >+ "945649993128979841136206248449867871357218035220901702390328579173252022" >+ "052897402080290685402160661237554998340267130003581248647904138574340187" >+ "552090159017259254714629617513415977493871857473787096164563890871811984" >+ "127167305601704549300470526959016576377688490826798697257336652176556794" >+ "107250876433756084600398490497214911746308553955635418864151316847843631" >+ "3080237596295773983001708984375", >+ -324, first_subnormal, second_subnormal, second_subnormal); >+ >+ // last_subnormal and first_normal. Round-to-even tie rounds up. >+ TestHalfwayValue( >+ "2." >+ "225073858507201136057409796709131975934819546351645648023426109724822222" >+ "021076945516529523908135087914149158913039621106870086438694594645527657" >+ "207407820621743379988141063267329253552286881372149012981122451451889849" >+ "057222307285255133155755015914397476397983411801999323962548289017107081" >+ "850690630666655994938275772572015763062690663332647565300009245888316433" >+ "037779791869612049497390377829704905051080609940730262937128958950003583" >+ "799967207254304360284078895771796150945516748243471030702609144621572289" >+ "880258182545180325707018860872113128079512233426288368622321503775666622" >+ "503982534335974568884423900265498198385487948292206894721689831099698365" >+ "846814022854243330660339850886445804001034933970427567186443383770486037" >+ "86162277173854562306587467901408672332763671875", >+ -308, last_subnormal, first_normal, first_normal); >+ >+ // first_normal and second_normal. Round-to-even tie rounds down. >+ TestHalfwayValue( >+ "2." >+ "225073858507201630123055637955676152503612414573018013083228724049586647" >+ "606759446192036794116886953213985520549032000903434781884412325572184367" >+ "563347617020518175998922941393629966742598285899994830148971433555578567" >+ "693279306015978183162142425067962460785295885199272493577688320732492479" >+ "924816869232247165964934329258783950102250973957579510571600738343645738" >+ "494324192997092179207389919761694314131497173265255020084997973676783743" >+ "155205818804439163810572367791175177756227497413804253387084478193655533" >+ "073867420834526162513029462022730109054820067654020201547112002028139700" >+ "141575259123440177362244273712468151750189745559978653234255886219611516" >+ "335924167958029604477064946470184777360934300451421683607013647479513962" >+ "13837722826145437693412532098591327667236328125", >+ -308, first_normal, second_normal, first_normal); >+ >+ // penultimate_normal and last_normal. Round-to-even rounds down. >+ TestHalfwayValue( >+ "1." >+ "797693134862315608353258760581052985162070023416521662616611746258695532" >+ "672923265745300992879465492467506314903358770175220871059269879629062776" >+ "047355692132901909191523941804762171253349609463563872612866401980290377" >+ "995141836029815117562837277714038305214839639239356331336428021390916694" >+ "57927874464075218944", >+ 308, penultimate_normal, last_normal, penultimate_normal); >+} >+ >+// Same test cases as DoubleRounding, now with new and improved Much Smaller >+// Precision! >+TEST(FromChars, FloatRounding) { >+ const float zero = 0.0; >+ const float first_subnormal = nextafterf(zero, 1.0); >+ const float second_subnormal = nextafterf(first_subnormal, 1.0); >+ >+ const float first_normal = FLT_MIN; >+ const float last_subnormal = nextafterf(first_normal, 0.0); >+ const float second_normal = nextafterf(first_normal, 1.0); >+ >+ const float last_normal = FLT_MAX; >+ const float penultimate_normal = nextafterf(last_normal, 0.0); >+ >+ // Test between zero and first_subnormal. Round-to-even tie rounds down. >+ TestHalfwayValue( >+ "7." >+ "006492321624085354618647916449580656401309709382578858785341419448955413" >+ "42930300743319094181060791015625", >+ -46, zero, first_subnormal, zero); >+ >+ // first_subnormal and second_subnormal. Round-to-even tie rounds up. >+ TestHalfwayValue( >+ "2." >+ "101947696487225606385594374934874196920392912814773657635602425834686624" >+ "028790902229957282543182373046875", >+ -45, first_subnormal, second_subnormal, second_subnormal); >+ >+ // last_subnormal and first_normal. Round-to-even tie rounds up. >+ TestHalfwayValue( >+ "1." >+ "175494280757364291727882991035766513322858992758990427682963118425003064" >+ "9651730385585324256680905818939208984375", >+ -38, last_subnormal, first_normal, first_normal); >+ >+ // first_normal and second_normal. Round-to-even tie rounds down. >+ TestHalfwayValue( >+ "1." >+ "175494420887210724209590083408724842314472120785184615334540294131831453" >+ "9442813071445925743319094181060791015625", >+ -38, first_normal, second_normal, first_normal); >+ >+ // penultimate_normal and last_normal. Round-to-even rounds down. >+ TestHalfwayValue("3.40282336497324057985868971510891282432", 38, >+ penultimate_normal, last_normal, penultimate_normal); >+} >+ >+TEST(FromChars, Underflow) { >+ // Check that underflow is handled correctly, according to the specification >+ // in DR 3081. >+ double d; >+ float f; >+ absl::from_chars_result result; >+ >+ std::string negative_underflow = "-1e-1000"; >+ const char* begin = negative_underflow.data(); >+ const char* end = begin + negative_underflow.size(); >+ d = 100.0; >+ result = absl::from_chars(begin, end, d); >+ EXPECT_EQ(result.ptr, end); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_TRUE(std::signbit(d)); // negative >+ EXPECT_GE(d, -std::numeric_limits<double>::min()); >+ f = 100.0; >+ result = absl::from_chars(begin, end, f); >+ EXPECT_EQ(result.ptr, end); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_TRUE(std::signbit(f)); // negative >+ EXPECT_GE(f, -std::numeric_limits<float>::min()); >+ >+ std::string positive_underflow = "1e-1000"; >+ begin = positive_underflow.data(); >+ end = begin + positive_underflow.size(); >+ d = -100.0; >+ result = absl::from_chars(begin, end, d); >+ EXPECT_EQ(result.ptr, end); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_FALSE(std::signbit(d)); // positive >+ EXPECT_LE(d, std::numeric_limits<double>::min()); >+ f = -100.0; >+ result = absl::from_chars(begin, end, f); >+ EXPECT_EQ(result.ptr, end); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_FALSE(std::signbit(f)); // positive >+ EXPECT_LE(f, std::numeric_limits<float>::min()); >+} >+ >+TEST(FromChars, Overflow) { >+ // Check that overflow is handled correctly, according to the specification >+ // in DR 3081. >+ double d; >+ float f; >+ absl::from_chars_result result; >+ >+ std::string negative_overflow = "-1e1000"; >+ const char* begin = negative_overflow.data(); >+ const char* end = begin + negative_overflow.size(); >+ d = 100.0; >+ result = absl::from_chars(begin, end, d); >+ EXPECT_EQ(result.ptr, end); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_TRUE(std::signbit(d)); // negative >+ EXPECT_EQ(d, -std::numeric_limits<double>::max()); >+ f = 100.0; >+ result = absl::from_chars(begin, end, f); >+ EXPECT_EQ(result.ptr, end); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_TRUE(std::signbit(f)); // negative >+ EXPECT_EQ(f, -std::numeric_limits<float>::max()); >+ >+ std::string positive_overflow = "1e1000"; >+ begin = positive_overflow.data(); >+ end = begin + positive_overflow.size(); >+ d = -100.0; >+ result = absl::from_chars(begin, end, d); >+ EXPECT_EQ(result.ptr, end); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_FALSE(std::signbit(d)); // positive >+ EXPECT_EQ(d, std::numeric_limits<double>::max()); >+ f = -100.0; >+ result = absl::from_chars(begin, end, f); >+ EXPECT_EQ(result.ptr, end); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_FALSE(std::signbit(f)); // positive >+ EXPECT_EQ(f, std::numeric_limits<float>::max()); >+} >+ >+TEST(FromChars, ReturnValuePtr) { >+ // Check that `ptr` points one past the number scanned, even if that number >+ // is not representable. >+ double d; >+ absl::from_chars_result result; >+ >+ std::string normal = "3.14@#$%@#$%"; >+ result = absl::from_chars(normal.data(), normal.data() + normal.size(), d); >+ EXPECT_EQ(result.ec, std::errc()); >+ EXPECT_EQ(result.ptr - normal.data(), 4); >+ >+ std::string overflow = "1e1000@#$%@#$%"; >+ result = absl::from_chars(overflow.data(), >+ overflow.data() + overflow.size(), d); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_EQ(result.ptr - overflow.data(), 6); >+ >+ std::string garbage = "#$%@#$%"; >+ result = absl::from_chars(garbage.data(), >+ garbage.data() + garbage.size(), d); >+ EXPECT_EQ(result.ec, std::errc::invalid_argument); >+ EXPECT_EQ(result.ptr - garbage.data(), 0); >+} >+ >+// Check for a wide range of inputs that strtod() and absl::from_chars() exactly >+// agree on the conversion amount. >+// >+// This test assumes the platform's strtod() uses perfect round_to_nearest >+// rounding. >+TEST(FromChars, TestVersusStrtod) { >+ for (int mantissa = 1000000; mantissa <= 9999999; mantissa += 501) { >+ for (int exponent = -300; exponent < 300; ++exponent) { >+ std::string candidate = absl::StrCat(mantissa, "e", exponent); >+ double strtod_value = strtod(candidate.c_str(), nullptr); >+ double absl_value = 0; >+ absl::from_chars(candidate.data(), candidate.data() + candidate.size(), >+ absl_value); >+ ASSERT_EQ(strtod_value, absl_value) << candidate; >+ } >+ } >+} >+ >+// Check for a wide range of inputs that strtof() and absl::from_chars() exactly >+// agree on the conversion amount. >+// >+// This test assumes the platform's strtof() uses perfect round_to_nearest >+// rounding. >+TEST(FromChars, TestVersusStrtof) { >+ for (int mantissa = 1000000; mantissa <= 9999999; mantissa += 501) { >+ for (int exponent = -43; exponent < 32; ++exponent) { >+ std::string candidate = absl::StrCat(mantissa, "e", exponent); >+ float strtod_value = strtof(candidate.c_str(), nullptr); >+ float absl_value = 0; >+ absl::from_chars(candidate.data(), candidate.data() + candidate.size(), >+ absl_value); >+ ASSERT_EQ(strtod_value, absl_value) << candidate; >+ } >+ } >+} >+ >+// Tests if two floating point values have identical bit layouts. (EXPECT_EQ >+// is not suitable for NaN testing, since NaNs are never equal.) >+template <typename Float> >+bool Identical(Float a, Float b) { >+ return 0 == memcmp(&a, &b, sizeof(Float)); >+} >+ >+// Check that NaNs are parsed correctly. The spec requires that >+// std::from_chars on "NaN(123abc)" return the same value as std::nan("123abc"). >+// How such an n-char-sequence affects the generated NaN is unspecified, so we >+// just test for symmetry with std::nan and strtod here. >+// >+// (In Linux, this parses the value as a number and stuffs that number into the >+// free bits of a quiet NaN.) >+TEST(FromChars, NaNDoubles) { >+ for (std::string n_char_sequence : >+ {"", "1", "2", "3", "fff", "FFF", "200000", "400000", "4000000000000", >+ "8000000000000", "abc123", "legal_but_unexpected", >+ "99999999999999999999999", "_"}) { >+ std::string input = absl::StrCat("nan(", n_char_sequence, ")"); >+ SCOPED_TRACE(input); >+ double from_chars_double; >+ absl::from_chars(input.data(), input.data() + input.size(), >+ from_chars_double); >+ double std_nan_double = std::nan(n_char_sequence.c_str()); >+ EXPECT_TRUE(Identical(from_chars_double, std_nan_double)); >+ >+ // Also check that we match strtod()'s behavior. This test assumes that the >+ // platform has a compliant strtod(). >+#if ABSL_STRTOD_HANDLES_NAN_CORRECTLY >+ double strtod_double = strtod(input.c_str(), nullptr); >+ EXPECT_TRUE(Identical(from_chars_double, strtod_double)); >+#endif // ABSL_STRTOD_HANDLES_NAN_CORRECTLY >+ >+ // Check that we can parse a negative NaN >+ std::string negative_input = "-" + input; >+ double negative_from_chars_double; >+ absl::from_chars(negative_input.data(), >+ negative_input.data() + negative_input.size(), >+ negative_from_chars_double); >+ EXPECT_TRUE(std::signbit(negative_from_chars_double)); >+ EXPECT_FALSE(Identical(negative_from_chars_double, from_chars_double)); >+ from_chars_double = std::copysign(from_chars_double, -1.0); >+ EXPECT_TRUE(Identical(negative_from_chars_double, from_chars_double)); >+ } >+} >+ >+TEST(FromChars, NaNFloats) { >+ for (std::string n_char_sequence : >+ {"", "1", "2", "3", "fff", "FFF", "200000", "400000", "4000000000000", >+ "8000000000000", "abc123", "legal_but_unexpected", >+ "99999999999999999999999", "_"}) { >+ std::string input = absl::StrCat("nan(", n_char_sequence, ")"); >+ SCOPED_TRACE(input); >+ float from_chars_float; >+ absl::from_chars(input.data(), input.data() + input.size(), >+ from_chars_float); >+ float std_nan_float = std::nanf(n_char_sequence.c_str()); >+ EXPECT_TRUE(Identical(from_chars_float, std_nan_float)); >+ >+ // Also check that we match strtof()'s behavior. This test assumes that the >+ // platform has a compliant strtof(). >+#if ABSL_STRTOD_HANDLES_NAN_CORRECTLY >+ float strtof_float = strtof(input.c_str(), nullptr); >+ EXPECT_TRUE(Identical(from_chars_float, strtof_float)); >+#endif // ABSL_STRTOD_HANDLES_NAN_CORRECTLY >+ >+ // Check that we can parse a negative NaN >+ std::string negative_input = "-" + input; >+ float negative_from_chars_float; >+ absl::from_chars(negative_input.data(), >+ negative_input.data() + negative_input.size(), >+ negative_from_chars_float); >+ EXPECT_TRUE(std::signbit(negative_from_chars_float)); >+ EXPECT_FALSE(Identical(negative_from_chars_float, from_chars_float)); >+ from_chars_float = std::copysign(from_chars_float, -1.0); >+ EXPECT_TRUE(Identical(negative_from_chars_float, from_chars_float)); >+ } >+} >+ >+// Returns an integer larger than step. The values grow exponentially. >+int NextStep(int step) { >+ return step + (step >> 2) + 1; >+} >+ >+// Test a conversion on a family of input strings, checking that the calculation >+// is correct for in-bounds values, and that overflow and underflow are done >+// correctly for out-of-bounds values. >+// >+// input_generator maps from an integer index to a std::string to test. >+// expected_generator maps from an integer index to an expected Float value. >+// from_chars conversion of input_generator(i) should result in >+// expected_generator(i). >+// >+// lower_bound and upper_bound denote the smallest and largest values for which >+// the conversion is expected to succeed. >+template <typename Float> >+void TestOverflowAndUnderflow( >+ const std::function<std::string(int)>& input_generator, >+ const std::function<Float(int)>& expected_generator, int lower_bound, >+ int upper_bound) { >+ // test legal values near lower_bound >+ int index, step; >+ for (index = lower_bound, step = 1; index < upper_bound; >+ index += step, step = NextStep(step)) { >+ std::string input = input_generator(index); >+ SCOPED_TRACE(input); >+ Float expected = expected_generator(index); >+ Float actual; >+ auto result = >+ absl::from_chars(input.data(), input.data() + input.size(), actual); >+ EXPECT_EQ(result.ec, std::errc()); >+ EXPECT_EQ(expected, actual); >+ } >+ // test legal values near upper_bound >+ for (index = upper_bound, step = 1; index > lower_bound; >+ index -= step, step = NextStep(step)) { >+ std::string input = input_generator(index); >+ SCOPED_TRACE(input); >+ Float expected = expected_generator(index); >+ Float actual; >+ auto result = >+ absl::from_chars(input.data(), input.data() + input.size(), actual); >+ EXPECT_EQ(result.ec, std::errc()); >+ EXPECT_EQ(expected, actual); >+ } >+ // Test underflow values below lower_bound >+ for (index = lower_bound - 1, step = 1; index > -1000000; >+ index -= step, step = NextStep(step)) { >+ std::string input = input_generator(index); >+ SCOPED_TRACE(input); >+ Float actual; >+ auto result = >+ absl::from_chars(input.data(), input.data() + input.size(), actual); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_LT(actual, 1.0); // check for underflow >+ } >+ // Test overflow values above upper_bound >+ for (index = upper_bound + 1, step = 1; index < 1000000; >+ index += step, step = NextStep(step)) { >+ std::string input = input_generator(index); >+ SCOPED_TRACE(input); >+ Float actual; >+ auto result = >+ absl::from_chars(input.data(), input.data() + input.size(), actual); >+ EXPECT_EQ(result.ec, std::errc::result_out_of_range); >+ EXPECT_GT(actual, 1.0); // check for overflow >+ } >+} >+ >+// Check that overflow and underflow are caught correctly for hex doubles. >+// >+// The largest representable double is 0x1.fffffffffffffp+1023, and the >+// smallest representable subnormal is 0x0.0000000000001p-1022, which equals >+// 0x1p-1074. Therefore 1023 and -1074 are the limits of acceptable exponents >+// in this test. >+TEST(FromChars, HexdecimalDoubleLimits) { >+ auto input_gen = [](int index) { return absl::StrCat("0x1.0p", index); }; >+ auto expected_gen = [](int index) { return std::ldexp(1.0, index); }; >+ TestOverflowAndUnderflow<double>(input_gen, expected_gen, -1074, 1023); >+} >+ >+// Check that overflow and underflow are caught correctly for hex floats. >+// >+// The largest representable float is 0x1.fffffep+127, and the smallest >+// representable subnormal is 0x0.000002p-126, which equals 0x1p-149. >+// Therefore 127 and -149 are the limits of acceptable exponents in this test. >+TEST(FromChars, HexdecimalFloatLimits) { >+ auto input_gen = [](int index) { return absl::StrCat("0x1.0p", index); }; >+ auto expected_gen = [](int index) { return std::ldexp(1.0f, index); }; >+ TestOverflowAndUnderflow<float>(input_gen, expected_gen, -149, 127); >+} >+ >+// Check that overflow and underflow are caught correctly for decimal doubles. >+// >+// The largest representable double is about 1.8e308, and the smallest >+// representable subnormal is about 5e-324. '1e-324' therefore rounds away from >+// the smallest representable positive value. -323 and 308 are the limits of >+// acceptable exponents in this test. >+TEST(FromChars, DecimalDoubleLimits) { >+ auto input_gen = [](int index) { return absl::StrCat("1.0e", index); }; >+ auto expected_gen = [](int index) { return std::pow(10.0, index); }; >+ TestOverflowAndUnderflow<double>(input_gen, expected_gen, -323, 308); >+} >+ >+// Check that overflow and underflow are caught correctly for decimal floats. >+// >+// The largest representable float is about 3.4e38, and the smallest >+// representable subnormal is about 1.45e-45. '1e-45' therefore rounds towards >+// the smallest representable positive value. -45 and 38 are the limits of >+// acceptable exponents in this test. >+TEST(FromChars, DecimalFloatLimits) { >+ auto input_gen = [](int index) { return absl::StrCat("1.0e", index); }; >+ auto expected_gen = [](int index) { return std::pow(10.0, index); }; >+ TestOverflowAndUnderflow<float>(input_gen, expected_gen, -45, 38); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..fbc9f756315fa7fe9a7bb025d48c3fb284b9e8fb >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping.cc >@@ -0,0 +1,1109 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/escaping.h" >+ >+#include <algorithm> >+#include <cassert> >+#include <cstdint> >+#include <cstring> >+#include <iterator> >+#include <limits> >+#include <string> >+ >+#include "absl/base/internal/endian.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/unaligned_access.h" >+#include "absl/strings/internal/char_map.h" >+#include "absl/strings/internal/resize_uninitialized.h" >+#include "absl/strings/internal/utf8.h" >+#include "absl/strings/str_cat.h" >+#include "absl/strings/str_join.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+namespace { >+ >+// Digit conversion. >+constexpr char kHexChar[] = "0123456789abcdef"; >+ >+constexpr char kHexTable[513] = >+ "000102030405060708090a0b0c0d0e0f" >+ "101112131415161718191a1b1c1d1e1f" >+ "202122232425262728292a2b2c2d2e2f" >+ "303132333435363738393a3b3c3d3e3f" >+ "404142434445464748494a4b4c4d4e4f" >+ "505152535455565758595a5b5c5d5e5f" >+ "606162636465666768696a6b6c6d6e6f" >+ "707172737475767778797a7b7c7d7e7f" >+ "808182838485868788898a8b8c8d8e8f" >+ "909192939495969798999a9b9c9d9e9f" >+ "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" >+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" >+ "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" >+ "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" >+ "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" >+ "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; >+ >+// These are used for the leave_nulls_escaped argument to CUnescapeInternal(). >+constexpr bool kUnescapeNulls = false; >+ >+inline bool is_octal_digit(char c) { return ('0' <= c) && (c <= '7'); } >+ >+inline int hex_digit_to_int(char c) { >+ static_assert('0' == 0x30 && 'A' == 0x41 && 'a' == 0x61, >+ "Character set must be ASCII."); >+ assert(absl::ascii_isxdigit(c)); >+ int x = static_cast<unsigned char>(c); >+ if (x > '9') { >+ x += 9; >+ } >+ return x & 0xf; >+} >+ >+inline bool IsSurrogate(char32_t c, absl::string_view src, std::string* error) { >+ if (c >= 0xD800 && c <= 0xDFFF) { >+ if (error) { >+ *error = absl::StrCat("invalid surrogate character (0xD800-DFFF): \\", >+ src); >+ } >+ return true; >+ } >+ return false; >+} >+ >+// ---------------------------------------------------------------------- >+// CUnescapeInternal() >+// Implements both CUnescape() and CUnescapeForNullTerminatedString(). >+// >+// Unescapes C escape sequences and is the reverse of CEscape(). >+// >+// If 'source' is valid, stores the unescaped std::string and its size in >+// 'dest' and 'dest_len' respectively, and returns true. Otherwise >+// returns false and optionally stores the error description in >+// 'error'. Set 'error' to nullptr to disable error reporting. >+// >+// 'dest' should point to a buffer that is at least as big as 'source'. >+// 'source' and 'dest' may be the same. >+// >+// NOTE: any changes to this function must also be reflected in the older >+// UnescapeCEscapeSequences(). >+// ---------------------------------------------------------------------- >+bool CUnescapeInternal(absl::string_view source, bool leave_nulls_escaped, >+ char* dest, ptrdiff_t* dest_len, std::string* error) { >+ char* d = dest; >+ const char* p = source.data(); >+ const char* end = source.end(); >+ const char* last_byte = end - 1; >+ >+ // Small optimization for case where source = dest and there's no escaping >+ while (p == d && p < end && *p != '\\') p++, d++; >+ >+ while (p < end) { >+ if (*p != '\\') { >+ *d++ = *p++; >+ } else { >+ if (++p > last_byte) { // skip past the '\\' >+ if (error) *error = "String cannot end with \\"; >+ return false; >+ } >+ switch (*p) { >+ case 'a': *d++ = '\a'; break; >+ case 'b': *d++ = '\b'; break; >+ case 'f': *d++ = '\f'; break; >+ case 'n': *d++ = '\n'; break; >+ case 'r': *d++ = '\r'; break; >+ case 't': *d++ = '\t'; break; >+ case 'v': *d++ = '\v'; break; >+ case '\\': *d++ = '\\'; break; >+ case '?': *d++ = '\?'; break; // \? Who knew? >+ case '\'': *d++ = '\''; break; >+ case '"': *d++ = '\"'; break; >+ case '0': >+ case '1': >+ case '2': >+ case '3': >+ case '4': >+ case '5': >+ case '6': >+ case '7': { >+ // octal digit: 1 to 3 digits >+ const char* octal_start = p; >+ unsigned int ch = *p - '0'; >+ if (p < last_byte && is_octal_digit(p[1])) ch = ch * 8 + *++p - '0'; >+ if (p < last_byte && is_octal_digit(p[1])) >+ ch = ch * 8 + *++p - '0'; // now points at last digit >+ if (ch > 0xff) { >+ if (error) { >+ *error = "Value of \\" + >+ std::string(octal_start, p + 1 - octal_start) + >+ " exceeds 0xff"; >+ } >+ return false; >+ } >+ if ((ch == 0) && leave_nulls_escaped) { >+ // Copy the escape sequence for the null character >+ const ptrdiff_t octal_size = p + 1 - octal_start; >+ *d++ = '\\'; >+ memcpy(d, octal_start, octal_size); >+ d += octal_size; >+ break; >+ } >+ *d++ = ch; >+ break; >+ } >+ case 'x': >+ case 'X': { >+ if (p >= last_byte) { >+ if (error) *error = "String cannot end with \\x"; >+ return false; >+ } else if (!absl::ascii_isxdigit(p[1])) { >+ if (error) *error = "\\x cannot be followed by a non-hex digit"; >+ return false; >+ } >+ unsigned int ch = 0; >+ const char* hex_start = p; >+ while (p < last_byte && absl::ascii_isxdigit(p[1])) >+ // Arbitrarily many hex digits >+ ch = (ch << 4) + hex_digit_to_int(*++p); >+ if (ch > 0xFF) { >+ if (error) { >+ *error = "Value of \\" + std::string(hex_start, p + 1 - hex_start) + >+ " exceeds 0xff"; >+ } >+ return false; >+ } >+ if ((ch == 0) && leave_nulls_escaped) { >+ // Copy the escape sequence for the null character >+ const ptrdiff_t hex_size = p + 1 - hex_start; >+ *d++ = '\\'; >+ memcpy(d, hex_start, hex_size); >+ d += hex_size; >+ break; >+ } >+ *d++ = ch; >+ break; >+ } >+ case 'u': { >+ // \uhhhh => convert 4 hex digits to UTF-8 >+ char32_t rune = 0; >+ const char* hex_start = p; >+ if (p + 4 >= end) { >+ if (error) { >+ *error = "\\u must be followed by 4 hex digits: \\" + >+ std::string(hex_start, p + 1 - hex_start); >+ } >+ return false; >+ } >+ for (int i = 0; i < 4; ++i) { >+ // Look one char ahead. >+ if (absl::ascii_isxdigit(p[1])) { >+ rune = (rune << 4) + hex_digit_to_int(*++p); // Advance p. >+ } else { >+ if (error) { >+ *error = "\\u must be followed by 4 hex digits: \\" + >+ std::string(hex_start, p + 1 - hex_start); >+ } >+ return false; >+ } >+ } >+ if ((rune == 0) && leave_nulls_escaped) { >+ // Copy the escape sequence for the null character >+ *d++ = '\\'; >+ memcpy(d, hex_start, 5); // u0000 >+ d += 5; >+ break; >+ } >+ if (IsSurrogate(rune, absl::string_view(hex_start, 5), error)) { >+ return false; >+ } >+ d += strings_internal::EncodeUTF8Char(d, rune); >+ break; >+ } >+ case 'U': { >+ // \Uhhhhhhhh => convert 8 hex digits to UTF-8 >+ char32_t rune = 0; >+ const char* hex_start = p; >+ if (p + 8 >= end) { >+ if (error) { >+ *error = "\\U must be followed by 8 hex digits: \\" + >+ std::string(hex_start, p + 1 - hex_start); >+ } >+ return false; >+ } >+ for (int i = 0; i < 8; ++i) { >+ // Look one char ahead. >+ if (absl::ascii_isxdigit(p[1])) { >+ // Don't change rune until we're sure this >+ // is within the Unicode limit, but do advance p. >+ uint32_t newrune = (rune << 4) + hex_digit_to_int(*++p); >+ if (newrune > 0x10FFFF) { >+ if (error) { >+ *error = "Value of \\" + >+ std::string(hex_start, p + 1 - hex_start) + >+ " exceeds Unicode limit (0x10FFFF)"; >+ } >+ return false; >+ } else { >+ rune = newrune; >+ } >+ } else { >+ if (error) { >+ *error = "\\U must be followed by 8 hex digits: \\" + >+ std::string(hex_start, p + 1 - hex_start); >+ } >+ return false; >+ } >+ } >+ if ((rune == 0) && leave_nulls_escaped) { >+ // Copy the escape sequence for the null character >+ *d++ = '\\'; >+ memcpy(d, hex_start, 9); // U00000000 >+ d += 9; >+ break; >+ } >+ if (IsSurrogate(rune, absl::string_view(hex_start, 9), error)) { >+ return false; >+ } >+ d += strings_internal::EncodeUTF8Char(d, rune); >+ break; >+ } >+ default: { >+ if (error) *error = std::string("Unknown escape sequence: \\") + *p; >+ return false; >+ } >+ } >+ p++; // read past letter we escaped >+ } >+ } >+ *dest_len = d - dest; >+ return true; >+} >+ >+// ---------------------------------------------------------------------- >+// CUnescapeInternal() >+// >+// Same as above but uses a C++ std::string for output. 'source' and 'dest' >+// may be the same. >+// ---------------------------------------------------------------------- >+bool CUnescapeInternal(absl::string_view source, bool leave_nulls_escaped, >+ std::string* dest, std::string* error) { >+ strings_internal::STLStringResizeUninitialized(dest, source.size()); >+ >+ ptrdiff_t dest_size; >+ if (!CUnescapeInternal(source, >+ leave_nulls_escaped, >+ const_cast<char*>(dest->data()), >+ &dest_size, >+ error)) { >+ return false; >+ } >+ dest->erase(dest_size); >+ return true; >+} >+ >+// ---------------------------------------------------------------------- >+// CEscape() >+// CHexEscape() >+// Utf8SafeCEscape() >+// Utf8SafeCHexEscape() >+// Escapes 'src' using C-style escape sequences. This is useful for >+// preparing query flags. The 'Hex' version uses hexadecimal rather than >+// octal sequences. The 'Utf8Safe' version does not touch UTF-8 bytes. >+// >+// Escaped chars: \n, \r, \t, ", ', \, and !absl::ascii_isprint(). >+// ---------------------------------------------------------------------- >+std::string CEscapeInternal(absl::string_view src, bool use_hex, bool utf8_safe) { >+ std::string dest; >+ bool last_hex_escape = false; // true if last output char was \xNN. >+ >+ for (unsigned char c : src) { >+ bool is_hex_escape = false; >+ switch (c) { >+ case '\n': dest.append("\\" "n"); break; >+ case '\r': dest.append("\\" "r"); break; >+ case '\t': dest.append("\\" "t"); break; >+ case '\"': dest.append("\\" "\""); break; >+ case '\'': dest.append("\\" "'"); break; >+ case '\\': dest.append("\\" "\\"); break; >+ default: >+ // Note that if we emit \xNN and the src character after that is a hex >+ // digit then that digit must be escaped too to prevent it being >+ // interpreted as part of the character code by C. >+ if ((!utf8_safe || c < 0x80) && >+ (!absl::ascii_isprint(c) || >+ (last_hex_escape && absl::ascii_isxdigit(c)))) { >+ if (use_hex) { >+ dest.append("\\" "x"); >+ dest.push_back(kHexChar[c / 16]); >+ dest.push_back(kHexChar[c % 16]); >+ is_hex_escape = true; >+ } else { >+ dest.append("\\"); >+ dest.push_back(kHexChar[c / 64]); >+ dest.push_back(kHexChar[(c % 64) / 8]); >+ dest.push_back(kHexChar[c % 8]); >+ } >+ } else { >+ dest.push_back(c); >+ break; >+ } >+ } >+ last_hex_escape = is_hex_escape; >+ } >+ >+ return dest; >+} >+ >+/* clang-format off */ >+constexpr char c_escaped_len[256] = { >+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4, // \t, \n, \r >+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, >+ 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // ", ' >+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // '0'..'9' >+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A'..'O' >+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 'P'..'Z', '\' >+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a'..'o' >+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, // 'p'..'z', DEL >+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, >+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, >+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, >+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, >+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, >+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, >+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, >+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, >+}; >+/* clang-format on */ >+ >+// Calculates the length of the C-style escaped version of 'src'. >+// Assumes that non-printable characters are escaped using octal sequences, and >+// that UTF-8 bytes are not handled specially. >+inline size_t CEscapedLength(absl::string_view src) { >+ size_t escaped_len = 0; >+ for (unsigned char c : src) escaped_len += c_escaped_len[c]; >+ return escaped_len; >+} >+ >+void CEscapeAndAppendInternal(absl::string_view src, std::string* dest) { >+ size_t escaped_len = CEscapedLength(src); >+ if (escaped_len == src.size()) { >+ dest->append(src.data(), src.size()); >+ return; >+ } >+ >+ size_t cur_dest_len = dest->size(); >+ strings_internal::STLStringResizeUninitialized(dest, >+ cur_dest_len + escaped_len); >+ char* append_ptr = &(*dest)[cur_dest_len]; >+ >+ for (unsigned char c : src) { >+ int char_len = c_escaped_len[c]; >+ if (char_len == 1) { >+ *append_ptr++ = c; >+ } else if (char_len == 2) { >+ switch (c) { >+ case '\n': >+ *append_ptr++ = '\\'; >+ *append_ptr++ = 'n'; >+ break; >+ case '\r': >+ *append_ptr++ = '\\'; >+ *append_ptr++ = 'r'; >+ break; >+ case '\t': >+ *append_ptr++ = '\\'; >+ *append_ptr++ = 't'; >+ break; >+ case '\"': >+ *append_ptr++ = '\\'; >+ *append_ptr++ = '\"'; >+ break; >+ case '\'': >+ *append_ptr++ = '\\'; >+ *append_ptr++ = '\''; >+ break; >+ case '\\': >+ *append_ptr++ = '\\'; >+ *append_ptr++ = '\\'; >+ break; >+ } >+ } else { >+ *append_ptr++ = '\\'; >+ *append_ptr++ = '0' + c / 64; >+ *append_ptr++ = '0' + (c % 64) / 8; >+ *append_ptr++ = '0' + c % 8; >+ } >+ } >+} >+ >+bool Base64UnescapeInternal(const char* src_param, size_t szsrc, char* dest, >+ size_t szdest, const signed char* unbase64, >+ size_t* len) { >+ static const char kPad64Equals = '='; >+ static const char kPad64Dot = '.'; >+ >+ size_t destidx = 0; >+ int decode = 0; >+ int state = 0; >+ unsigned int ch = 0; >+ unsigned int temp = 0; >+ >+ // If "char" is signed by default, using *src as an array index results in >+ // accessing negative array elements. Treat the input as a pointer to >+ // unsigned char to avoid this. >+ const unsigned char* src = reinterpret_cast<const unsigned char*>(src_param); >+ >+ // The GET_INPUT macro gets the next input character, skipping >+ // over any whitespace, and stopping when we reach the end of the >+ // std::string or when we read any non-data character. The arguments are >+ // an arbitrary identifier (used as a label for goto) and the number >+ // of data bytes that must remain in the input to avoid aborting the >+ // loop. >+#define GET_INPUT(label, remain) \ >+ label: \ >+ --szsrc; \ >+ ch = *src++; \ >+ decode = unbase64[ch]; \ >+ if (decode < 0) { \ >+ if (absl::ascii_isspace(ch) && szsrc >= remain) goto label; \ >+ state = 4 - remain; \ >+ break; \ >+ } >+ >+ // if dest is null, we're just checking to see if it's legal input >+ // rather than producing output. (I suspect this could just be done >+ // with a regexp...). We duplicate the loop so this test can be >+ // outside it instead of in every iteration. >+ >+ if (dest) { >+ // This loop consumes 4 input bytes and produces 3 output bytes >+ // per iteration. We can't know at the start that there is enough >+ // data left in the std::string for a full iteration, so the loop may >+ // break out in the middle; if so 'state' will be set to the >+ // number of input bytes read. >+ >+ while (szsrc >= 4) { >+ // We'll start by optimistically assuming that the next four >+ // bytes of the std::string (src[0..3]) are four good data bytes >+ // (that is, no nulls, whitespace, padding chars, or illegal >+ // chars). We need to test src[0..2] for nulls individually >+ // before constructing temp to preserve the property that we >+ // never read past a null in the std::string (no matter how long >+ // szsrc claims the std::string is). >+ >+ if (!src[0] || !src[1] || !src[2] || >+ ((temp = ((unsigned(unbase64[src[0]]) << 18) | >+ (unsigned(unbase64[src[1]]) << 12) | >+ (unsigned(unbase64[src[2]]) << 6) | >+ (unsigned(unbase64[src[3]])))) & >+ 0x80000000)) { >+ // Iff any of those four characters was bad (null, illegal, >+ // whitespace, padding), then temp's high bit will be set >+ // (because unbase64[] is -1 for all bad characters). >+ // >+ // We'll back up and resort to the slower decoder, which knows >+ // how to handle those cases. >+ >+ GET_INPUT(first, 4); >+ temp = decode; >+ GET_INPUT(second, 3); >+ temp = (temp << 6) | decode; >+ GET_INPUT(third, 2); >+ temp = (temp << 6) | decode; >+ GET_INPUT(fourth, 1); >+ temp = (temp << 6) | decode; >+ } else { >+ // We really did have four good data bytes, so advance four >+ // characters in the std::string. >+ >+ szsrc -= 4; >+ src += 4; >+ } >+ >+ // temp has 24 bits of input, so write that out as three bytes. >+ >+ if (destidx + 3 > szdest) return false; >+ dest[destidx + 2] = temp; >+ temp >>= 8; >+ dest[destidx + 1] = temp; >+ temp >>= 8; >+ dest[destidx] = temp; >+ destidx += 3; >+ } >+ } else { >+ while (szsrc >= 4) { >+ if (!src[0] || !src[1] || !src[2] || >+ ((temp = ((unsigned(unbase64[src[0]]) << 18) | >+ (unsigned(unbase64[src[1]]) << 12) | >+ (unsigned(unbase64[src[2]]) << 6) | >+ (unsigned(unbase64[src[3]])))) & >+ 0x80000000)) { >+ GET_INPUT(first_no_dest, 4); >+ GET_INPUT(second_no_dest, 3); >+ GET_INPUT(third_no_dest, 2); >+ GET_INPUT(fourth_no_dest, 1); >+ } else { >+ szsrc -= 4; >+ src += 4; >+ } >+ destidx += 3; >+ } >+ } >+ >+#undef GET_INPUT >+ >+ // if the loop terminated because we read a bad character, return >+ // now. >+ if (decode < 0 && ch != kPad64Equals && ch != kPad64Dot && >+ !absl::ascii_isspace(ch)) >+ return false; >+ >+ if (ch == kPad64Equals || ch == kPad64Dot) { >+ // if we stopped by hitting an '=' or '.', un-read that character -- we'll >+ // look at it again when we count to check for the proper number of >+ // equals signs at the end. >+ ++szsrc; >+ --src; >+ } else { >+ // This loop consumes 1 input byte per iteration. It's used to >+ // clean up the 0-3 input bytes remaining when the first, faster >+ // loop finishes. 'temp' contains the data from 'state' input >+ // characters read by the first loop. >+ while (szsrc > 0) { >+ --szsrc; >+ ch = *src++; >+ decode = unbase64[ch]; >+ if (decode < 0) { >+ if (absl::ascii_isspace(ch)) { >+ continue; >+ } else if (ch == kPad64Equals || ch == kPad64Dot) { >+ // back up one character; we'll read it again when we check >+ // for the correct number of pad characters at the end. >+ ++szsrc; >+ --src; >+ break; >+ } else { >+ return false; >+ } >+ } >+ >+ // Each input character gives us six bits of output. >+ temp = (temp << 6) | decode; >+ ++state; >+ if (state == 4) { >+ // If we've accumulated 24 bits of output, write that out as >+ // three bytes. >+ if (dest) { >+ if (destidx + 3 > szdest) return false; >+ dest[destidx + 2] = temp; >+ temp >>= 8; >+ dest[destidx + 1] = temp; >+ temp >>= 8; >+ dest[destidx] = temp; >+ } >+ destidx += 3; >+ state = 0; >+ temp = 0; >+ } >+ } >+ } >+ >+ // Process the leftover data contained in 'temp' at the end of the input. >+ int expected_equals = 0; >+ switch (state) { >+ case 0: >+ // Nothing left over; output is a multiple of 3 bytes. >+ break; >+ >+ case 1: >+ // Bad input; we have 6 bits left over. >+ return false; >+ >+ case 2: >+ // Produce one more output byte from the 12 input bits we have left. >+ if (dest) { >+ if (destidx + 1 > szdest) return false; >+ temp >>= 4; >+ dest[destidx] = temp; >+ } >+ ++destidx; >+ expected_equals = 2; >+ break; >+ >+ case 3: >+ // Produce two more output bytes from the 18 input bits we have left. >+ if (dest) { >+ if (destidx + 2 > szdest) return false; >+ temp >>= 2; >+ dest[destidx + 1] = temp; >+ temp >>= 8; >+ dest[destidx] = temp; >+ } >+ destidx += 2; >+ expected_equals = 1; >+ break; >+ >+ default: >+ // state should have no other values at this point. >+ ABSL_RAW_LOG(FATAL, "This can't happen; base64 decoder state = %d", >+ state); >+ } >+ >+ // The remainder of the std::string should be all whitespace, mixed with >+ // exactly 0 equals signs, or exactly 'expected_equals' equals >+ // signs. (Always accepting 0 equals signs is an Abseil extension >+ // not covered in the RFC, as is accepting dot as the pad character.) >+ >+ int equals = 0; >+ while (szsrc > 0) { >+ if (*src == kPad64Equals || *src == kPad64Dot) >+ ++equals; >+ else if (!absl::ascii_isspace(*src)) >+ return false; >+ --szsrc; >+ ++src; >+ } >+ >+ const bool ok = (equals == 0 || equals == expected_equals); >+ if (ok) *len = destidx; >+ return ok; >+} >+ >+// The arrays below were generated by the following code >+// #include <sys/time.h> >+// #include <stdlib.h> >+// #include <std::string.h> >+// main() >+// { >+// static const char Base64[] = >+// "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; >+// char* pos; >+// int idx, i, j; >+// printf(" "); >+// for (i = 0; i < 255; i += 8) { >+// for (j = i; j < i + 8; j++) { >+// pos = strchr(Base64, j); >+// if ((pos == nullptr) || (j == 0)) >+// idx = -1; >+// else >+// idx = pos - Base64; >+// if (idx == -1) >+// printf(" %2d, ", idx); >+// else >+// printf(" %2d/*%c*/,", idx, j); >+// } >+// printf("\n "); >+// } >+// } >+// >+// where the value of "Base64[]" was replaced by one of the base-64 conversion >+// tables from the functions below. >+/* clang-format off */ >+constexpr signed char kUnBase64[] = { >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, 62/*+*/, -1, -1, -1, 63/*/ */, >+ 52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/, >+ 60/*8*/, 61/*9*/, -1, -1, -1, -1, -1, -1, >+ -1, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/, >+ 07/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/, >+ 15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/, >+ 23/*X*/, 24/*Y*/, 25/*Z*/, -1, -1, -1, -1, -1, >+ -1, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/, >+ 33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/, >+ 41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/, >+ 49/*x*/, 50/*y*/, 51/*z*/, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1 >+}; >+ >+constexpr signed char kUnWebSafeBase64[] = { >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, 62/*-*/, -1, -1, >+ 52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/, >+ 60/*8*/, 61/*9*/, -1, -1, -1, -1, -1, -1, >+ -1, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/, >+ 07/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/, >+ 15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/, >+ 23/*X*/, 24/*Y*/, 25/*Z*/, -1, -1, -1, -1, 63/*_*/, >+ -1, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/, >+ 33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/, >+ 41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/, >+ 49/*x*/, 50/*y*/, 51/*z*/, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1 >+}; >+/* clang-format on */ >+ >+size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { >+ // Base64 encodes three bytes of input at a time. If the input is not >+ // divisible by three, we pad as appropriate. >+ // >+ // (from http://tools.ietf.org/html/rfc3548) >+ // Special processing is performed if fewer than 24 bits are available >+ // at the end of the data being encoded. A full encoding quantum is >+ // always completed at the end of a quantity. When fewer than 24 input >+ // bits are available in an input group, zero bits are added (on the >+ // right) to form an integral number of 6-bit groups. Padding at the >+ // end of the data is performed using the '=' character. Since all base >+ // 64 input is an integral number of octets, only the following cases >+ // can arise: >+ >+ // Base64 encodes each three bytes of input into four bytes of output. >+ size_t len = (input_len / 3) * 4; >+ >+ if (input_len % 3 == 0) { >+ // (from http://tools.ietf.org/html/rfc3548) >+ // (1) the final quantum of encoding input is an integral multiple of 24 >+ // bits; here, the final unit of encoded output will be an integral >+ // multiple of 4 characters with no "=" padding, >+ } else if (input_len % 3 == 1) { >+ // (from http://tools.ietf.org/html/rfc3548) >+ // (2) the final quantum of encoding input is exactly 8 bits; here, the >+ // final unit of encoded output will be two characters followed by two >+ // "=" padding characters, or >+ len += 2; >+ if (do_padding) { >+ len += 2; >+ } >+ } else { // (input_len % 3 == 2) >+ // (from http://tools.ietf.org/html/rfc3548) >+ // (3) the final quantum of encoding input is exactly 16 bits; here, the >+ // final unit of encoded output will be three characters followed by one >+ // "=" padding character. >+ len += 3; >+ if (do_padding) { >+ len += 1; >+ } >+ } >+ >+ assert(len >= input_len); // make sure we didn't overflow >+ return len; >+} >+ >+size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, >+ size_t szdest, const char* base64, >+ bool do_padding) { >+ static const char kPad64 = '='; >+ >+ if (szsrc * 4 > szdest * 3) return 0; >+ >+ char* cur_dest = dest; >+ const unsigned char* cur_src = src; >+ >+ char* const limit_dest = dest + szdest; >+ const unsigned char* const limit_src = src + szsrc; >+ >+ // Three bytes of data encodes to four characters of cyphertext. >+ // So we can pump through three-byte chunks atomically. >+ if (szsrc >= 3) { // "limit_src - 3" is UB if szsrc < 3 >+ while (cur_src < limit_src - 3) { // as long as we have >= 32 bits >+ uint32_t in = absl::big_endian::Load32(cur_src) >> 8; >+ >+ cur_dest[0] = base64[in >> 18]; >+ in &= 0x3FFFF; >+ cur_dest[1] = base64[in >> 12]; >+ in &= 0xFFF; >+ cur_dest[2] = base64[in >> 6]; >+ in &= 0x3F; >+ cur_dest[3] = base64[in]; >+ >+ cur_dest += 4; >+ cur_src += 3; >+ } >+ } >+ // To save time, we didn't update szdest or szsrc in the loop. So do it now. >+ szdest = limit_dest - cur_dest; >+ szsrc = limit_src - cur_src; >+ >+ /* now deal with the tail (<=3 bytes) */ >+ switch (szsrc) { >+ case 0: >+ // Nothing left; nothing more to do. >+ break; >+ case 1: { >+ // One byte left: this encodes to two characters, and (optionally) >+ // two pad characters to round out the four-character cypherblock. >+ if (szdest < 2) return 0; >+ uint32_t in = cur_src[0]; >+ cur_dest[0] = base64[in >> 2]; >+ in &= 0x3; >+ cur_dest[1] = base64[in << 4]; >+ cur_dest += 2; >+ szdest -= 2; >+ if (do_padding) { >+ if (szdest < 2) return 0; >+ cur_dest[0] = kPad64; >+ cur_dest[1] = kPad64; >+ cur_dest += 2; >+ szdest -= 2; >+ } >+ break; >+ } >+ case 2: { >+ // Two bytes left: this encodes to three characters, and (optionally) >+ // one pad character to round out the four-character cypherblock. >+ if (szdest < 3) return 0; >+ uint32_t in = absl::big_endian::Load16(cur_src); >+ cur_dest[0] = base64[in >> 10]; >+ in &= 0x3FF; >+ cur_dest[1] = base64[in >> 4]; >+ in &= 0x00F; >+ cur_dest[2] = base64[in << 2]; >+ cur_dest += 3; >+ szdest -= 3; >+ if (do_padding) { >+ if (szdest < 1) return 0; >+ cur_dest[0] = kPad64; >+ cur_dest += 1; >+ szdest -= 1; >+ } >+ break; >+ } >+ case 3: { >+ // Three bytes left: same as in the big loop above. We can't do this in >+ // the loop because the loop above always reads 4 bytes, and the fourth >+ // byte is past the end of the input. >+ if (szdest < 4) return 0; >+ uint32_t in = (cur_src[0] << 16) + absl::big_endian::Load16(cur_src + 1); >+ cur_dest[0] = base64[in >> 18]; >+ in &= 0x3FFFF; >+ cur_dest[1] = base64[in >> 12]; >+ in &= 0xFFF; >+ cur_dest[2] = base64[in >> 6]; >+ in &= 0x3F; >+ cur_dest[3] = base64[in]; >+ cur_dest += 4; >+ szdest -= 4; >+ break; >+ } >+ default: >+ // Should not be reached: blocks of 4 bytes are handled >+ // in the while loop before this switch statement. >+ ABSL_RAW_LOG(FATAL, "Logic problem? szsrc = %zu", szsrc); >+ break; >+ } >+ return (cur_dest - dest); >+} >+ >+constexpr char kBase64Chars[] = >+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; >+ >+constexpr char kWebSafeBase64Chars[] = >+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; >+ >+void Base64EscapeInternal(const unsigned char* src, size_t szsrc, std::string* dest, >+ bool do_padding, const char* base64_chars) { >+ const size_t calc_escaped_size = >+ CalculateBase64EscapedLenInternal(szsrc, do_padding); >+ strings_internal::STLStringResizeUninitialized(dest, calc_escaped_size); >+ >+ const size_t escaped_len = Base64EscapeInternal( >+ src, szsrc, &(*dest)[0], dest->size(), base64_chars, do_padding); >+ assert(calc_escaped_size == escaped_len); >+ dest->erase(escaped_len); >+} >+ >+bool Base64UnescapeInternal(const char* src, size_t slen, std::string* dest, >+ const signed char* unbase64) { >+ // Determine the size of the output std::string. Base64 encodes every 3 bytes into >+ // 4 characters. any leftover chars are added directly for good measure. >+ // This is documented in the base64 RFC: http://tools.ietf.org/html/rfc3548 >+ const size_t dest_len = 3 * (slen / 4) + (slen % 4); >+ >+ strings_internal::STLStringResizeUninitialized(dest, dest_len); >+ >+ // We are getting the destination buffer by getting the beginning of the >+ // std::string and converting it into a char *. >+ size_t len; >+ const bool ok = >+ Base64UnescapeInternal(src, slen, &(*dest)[0], dest_len, unbase64, &len); >+ if (!ok) { >+ dest->clear(); >+ return false; >+ } >+ >+ // could be shorter if there was padding >+ assert(len <= dest_len); >+ dest->erase(len); >+ >+ return true; >+} >+ >+/* clang-format off */ >+constexpr char kHexValue[256] = { >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, // '0'..'9' >+ 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'A'..'F' >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'a'..'f' >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 >+}; >+/* clang-format on */ >+ >+// This is a templated function so that T can be either a char* >+// or a std::string. This works because we use the [] operator to access >+// individual characters at a time. >+template <typename T> >+void HexStringToBytesInternal(const char* from, T to, ptrdiff_t num) { >+ for (int i = 0; i < num; i++) { >+ to[i] = (kHexValue[from[i * 2] & 0xFF] << 4) + >+ (kHexValue[from[i * 2 + 1] & 0xFF]); >+ } >+} >+ >+// This is a templated function so that T can be either a char* or a std::string. >+template <typename T> >+void BytesToHexStringInternal(const unsigned char* src, T dest, ptrdiff_t num) { >+ auto dest_ptr = &dest[0]; >+ for (auto src_ptr = src; src_ptr != (src + num); ++src_ptr, dest_ptr += 2) { >+ const char* hex_p = &kHexTable[*src_ptr * 2]; >+ std::copy(hex_p, hex_p + 2, dest_ptr); >+ } >+} >+ >+} // namespace >+ >+// ---------------------------------------------------------------------- >+// CUnescape() >+// >+// See CUnescapeInternal() for implementation details. >+// ---------------------------------------------------------------------- >+bool CUnescape(absl::string_view source, std::string* dest, std::string* error) { >+ return CUnescapeInternal(source, kUnescapeNulls, dest, error); >+} >+ >+std::string CEscape(absl::string_view src) { >+ std::string dest; >+ CEscapeAndAppendInternal(src, &dest); >+ return dest; >+} >+ >+std::string CHexEscape(absl::string_view src) { >+ return CEscapeInternal(src, true, false); >+} >+ >+std::string Utf8SafeCEscape(absl::string_view src) { >+ return CEscapeInternal(src, false, true); >+} >+ >+std::string Utf8SafeCHexEscape(absl::string_view src) { >+ return CEscapeInternal(src, true, true); >+} >+ >+// ---------------------------------------------------------------------- >+// ptrdiff_t Base64Unescape() - base64 decoder >+// ptrdiff_t Base64Escape() - base64 encoder >+// ptrdiff_t WebSafeBase64Unescape() - Google's variation of base64 decoder >+// ptrdiff_t WebSafeBase64Escape() - Google's variation of base64 encoder >+// >+// Check out >+// http://tools.ietf.org/html/rfc2045 for formal description, but what we >+// care about is that... >+// Take the encoded stuff in groups of 4 characters and turn each >+// character into a code 0 to 63 thus: >+// A-Z map to 0 to 25 >+// a-z map to 26 to 51 >+// 0-9 map to 52 to 61 >+// +(- for WebSafe) maps to 62 >+// /(_ for WebSafe) maps to 63 >+// There will be four numbers, all less than 64 which can be represented >+// by a 6 digit binary number (aaaaaa, bbbbbb, cccccc, dddddd respectively). >+// Arrange the 6 digit binary numbers into three bytes as such: >+// aaaaaabb bbbbcccc ccdddddd >+// Equals signs (one or two) are used at the end of the encoded block to >+// indicate that the text was not an integer multiple of three bytes long. >+// ---------------------------------------------------------------------- >+ >+bool Base64Unescape(absl::string_view src, std::string* dest) { >+ return Base64UnescapeInternal(src.data(), src.size(), dest, kUnBase64); >+} >+ >+bool WebSafeBase64Unescape(absl::string_view src, std::string* dest) { >+ return Base64UnescapeInternal(src.data(), src.size(), dest, kUnWebSafeBase64); >+} >+ >+void Base64Escape(absl::string_view src, std::string* dest) { >+ Base64EscapeInternal(reinterpret_cast<const unsigned char*>(src.data()), >+ src.size(), dest, true, kBase64Chars); >+} >+ >+void WebSafeBase64Escape(absl::string_view src, std::string* dest) { >+ Base64EscapeInternal(reinterpret_cast<const unsigned char*>(src.data()), >+ src.size(), dest, false, kWebSafeBase64Chars); >+} >+ >+std::string HexStringToBytes(absl::string_view from) { >+ std::string result; >+ const auto num = from.size() / 2; >+ strings_internal::STLStringResizeUninitialized(&result, num); >+ absl::HexStringToBytesInternal<std::string&>(from.data(), result, num); >+ return result; >+} >+ >+std::string BytesToHexString(absl::string_view from) { >+ std::string result; >+ strings_internal::STLStringResizeUninitialized(&result, 2 * from.size()); >+ absl::BytesToHexStringInternal<std::string&>( >+ reinterpret_cast<const unsigned char*>(from.data()), result, from.size()); >+ return result; >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping.h >new file mode 100644 >index 0000000000000000000000000000000000000000..7f1ab96d8ff15d56042b4659d66148214705f0a5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping.h >@@ -0,0 +1,161 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: escaping.h >+// ----------------------------------------------------------------------------- >+// >+// This header file contains std::string utilities involved in escaping and >+// unescaping strings in various ways. >+// >+ >+#ifndef ABSL_STRINGS_ESCAPING_H_ >+#define ABSL_STRINGS_ESCAPING_H_ >+ >+#include <cstddef> >+#include <string> >+#include <vector> >+ >+#include "absl/base/macros.h" >+#include "absl/strings/ascii.h" >+#include "absl/strings/str_join.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+ >+// CUnescape() >+// >+// Unescapes a `source` std::string and copies it into `dest`, rewriting C-style >+// escape sequences (http://en.cppreference.com/w/cpp/language/escape) into >+// their proper code point equivalents, returning `true` if successful. >+// >+// The following unescape sequences can be handled: >+// >+// * ASCII escape sequences ('\n','\r','\\', etc.) to their ASCII equivalents >+// * Octal escape sequences ('\nnn') to byte nnn. The unescaped value must >+// resolve to a single byte or an error will occur. E.g. values greater than >+// 0xff will produce an error. >+// * Hexadecimal escape sequences ('\xnn') to byte nn. While an arbitrary >+// number of following digits are allowed, the unescaped value must resolve >+// to a single byte or an error will occur. E.g. '\x0045' is equivalent to >+// '\x45', but '\x1234' will produce an error. >+// * Unicode escape sequences ('\unnnn' for exactly four hex digits or >+// '\Unnnnnnnn' for exactly eight hex digits, which will be encoded in >+// UTF-8. (E.g., `\u2019` unescapes to the three bytes 0xE2, 0x80, and >+// 0x99). >+// >+// >+// If any errors are encountered, this function returns `false` and stores the >+// first encountered error in `error`. To disable error reporting, set `error` >+// to `nullptr` or use the overload with no error reporting below. >+// >+// Example: >+// >+// std::string s = "foo\\rbar\\nbaz\\t"; >+// std::string unescaped_s; >+// if (!absl::CUnescape(s, &unescaped_s) { >+// ... >+// } >+// EXPECT_EQ(unescaped_s, "foo\rbar\nbaz\t"); >+bool CUnescape(absl::string_view source, std::string* dest, std::string* error); >+ >+// Overload of `CUnescape()` with no error reporting. >+inline bool CUnescape(absl::string_view source, std::string* dest) { >+ return CUnescape(source, dest, nullptr); >+} >+ >+// CEscape() >+// >+// Escapes a 'src' std::string using C-style escapes sequences >+// (http://en.cppreference.com/w/cpp/language/escape), escaping other >+// non-printable/non-whitespace bytes as octal sequences (e.g. "\377"). >+// >+// Example: >+// >+// std::string s = "foo\rbar\tbaz\010\011\012\013\014\x0d\n"; >+// std::string escaped_s = absl::CEscape(s); >+// EXPECT_EQ(escaped_s, "foo\\rbar\\tbaz\\010\\t\\n\\013\\014\\r\\n"); >+std::string CEscape(absl::string_view src); >+ >+// CHexEscape() >+// >+// Escapes a 'src' std::string using C-style escape sequences, escaping >+// other non-printable/non-whitespace bytes as hexadecimal sequences (e.g. >+// "\xFF"). >+// >+// Example: >+// >+// std::string s = "foo\rbar\tbaz\010\011\012\013\014\x0d\n"; >+// std::string escaped_s = absl::CHexEscape(s); >+// EXPECT_EQ(escaped_s, "foo\\rbar\\tbaz\\x08\\t\\n\\x0b\\x0c\\r\\n"); >+std::string CHexEscape(absl::string_view src); >+ >+// Utf8SafeCEscape() >+// >+// Escapes a 'src' std::string using C-style escape sequences, escaping bytes as >+// octal sequences, and passing through UTF-8 characters without conversion. >+// I.e., when encountering any bytes with their high bit set, this function >+// will not escape those values, whether or not they are valid UTF-8. >+std::string Utf8SafeCEscape(absl::string_view src); >+ >+// Utf8SafeCHexEscape() >+// >+// Escapes a 'src' std::string using C-style escape sequences, escaping bytes as >+// hexadecimal sequences, and passing through UTF-8 characters without >+// conversion. >+std::string Utf8SafeCHexEscape(absl::string_view src); >+ >+// Base64Unescape() >+// >+// Converts a `src` std::string encoded in Base64 to its binary equivalent, writing >+// it to a `dest` buffer, returning `true` on success. If `src` contains invalid >+// characters, `dest` is cleared and returns `false`. >+bool Base64Unescape(absl::string_view src, std::string* dest); >+ >+// WebSafeBase64Unescape(absl::string_view, std::string*) >+// >+// Converts a `src` std::string encoded in Base64 to its binary equivalent, writing >+// it to a `dest` buffer, but using '-' instead of '+', and '_' instead of '/'. >+// If `src` contains invalid characters, `dest` is cleared and returns `false`. >+bool WebSafeBase64Unescape(absl::string_view src, std::string* dest); >+ >+// Base64Escape() >+// >+// Encodes a `src` std::string into a `dest` buffer using base64 encoding, with >+// padding characters. This function conforms with RFC 4648 section 4 (base64). >+void Base64Escape(absl::string_view src, std::string* dest); >+ >+// WebSafeBase64Escape() >+// >+// Encodes a `src` std::string into a `dest` buffer using '-' instead of '+' and >+// '_' instead of '/', and without padding. This function conforms with RFC 4648 >+// section 5 (base64url). >+void WebSafeBase64Escape(absl::string_view src, std::string* dest); >+ >+// HexStringToBytes() >+// >+// Converts an ASCII hex std::string into bytes, returning binary data of length >+// `from.size()/2`. >+std::string HexStringToBytes(absl::string_view from); >+ >+// BytesToHexString() >+// >+// Converts binary data into an ASCII text std::string, returning a std::string of size >+// `2*from.size()`. >+std::string BytesToHexString(absl::string_view from); >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_ESCAPING_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..0f791f4e87509a0c5955856b3538fcd368ae4a09 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping_benchmark.cc >@@ -0,0 +1,94 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/escaping.h" >+ >+#include <cstdio> >+#include <cstring> >+#include <random> >+ >+#include "benchmark/benchmark.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/strings/internal/escaping_test_common.h" >+ >+namespace { >+ >+void BM_CUnescapeHexString(benchmark::State& state) { >+ std::string src; >+ for (int i = 0; i < 50; i++) { >+ src += "\\x55"; >+ } >+ std::string dest; >+ for (auto _ : state) { >+ absl::CUnescape(src, &dest); >+ } >+} >+BENCHMARK(BM_CUnescapeHexString); >+ >+void BM_WebSafeBase64Escape_string(benchmark::State& state) { >+ std::string raw; >+ for (int i = 0; i < 10; ++i) { >+ for (const auto& test_set : absl::strings_internal::base64_strings()) { >+ raw += std::string(test_set.plaintext); >+ } >+ } >+ >+ // The actual benchmark loop is tiny... >+ std::string escaped; >+ for (auto _ : state) { >+ absl::WebSafeBase64Escape(raw, &escaped); >+ } >+ >+ // We want to be sure the compiler doesn't throw away the loop above, >+ // and the easiest way to ensure that is to round-trip the results and verify >+ // them. >+ std::string round_trip; >+ absl::WebSafeBase64Unescape(escaped, &round_trip); >+ ABSL_RAW_CHECK(round_trip == raw, ""); >+} >+BENCHMARK(BM_WebSafeBase64Escape_string); >+ >+// Used for the CEscape benchmarks >+const char kStringValueNoEscape[] = "1234567890"; >+const char kStringValueSomeEscaped[] = "123\n56789\xA1"; >+const char kStringValueMostEscaped[] = "\xA1\xA2\ny\xA4\xA5\xA6z\b\r"; >+ >+void CEscapeBenchmarkHelper(benchmark::State& state, const char* string_value, >+ int max_len) { >+ std::string src; >+ while (src.size() < max_len) { >+ absl::StrAppend(&src, string_value); >+ } >+ >+ for (auto _ : state) { >+ absl::CEscape(src); >+ } >+} >+ >+void BM_CEscape_NoEscape(benchmark::State& state) { >+ CEscapeBenchmarkHelper(state, kStringValueNoEscape, state.range(0)); >+} >+BENCHMARK(BM_CEscape_NoEscape)->Range(1, 1 << 14); >+ >+void BM_CEscape_SomeEscaped(benchmark::State& state) { >+ CEscapeBenchmarkHelper(state, kStringValueSomeEscaped, state.range(0)); >+} >+BENCHMARK(BM_CEscape_SomeEscaped)->Range(1, 1 << 14); >+ >+void BM_CEscape_MostEscaped(benchmark::State& state) { >+ CEscapeBenchmarkHelper(state, kStringValueMostEscaped, state.range(0)); >+} >+BENCHMARK(BM_CEscape_MostEscaped)->Range(1, 1 << 14); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..3f65ec107f4555c950ff777e89e93d23e43378e5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/escaping_test.cc >@@ -0,0 +1,641 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/escaping.h" >+ >+#include <array> >+#include <cstdio> >+#include <cstring> >+#include <memory> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/container/fixed_array.h" >+#include "absl/strings/str_cat.h" >+ >+#include "absl/strings/internal/escaping_test_common.h" >+ >+namespace { >+ >+struct epair { >+ std::string escaped; >+ std::string unescaped; >+}; >+ >+TEST(CEscape, EscapeAndUnescape) { >+ const std::string inputs[] = { >+ std::string("foo\nxx\r\b\0023"), >+ std::string(""), >+ std::string("abc"), >+ std::string("\1chad_rules"), >+ std::string("\1arnar_drools"), >+ std::string("xxxx\r\t'\"\\"), >+ std::string("\0xx\0", 4), >+ std::string("\x01\x31"), >+ std::string("abc\xb\x42\141bc"), >+ std::string("123\1\x31\x32\x33"), >+ std::string("\xc1\xca\x1b\x62\x19o\xcc\x04"), >+ std::string("\\\"\xe8\xb0\xb7\xe6\xad\x8c\\\" is Google\\\'s Chinese name"), >+ }; >+ // Do this twice, once for octal escapes and once for hex escapes. >+ for (int kind = 0; kind < 4; kind++) { >+ for (const std::string& original : inputs) { >+ std::string escaped; >+ switch (kind) { >+ case 0: >+ escaped = absl::CEscape(original); >+ break; >+ case 1: >+ escaped = absl::CHexEscape(original); >+ break; >+ case 2: >+ escaped = absl::Utf8SafeCEscape(original); >+ break; >+ case 3: >+ escaped = absl::Utf8SafeCHexEscape(original); >+ break; >+ } >+ std::string unescaped_str; >+ EXPECT_TRUE(absl::CUnescape(escaped, &unescaped_str)); >+ EXPECT_EQ(unescaped_str, original); >+ >+ // Check in-place unescaping >+ std::string s = escaped; >+ EXPECT_TRUE(absl::CUnescape(s, &s)); >+ ASSERT_EQ(s, original); >+ } >+ } >+ // Check that all possible two character strings can be escaped then >+ // unescaped successfully. >+ for (int char0 = 0; char0 < 256; char0++) { >+ for (int char1 = 0; char1 < 256; char1++) { >+ char chars[2]; >+ chars[0] = char0; >+ chars[1] = char1; >+ std::string s(chars, 2); >+ std::string escaped = absl::CHexEscape(s); >+ std::string unescaped; >+ EXPECT_TRUE(absl::CUnescape(escaped, &unescaped)); >+ EXPECT_EQ(s, unescaped); >+ } >+ } >+} >+ >+TEST(CEscape, BasicEscaping) { >+ epair oct_values[] = { >+ {"foo\\rbar\\nbaz\\t", "foo\rbar\nbaz\t"}, >+ {"\\'full of \\\"sound\\\" and \\\"fury\\\"\\'", >+ "'full of \"sound\" and \"fury\"'"}, >+ {"signi\\\\fying\\\\ nothing\\\\", "signi\\fying\\ nothing\\"}, >+ {"\\010\\t\\n\\013\\014\\r", "\010\011\012\013\014\015"} >+ }; >+ epair hex_values[] = { >+ {"ubik\\rubik\\nubik\\t", "ubik\rubik\nubik\t"}, >+ {"I\\\'ve just seen a \\\"face\\\"", >+ "I've just seen a \"face\""}, >+ {"hel\\\\ter\\\\skel\\\\ter\\\\", "hel\\ter\\skel\\ter\\"}, >+ {"\\x08\\t\\n\\x0b\\x0c\\r", "\010\011\012\013\014\015"} >+ }; >+ epair utf8_oct_values[] = { >+ {"\xe8\xb0\xb7\xe6\xad\x8c\\r\xe8\xb0\xb7\xe6\xad\x8c\\nbaz\\t", >+ "\xe8\xb0\xb7\xe6\xad\x8c\r\xe8\xb0\xb7\xe6\xad\x8c\nbaz\t"}, >+ {"\\\"\xe8\xb0\xb7\xe6\xad\x8c\\\" is Google\\\'s Chinese name", >+ "\"\xe8\xb0\xb7\xe6\xad\x8c\" is Google\'s Chinese name"}, >+ {"\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab\\\\are\\\\Japanese\\\\chars\\\\", >+ "\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab\\are\\Japanese\\chars\\"}, >+ {"\xed\x81\xac\xeb\xa1\xac\\010\\t\\n\\013\\014\\r", >+ "\xed\x81\xac\xeb\xa1\xac\010\011\012\013\014\015"} >+ }; >+ epair utf8_hex_values[] = { >+ {"\x20\xe4\xbd\xa0\\t\xe5\xa5\xbd,\\r!\\n", >+ "\x20\xe4\xbd\xa0\t\xe5\xa5\xbd,\r!\n"}, >+ {"\xe8\xa9\xa6\xe9\xa8\x93\\\' means \\\"test\\\"", >+ "\xe8\xa9\xa6\xe9\xa8\x93\' means \"test\""}, >+ {"\\\\\xe6\x88\x91\\\\:\\\\\xe6\x9d\xa8\xe6\xac\xa2\\\\", >+ "\\\xe6\x88\x91\\:\\\xe6\x9d\xa8\xe6\xac\xa2\\"}, >+ {"\xed\x81\xac\xeb\xa1\xac\\x08\\t\\n\\x0b\\x0c\\r", >+ "\xed\x81\xac\xeb\xa1\xac\010\011\012\013\014\015"} >+ }; >+ >+ for (const epair& val : oct_values) { >+ std::string escaped = absl::CEscape(val.unescaped); >+ EXPECT_EQ(escaped, val.escaped); >+ } >+ for (const epair& val : hex_values) { >+ std::string escaped = absl::CHexEscape(val.unescaped); >+ EXPECT_EQ(escaped, val.escaped); >+ } >+ for (const epair& val : utf8_oct_values) { >+ std::string escaped = absl::Utf8SafeCEscape(val.unescaped); >+ EXPECT_EQ(escaped, val.escaped); >+ } >+ for (const epair& val : utf8_hex_values) { >+ std::string escaped = absl::Utf8SafeCHexEscape(val.unescaped); >+ EXPECT_EQ(escaped, val.escaped); >+ } >+} >+ >+TEST(Unescape, BasicFunction) { >+ epair tests[] = >+ {{"\\u0030", "0"}, >+ {"\\u00A3", "\xC2\xA3"}, >+ {"\\u22FD", "\xE2\x8B\xBD"}, >+ {"\\U00010000", "\xF0\x90\x80\x80"}, >+ {"\\U0010FFFD", "\xF4\x8F\xBF\xBD"}}; >+ for (const epair& val : tests) { >+ std::string out; >+ EXPECT_TRUE(absl::CUnescape(val.escaped, &out)); >+ EXPECT_EQ(out, val.unescaped); >+ } >+ std::string bad[] = >+ {"\\u1", // too short >+ "\\U1", // too short >+ "\\Uffffff", // exceeds 0x10ffff (largest Unicode) >+ "\\U00110000", // exceeds 0x10ffff (largest Unicode) >+ "\\uD835", // surrogate character (D800-DFFF) >+ "\\U0000DD04", // surrogate character (D800-DFFF) >+ "\\777", // exceeds 0xff >+ "\\xABCD"}; // exceeds 0xff >+ for (const std::string& e : bad) { >+ std::string error; >+ std::string out; >+ EXPECT_FALSE(absl::CUnescape(e, &out, &error)); >+ EXPECT_FALSE(error.empty()); >+ } >+} >+ >+class CUnescapeTest : public testing::Test { >+ protected: >+ static const char kStringWithMultipleOctalNulls[]; >+ static const char kStringWithMultipleHexNulls[]; >+ static const char kStringWithMultipleUnicodeNulls[]; >+ >+ std::string result_string_; >+}; >+ >+const char CUnescapeTest::kStringWithMultipleOctalNulls[] = >+ "\\0\\n" // null escape \0 plus newline >+ "0\\n" // just a number 0 (not a null escape) plus newline >+ "\\00\\12" // null escape \00 plus octal newline code >+ "\\000"; // null escape \000 >+ >+// This has the same ingredients as kStringWithMultipleOctalNulls >+// but with \x hex escapes instead of octal escapes. >+const char CUnescapeTest::kStringWithMultipleHexNulls[] = >+ "\\x0\\n" >+ "0\\n" >+ "\\x00\\xa" >+ "\\x000"; >+ >+const char CUnescapeTest::kStringWithMultipleUnicodeNulls[] = >+ "\\u0000\\n" // short-form (4-digit) null escape plus newline >+ "0\\n" // just a number 0 (not a null escape) plus newline >+ "\\U00000000"; // long-form (8-digit) null escape >+ >+TEST_F(CUnescapeTest, Unescapes1CharOctalNull) { >+ std::string original_string = "\\0"; >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ EXPECT_EQ(std::string("\0", 1), result_string_); >+} >+ >+TEST_F(CUnescapeTest, Unescapes2CharOctalNull) { >+ std::string original_string = "\\00"; >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ EXPECT_EQ(std::string("\0", 1), result_string_); >+} >+ >+TEST_F(CUnescapeTest, Unescapes3CharOctalNull) { >+ std::string original_string = "\\000"; >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ EXPECT_EQ(std::string("\0", 1), result_string_); >+} >+ >+TEST_F(CUnescapeTest, Unescapes1CharHexNull) { >+ std::string original_string = "\\x0"; >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ EXPECT_EQ(std::string("\0", 1), result_string_); >+} >+ >+TEST_F(CUnescapeTest, Unescapes2CharHexNull) { >+ std::string original_string = "\\x00"; >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ EXPECT_EQ(std::string("\0", 1), result_string_); >+} >+ >+TEST_F(CUnescapeTest, Unescapes3CharHexNull) { >+ std::string original_string = "\\x000"; >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ EXPECT_EQ(std::string("\0", 1), result_string_); >+} >+ >+TEST_F(CUnescapeTest, Unescapes4CharUnicodeNull) { >+ std::string original_string = "\\u0000"; >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ EXPECT_EQ(std::string("\0", 1), result_string_); >+} >+ >+TEST_F(CUnescapeTest, Unescapes8CharUnicodeNull) { >+ std::string original_string = "\\U00000000"; >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ EXPECT_EQ(std::string("\0", 1), result_string_); >+} >+ >+TEST_F(CUnescapeTest, UnescapesMultipleOctalNulls) { >+ std::string original_string(kStringWithMultipleOctalNulls); >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ // All escapes, including newlines and null escapes, should have been >+ // converted to the equivalent characters. >+ EXPECT_EQ(std::string("\0\n" >+ "0\n" >+ "\0\n" >+ "\0", 7), result_string_); >+} >+ >+ >+TEST_F(CUnescapeTest, UnescapesMultipleHexNulls) { >+ std::string original_string(kStringWithMultipleHexNulls); >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ EXPECT_EQ(std::string("\0\n" >+ "0\n" >+ "\0\n" >+ "\0", 7), result_string_); >+} >+ >+TEST_F(CUnescapeTest, UnescapesMultipleUnicodeNulls) { >+ std::string original_string(kStringWithMultipleUnicodeNulls); >+ EXPECT_TRUE(absl::CUnescape(original_string, &result_string_)); >+ EXPECT_EQ(std::string("\0\n" >+ "0\n" >+ "\0", 5), result_string_); >+} >+ >+static struct { >+ absl::string_view plaintext; >+ absl::string_view cyphertext; >+} const base64_tests[] = { >+ // Empty std::string. >+ {{"", 0}, {"", 0}}, >+ {{nullptr, 0}, >+ {"", 0}}, // if length is zero, plaintext ptr must be ignored! >+ >+ // Basic bit patterns; >+ // values obtained with "echo -n '...' | uuencode -m test" >+ >+ {{"\000", 1}, "AA=="}, >+ {{"\001", 1}, "AQ=="}, >+ {{"\002", 1}, "Ag=="}, >+ {{"\004", 1}, "BA=="}, >+ {{"\010", 1}, "CA=="}, >+ {{"\020", 1}, "EA=="}, >+ {{"\040", 1}, "IA=="}, >+ {{"\100", 1}, "QA=="}, >+ {{"\200", 1}, "gA=="}, >+ >+ {{"\377", 1}, "/w=="}, >+ {{"\376", 1}, "/g=="}, >+ {{"\375", 1}, "/Q=="}, >+ {{"\373", 1}, "+w=="}, >+ {{"\367", 1}, "9w=="}, >+ {{"\357", 1}, "7w=="}, >+ {{"\337", 1}, "3w=="}, >+ {{"\277", 1}, "vw=="}, >+ {{"\177", 1}, "fw=="}, >+ {{"\000\000", 2}, "AAA="}, >+ {{"\000\001", 2}, "AAE="}, >+ {{"\000\002", 2}, "AAI="}, >+ {{"\000\004", 2}, "AAQ="}, >+ {{"\000\010", 2}, "AAg="}, >+ {{"\000\020", 2}, "ABA="}, >+ {{"\000\040", 2}, "ACA="}, >+ {{"\000\100", 2}, "AEA="}, >+ {{"\000\200", 2}, "AIA="}, >+ {{"\001\000", 2}, "AQA="}, >+ {{"\002\000", 2}, "AgA="}, >+ {{"\004\000", 2}, "BAA="}, >+ {{"\010\000", 2}, "CAA="}, >+ {{"\020\000", 2}, "EAA="}, >+ {{"\040\000", 2}, "IAA="}, >+ {{"\100\000", 2}, "QAA="}, >+ {{"\200\000", 2}, "gAA="}, >+ >+ {{"\377\377", 2}, "//8="}, >+ {{"\377\376", 2}, "//4="}, >+ {{"\377\375", 2}, "//0="}, >+ {{"\377\373", 2}, "//s="}, >+ {{"\377\367", 2}, "//c="}, >+ {{"\377\357", 2}, "/+8="}, >+ {{"\377\337", 2}, "/98="}, >+ {{"\377\277", 2}, "/78="}, >+ {{"\377\177", 2}, "/38="}, >+ {{"\376\377", 2}, "/v8="}, >+ {{"\375\377", 2}, "/f8="}, >+ {{"\373\377", 2}, "+/8="}, >+ {{"\367\377", 2}, "9/8="}, >+ {{"\357\377", 2}, "7/8="}, >+ {{"\337\377", 2}, "3/8="}, >+ {{"\277\377", 2}, "v/8="}, >+ {{"\177\377", 2}, "f/8="}, >+ >+ {{"\000\000\000", 3}, "AAAA"}, >+ {{"\000\000\001", 3}, "AAAB"}, >+ {{"\000\000\002", 3}, "AAAC"}, >+ {{"\000\000\004", 3}, "AAAE"}, >+ {{"\000\000\010", 3}, "AAAI"}, >+ {{"\000\000\020", 3}, "AAAQ"}, >+ {{"\000\000\040", 3}, "AAAg"}, >+ {{"\000\000\100", 3}, "AABA"}, >+ {{"\000\000\200", 3}, "AACA"}, >+ {{"\000\001\000", 3}, "AAEA"}, >+ {{"\000\002\000", 3}, "AAIA"}, >+ {{"\000\004\000", 3}, "AAQA"}, >+ {{"\000\010\000", 3}, "AAgA"}, >+ {{"\000\020\000", 3}, "ABAA"}, >+ {{"\000\040\000", 3}, "ACAA"}, >+ {{"\000\100\000", 3}, "AEAA"}, >+ {{"\000\200\000", 3}, "AIAA"}, >+ {{"\001\000\000", 3}, "AQAA"}, >+ {{"\002\000\000", 3}, "AgAA"}, >+ {{"\004\000\000", 3}, "BAAA"}, >+ {{"\010\000\000", 3}, "CAAA"}, >+ {{"\020\000\000", 3}, "EAAA"}, >+ {{"\040\000\000", 3}, "IAAA"}, >+ {{"\100\000\000", 3}, "QAAA"}, >+ {{"\200\000\000", 3}, "gAAA"}, >+ >+ {{"\377\377\377", 3}, "////"}, >+ {{"\377\377\376", 3}, "///+"}, >+ {{"\377\377\375", 3}, "///9"}, >+ {{"\377\377\373", 3}, "///7"}, >+ {{"\377\377\367", 3}, "///3"}, >+ {{"\377\377\357", 3}, "///v"}, >+ {{"\377\377\337", 3}, "///f"}, >+ {{"\377\377\277", 3}, "//+/"}, >+ {{"\377\377\177", 3}, "//9/"}, >+ {{"\377\376\377", 3}, "//7/"}, >+ {{"\377\375\377", 3}, "//3/"}, >+ {{"\377\373\377", 3}, "//v/"}, >+ {{"\377\367\377", 3}, "//f/"}, >+ {{"\377\357\377", 3}, "/+//"}, >+ {{"\377\337\377", 3}, "/9//"}, >+ {{"\377\277\377", 3}, "/7//"}, >+ {{"\377\177\377", 3}, "/3//"}, >+ {{"\376\377\377", 3}, "/v//"}, >+ {{"\375\377\377", 3}, "/f//"}, >+ {{"\373\377\377", 3}, "+///"}, >+ {{"\367\377\377", 3}, "9///"}, >+ {{"\357\377\377", 3}, "7///"}, >+ {{"\337\377\377", 3}, "3///"}, >+ {{"\277\377\377", 3}, "v///"}, >+ {{"\177\377\377", 3}, "f///"}, >+ >+ // Random numbers: values obtained with >+ // >+ // #! /bin/bash >+ // dd bs=$1 count=1 if=/dev/random of=/tmp/bar.random >+ // od -N $1 -t o1 /tmp/bar.random >+ // uuencode -m test < /tmp/bar.random >+ // >+ // where $1 is the number of bytes (2, 3) >+ >+ {{"\243\361", 2}, "o/E="}, >+ {{"\024\167", 2}, "FHc="}, >+ {{"\313\252", 2}, "y6o="}, >+ {{"\046\041", 2}, "JiE="}, >+ {{"\145\236", 2}, "ZZ4="}, >+ {{"\254\325", 2}, "rNU="}, >+ {{"\061\330", 2}, "Mdg="}, >+ {{"\245\032", 2}, "pRo="}, >+ {{"\006\000", 2}, "BgA="}, >+ {{"\375\131", 2}, "/Vk="}, >+ {{"\303\210", 2}, "w4g="}, >+ {{"\040\037", 2}, "IB8="}, >+ {{"\261\372", 2}, "sfo="}, >+ {{"\335\014", 2}, "3Qw="}, >+ {{"\233\217", 2}, "m48="}, >+ {{"\373\056", 2}, "+y4="}, >+ {{"\247\232", 2}, "p5o="}, >+ {{"\107\053", 2}, "Rys="}, >+ {{"\204\077", 2}, "hD8="}, >+ {{"\276\211", 2}, "vok="}, >+ {{"\313\110", 2}, "y0g="}, >+ {{"\363\376", 2}, "8/4="}, >+ {{"\251\234", 2}, "qZw="}, >+ {{"\103\262", 2}, "Q7I="}, >+ {{"\142\312", 2}, "Yso="}, >+ {{"\067\211", 2}, "N4k="}, >+ {{"\220\001", 2}, "kAE="}, >+ {{"\152\240", 2}, "aqA="}, >+ {{"\367\061", 2}, "9zE="}, >+ {{"\133\255", 2}, "W60="}, >+ {{"\176\035", 2}, "fh0="}, >+ {{"\032\231", 2}, "Gpk="}, >+ >+ {{"\013\007\144", 3}, "Cwdk"}, >+ {{"\030\112\106", 3}, "GEpG"}, >+ {{"\047\325\046", 3}, "J9Um"}, >+ {{"\310\160\022", 3}, "yHAS"}, >+ {{"\131\100\237", 3}, "WUCf"}, >+ {{"\064\342\134", 3}, "NOJc"}, >+ {{"\010\177\004", 3}, "CH8E"}, >+ {{"\345\147\205", 3}, "5WeF"}, >+ {{"\300\343\360", 3}, "wOPw"}, >+ {{"\061\240\201", 3}, "MaCB"}, >+ {{"\225\333\044", 3}, "ldsk"}, >+ {{"\215\137\352", 3}, "jV/q"}, >+ {{"\371\147\160", 3}, "+Wdw"}, >+ {{"\030\320\051", 3}, "GNAp"}, >+ {{"\044\174\241", 3}, "JHyh"}, >+ {{"\260\127\037", 3}, "sFcf"}, >+ {{"\111\045\033", 3}, "SSUb"}, >+ {{"\202\114\107", 3}, "gkxH"}, >+ {{"\057\371\042", 3}, "L/ki"}, >+ {{"\223\247\244", 3}, "k6ek"}, >+ {{"\047\216\144", 3}, "J45k"}, >+ {{"\203\070\327", 3}, "gzjX"}, >+ {{"\247\140\072", 3}, "p2A6"}, >+ {{"\124\115\116", 3}, "VE1O"}, >+ {{"\157\162\050", 3}, "b3Io"}, >+ {{"\357\223\004", 3}, "75ME"}, >+ {{"\052\117\156", 3}, "Kk9u"}, >+ {{"\347\154\000", 3}, "52wA"}, >+ {{"\303\012\142", 3}, "wwpi"}, >+ {{"\060\035\362", 3}, "MB3y"}, >+ {{"\130\226\361", 3}, "WJbx"}, >+ {{"\173\013\071", 3}, "ews5"}, >+ {{"\336\004\027", 3}, "3gQX"}, >+ {{"\357\366\234", 3}, "7/ac"}, >+ {{"\353\304\111", 3}, "68RJ"}, >+ {{"\024\264\131", 3}, "FLRZ"}, >+ {{"\075\114\251", 3}, "PUyp"}, >+ {{"\315\031\225", 3}, "zRmV"}, >+ {{"\154\201\276", 3}, "bIG+"}, >+ {{"\200\066\072", 3}, "gDY6"}, >+ {{"\142\350\267", 3}, "Yui3"}, >+ {{"\033\000\166", 3}, "GwB2"}, >+ {{"\210\055\077", 3}, "iC0/"}, >+ {{"\341\037\124", 3}, "4R9U"}, >+ {{"\161\103\152", 3}, "cUNq"}, >+ {{"\270\142\131", 3}, "uGJZ"}, >+ {{"\337\076\074", 3}, "3z48"}, >+ {{"\375\106\362", 3}, "/Uby"}, >+ {{"\227\301\127", 3}, "l8FX"}, >+ {{"\340\002\234", 3}, "4AKc"}, >+ {{"\121\064\033", 3}, "UTQb"}, >+ {{"\157\134\143", 3}, "b1xj"}, >+ {{"\247\055\327", 3}, "py3X"}, >+ {{"\340\142\005", 3}, "4GIF"}, >+ {{"\060\260\143", 3}, "MLBj"}, >+ {{"\075\203\170", 3}, "PYN4"}, >+ {{"\143\160\016", 3}, "Y3AO"}, >+ {{"\313\013\063", 3}, "ywsz"}, >+ {{"\174\236\135", 3}, "fJ5d"}, >+ {{"\103\047\026", 3}, "QycW"}, >+ {{"\365\005\343", 3}, "9QXj"}, >+ {{"\271\160\223", 3}, "uXCT"}, >+ {{"\362\255\172", 3}, "8q16"}, >+ {{"\113\012\015", 3}, "SwoN"}, >+ >+ // various lengths, generated by this python script: >+ // >+ // from std::string import lowercase as lc >+ // for i in range(27): >+ // print '{ %2d, "%s",%s "%s" },' % (i, lc[:i], ' ' * (26-i), >+ // lc[:i].encode('base64').strip()) >+ >+ {{"", 0}, {"", 0}}, >+ {"a", "YQ=="}, >+ {"ab", "YWI="}, >+ {"abc", "YWJj"}, >+ {"abcd", "YWJjZA=="}, >+ {"abcde", "YWJjZGU="}, >+ {"abcdef", "YWJjZGVm"}, >+ {"abcdefg", "YWJjZGVmZw=="}, >+ {"abcdefgh", "YWJjZGVmZ2g="}, >+ {"abcdefghi", "YWJjZGVmZ2hp"}, >+ {"abcdefghij", "YWJjZGVmZ2hpag=="}, >+ {"abcdefghijk", "YWJjZGVmZ2hpams="}, >+ {"abcdefghijkl", "YWJjZGVmZ2hpamts"}, >+ {"abcdefghijklm", "YWJjZGVmZ2hpamtsbQ=="}, >+ {"abcdefghijklmn", "YWJjZGVmZ2hpamtsbW4="}, >+ {"abcdefghijklmno", "YWJjZGVmZ2hpamtsbW5v"}, >+ {"abcdefghijklmnop", "YWJjZGVmZ2hpamtsbW5vcA=="}, >+ {"abcdefghijklmnopq", "YWJjZGVmZ2hpamtsbW5vcHE="}, >+ {"abcdefghijklmnopqr", "YWJjZGVmZ2hpamtsbW5vcHFy"}, >+ {"abcdefghijklmnopqrs", "YWJjZGVmZ2hpamtsbW5vcHFycw=="}, >+ {"abcdefghijklmnopqrst", "YWJjZGVmZ2hpamtsbW5vcHFyc3Q="}, >+ {"abcdefghijklmnopqrstu", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1"}, >+ {"abcdefghijklmnopqrstuv", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dg=="}, >+ {"abcdefghijklmnopqrstuvw", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnc="}, >+ {"abcdefghijklmnopqrstuvwx", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4"}, >+ {"abcdefghijklmnopqrstuvwxy", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eQ=="}, >+ {"abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="}, >+}; >+ >+TEST(Base64, EscapeAndUnescape) { >+ // Check the short strings; this tests the math (and boundaries) >+ for (const auto& tc : base64_tests) { >+ std::string encoded("this junk should be ignored"); >+ absl::Base64Escape(tc.plaintext, &encoded); >+ EXPECT_EQ(encoded, tc.cyphertext); >+ >+ std::string decoded("this junk should be ignored"); >+ EXPECT_TRUE(absl::Base64Unescape(encoded, &decoded)); >+ EXPECT_EQ(decoded, tc.plaintext); >+ >+ std::string websafe(tc.cyphertext); >+ for (int c = 0; c < websafe.size(); ++c) { >+ if ('+' == websafe[c]) websafe[c] = '-'; >+ if ('/' == websafe[c]) websafe[c] = '_'; >+ if ('=' == websafe[c]) { >+ websafe.resize(c); >+ break; >+ } >+ } >+ >+ encoded = "this junk should be ignored"; >+ absl::WebSafeBase64Escape(tc.plaintext, &encoded); >+ EXPECT_EQ(encoded, websafe); >+ >+ // Let's try the std::string version of the decoder >+ decoded = "this junk should be ignored"; >+ EXPECT_TRUE(absl::WebSafeBase64Unescape(websafe, &decoded)); >+ EXPECT_EQ(decoded, tc.plaintext); >+ } >+ >+ // Now try the long strings, this tests the streaming >+ for (const auto& tc : absl::strings_internal::base64_strings()) { >+ std::string buffer; >+ absl::WebSafeBase64Escape(tc.plaintext, &buffer); >+ EXPECT_EQ(tc.cyphertext, buffer); >+ } >+ >+ // Verify the behavior when decoding bad data >+ { >+ absl::string_view data_set[] = {"ab-/", absl::string_view("\0bcd", 4), >+ absl::string_view("abc.\0", 5)}; >+ for (absl::string_view bad_data : data_set) { >+ std::string buf; >+ EXPECT_FALSE(absl::Base64Unescape(bad_data, &buf)); >+ EXPECT_FALSE(absl::WebSafeBase64Unescape(bad_data, &buf)); >+ EXPECT_TRUE(buf.empty()); >+ } >+ } >+} >+ >+TEST(Base64, DISABLED_HugeData) { >+ const size_t kSize = size_t(3) * 1000 * 1000 * 1000; >+ static_assert(kSize % 3 == 0, "kSize must be divisible by 3"); >+ const std::string huge(kSize, 'x'); >+ >+ std::string escaped; >+ absl::Base64Escape(huge, &escaped); >+ >+ // Generates the std::string that should match a base64 encoded "xxx..." std::string. >+ // "xxx" in base64 is "eHh4". >+ std::string expected_encoding; >+ expected_encoding.reserve(kSize / 3 * 4); >+ for (size_t i = 0; i < kSize / 3; ++i) { >+ expected_encoding.append("eHh4"); >+ } >+ EXPECT_EQ(expected_encoding, escaped); >+ >+ std::string unescaped; >+ EXPECT_TRUE(absl::Base64Unescape(escaped, &unescaped)); >+ EXPECT_EQ(huge, unescaped); >+} >+ >+TEST(HexAndBack, HexStringToBytes_and_BytesToHexString) { >+ std::string hex_mixed = "0123456789abcdefABCDEF"; >+ std::string bytes_expected = "\x01\x23\x45\x67\x89\xab\xcd\xef\xAB\xCD\xEF"; >+ std::string hex_only_lower = "0123456789abcdefabcdef"; >+ >+ std::string bytes_result = absl::HexStringToBytes(hex_mixed); >+ EXPECT_EQ(bytes_expected, bytes_result); >+ >+ std::string prefix_valid = hex_mixed + "?"; >+ std::string prefix_valid_result = absl::HexStringToBytes( >+ absl::string_view(prefix_valid.data(), prefix_valid.size() - 1)); >+ EXPECT_EQ(bytes_expected, prefix_valid_result); >+ >+ std::string infix_valid = "?" + hex_mixed + "???"; >+ std::string infix_valid_result = absl::HexStringToBytes( >+ absl::string_view(infix_valid.data() + 1, hex_mixed.size())); >+ EXPECT_EQ(bytes_expected, infix_valid_result); >+ >+ std::string hex_result = absl::BytesToHexString(bytes_expected); >+ EXPECT_EQ(hex_only_lower, hex_result); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/bits.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/bits.h >new file mode 100644 >index 0000000000000000000000000000000000000000..901082ccddfca78457c746fbe22ee5709933bfaf >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/bits.h >@@ -0,0 +1,53 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_STRINGS_INTERNAL_BITS_H_ >+#define ABSL_STRINGS_INTERNAL_BITS_H_ >+ >+#include <cstdint> >+ >+#if defined(_MSC_VER) && defined(_M_X64) >+#include <intrin.h> >+#pragma intrinsic(_BitScanReverse64) >+#endif >+ >+namespace absl { >+namespace strings_internal { >+ >+// Returns the number of leading 0 bits in a 64-bit value. >+inline int CountLeadingZeros64(uint64_t n) { >+#if defined(__GNUC__) >+ static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int) >+ "__builtin_clzll does not take 64bit arg"); >+ return n == 0 ? 64 : __builtin_clzll(n); >+#elif defined(_MSC_VER) && defined(_M_X64) >+ unsigned long result; // NOLINT(runtime/int) >+ if (_BitScanReverse64(&result, n)) { >+ return 63 - result; >+ } >+ return 64; >+#else >+ 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\0"[n] + zeroes; >+#endif >+} >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_BITS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/char_map.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/char_map.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8d92963a4dea3dc11ca71232d0b3f088960d4d03 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/char_map.h >@@ -0,0 +1,154 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Character Map Class >+// >+// A fast, bit-vector map for 8-bit unsigned characters. >+// This class is useful for non-character purposes as well. >+ >+#ifndef ABSL_STRINGS_INTERNAL_CHAR_MAP_H_ >+#define ABSL_STRINGS_INTERNAL_CHAR_MAP_H_ >+ >+#include <cstddef> >+#include <cstdint> >+#include <cstring> >+ >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+class Charmap { >+ public: >+ constexpr Charmap() : m_() {} >+ >+ // Initializes with a given char*. Note that NUL is not treated as >+ // a terminator, but rather a char to be flicked. >+ Charmap(const char* str, int len) : m_() { >+ while (len--) SetChar(*str++); >+ } >+ >+ // Initializes with a given char*. NUL is treated as a terminator >+ // and will not be in the charmap. >+ explicit Charmap(const char* str) : m_() { >+ while (*str) SetChar(*str++); >+ } >+ >+ constexpr bool contains(unsigned char c) const { >+ return (m_[c / 64] >> (c % 64)) & 0x1; >+ } >+ >+ // Returns true if and only if a character exists in both maps. >+ bool IntersectsWith(const Charmap& c) const { >+ for (size_t i = 0; i < ABSL_ARRAYSIZE(m_); ++i) { >+ if ((m_[i] & c.m_[i]) != 0) return true; >+ } >+ return false; >+ } >+ >+ bool IsZero() const { >+ for (uint64_t c : m_) { >+ if (c != 0) return false; >+ } >+ return true; >+ } >+ >+ // Containing only a single specified char. >+ static constexpr Charmap Char(char x) { >+ return Charmap(CharMaskForWord(x, 0), CharMaskForWord(x, 1), >+ CharMaskForWord(x, 2), CharMaskForWord(x, 3)); >+ } >+ >+ // Containing all the chars in the C-std::string 's'. >+ // Note that this is expensively recursive because of the C++11 constexpr >+ // formulation. Use only in constexpr initializers. >+ static constexpr Charmap FromString(const char* s) { >+ return *s == 0 ? Charmap() : (Char(*s) | FromString(s + 1)); >+ } >+ >+ // Containing all the chars in the closed interval [lo,hi]. >+ static constexpr Charmap Range(char lo, char hi) { >+ return Charmap(RangeForWord(lo, hi, 0), RangeForWord(lo, hi, 1), >+ RangeForWord(lo, hi, 2), RangeForWord(lo, hi, 3)); >+ } >+ >+ friend constexpr Charmap operator&(const Charmap& a, const Charmap& b) { >+ return Charmap(a.m_[0] & b.m_[0], a.m_[1] & b.m_[1], a.m_[2] & b.m_[2], >+ a.m_[3] & b.m_[3]); >+ } >+ >+ friend constexpr Charmap operator|(const Charmap& a, const Charmap& b) { >+ return Charmap(a.m_[0] | b.m_[0], a.m_[1] | b.m_[1], a.m_[2] | b.m_[2], >+ a.m_[3] | b.m_[3]); >+ } >+ >+ friend constexpr Charmap operator~(const Charmap& a) { >+ return Charmap(~a.m_[0], ~a.m_[1], ~a.m_[2], ~a.m_[3]); >+ } >+ >+ private: >+ constexpr Charmap(uint64_t b0, uint64_t b1, uint64_t b2, uint64_t b3) >+ : m_{b0, b1, b2, b3} {} >+ >+ static constexpr uint64_t RangeForWord(unsigned char lo, unsigned char hi, >+ uint64_t word) { >+ return OpenRangeFromZeroForWord(hi + 1, word) & >+ ~OpenRangeFromZeroForWord(lo, word); >+ } >+ >+ // All the chars in the specified word of the range [0, upper). >+ static constexpr uint64_t OpenRangeFromZeroForWord(uint64_t upper, >+ uint64_t word) { >+ return (upper <= 64 * word) >+ ? 0 >+ : (upper >= 64 * (word + 1)) >+ ? ~static_cast<uint64_t>(0) >+ : (~static_cast<uint64_t>(0) >> (64 - upper % 64)); >+ } >+ >+ static constexpr uint64_t CharMaskForWord(unsigned char x, uint64_t word) { >+ return (x / 64 == word) ? (static_cast<uint64_t>(1) << (x % 64)) : 0; >+ } >+ >+ private: >+ void SetChar(unsigned char c) { >+ m_[c / 64] |= static_cast<uint64_t>(1) << (c % 64); >+ } >+ >+ uint64_t m_[4]; >+}; >+ >+// Mirror the char-classifying predicates in <cctype> >+constexpr Charmap UpperCharmap() { return Charmap::Range('A', 'Z'); } >+constexpr Charmap LowerCharmap() { return Charmap::Range('a', 'z'); } >+constexpr Charmap DigitCharmap() { return Charmap::Range('0', '9'); } >+constexpr Charmap AlphaCharmap() { return LowerCharmap() | UpperCharmap(); } >+constexpr Charmap AlnumCharmap() { return DigitCharmap() | AlphaCharmap(); } >+constexpr Charmap XDigitCharmap() { >+ return DigitCharmap() | Charmap::Range('A', 'F') | Charmap::Range('a', 'f'); >+} >+constexpr Charmap PrintCharmap() { return Charmap::Range(0x20, 0x7e); } >+constexpr Charmap SpaceCharmap() { return Charmap::FromString("\t\n\v\f\r "); } >+constexpr Charmap CntrlCharmap() { >+ return Charmap::Range(0, 0x7f) & ~PrintCharmap(); >+} >+constexpr Charmap BlankCharmap() { return Charmap::FromString("\t "); } >+constexpr Charmap GraphCharmap() { return PrintCharmap() & ~SpaceCharmap(); } >+constexpr Charmap PunctCharmap() { return GraphCharmap() & ~AlnumCharmap(); } >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_CHAR_MAP_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/char_map_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/char_map_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..c45f3157c2917926d72ab888120d5a577ebfaf8a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/char_map_benchmark.cc >@@ -0,0 +1,61 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/char_map.h" >+ >+#include <cstdint> >+ >+#include "benchmark/benchmark.h" >+ >+namespace { >+ >+absl::strings_internal::Charmap MakeBenchmarkMap() { >+ absl::strings_internal::Charmap m; >+ uint32_t x[] = {0x0, 0x1, 0x2, 0x3, 0xf, 0xe, 0xd, 0xc}; >+ for (uint32_t& t : x) t *= static_cast<uint32_t>(0x11111111UL); >+ for (uint32_t i = 0; i < 256; ++i) { >+ if ((x[i / 32] >> (i % 32)) & 1) >+ m = m | absl::strings_internal::Charmap::Char(i); >+ } >+ return m; >+} >+ >+// Micro-benchmark for Charmap::contains. >+void BM_Contains(benchmark::State& state) { >+ // Loop-body replicated 10 times to increase time per iteration. >+ // Argument continuously changed to avoid generating common subexpressions. >+ const absl::strings_internal::Charmap benchmark_map = MakeBenchmarkMap(); >+ unsigned char c = 0; >+ int ops = 0; >+ for (auto _ : state) { >+ ops += benchmark_map.contains(c++); >+ ops += benchmark_map.contains(c++); >+ ops += benchmark_map.contains(c++); >+ ops += benchmark_map.contains(c++); >+ ops += benchmark_map.contains(c++); >+ ops += benchmark_map.contains(c++); >+ ops += benchmark_map.contains(c++); >+ ops += benchmark_map.contains(c++); >+ ops += benchmark_map.contains(c++); >+ ops += benchmark_map.contains(c++); >+ } >+ benchmark::DoNotOptimize(ops); >+} >+BENCHMARK(BM_Contains); >+ >+// We don't bother benchmarking Charmap::IsZero or Charmap::IntersectsWith; >+// their running time is data-dependent and it is not worth characterizing >+// "typical" data. >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/char_map_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/char_map_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..c3601e101e2a936ff57a2fae980cf4f800bf8c4c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/char_map_test.cc >@@ -0,0 +1,172 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/char_map.h" >+ >+#include <cctype> >+#include <string> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+ >+namespace { >+ >+constexpr absl::strings_internal::Charmap everything_map = >+ ~absl::strings_internal::Charmap(); >+constexpr absl::strings_internal::Charmap nothing_map{}; >+ >+TEST(Charmap, AllTests) { >+ const absl::strings_internal::Charmap also_nothing_map("", 0); >+ ASSERT_TRUE(everything_map.contains('\0')); >+ ASSERT_TRUE(!nothing_map.contains('\0')); >+ ASSERT_TRUE(!also_nothing_map.contains('\0')); >+ for (unsigned char ch = 1; ch != 0; ++ch) { >+ ASSERT_TRUE(everything_map.contains(ch)); >+ ASSERT_TRUE(!nothing_map.contains(ch)); >+ ASSERT_TRUE(!also_nothing_map.contains(ch)); >+ } >+ >+ const absl::strings_internal::Charmap symbols("&@#@^!@?", 5); >+ ASSERT_TRUE(symbols.contains('&')); >+ ASSERT_TRUE(symbols.contains('@')); >+ ASSERT_TRUE(symbols.contains('#')); >+ ASSERT_TRUE(symbols.contains('^')); >+ ASSERT_TRUE(!symbols.contains('!')); >+ ASSERT_TRUE(!symbols.contains('?')); >+ int cnt = 0; >+ for (unsigned char ch = 1; ch != 0; ++ch) >+ cnt += symbols.contains(ch); >+ ASSERT_EQ(cnt, 4); >+ >+ const absl::strings_internal::Charmap lets("^abcde", 3); >+ const absl::strings_internal::Charmap lets2("fghij\0klmnop", 10); >+ const absl::strings_internal::Charmap lets3("fghij\0klmnop"); >+ ASSERT_TRUE(lets2.contains('k')); >+ ASSERT_TRUE(!lets3.contains('k')); >+ >+ ASSERT_TRUE(symbols.IntersectsWith(lets)); >+ ASSERT_TRUE(!lets2.IntersectsWith(lets)); >+ ASSERT_TRUE(lets.IntersectsWith(symbols)); >+ ASSERT_TRUE(!lets.IntersectsWith(lets2)); >+ >+ ASSERT_TRUE(nothing_map.IsZero()); >+ ASSERT_TRUE(!lets.IsZero()); >+} >+ >+namespace { >+std::string Members(const absl::strings_internal::Charmap& m) { >+ std::string r; >+ for (size_t i = 0; i < 256; ++i) >+ if (m.contains(i)) r.push_back(i); >+ return r; >+} >+ >+std::string ClosedRangeString(unsigned char lo, unsigned char hi) { >+ // Don't depend on lo<hi. Just increment until lo==hi. >+ std::string s; >+ while (true) { >+ s.push_back(lo); >+ if (lo == hi) break; >+ ++lo; >+ } >+ return s; >+} >+ >+} // namespace >+ >+TEST(Charmap, Constexpr) { >+ constexpr absl::strings_internal::Charmap kEmpty = nothing_map; >+ EXPECT_THAT(Members(kEmpty), ""); >+ constexpr absl::strings_internal::Charmap kA = >+ absl::strings_internal::Charmap::Char('A'); >+ EXPECT_THAT(Members(kA), "A"); >+ constexpr absl::strings_internal::Charmap kAZ = >+ absl::strings_internal::Charmap::Range('A', 'Z'); >+ EXPECT_THAT(Members(kAZ), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); >+ constexpr absl::strings_internal::Charmap kIdentifier = >+ absl::strings_internal::Charmap::Range('0', '9') | >+ absl::strings_internal::Charmap::Range('A', 'Z') | >+ absl::strings_internal::Charmap::Range('a', 'z') | >+ absl::strings_internal::Charmap::Char('_'); >+ EXPECT_THAT(Members(kIdentifier), >+ "0123456789" >+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >+ "_" >+ "abcdefghijklmnopqrstuvwxyz"); >+ constexpr absl::strings_internal::Charmap kAll = everything_map; >+ for (size_t i = 0; i < 256; ++i) { >+ EXPECT_TRUE(kAll.contains(i)) << i; >+ } >+ constexpr absl::strings_internal::Charmap kHello = >+ absl::strings_internal::Charmap::FromString("Hello, world!"); >+ EXPECT_THAT(Members(kHello), " !,Hdelorw"); >+ >+ // test negation and intersection >+ constexpr absl::strings_internal::Charmap kABC = >+ absl::strings_internal::Charmap::Range('A', 'Z') & >+ ~absl::strings_internal::Charmap::Range('D', 'Z'); >+ EXPECT_THAT(Members(kABC), "ABC"); >+} >+ >+TEST(Charmap, Range) { >+ // Exhaustive testing takes too long, so test some of the boundaries that >+ // are perhaps going to cause trouble. >+ std::vector<size_t> poi = {0, 1, 2, 3, 4, 7, 8, 9, 15, >+ 16, 17, 30, 31, 32, 33, 63, 64, 65, >+ 127, 128, 129, 223, 224, 225, 254, 255}; >+ for (auto lo = poi.begin(); lo != poi.end(); ++lo) { >+ SCOPED_TRACE(*lo); >+ for (auto hi = lo; hi != poi.end(); ++hi) { >+ SCOPED_TRACE(*hi); >+ EXPECT_THAT(Members(absl::strings_internal::Charmap::Range(*lo, *hi)), >+ ClosedRangeString(*lo, *hi)); >+ } >+ } >+} >+ >+bool AsBool(int x) { return static_cast<bool>(x); } >+ >+TEST(CharmapCtype, Match) { >+ for (int c = 0; c < 256; ++c) { >+ SCOPED_TRACE(c); >+ SCOPED_TRACE(static_cast<char>(c)); >+ EXPECT_EQ(AsBool(std::isupper(c)), >+ absl::strings_internal::UpperCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::islower(c)), >+ absl::strings_internal::LowerCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::isdigit(c)), >+ absl::strings_internal::DigitCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::isalpha(c)), >+ absl::strings_internal::AlphaCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::isalnum(c)), >+ absl::strings_internal::AlnumCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::isxdigit(c)), >+ absl::strings_internal::XDigitCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::isprint(c)), >+ absl::strings_internal::PrintCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::isspace(c)), >+ absl::strings_internal::SpaceCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::iscntrl(c)), >+ absl::strings_internal::CntrlCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::isblank(c)), >+ absl::strings_internal::BlankCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::isgraph(c)), >+ absl::strings_internal::GraphCharmap().contains(c)); >+ EXPECT_EQ(AsBool(std::ispunct(c)), >+ absl::strings_internal::PunctCharmap().contains(c)); >+ } >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..3e7296e7068a54b13e03016dd4e3a261af78e048 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc >@@ -0,0 +1,357 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/charconv_bigint.h" >+ >+#include <algorithm> >+#include <cassert> >+#include <string> >+ >+namespace absl { >+namespace strings_internal { >+ >+namespace { >+ >+// Table containing some large powers of 5, for fast computation. >+ >+// Constant step size for entries in the kLargePowersOfFive table. Each entry >+// is larger than the previous entry by a factor of 5**kLargePowerOfFiveStep >+// (or 5**27). >+// >+// In other words, the Nth entry in the table is 5**(27*N). >+// >+// 5**27 is the largest power of 5 that fits in 64 bits. >+constexpr int kLargePowerOfFiveStep = 27; >+ >+// The largest legal index into the kLargePowersOfFive table. >+// >+// In other words, the largest precomputed power of 5 is 5**(27*20). >+constexpr int kLargestPowerOfFiveIndex = 20; >+ >+// Table of powers of (5**27), up to (5**27)**20 == 5**540. >+// >+// Used to generate large powers of 5 while limiting the number of repeated >+// multiplications required. >+// >+// clang-format off >+const uint32_t kLargePowersOfFive[] = { >+// 5**27 (i=1), start=0, end=2 >+ 0xfa10079dU, 0x6765c793U, >+// 5**54 (i=2), start=2, end=6 >+ 0x97d9f649U, 0x6664242dU, 0x29939b14U, 0x29c30f10U, >+// 5**81 (i=3), start=6, end=12 >+ 0xc4f809c5U, 0x7bf3f22aU, 0x67bdae34U, 0xad340517U, 0x369d1b5fU, 0x10de1593U, >+// 5**108 (i=4), start=12, end=20 >+ 0x92b260d1U, 0x9efff7c7U, 0x81de0ec6U, 0xaeba5d56U, 0x410664a4U, 0x4f40737aU, >+ 0x20d3846fU, 0x06d00f73U, >+// 5**135 (i=5), start=20, end=30 >+ 0xff1b172dU, 0x13a1d71cU, 0xefa07617U, 0x7f682d3dU, 0xff8c90c0U, 0x3f0131e7U, >+ 0x3fdcb9feU, 0x917b0177U, 0x16c407a7U, 0x02c06b9dU, >+// 5**162 (i=6), start=30, end=42 >+ 0x960f7199U, 0x056667ecU, 0xe07aefd8U, 0x80f2b9ccU, 0x8273f5e3U, 0xeb9a214aU, >+ 0x40b38005U, 0x0e477ad4U, 0x277d08e6U, 0xfa28b11eU, 0xd3f7d784U, 0x011c835bU, >+// 5**189 (i=7), start=42, end=56 >+ 0xf723d9d5U, 0x3282d3f3U, 0xe00857d1U, 0x69659d25U, 0x2cf117cfU, 0x24da6d07U, >+ 0x954d1417U, 0x3e5d8cedU, 0x7a8bb766U, 0xfd785ae6U, 0x645436d2U, 0x40c78b34U, >+ 0x94151217U, 0x0072e9f7U, >+// 5**216 (i=8), start=56, end=72 >+ 0x2b416aa1U, 0x7893c5a7U, 0xe37dc6d4U, 0x2bad2beaU, 0xf0fc846cU, 0x7575ae4bU, >+ 0x62587b14U, 0x83b67a34U, 0x02110cdbU, 0xf7992f55U, 0x00deb022U, 0xa4a23becU, >+ 0x8af5c5cdU, 0xb85b654fU, 0x818df38bU, 0x002e69d2U, >+// 5**243 (i=9), start=72, end=90 >+ 0x3518cbbdU, 0x20b0c15fU, 0x38756c2fU, 0xfb5dc3ddU, 0x22ad2d94U, 0xbf35a952U, >+ 0xa699192aU, 0x9a613326U, 0xad2a9cedU, 0xd7f48968U, 0xe87dfb54U, 0xc8f05db6U, >+ 0x5ef67531U, 0x31c1ab49U, 0xe202ac9fU, 0x9b2957b5U, 0xa143f6d3U, 0x0012bf07U, >+// 5**270 (i=10), start=90, end=110 >+ 0x8b971de9U, 0x21aba2e1U, 0x63944362U, 0x57172336U, 0xd9544225U, 0xfb534166U, >+ 0x08c563eeU, 0x14640ee2U, 0x24e40d31U, 0x02b06537U, 0x03887f14U, 0x0285e533U, >+ 0xb744ef26U, 0x8be3a6c4U, 0x266979b4U, 0x6761ece2U, 0xd9cb39e4U, 0xe67de319U, >+ 0x0d39e796U, 0x00079250U, >+// 5**297 (i=11), start=110, end=132 >+ 0x260eb6e5U, 0xf414a796U, 0xee1a7491U, 0xdb9368ebU, 0xf50c105bU, 0x59157750U, >+ 0x9ed2fb5cU, 0xf6e56d8bU, 0xeaee8d23U, 0x0f319f75U, 0x2aa134d6U, 0xac2908e9U, >+ 0xd4413298U, 0x02f02a55U, 0x989d5a7aU, 0x70dde184U, 0xba8040a7U, 0x03200981U, >+ 0xbe03b11cU, 0x3c1c2a18U, 0xd60427a1U, 0x00030ee0U, >+// 5**324 (i=12), start=132, end=156 >+ 0xce566d71U, 0xf1c4aa25U, 0x4e93ca53U, 0xa72283d0U, 0x551a73eaU, 0x3d0538e2U, >+ 0x8da4303fU, 0x6a58de60U, 0x0e660221U, 0x49cf61a6U, 0x8d058fc1U, 0xb9d1a14cU, >+ 0x4bab157dU, 0xc85c6932U, 0x518c8b9eU, 0x9b92b8d0U, 0x0d8a0e21U, 0xbd855df9U, >+ 0xb3ea59a1U, 0x8da29289U, 0x4584d506U, 0x3752d80fU, 0xb72569c6U, 0x00013c33U, >+// 5**351 (i=13), start=156, end=182 >+ 0x190f354dU, 0x83695cfeU, 0xe5a4d0c7U, 0xb60fb7e8U, 0xee5bbcc4U, 0xb922054cU, >+ 0xbb4f0d85U, 0x48394028U, 0x1d8957dbU, 0x0d7edb14U, 0x4ecc7587U, 0x505e9e02U, >+ 0x4c87f36bU, 0x99e66bd6U, 0x44b9ed35U, 0x753037d4U, 0xe5fe5f27U, 0x2742c203U, >+ 0x13b2ed2bU, 0xdc525d2cU, 0xe6fde59aU, 0x77ffb18fU, 0x13c5752cU, 0x08a84bccU, >+ 0x859a4940U, 0x00007fb6U, >+// 5**378 (i=14), start=182, end=210 >+ 0x4f98cb39U, 0xa60edbbcU, 0x83b5872eU, 0xa501acffU, 0x9cc76f78U, 0xbadd4c73U, >+ 0x43e989faU, 0xca7acf80U, 0x2e0c824fU, 0xb19f4ffcU, 0x092fd81cU, 0xe4eb645bU, >+ 0xa1ff84c2U, 0x8a5a83baU, 0xa8a1fae9U, 0x1db43609U, 0xb0fed50bU, 0x0dd7d2bdU, >+ 0x7d7accd8U, 0x91fa640fU, 0x37dcc6c5U, 0x1c417fd5U, 0xe4d462adU, 0xe8a43399U, >+ 0x131bf9a5U, 0x8df54d29U, 0x36547dc1U, 0x00003395U, >+// 5**405 (i=15), start=210, end=240 >+ 0x5bd330f5U, 0x77d21967U, 0x1ac481b7U, 0x6be2f7ceU, 0x7f4792a9U, 0xe84c2c52U, >+ 0x84592228U, 0x9dcaf829U, 0xdab44ce1U, 0x3d0c311bU, 0x532e297dU, 0x4704e8b4U, >+ 0x9cdc32beU, 0x41e64d9dU, 0x7717bea1U, 0xa824c00dU, 0x08f50b27U, 0x0f198d77U, >+ 0x49bbfdf0U, 0x025c6c69U, 0xd4e55cd3U, 0xf083602bU, 0xb9f0fecdU, 0xc0864aeaU, >+ 0x9cb98681U, 0xaaf620e9U, 0xacb6df30U, 0x4faafe66U, 0x8af13c3bU, 0x000014d5U, >+// 5**432 (i=16), start=240, end=272 >+ 0x682bb941U, 0x89a9f297U, 0xcba75d7bU, 0x404217b1U, 0xb4e519e9U, 0xa1bc162bU, >+ 0xf7f5910aU, 0x98715af5U, 0x2ff53e57U, 0xe3ef118cU, 0x490c4543U, 0xbc9b1734U, >+ 0x2affbe4dU, 0x4cedcb4cU, 0xfb14e99eU, 0x35e34212U, 0xece39c24U, 0x07673ab3U, >+ 0xe73115ddU, 0xd15d38e7U, 0x093eed3bU, 0xf8e7eac5U, 0x78a8cc80U, 0x25227aacU, >+ 0x3f590551U, 0x413da1cbU, 0xdf643a55U, 0xab65ad44U, 0xd70b23d7U, 0xc672cd76U, >+ 0x3364ea62U, 0x0000086aU, >+// 5**459 (i=17), start=272, end=306 >+ 0x22f163ddU, 0x23cf07acU, 0xbe2af6c2U, 0xf412f6f6U, 0xc3ff541eU, 0x6eeaf7deU, >+ 0xa47047e0U, 0x408cda92U, 0x0f0eeb08U, 0x56deba9dU, 0xcfc6b090U, 0x8bbbdf04U, >+ 0x3933cdb3U, 0x9e7bb67dU, 0x9f297035U, 0x38946244U, 0xee1d37bbU, 0xde898174U, >+ 0x63f3559dU, 0x705b72fbU, 0x138d27d9U, 0xf8603a78U, 0x735eec44U, 0xe30987d5U, >+ 0xc6d38070U, 0x9cfe548eU, 0x9ff01422U, 0x7c564aa8U, 0x91cc60baU, 0xcbc3565dU, >+ 0x7550a50bU, 0x6909aeadU, 0x13234c45U, 0x00000366U, >+// 5**486 (i=18), start=306, end=342 >+ 0x17954989U, 0x3a7d7709U, 0x98042de5U, 0xa9011443U, 0x45e723c2U, 0x269ffd6fU, >+ 0x58852a46U, 0xaaa1042aU, 0x2eee8153U, 0xb2b6c39eU, 0xaf845b65U, 0xf6c365d7U, >+ 0xe4cffb2bU, 0xc840e90cU, 0xabea8abbU, 0x5c58f8d2U, 0x5c19fa3aU, 0x4670910aU, >+ 0x4449f21cU, 0xefa645b3U, 0xcc427decU, 0x083c3d73U, 0x467cb413U, 0x6fe10ae4U, >+ 0x3caffc72U, 0x9f8da55eU, 0x5e5c8ea7U, 0x490594bbU, 0xf0871b0bU, 0xdd89816cU, >+ 0x8e931df8U, 0xe85ce1c9U, 0xcca090a5U, 0x575fa16bU, 0x6b9f106cU, 0x0000015fU, >+// 5**513 (i=19), start=342, end=380 >+ 0xee20d805U, 0x57bc3c07U, 0xcdea624eU, 0xd3f0f52dU, 0x9924b4f4U, 0xcf968640U, >+ 0x61d41962U, 0xe87fb464U, 0xeaaf51c7U, 0x564c8b60U, 0xccda4028U, 0x529428bbU, >+ 0x313a1fa8U, 0x96bd0f94U, 0x7a82ebaaU, 0xad99e7e9U, 0xf2668cd4U, 0xbe33a45eU, >+ 0xfd0db669U, 0x87ee369fU, 0xd3ec20edU, 0x9c4d7db7U, 0xdedcf0d8U, 0x7cd2ca64U, >+ 0xe25a6577U, 0x61003fd4U, 0xe56f54ccU, 0x10b7c748U, 0x40526e5eU, 0x7300ae87U, >+ 0x5c439261U, 0x2c0ff469U, 0xbf723f12U, 0xb2379b61U, 0xbf59b4f5U, 0xc91b1c3fU, >+ 0xf0046d27U, 0x0000008dU, >+// 5**540 (i=20), start=380, end=420 >+ 0x525c9e11U, 0xf4e0eb41U, 0xebb2895dU, 0x5da512f9U, 0x7d9b29d4U, 0x452f4edcU, >+ 0x0b90bc37U, 0x341777cbU, 0x63d269afU, 0x1da77929U, 0x0a5c1826U, 0x77991898U, >+ 0x5aeddf86U, 0xf853a877U, 0x538c31ccU, 0xe84896daU, 0xb7a0010bU, 0x17ef4de5U, >+ 0xa52a2adeU, 0x029fd81cU, 0x987ce701U, 0x27fefd77U, 0xdb46c66fU, 0x5d301900U, >+ 0x496998c0U, 0xbb6598b9U, 0x5eebb607U, 0xe547354aU, 0xdf4a2f7eU, 0xf06c4955U, >+ 0x96242ffaU, 0x1775fb27U, 0xbecc58ceU, 0xebf2a53bU, 0x3eaad82aU, 0xf41137baU, >+ 0x573e6fbaU, 0xfb4866b8U, 0x54002148U, 0x00000039U, >+}; >+// clang-format on >+ >+// Returns a pointer to the big integer data for (5**27)**i. i must be >+// between 1 and 20, inclusive. >+const uint32_t* LargePowerOfFiveData(int i) { >+ return kLargePowersOfFive + i * (i - 1); >+} >+ >+// Returns the size of the big integer data for (5**27)**i, in words. i must be >+// between 1 and 20, inclusive. >+int LargePowerOfFiveSize(int i) { return 2 * i; } >+} // namespace >+ >+const uint32_t kFiveToNth[14] = { >+ 1, 5, 25, 125, 625, 3125, 15625, >+ 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125, >+}; >+ >+const uint32_t kTenToNth[10] = { >+ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, >+}; >+ >+template <int max_words> >+int BigUnsigned<max_words>::ReadFloatMantissa(const ParsedFloat& fp, >+ int significant_digits) { >+ SetToZero(); >+ assert(fp.type == FloatType::kNumber); >+ >+ if (fp.subrange_begin == nullptr) { >+ // We already exactly parsed the mantissa, so no more work is necessary. >+ words_[0] = fp.mantissa & 0xffffffffu; >+ words_[1] = fp.mantissa >> 32; >+ if (words_[1]) { >+ size_ = 2; >+ } else if (words_[0]) { >+ size_ = 1; >+ } >+ return fp.exponent; >+ } >+ int exponent_adjust = >+ ReadDigits(fp.subrange_begin, fp.subrange_end, significant_digits); >+ return fp.literal_exponent + exponent_adjust; >+} >+ >+template <int max_words> >+int BigUnsigned<max_words>::ReadDigits(const char* begin, const char* end, >+ int significant_digits) { >+ assert(significant_digits <= Digits10() + 1); >+ SetToZero(); >+ >+ bool after_decimal_point = false; >+ // Discard any leading zeroes before the decimal point >+ while (begin < end && *begin == '0') { >+ ++begin; >+ } >+ int dropped_digits = 0; >+ // Discard any trailing zeroes. These may or may not be after the decimal >+ // point. >+ while (begin < end && *std::prev(end) == '0') { >+ --end; >+ ++dropped_digits; >+ } >+ if (begin < end && *std::prev(end) == '.') { >+ // If the std::string ends in '.', either before or after dropping zeroes, then >+ // drop the decimal point and look for more digits to drop. >+ dropped_digits = 0; >+ --end; >+ while (begin < end && *std::prev(end) == '0') { >+ --end; >+ ++dropped_digits; >+ } >+ } else if (dropped_digits) { >+ // We dropped digits, and aren't sure if they're before or after the decimal >+ // point. Figure that out now. >+ const char* dp = std::find(begin, end, '.'); >+ if (dp != end) { >+ // The dropped trailing digits were after the decimal point, so don't >+ // count them. >+ dropped_digits = 0; >+ } >+ } >+ // Any non-fraction digits we dropped need to be accounted for in our exponent >+ // adjustment. >+ int exponent_adjust = dropped_digits; >+ >+ uint32_t queued = 0; >+ int digits_queued = 0; >+ for (; begin != end && significant_digits > 0; ++begin) { >+ if (*begin == '.') { >+ after_decimal_point = true; >+ continue; >+ } >+ if (after_decimal_point) { >+ // For each fractional digit we emit in our parsed integer, adjust our >+ // decimal exponent to compensate. >+ --exponent_adjust; >+ } >+ int digit = (*begin - '0'); >+ --significant_digits; >+ if (significant_digits == 0 && std::next(begin) != end && >+ (digit == 0 || digit == 5)) { >+ // If this is the very last significant digit, but insignificant digits >+ // remain, we know that the last of those remaining significant digits is >+ // nonzero. (If it wasn't, we would have stripped it before we got here.) >+ // So if this final digit is a 0 or 5, adjust it upward by 1. >+ // >+ // This adjustment is what allows incredibly large mantissas ending in >+ // 500000...000000000001 to correctly round up, rather than to nearest. >+ ++digit; >+ } >+ queued = 10 * queued + digit; >+ ++digits_queued; >+ if (digits_queued == kMaxSmallPowerOfTen) { >+ MultiplyBy(kTenToNth[kMaxSmallPowerOfTen]); >+ AddWithCarry(0, queued); >+ queued = digits_queued = 0; >+ } >+ } >+ // Encode any remaining digits. >+ if (digits_queued) { >+ MultiplyBy(kTenToNth[digits_queued]); >+ AddWithCarry(0, queued); >+ } >+ >+ // If any insignificant digits remain, we will drop them. But if we have not >+ // yet read the decimal point, then we have to adjust the exponent to account >+ // for the dropped digits. >+ if (begin < end && !after_decimal_point) { >+ // This call to std::find will result in a pointer either to the decimal >+ // point, or to the end of our buffer if there was none. >+ // >+ // Either way, [begin, decimal_point) will contain the set of dropped digits >+ // that require an exponent adjustment. >+ const char* decimal_point = std::find(begin, end, '.'); >+ exponent_adjust += (decimal_point - begin); >+ } >+ return exponent_adjust; >+} >+ >+template <int max_words> >+/* static */ BigUnsigned<max_words> BigUnsigned<max_words>::FiveToTheNth( >+ int n) { >+ BigUnsigned answer(1u); >+ >+ // Seed from the table of large powers, if possible. >+ bool first_pass = true; >+ while (n >= kLargePowerOfFiveStep) { >+ int big_power = >+ std::min(n / kLargePowerOfFiveStep, kLargestPowerOfFiveIndex); >+ if (first_pass) { >+ // just copy, rather than multiplying by 1 >+ std::copy( >+ LargePowerOfFiveData(big_power), >+ LargePowerOfFiveData(big_power) + LargePowerOfFiveSize(big_power), >+ answer.words_); >+ answer.size_ = LargePowerOfFiveSize(big_power); >+ first_pass = false; >+ } else { >+ answer.MultiplyBy(LargePowerOfFiveSize(big_power), >+ LargePowerOfFiveData(big_power)); >+ } >+ n -= kLargePowerOfFiveStep * big_power; >+ } >+ answer.MultiplyByFiveToTheNth(n); >+ return answer; >+} >+ >+template <int max_words> >+void BigUnsigned<max_words>::MultiplyStep(int original_size, >+ const uint32_t* other_words, >+ int other_size, int step) { >+ int this_i = std::min(original_size - 1, step); >+ int other_i = step - this_i; >+ >+ uint64_t this_word = 0; >+ uint64_t carry = 0; >+ for (; this_i >= 0 && other_i < other_size; --this_i, ++other_i) { >+ uint64_t product = words_[this_i]; >+ product *= other_words[other_i]; >+ this_word += product; >+ carry += (this_word >> 32); >+ this_word &= 0xffffffff; >+ } >+ AddWithCarry(step + 1, carry); >+ words_[step] = this_word & 0xffffffff; >+ if (this_word > 0 && size_ <= step) { >+ size_ = step + 1; >+ } >+} >+ >+template <int max_words> >+std::string BigUnsigned<max_words>::ToString() const { >+ BigUnsigned<max_words> copy = *this; >+ std::string result; >+ // Build result in reverse order >+ while (copy.size() > 0) { >+ int next_digit = copy.DivMod<10>(); >+ result.push_back('0' + next_digit); >+ } >+ if (result.empty()) { >+ result.push_back('0'); >+ } >+ std::reverse(result.begin(), result.end()); >+ return result; >+} >+ >+template class BigUnsigned<4>; >+template class BigUnsigned<84>; >+ >+} // namespace strings_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h >new file mode 100644 >index 0000000000000000000000000000000000000000..aa70af2c28941acc1fd9bb070c5f5ebd3903f6d2 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h >@@ -0,0 +1,426 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_ >+#define ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_ >+ >+#include <algorithm> >+#include <cstdint> >+#include <iostream> >+#include <string> >+ >+#include "absl/strings/ascii.h" >+#include "absl/strings/internal/charconv_parse.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+// The largest power that 5 that can be raised to, and still fit in a uint32_t. >+constexpr int kMaxSmallPowerOfFive = 13; >+// The largest power that 10 that can be raised to, and still fit in a uint32_t. >+constexpr int kMaxSmallPowerOfTen = 9; >+ >+extern const uint32_t kFiveToNth[kMaxSmallPowerOfFive + 1]; >+extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; >+ >+// Large, fixed-width unsigned integer. >+// >+// Exact rounding for decimal-to-binary floating point conversion requires very >+// large integer math, but a design goal of absl::from_chars is to avoid >+// allocating memory. The integer precision needed for decimal-to-binary >+// conversions is large but bounded, so a huge fixed-width integer class >+// suffices. >+// >+// This is an intentionally limited big integer class. Only needed operations >+// are implemented. All storage lives in an array data member, and all >+// arithmetic is done in-place, to avoid requiring separate storage for operand >+// and result. >+// >+// This is an internal class. Some methods live in the .cc file, and are >+// instantiated only for the values of max_words we need. >+template <int max_words> >+class BigUnsigned { >+ public: >+ static_assert(max_words == 4 || max_words == 84, >+ "unsupported max_words value"); >+ >+ BigUnsigned() : size_(0), words_{} {} >+ explicit BigUnsigned(uint32_t v) : size_(v > 0 ? 1 : 0), words_{v} {} >+ explicit BigUnsigned(uint64_t v) >+ : size_(0), >+ words_{static_cast<uint32_t>(v & 0xffffffff), >+ static_cast<uint32_t>(v >> 32)} { >+ if (words_[1]) { >+ size_ = 2; >+ } else if (words_[0]) { >+ size_ = 1; >+ } >+ } >+ >+ // Constructs a BigUnsigned from the given string_view containing a decimal >+ // value. If the input std::string is not a decimal integer, constructs a 0 >+ // instead. >+ explicit BigUnsigned(absl::string_view sv) : size_(0), words_{} { >+ // Check for valid input, returning a 0 otherwise. This is reasonable >+ // behavior only because this constructor is for unit tests. >+ if (std::find_if_not(sv.begin(), sv.end(), ascii_isdigit) != sv.end() || >+ sv.empty()) { >+ return; >+ } >+ int exponent_adjust = >+ ReadDigits(sv.data(), sv.data() + sv.size(), Digits10() + 1); >+ if (exponent_adjust > 0) { >+ MultiplyByTenToTheNth(exponent_adjust); >+ } >+ } >+ >+ // Loads the mantissa value of a previously-parsed float. >+ // >+ // Returns the associated decimal exponent. The value of the parsed float is >+ // exactly *this * 10**exponent. >+ int ReadFloatMantissa(const ParsedFloat& fp, int significant_digits); >+ >+ // Returns the number of decimal digits of precision this type provides. All >+ // numbers with this many decimal digits or fewer are representable by this >+ // type. >+ // >+ // Analagous to std::numeric_limits<BigUnsigned>::digits10. >+ static constexpr int Digits10() { >+ // 9975007/1035508 is very slightly less than log10(2**32). >+ return static_cast<uint64_t>(max_words) * 9975007 / 1035508; >+ } >+ >+ // Shifts left by the given number of bits. >+ void ShiftLeft(int count) { >+ if (count > 0) { >+ const int word_shift = count / 32; >+ if (word_shift >= max_words) { >+ SetToZero(); >+ return; >+ } >+ size_ = std::min(size_ + word_shift, max_words); >+ count %= 32; >+ if (count == 0) { >+ std::copy_backward(words_, words_ + size_ - word_shift, words_ + size_); >+ } else { >+ for (int i = std::min(size_, max_words - 1); i > word_shift; --i) { >+ words_[i] = (words_[i - word_shift] << count) | >+ (words_[i - word_shift - 1] >> (32 - count)); >+ } >+ words_[word_shift] = words_[0] << count; >+ // Grow size_ if necessary. >+ if (size_ < max_words && words_[size_]) { >+ ++size_; >+ } >+ } >+ std::fill(words_, words_ + word_shift, 0u); >+ } >+ } >+ >+ >+ // Multiplies by v in-place. >+ void MultiplyBy(uint32_t v) { >+ if (size_ == 0 || v == 1) { >+ return; >+ } >+ if (v == 0) { >+ SetToZero(); >+ return; >+ } >+ const uint64_t factor = v; >+ uint64_t window = 0; >+ for (int i = 0; i < size_; ++i) { >+ window += factor * words_[i]; >+ words_[i] = window & 0xffffffff; >+ window >>= 32; >+ } >+ // If carry bits remain and there's space for them, grow size_. >+ if (window && size_ < max_words) { >+ words_[size_] = window & 0xffffffff; >+ ++size_; >+ } >+ } >+ >+ void MultiplyBy(uint64_t v) { >+ uint32_t words[2]; >+ words[0] = static_cast<uint32_t>(v); >+ words[1] = static_cast<uint32_t>(v >> 32); >+ if (words[1] == 0) { >+ MultiplyBy(words[0]); >+ } else { >+ MultiplyBy(2, words); >+ } >+ } >+ >+ // Multiplies in place by 5 to the power of n. n must be non-negative. >+ void MultiplyByFiveToTheNth(int n) { >+ while (n >= kMaxSmallPowerOfFive) { >+ MultiplyBy(kFiveToNth[kMaxSmallPowerOfFive]); >+ n -= kMaxSmallPowerOfFive; >+ } >+ if (n > 0) { >+ MultiplyBy(kFiveToNth[n]); >+ } >+ } >+ >+ // Multiplies in place by 10 to the power of n. n must be non-negative. >+ void MultiplyByTenToTheNth(int n) { >+ if (n > kMaxSmallPowerOfTen) { >+ // For large n, raise to a power of 5, then shift left by the same amount. >+ // (10**n == 5**n * 2**n.) This requires fewer multiplications overall. >+ MultiplyByFiveToTheNth(n); >+ ShiftLeft(n); >+ } else if (n > 0) { >+ // We can do this more quickly for very small N by using a single >+ // multiplication. >+ MultiplyBy(kTenToNth[n]); >+ } >+ } >+ >+ // Returns the value of 5**n, for non-negative n. This implementation uses >+ // a lookup table, and is faster then seeding a BigUnsigned with 1 and calling >+ // MultiplyByFiveToTheNth(). >+ static BigUnsigned FiveToTheNth(int n); >+ >+ // Multiplies by another BigUnsigned, in-place. >+ template <int M> >+ void MultiplyBy(const BigUnsigned<M>& other) { >+ MultiplyBy(other.size(), other.words()); >+ } >+ >+ void SetToZero() { >+ std::fill(words_, words_ + size_, 0u); >+ size_ = 0; >+ } >+ >+ // Returns the value of the nth word of this BigUnsigned. This is >+ // range-checked, and returns 0 on out-of-bounds accesses. >+ uint32_t GetWord(int index) const { >+ if (index < 0 || index >= size_) { >+ return 0; >+ } >+ return words_[index]; >+ } >+ >+ // Returns this integer as a decimal std::string. This is not used in the decimal- >+ // to-binary conversion; it is intended to aid in testing. >+ std::string ToString() const; >+ >+ int size() const { return size_; } >+ const uint32_t* words() const { return words_; } >+ >+ private: >+ // Reads the number between [begin, end), possibly containing a decimal point, >+ // into this BigUnsigned. >+ // >+ // Callers are required to ensure [begin, end) contains a valid number, with >+ // one or more decimal digits and at most one decimal point. This routine >+ // will behave unpredictably if these preconditions are not met. >+ // >+ // Only the first `significant_digits` digits are read. Digits beyond this >+ // limit are "sticky": If the final significant digit is 0 or 5, and if any >+ // dropped digit is nonzero, then that final significant digit is adjusted up >+ // to 1 or 6. This adjustment allows for precise rounding. >+ // >+ // Returns `exponent_adjustment`, a power-of-ten exponent adjustment to >+ // account for the decimal point and for dropped significant digits. After >+ // this function returns, >+ // actual_value_of_parsed_string ~= *this * 10**exponent_adjustment. >+ int ReadDigits(const char* begin, const char* end, int significant_digits); >+ >+ // Performs a step of big integer multiplication. This computes the full >+ // (64-bit-wide) values that should be added at the given index (step), and >+ // adds to that location in-place. >+ // >+ // Because our math all occurs in place, we must multiply starting from the >+ // highest word working downward. (This is a bit more expensive due to the >+ // extra carries involved.) >+ // >+ // This must be called in steps, for each word to be calculated, starting from >+ // the high end and working down to 0. The first value of `step` should be >+ // `std::min(original_size + other.size_ - 2, max_words - 1)`. >+ // The reason for this expression is that multiplying the i'th word from one >+ // multiplicand and the j'th word of another multiplicand creates a >+ // two-word-wide value to be stored at the (i+j)'th element. The highest >+ // word indices we will access are `original_size - 1` from this object, and >+ // `other.size_ - 1` from our operand. Therefore, >+ // `original_size + other.size_ - 2` is the first step we should calculate, >+ // but limited on an upper bound by max_words. >+ >+ // Working from high-to-low ensures that we do not overwrite the portions of >+ // the initial value of *this which are still needed for later steps. >+ // >+ // Once called with step == 0, *this contains the result of the >+ // multiplication. >+ // >+ // `original_size` is the size_ of *this before the first call to >+ // MultiplyStep(). `other_words` and `other_size` are the contents of our >+ // operand. `step` is the step to perform, as described above. >+ void MultiplyStep(int original_size, const uint32_t* other_words, >+ int other_size, int step); >+ >+ void MultiplyBy(int other_size, const uint32_t* other_words) { >+ const int original_size = size_; >+ const int first_step = >+ std::min(original_size + other_size - 2, max_words - 1); >+ for (int step = first_step; step >= 0; --step) { >+ MultiplyStep(original_size, other_words, other_size, step); >+ } >+ } >+ >+ // Adds a 32-bit value to the index'th word, with carry. >+ void AddWithCarry(int index, uint32_t value) { >+ if (value) { >+ while (index < max_words && value > 0) { >+ words_[index] += value; >+ // carry if we overflowed in this word: >+ if (value > words_[index]) { >+ value = 1; >+ ++index; >+ } else { >+ value = 0; >+ } >+ } >+ size_ = std::min(max_words, std::max(index + 1, size_)); >+ } >+ } >+ >+ void AddWithCarry(int index, uint64_t value) { >+ if (value && index < max_words) { >+ uint32_t high = value >> 32; >+ uint32_t low = value & 0xffffffff; >+ words_[index] += low; >+ if (words_[index] < low) { >+ ++high; >+ if (high == 0) { >+ // Carry from the low word caused our high word to overflow. >+ // Short circuit here to do the right thing. >+ AddWithCarry(index + 2, static_cast<uint32_t>(1)); >+ return; >+ } >+ } >+ if (high > 0) { >+ AddWithCarry(index + 1, high); >+ } else { >+ // Normally 32-bit AddWithCarry() sets size_, but since we don't call >+ // it when `high` is 0, do it ourselves here. >+ size_ = std::min(max_words, std::max(index + 1, size_)); >+ } >+ } >+ } >+ >+ // Divide this in place by a constant divisor. Returns the remainder of the >+ // division. >+ template <uint32_t divisor> >+ uint32_t DivMod() { >+ uint64_t accumulator = 0; >+ for (int i = size_ - 1; i >= 0; --i) { >+ accumulator <<= 32; >+ accumulator += words_[i]; >+ // accumulator / divisor will never overflow an int32_t in this loop >+ words_[i] = static_cast<uint32_t>(accumulator / divisor); >+ accumulator = accumulator % divisor; >+ } >+ while (size_ > 0 && words_[size_ - 1] == 0) { >+ --size_; >+ } >+ return static_cast<uint32_t>(accumulator); >+ } >+ >+ // The number of elements in words_ that may carry significant values. >+ // All elements beyond this point are 0. >+ // >+ // When size_ is 0, this BigUnsigned stores the value 0. >+ // When size_ is nonzero, is *not* guaranteed that words_[size_ - 1] is >+ // nonzero. This can occur due to overflow truncation. >+ // In particular, x.size_ != y.size_ does *not* imply x != y. >+ int size_; >+ uint32_t words_[max_words]; >+}; >+ >+// Compares two big integer instances. >+// >+// Returns -1 if lhs < rhs, 0 if lhs == rhs, and 1 if lhs > rhs. >+template <int N, int M> >+int Compare(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { >+ int limit = std::max(lhs.size(), rhs.size()); >+ for (int i = limit - 1; i >= 0; --i) { >+ const uint32_t lhs_word = lhs.GetWord(i); >+ const uint32_t rhs_word = rhs.GetWord(i); >+ if (lhs_word < rhs_word) { >+ return -1; >+ } else if (lhs_word > rhs_word) { >+ return 1; >+ } >+ } >+ return 0; >+} >+ >+template <int N, int M> >+bool operator==(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { >+ int limit = std::max(lhs.size(), rhs.size()); >+ for (int i = 0; i < limit; ++i) { >+ if (lhs.GetWord(i) != rhs.GetWord(i)) { >+ return false; >+ } >+ } >+ return true; >+} >+ >+template <int N, int M> >+bool operator!=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { >+ return !(lhs == rhs); >+} >+ >+template <int N, int M> >+bool operator<(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { >+ return Compare(lhs, rhs) == -1; >+} >+ >+template <int N, int M> >+bool operator>(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { >+ return rhs < lhs; >+} >+template <int N, int M> >+bool operator<=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { >+ return !(rhs < lhs); >+} >+template <int N, int M> >+bool operator>=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { >+ return !(lhs < rhs); >+} >+ >+// Output operator for BigUnsigned, for testing purposes only. >+template <int N> >+std::ostream& operator<<(std::ostream& os, const BigUnsigned<N>& num) { >+ return os << num.ToString(); >+} >+ >+// Explicit instantiation declarations for the sizes of BigUnsigned that we >+// are using. >+// >+// For now, the choices of 4 and 84 are arbitrary; 4 is a small value that is >+// still bigger than an int128, and 84 is a large value we will want to use >+// in the from_chars implementation. >+// >+// Comments justifying the use of 84 belong in the from_chars implementation, >+// and will be added in a follow-up CL. >+extern template class BigUnsigned<4>; >+extern template class BigUnsigned<84>; >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..9b6357888fbf47ebdcc6cd516b81ad140b97cba5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc >@@ -0,0 +1,203 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/charconv_bigint.h" >+ >+#include <string> >+ >+#include "gtest/gtest.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+TEST(BigUnsigned, ShiftLeft) { >+ { >+ // Check that 3 * 2**100 is calculated correctly >+ BigUnsigned<4> num(3u); >+ num.ShiftLeft(100); >+ EXPECT_EQ(num, BigUnsigned<4>("3802951800684688204490109616128")); >+ } >+ { >+ // Test that overflow is truncated properly. >+ // 15 is 4 bits long, and BigUnsigned<4> is a 128-bit bigint. >+ // Shifting left by 125 bits should truncate off the high bit, so that >+ // 15 << 125 == 7 << 125 >+ // after truncation. >+ BigUnsigned<4> a(15u); >+ BigUnsigned<4> b(7u); >+ BigUnsigned<4> c(3u); >+ a.ShiftLeft(125); >+ b.ShiftLeft(125); >+ c.ShiftLeft(125); >+ EXPECT_EQ(a, b); >+ EXPECT_NE(a, c); >+ } >+ { >+ // Same test, larger bigint: >+ BigUnsigned<84> a(15u); >+ BigUnsigned<84> b(7u); >+ BigUnsigned<84> c(3u); >+ a.ShiftLeft(84 * 32 - 3); >+ b.ShiftLeft(84 * 32 - 3); >+ c.ShiftLeft(84 * 32 - 3); >+ EXPECT_EQ(a, b); >+ EXPECT_NE(a, c); >+ } >+ { >+ // Check that incrementally shifting has the same result as doing it all at >+ // once (attempting to capture corner cases.) >+ const std::string seed = "1234567890123456789012345678901234567890"; >+ BigUnsigned<84> a(seed); >+ for (int i = 1; i <= 84 * 32; ++i) { >+ a.ShiftLeft(1); >+ BigUnsigned<84> b(seed); >+ b.ShiftLeft(i); >+ EXPECT_EQ(a, b); >+ } >+ // And we should have fully rotated all bits off by now: >+ EXPECT_EQ(a, BigUnsigned<84>(0u)); >+ } >+} >+ >+TEST(BigUnsigned, MultiplyByUint32) { >+ const BigUnsigned<84> factorial_100( >+ "933262154439441526816992388562667004907159682643816214685929638952175999" >+ "932299156089414639761565182862536979208272237582511852109168640000000000" >+ "00000000000000"); >+ BigUnsigned<84> a(1u); >+ for (uint32_t i = 1; i <= 100; ++i) { >+ a.MultiplyBy(i); >+ } >+ EXPECT_EQ(a, BigUnsigned<84>(factorial_100)); >+} >+ >+TEST(BigUnsigned, MultiplyByBigUnsigned) { >+ { >+ // Put the terms of factorial_200 into two bigints, and multiply them >+ // together. >+ const BigUnsigned<84> factorial_200( >+ "7886578673647905035523632139321850622951359776871732632947425332443594" >+ "4996340334292030428401198462390417721213891963883025764279024263710506" >+ "1926624952829931113462857270763317237396988943922445621451664240254033" >+ "2918641312274282948532775242424075739032403212574055795686602260319041" >+ "7032406235170085879617892222278962370389737472000000000000000000000000" >+ "0000000000000000000000000"); >+ BigUnsigned<84> evens(1u); >+ BigUnsigned<84> odds(1u); >+ for (uint32_t i = 1; i < 200; i += 2) { >+ odds.MultiplyBy(i); >+ evens.MultiplyBy(i + 1); >+ } >+ evens.MultiplyBy(odds); >+ EXPECT_EQ(evens, factorial_200); >+ } >+ { >+ // Multiply various powers of 10 together. >+ for (int a = 0 ; a < 700; a += 25) { >+ SCOPED_TRACE(a); >+ BigUnsigned<84> a_value("3" + std::string(a, '0')); >+ for (int b = 0; b < (700 - a); b += 25) { >+ SCOPED_TRACE(b); >+ BigUnsigned<84> b_value("2" + std::string(b, '0')); >+ BigUnsigned<84> expected_product("6" + std::string(a + b, '0')); >+ b_value.MultiplyBy(a_value); >+ EXPECT_EQ(b_value, expected_product); >+ } >+ } >+ } >+} >+ >+TEST(BigUnsigned, MultiplyByOverflow) { >+ { >+ // Check that multiplcation overflow predictably truncates. >+ >+ // A big int with all bits on. >+ BigUnsigned<4> all_bits_on("340282366920938463463374607431768211455"); >+ // Modulo 2**128, this is equal to -1. Therefore the square of this, >+ // modulo 2**128, should be 1. >+ all_bits_on.MultiplyBy(all_bits_on); >+ EXPECT_EQ(all_bits_on, BigUnsigned<4>(1u)); >+ } >+ { >+ // Try multiplying a large bigint by 2**50, and compare the result to >+ // shifting. >+ BigUnsigned<4> value_1("12345678901234567890123456789012345678"); >+ BigUnsigned<4> value_2("12345678901234567890123456789012345678"); >+ BigUnsigned<4> two_to_fiftieth(1u); >+ two_to_fiftieth.ShiftLeft(50); >+ >+ value_1.ShiftLeft(50); >+ value_2.MultiplyBy(two_to_fiftieth); >+ EXPECT_EQ(value_1, value_2); >+ } >+} >+ >+TEST(BigUnsigned, FiveToTheNth) { >+ { >+ // Sanity check that MultiplyByFiveToTheNth gives consistent answers, up to >+ // and including overflow. >+ for (int i = 0; i < 1160; ++i) { >+ SCOPED_TRACE(i); >+ BigUnsigned<84> value_1(123u); >+ BigUnsigned<84> value_2(123u); >+ value_1.MultiplyByFiveToTheNth(i); >+ for (int j = 0; j < i; j++) { >+ value_2.MultiplyBy(5u); >+ } >+ EXPECT_EQ(value_1, value_2); >+ } >+ } >+ { >+ // Check that the faster, table-lookup-based static method returns the same >+ // result that multiplying in-place would return, up to and including >+ // overflow. >+ for (int i = 0; i < 1160; ++i) { >+ SCOPED_TRACE(i); >+ BigUnsigned<84> value_1(1u); >+ value_1.MultiplyByFiveToTheNth(i); >+ BigUnsigned<84> value_2 = BigUnsigned<84>::FiveToTheNth(i); >+ EXPECT_EQ(value_1, value_2); >+ } >+ } >+} >+ >+TEST(BigUnsigned, TenToTheNth) { >+ { >+ // Sanity check MultiplyByTenToTheNth. >+ for (int i = 0; i < 800; ++i) { >+ SCOPED_TRACE(i); >+ BigUnsigned<84> value_1(123u); >+ BigUnsigned<84> value_2(123u); >+ value_1.MultiplyByTenToTheNth(i); >+ for (int j = 0; j < i; j++) { >+ value_2.MultiplyBy(10u); >+ } >+ EXPECT_EQ(value_1, value_2); >+ } >+ } >+ { >+ // Alternate testing approach, taking advantage of the decimal parser. >+ for (int i = 0; i < 200; ++i) { >+ SCOPED_TRACE(i); >+ BigUnsigned<84> value_1(135u); >+ value_1.MultiplyByTenToTheNth(i); >+ BigUnsigned<84> value_2("135" + std::string(i, '0')); >+ EXPECT_EQ(value_1, value_2); >+ } >+ } >+} >+ >+ >+} // namespace strings_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..a04cc67669a7f75f936a767c5f223cb3592d9ebb >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc >@@ -0,0 +1,496 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/charconv_parse.h" >+#include "absl/strings/charconv.h" >+ >+#include <cassert> >+#include <cstdint> >+#include <limits> >+ >+#include "absl/strings/internal/memutil.h" >+ >+namespace absl { >+namespace { >+ >+// ParseFloat<10> will read the first 19 significant digits of the mantissa. >+// This number was chosen for multiple reasons. >+// >+// (a) First, for whatever integer type we choose to represent the mantissa, we >+// want to choose the largest possible number of decimal digits for that integer >+// type. We are using uint64_t, which can express any 19-digit unsigned >+// integer. >+// >+// (b) Second, we need to parse enough digits that the binary value of any >+// mantissa we capture has more bits of resolution than the mantissa >+// representation in the target float. Our algorithm requires at least 3 bits >+// of headway, but 19 decimal digits give a little more than that. >+// >+// The following static assertions verify the above comments: >+constexpr int kDecimalMantissaDigitsMax = 19; >+ >+static_assert(std::numeric_limits<uint64_t>::digits10 == >+ kDecimalMantissaDigitsMax, >+ "(a) above"); >+ >+// IEEE doubles, which we assume in Abseil, have 53 binary bits of mantissa. >+static_assert(std::numeric_limits<double>::is_iec559, "IEEE double assumed"); >+static_assert(std::numeric_limits<double>::radix == 2, "IEEE double fact"); >+static_assert(std::numeric_limits<double>::digits == 53, "IEEE double fact"); >+ >+// The lowest valued 19-digit decimal mantissa we can read still contains >+// sufficient information to reconstruct a binary mantissa. >+static_assert(1000000000000000000u > (uint64_t(1) << (53 + 3)), "(b) above"); >+ >+// ParseFloat<16> will read the first 15 significant digits of the mantissa. >+// >+// Because a base-16-to-base-2 conversion can be done exactly, we do not need >+// to maximize the number of scanned hex digits to improve our conversion. What >+// is required is to scan two more bits than the mantissa can represent, so that >+// we always round correctly. >+// >+// (One extra bit does not suffice to perform correct rounding, since a number >+// exactly halfway between two representable floats has unique rounding rules, >+// so we need to differentiate between a "halfway between" number and a "closer >+// to the larger value" number.) >+constexpr int kHexadecimalMantissaDigitsMax = 15; >+ >+// The minimum number of significant bits that will be read from >+// kHexadecimalMantissaDigitsMax hex digits. We must subtract by three, since >+// the most significant digit can be a "1", which only contributes a single >+// significant bit. >+constexpr int kGuaranteedHexadecimalMantissaBitPrecision = >+ 4 * kHexadecimalMantissaDigitsMax - 3; >+ >+static_assert(kGuaranteedHexadecimalMantissaBitPrecision > >+ std::numeric_limits<double>::digits + 2, >+ "kHexadecimalMantissaDigitsMax too small"); >+ >+// We also impose a limit on the number of significant digits we will read from >+// an exponent, to avoid having to deal with integer overflow. We use 9 for >+// this purpose. >+// >+// If we read a 9 digit exponent, the end result of the conversion will >+// necessarily be infinity or zero, depending on the sign of the exponent. >+// Therefore we can just drop extra digits on the floor without any extra >+// logic. >+constexpr int kDecimalExponentDigitsMax = 9; >+static_assert(std::numeric_limits<int>::digits10 >= kDecimalExponentDigitsMax, >+ "int type too small"); >+ >+// To avoid incredibly large inputs causing integer overflow for our exponent, >+// we impose an arbitrary but very large limit on the number of significant >+// digits we will accept. The implementation refuses to match a std::string with >+// more consecutive significant mantissa digits than this. >+constexpr int kDecimalDigitLimit = 50000000; >+ >+// Corresponding limit for hexadecimal digit inputs. This is one fourth the >+// amount of kDecimalDigitLimit, since each dropped hexadecimal digit requires >+// a binary exponent adjustment of 4. >+constexpr int kHexadecimalDigitLimit = kDecimalDigitLimit / 4; >+ >+// The largest exponent we can read is 999999999 (per >+// kDecimalExponentDigitsMax), and the largest exponent adjustment we can get >+// from dropped mantissa digits is 2 * kDecimalDigitLimit, and the sum of these >+// comfortably fits in an integer. >+// >+// We count kDecimalDigitLimit twice because there are independent limits for >+// numbers before and after the decimal point. (In the case where there are no >+// significant digits before the decimal point, there are independent limits for >+// post-decimal-point leading zeroes and for significant digits.) >+static_assert(999999999 + 2 * kDecimalDigitLimit < >+ std::numeric_limits<int>::max(), >+ "int type too small"); >+static_assert(999999999 + 2 * (4 * kHexadecimalDigitLimit) < >+ std::numeric_limits<int>::max(), >+ "int type too small"); >+ >+// Returns true if the provided bitfield allows parsing an exponent value >+// (e.g., "1.5e100"). >+bool AllowExponent(chars_format flags) { >+ bool fixed = (flags & chars_format::fixed) == chars_format::fixed; >+ bool scientific = >+ (flags & chars_format::scientific) == chars_format::scientific; >+ return scientific || !fixed; >+} >+ >+// Returns true if the provided bitfield requires an exponent value be present. >+bool RequireExponent(chars_format flags) { >+ bool fixed = (flags & chars_format::fixed) == chars_format::fixed; >+ bool scientific = >+ (flags & chars_format::scientific) == chars_format::scientific; >+ return scientific && !fixed; >+} >+ >+const int8_t kAsciiToInt[256] = { >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, >+ 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, >+ -1, -1, -1, -1, -1, -1, -1, -1, -1}; >+ >+// Returns true if `ch` is a digit in the given base >+template <int base> >+bool IsDigit(char ch); >+ >+// Converts a valid `ch` to its digit value in the given base. >+template <int base> >+unsigned ToDigit(char ch); >+ >+// Returns true if `ch` is the exponent delimiter for the given base. >+template <int base> >+bool IsExponentCharacter(char ch); >+ >+// Returns the maximum number of significant digits we will read for a float >+// in the given base. >+template <int base> >+constexpr int MantissaDigitsMax(); >+ >+// Returns the largest consecutive run of digits we will accept when parsing a >+// number in the given base. >+template <int base> >+constexpr int DigitLimit(); >+ >+// Returns the amount the exponent must be adjusted by for each dropped digit. >+// (For decimal this is 1, since the digits are in base 10 and the exponent base >+// is also 10, but for hexadecimal this is 4, since the digits are base 16 but >+// the exponent base is 2.) >+template <int base> >+constexpr int DigitMagnitude(); >+ >+template <> >+bool IsDigit<10>(char ch) { >+ return ch >= '0' && ch <= '9'; >+} >+template <> >+bool IsDigit<16>(char ch) { >+ return kAsciiToInt[static_cast<unsigned char>(ch)] >= 0; >+} >+ >+template <> >+unsigned ToDigit<10>(char ch) { >+ return ch - '0'; >+} >+template <> >+unsigned ToDigit<16>(char ch) { >+ return kAsciiToInt[static_cast<unsigned char>(ch)]; >+} >+ >+template <> >+bool IsExponentCharacter<10>(char ch) { >+ return ch == 'e' || ch == 'E'; >+} >+ >+template <> >+bool IsExponentCharacter<16>(char ch) { >+ return ch == 'p' || ch == 'P'; >+} >+ >+template <> >+constexpr int MantissaDigitsMax<10>() { >+ return kDecimalMantissaDigitsMax; >+} >+template <> >+constexpr int MantissaDigitsMax<16>() { >+ return kHexadecimalMantissaDigitsMax; >+} >+ >+template <> >+constexpr int DigitLimit<10>() { >+ return kDecimalDigitLimit; >+} >+template <> >+constexpr int DigitLimit<16>() { >+ return kHexadecimalDigitLimit; >+} >+ >+template <> >+constexpr int DigitMagnitude<10>() { >+ return 1; >+} >+template <> >+constexpr int DigitMagnitude<16>() { >+ return 4; >+} >+ >+// Reads decimal digits from [begin, end) into *out. Returns the number of >+// digits consumed. >+// >+// After max_digits has been read, keeps consuming characters, but no longer >+// adjusts *out. If a nonzero digit is dropped this way, *dropped_nonzero_digit >+// is set; otherwise, it is left unmodified. >+// >+// If no digits are matched, returns 0 and leaves *out unchanged. >+// >+// ConsumeDigits does not protect against overflow on *out; max_digits must >+// be chosen with respect to type T to avoid the possibility of overflow. >+template <int base, typename T> >+std::size_t ConsumeDigits(const char* begin, const char* end, int max_digits, >+ T* out, bool* dropped_nonzero_digit) { >+ if (base == 10) { >+ assert(max_digits <= std::numeric_limits<T>::digits10); >+ } else if (base == 16) { >+ assert(max_digits * 4 <= std::numeric_limits<T>::digits); >+ } >+ const char* const original_begin = begin; >+ T accumulator = *out; >+ const char* significant_digits_end = >+ (end - begin > max_digits) ? begin + max_digits : end; >+ while (begin < significant_digits_end && IsDigit<base>(*begin)) { >+ // Do not guard against *out overflow; max_digits was chosen to avoid this. >+ // Do assert against it, to detect problems in debug builds. >+ auto digit = static_cast<T>(ToDigit<base>(*begin)); >+ assert(accumulator * base >= accumulator); >+ accumulator *= base; >+ assert(accumulator + digit >= accumulator); >+ accumulator += digit; >+ ++begin; >+ } >+ bool dropped_nonzero = false; >+ while (begin < end && IsDigit<base>(*begin)) { >+ dropped_nonzero = dropped_nonzero || (*begin != '0'); >+ ++begin; >+ } >+ if (dropped_nonzero && dropped_nonzero_digit != nullptr) { >+ *dropped_nonzero_digit = true; >+ } >+ *out = accumulator; >+ return begin - original_begin; >+} >+ >+// Returns true if `v` is one of the chars allowed inside parentheses following >+// a NaN. >+bool IsNanChar(char v) { >+ return (v == '_') || (v >= '0' && v <= '9') || (v >= 'a' && v <= 'z') || >+ (v >= 'A' && v <= 'Z'); >+} >+ >+// Checks the range [begin, end) for a strtod()-formatted infinity or NaN. If >+// one is found, sets `out` appropriately and returns true. >+bool ParseInfinityOrNan(const char* begin, const char* end, >+ strings_internal::ParsedFloat* out) { >+ if (end - begin < 3) { >+ return false; >+ } >+ switch (*begin) { >+ case 'i': >+ case 'I': { >+ // An infinity std::string consists of the characters "inf" or "infinity", >+ // case insensitive. >+ if (strings_internal::memcasecmp(begin + 1, "nf", 2) != 0) { >+ return false; >+ } >+ out->type = strings_internal::FloatType::kInfinity; >+ if (end - begin >= 8 && >+ strings_internal::memcasecmp(begin + 3, "inity", 5) == 0) { >+ out->end = begin + 8; >+ } else { >+ out->end = begin + 3; >+ } >+ return true; >+ } >+ case 'n': >+ case 'N': { >+ // A NaN consists of the characters "nan", case insensitive, optionally >+ // followed by a parenthesized sequence of zero or more alphanumeric >+ // characters and/or underscores. >+ if (strings_internal::memcasecmp(begin + 1, "an", 2) != 0) { >+ return false; >+ } >+ out->type = strings_internal::FloatType::kNan; >+ out->end = begin + 3; >+ // NaN is allowed to be followed by a parenthesized std::string, consisting of >+ // only the characters [a-zA-Z0-9_]. Match that if it's present. >+ begin += 3; >+ if (begin < end && *begin == '(') { >+ const char* nan_begin = begin + 1; >+ while (nan_begin < end && IsNanChar(*nan_begin)) { >+ ++nan_begin; >+ } >+ if (nan_begin < end && *nan_begin == ')') { >+ // We found an extra NaN specifier range >+ out->subrange_begin = begin + 1; >+ out->subrange_end = nan_begin; >+ out->end = nan_begin + 1; >+ } >+ } >+ return true; >+ } >+ default: >+ return false; >+ } >+} >+} // namespace >+ >+namespace strings_internal { >+ >+template <int base> >+strings_internal::ParsedFloat ParseFloat(const char* begin, const char* end, >+ chars_format format_flags) { >+ strings_internal::ParsedFloat result; >+ >+ // Exit early if we're given an empty range. >+ if (begin == end) return result; >+ >+ // Handle the infinity and NaN cases. >+ if (ParseInfinityOrNan(begin, end, &result)) { >+ return result; >+ } >+ >+ const char* const mantissa_begin = begin; >+ while (begin < end && *begin == '0') { >+ ++begin; // skip leading zeros >+ } >+ uint64_t mantissa = 0; >+ >+ int exponent_adjustment = 0; >+ bool mantissa_is_inexact = false; >+ std::size_t pre_decimal_digits = ConsumeDigits<base>( >+ begin, end, MantissaDigitsMax<base>(), &mantissa, &mantissa_is_inexact); >+ begin += pre_decimal_digits; >+ int digits_left; >+ if (pre_decimal_digits >= DigitLimit<base>()) { >+ // refuse to parse pathological inputs >+ return result; >+ } else if (pre_decimal_digits > MantissaDigitsMax<base>()) { >+ // We dropped some non-fraction digits on the floor. Adjust our exponent >+ // to compensate. >+ exponent_adjustment = >+ static_cast<int>(pre_decimal_digits - MantissaDigitsMax<base>()); >+ digits_left = 0; >+ } else { >+ digits_left = >+ static_cast<int>(MantissaDigitsMax<base>() - pre_decimal_digits); >+ } >+ if (begin < end && *begin == '.') { >+ ++begin; >+ if (mantissa == 0) { >+ // If we haven't seen any nonzero digits yet, keep skipping zeros. We >+ // have to adjust the exponent to reflect the changed place value. >+ const char* begin_zeros = begin; >+ while (begin < end && *begin == '0') { >+ ++begin; >+ } >+ std::size_t zeros_skipped = begin - begin_zeros; >+ if (zeros_skipped >= DigitLimit<base>()) { >+ // refuse to parse pathological inputs >+ return result; >+ } >+ exponent_adjustment -= static_cast<int>(zeros_skipped); >+ } >+ std::size_t post_decimal_digits = ConsumeDigits<base>( >+ begin, end, digits_left, &mantissa, &mantissa_is_inexact); >+ begin += post_decimal_digits; >+ >+ // Since `mantissa` is an integer, each significant digit we read after >+ // the decimal point requires an adjustment to the exponent. "1.23e0" will >+ // be stored as `mantissa` == 123 and `exponent` == -2 (that is, >+ // "123e-2"). >+ if (post_decimal_digits >= DigitLimit<base>()) { >+ // refuse to parse pathological inputs >+ return result; >+ } else if (post_decimal_digits > digits_left) { >+ exponent_adjustment -= digits_left; >+ } else { >+ exponent_adjustment -= post_decimal_digits; >+ } >+ } >+ // If we've found no mantissa whatsoever, this isn't a number. >+ if (mantissa_begin == begin) { >+ return result; >+ } >+ // A bare "." doesn't count as a mantissa either. >+ if (begin - mantissa_begin == 1 && *mantissa_begin == '.') { >+ return result; >+ } >+ >+ if (mantissa_is_inexact) { >+ // We dropped significant digits on the floor. Handle this appropriately. >+ if (base == 10) { >+ // If we truncated significant decimal digits, store the full range of the >+ // mantissa for future big integer math for exact rounding. >+ result.subrange_begin = mantissa_begin; >+ result.subrange_end = begin; >+ } else if (base == 16) { >+ // If we truncated hex digits, reflect this fact by setting the low >+ // ("sticky") bit. This allows for correct rounding in all cases. >+ mantissa |= 1; >+ } >+ } >+ result.mantissa = mantissa; >+ >+ const char* const exponent_begin = begin; >+ result.literal_exponent = 0; >+ bool found_exponent = false; >+ if (AllowExponent(format_flags) && begin < end && >+ IsExponentCharacter<base>(*begin)) { >+ bool negative_exponent = false; >+ ++begin; >+ if (begin < end && *begin == '-') { >+ negative_exponent = true; >+ ++begin; >+ } else if (begin < end && *begin == '+') { >+ ++begin; >+ } >+ const char* const exponent_digits_begin = begin; >+ // Exponent is always expressed in decimal, even for hexadecimal floats. >+ begin += ConsumeDigits<10>(begin, end, kDecimalExponentDigitsMax, >+ &result.literal_exponent, nullptr); >+ if (begin == exponent_digits_begin) { >+ // there were no digits where we expected an exponent. We failed to read >+ // an exponent and should not consume the 'e' after all. Rewind 'begin'. >+ found_exponent = false; >+ begin = exponent_begin; >+ } else { >+ found_exponent = true; >+ if (negative_exponent) { >+ result.literal_exponent = -result.literal_exponent; >+ } >+ } >+ } >+ >+ if (!found_exponent && RequireExponent(format_flags)) { >+ // Provided flags required an exponent, but none was found. This results >+ // in a failure to scan. >+ return result; >+ } >+ >+ // Success! >+ result.type = strings_internal::FloatType::kNumber; >+ if (result.mantissa > 0) { >+ result.exponent = result.literal_exponent + >+ (DigitMagnitude<base>() * exponent_adjustment); >+ } else { >+ result.exponent = 0; >+ } >+ result.end = begin; >+ return result; >+} >+ >+template ParsedFloat ParseFloat<10>(const char* begin, const char* end, >+ chars_format format_flags); >+template ParsedFloat ParseFloat<16>(const char* begin, const char* end, >+ chars_format format_flags); >+ >+} // namespace strings_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_parse.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_parse.h >new file mode 100644 >index 0000000000000000000000000000000000000000..7a5c0874b804a58538989aaa0fd6d6dd8b31b28b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_parse.h >@@ -0,0 +1,96 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_ >+#define ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_ >+ >+#include <cstdint> >+ >+#include "absl/strings/charconv.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+// Enum indicating whether a parsed float is a number or special value. >+enum class FloatType { kNumber, kInfinity, kNan }; >+ >+// The decomposed parts of a parsed `float` or `double`. >+struct ParsedFloat { >+ // Representation of the parsed mantissa, with the decimal point adjusted to >+ // make it an integer. >+ // >+ // During decimal scanning, this contains 19 significant digits worth of >+ // mantissa value. If digits beyond this point are found, they >+ // are truncated, and if any of these dropped digits are nonzero, then >+ // `mantissa` is inexact, and the full mantissa is stored in [subrange_begin, >+ // subrange_end). >+ // >+ // During hexadecimal scanning, this contains 15 significant hex digits worth >+ // of mantissa value. Digits beyond this point are sticky -- they are >+ // truncated, but if any dropped digits are nonzero, the low bit of mantissa >+ // will be set. (This allows for precise rounding, and avoids the need >+ // to store the full mantissa in [subrange_begin, subrange_end).) >+ uint64_t mantissa = 0; >+ >+ // Floating point expontent. This reflects any decimal point adjustments and >+ // any truncated digits from the mantissa. The absolute value of the parsed >+ // number is represented by mantissa * (base ** exponent), where base==10 for >+ // decimal floats, and base==2 for hexadecimal floats. >+ int exponent = 0; >+ >+ // The literal exponent value scanned from the input, or 0 if none was >+ // present. This does not reflect any adjustments applied to mantissa. >+ int literal_exponent = 0; >+ >+ // The type of number scanned. >+ FloatType type = FloatType::kNumber; >+ >+ // When non-null, [subrange_begin, subrange_end) marks a range of characters >+ // that require further processing. The meaning is dependent on float type. >+ // If type == kNumber and this is set, this is a "wide input": the input >+ // mantissa contained more than 19 digits. The range contains the full >+ // mantissa. It plus `literal_exponent` need to be examined to find the best >+ // floating point match. >+ // If type == kNan and this is set, the range marks the contents of a >+ // matched parenthesized character region after the NaN. >+ const char* subrange_begin = nullptr; >+ const char* subrange_end = nullptr; >+ >+ // One-past-the-end of the successfully parsed region, or nullptr if no >+ // matching pattern was found. >+ const char* end = nullptr; >+}; >+ >+// Read the floating point number in the provided range, and populate >+// ParsedFloat accordingly. >+// >+// format_flags is a bitmask value specifying what patterns this API will match. >+// `scientific` and `fixed` are honored per std::from_chars rules >+// ([utility.from.chars], C++17): if exactly one of these bits is set, then an >+// exponent is required, or dislallowed, respectively. >+// >+// Template parameter `base` must be either 10 or 16. For base 16, a "0x" is >+// *not* consumed. The `hex` bit from format_flags is ignored by ParseFloat. >+template <int base> >+ParsedFloat ParseFloat(const char* begin, const char* end, >+ absl::chars_format format_flags); >+ >+extern template ParsedFloat ParseFloat<10>(const char* begin, const char* end, >+ absl::chars_format format_flags); >+extern template ParsedFloat ParseFloat<16>(const char* begin, const char* end, >+ absl::chars_format format_flags); >+ >+} // namespace strings_internal >+} // namespace absl >+#endif // ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..1ff86004973a82fcd70e301c808a94349ed3bbb1 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc >@@ -0,0 +1,357 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/charconv_parse.h" >+ >+#include <string> >+#include <utility> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/strings/str_cat.h" >+ >+using absl::chars_format; >+using absl::strings_internal::FloatType; >+using absl::strings_internal::ParsedFloat; >+using absl::strings_internal::ParseFloat; >+ >+namespace { >+ >+// Check that a given std::string input is parsed to the expected mantissa and >+// exponent. >+// >+// Input std::string `s` must contain a '$' character. It marks the end of the >+// characters that should be consumed by the match. It is stripped from the >+// input to ParseFloat. >+// >+// If input std::string `s` contains '[' and ']' characters, these mark the region >+// of characters that should be marked as the "subrange". For NaNs, this is >+// the location of the extended NaN std::string. For numbers, this is the location >+// of the full, over-large mantissa. >+template <int base> >+void ExpectParsedFloat(std::string s, absl::chars_format format_flags, >+ FloatType expected_type, uint64_t expected_mantissa, >+ int expected_exponent, >+ int expected_literal_exponent = -999) { >+ SCOPED_TRACE(s); >+ >+ int begin_subrange = -1; >+ int end_subrange = -1; >+ // If s contains '[' and ']', then strip these characters and set the subrange >+ // indices appropriately. >+ std::string::size_type open_bracket_pos = s.find('['); >+ if (open_bracket_pos != std::string::npos) { >+ begin_subrange = static_cast<int>(open_bracket_pos); >+ s.replace(open_bracket_pos, 1, ""); >+ std::string::size_type close_bracket_pos = s.find(']'); >+ ABSL_RAW_CHECK(close_bracket_pos != absl::string_view::npos, >+ "Test input contains [ without matching ]"); >+ end_subrange = static_cast<int>(close_bracket_pos); >+ s.replace(close_bracket_pos, 1, ""); >+ } >+ const std::string::size_type expected_characters_matched = s.find('$'); >+ ABSL_RAW_CHECK(expected_characters_matched != std::string::npos, >+ "Input std::string must contain $"); >+ s.replace(expected_characters_matched, 1, ""); >+ >+ ParsedFloat parsed = >+ ParseFloat<base>(s.data(), s.data() + s.size(), format_flags); >+ >+ EXPECT_NE(parsed.end, nullptr); >+ if (parsed.end == nullptr) { >+ return; // The following tests are not useful if we fully failed to parse >+ } >+ EXPECT_EQ(parsed.type, expected_type); >+ if (begin_subrange == -1) { >+ EXPECT_EQ(parsed.subrange_begin, nullptr); >+ EXPECT_EQ(parsed.subrange_end, nullptr); >+ } else { >+ EXPECT_EQ(parsed.subrange_begin, s.data() + begin_subrange); >+ EXPECT_EQ(parsed.subrange_end, s.data() + end_subrange); >+ } >+ if (parsed.type == FloatType::kNumber) { >+ EXPECT_EQ(parsed.mantissa, expected_mantissa); >+ EXPECT_EQ(parsed.exponent, expected_exponent); >+ if (expected_literal_exponent != -999) { >+ EXPECT_EQ(parsed.literal_exponent, expected_literal_exponent); >+ } >+ } >+ auto characters_matched = static_cast<int>(parsed.end - s.data()); >+ EXPECT_EQ(characters_matched, expected_characters_matched); >+} >+ >+// Check that a given std::string input is parsed to the expected mantissa and >+// exponent. >+// >+// Input std::string `s` must contain a '$' character. It marks the end of the >+// characters that were consumed by the match. >+template <int base> >+void ExpectNumber(std::string s, absl::chars_format format_flags, >+ uint64_t expected_mantissa, int expected_exponent, >+ int expected_literal_exponent = -999) { >+ ExpectParsedFloat<base>(std::move(s), format_flags, FloatType::kNumber, >+ expected_mantissa, expected_exponent, >+ expected_literal_exponent); >+} >+ >+// Check that a given std::string input is parsed to the given special value. >+// >+// This tests against both number bases, since infinities and NaNs have >+// identical representations in both modes. >+void ExpectSpecial(const std::string& s, absl::chars_format format_flags, >+ FloatType type) { >+ ExpectParsedFloat<10>(s, format_flags, type, 0, 0); >+ ExpectParsedFloat<16>(s, format_flags, type, 0, 0); >+} >+ >+// Check that a given input std::string is not matched by Float. >+template <int base> >+void ExpectFailedParse(absl::string_view s, absl::chars_format format_flags) { >+ ParsedFloat parsed = >+ ParseFloat<base>(s.data(), s.data() + s.size(), format_flags); >+ EXPECT_EQ(parsed.end, nullptr); >+} >+ >+TEST(ParseFloat, SimpleValue) { >+ // Test that various forms of floating point numbers all parse correctly. >+ ExpectNumber<10>("1.23456789e5$", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("1.23456789e+5$", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("1.23456789E5$", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("1.23456789e05$", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("123.456789e3$", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("0.000123456789e9$", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("123456.789$", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("123456789e-3$", chars_format::general, 123456789, -3); >+ >+ ExpectNumber<16>("1.234abcdefp28$", chars_format::general, 0x1234abcdef, -8); >+ ExpectNumber<16>("1.234abcdefp+28$", chars_format::general, 0x1234abcdef, -8); >+ ExpectNumber<16>("1.234ABCDEFp28$", chars_format::general, 0x1234abcdef, -8); >+ ExpectNumber<16>("1.234AbCdEfP0028$", chars_format::general, 0x1234abcdef, >+ -8); >+ ExpectNumber<16>("123.4abcdefp20$", chars_format::general, 0x1234abcdef, -8); >+ ExpectNumber<16>("0.0001234abcdefp44$", chars_format::general, 0x1234abcdef, >+ -8); >+ ExpectNumber<16>("1234abcd.ef$", chars_format::general, 0x1234abcdef, -8); >+ ExpectNumber<16>("1234abcdefp-8$", chars_format::general, 0x1234abcdef, -8); >+ >+ // ExpectNumber does not attempt to drop trailing zeroes. >+ ExpectNumber<10>("0001.2345678900e005$", chars_format::general, 12345678900, >+ -5); >+ ExpectNumber<16>("0001.234abcdef000p28$", chars_format::general, >+ 0x1234abcdef000, -20); >+ >+ // Ensure non-matching characters after a number are ignored, even when they >+ // look like potentially matching characters. >+ ExpectNumber<10>("1.23456789e5$ ", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("1.23456789e5$e5e5", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("1.23456789e5$.25", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("1.23456789e5$-", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("1.23456789e5$PUPPERS!!!", chars_format::general, 123456789, >+ -3); >+ ExpectNumber<10>("123456.789$efghij", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("123456.789$e", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("123456.789$p5", chars_format::general, 123456789, -3); >+ ExpectNumber<10>("123456.789$.10", chars_format::general, 123456789, -3); >+ >+ ExpectNumber<16>("1.234abcdefp28$ ", chars_format::general, 0x1234abcdef, >+ -8); >+ ExpectNumber<16>("1.234abcdefp28$p28", chars_format::general, 0x1234abcdef, >+ -8); >+ ExpectNumber<16>("1.234abcdefp28$.125", chars_format::general, 0x1234abcdef, >+ -8); >+ ExpectNumber<16>("1.234abcdefp28$-", chars_format::general, 0x1234abcdef, -8); >+ ExpectNumber<16>("1.234abcdefp28$KITTEHS!!!", chars_format::general, >+ 0x1234abcdef, -8); >+ ExpectNumber<16>("1234abcd.ef$ghijk", chars_format::general, 0x1234abcdef, >+ -8); >+ ExpectNumber<16>("1234abcd.ef$p", chars_format::general, 0x1234abcdef, -8); >+ ExpectNumber<16>("1234abcd.ef$.10", chars_format::general, 0x1234abcdef, -8); >+ >+ // Ensure we can read a full resolution mantissa without overflow. >+ ExpectNumber<10>("9999999999999999999$", chars_format::general, >+ 9999999999999999999u, 0); >+ ExpectNumber<16>("fffffffffffffff$", chars_format::general, >+ 0xfffffffffffffffu, 0); >+ >+ // Check that zero is consistently read. >+ ExpectNumber<10>("0$", chars_format::general, 0, 0); >+ ExpectNumber<16>("0$", chars_format::general, 0, 0); >+ ExpectNumber<10>("000000000000000000000000000000000000000$", >+ chars_format::general, 0, 0); >+ ExpectNumber<16>("000000000000000000000000000000000000000$", >+ chars_format::general, 0, 0); >+ ExpectNumber<10>("0000000000000000000000.000000000000000000$", >+ chars_format::general, 0, 0); >+ ExpectNumber<16>("0000000000000000000000.000000000000000000$", >+ chars_format::general, 0, 0); >+ ExpectNumber<10>("0.00000000000000000000000000000000e123456$", >+ chars_format::general, 0, 0); >+ ExpectNumber<16>("0.00000000000000000000000000000000p123456$", >+ chars_format::general, 0, 0); >+} >+ >+TEST(ParseFloat, LargeDecimalMantissa) { >+ // After 19 significant decimal digits in the mantissa, ParsedFloat will >+ // truncate additional digits. We need to test that: >+ // 1) the truncation to 19 digits happens >+ // 2) the returned exponent reflects the dropped significant digits >+ // 3) a correct literal_exponent is set >+ // >+ // If and only if a significant digit is found after 19 digits, then the >+ // entirety of the mantissa in case the exact value is needed to make a >+ // rounding decision. The [ and ] characters below denote where such a >+ // subregion was marked by by ParseFloat. They are not part of the input. >+ >+ // Mark a capture group only if a dropped digit is significant (nonzero). >+ ExpectNumber<10>("100000000000000000000000000$", chars_format::general, >+ 1000000000000000000, >+ /* adjusted exponent */ 8); >+ >+ ExpectNumber<10>("123456789123456789100000000$", chars_format::general, >+ 1234567891234567891, >+ /* adjusted exponent */ 8); >+ >+ ExpectNumber<10>("[123456789123456789123456789]$", chars_format::general, >+ 1234567891234567891, >+ /* adjusted exponent */ 8, >+ /* literal exponent */ 0); >+ >+ ExpectNumber<10>("[123456789123456789100000009]$", chars_format::general, >+ 1234567891234567891, >+ /* adjusted exponent */ 8, >+ /* literal exponent */ 0); >+ >+ ExpectNumber<10>("[123456789123456789120000000]$", chars_format::general, >+ 1234567891234567891, >+ /* adjusted exponent */ 8, >+ /* literal exponent */ 0); >+ >+ // Leading zeroes should not count towards the 19 significant digit limit >+ ExpectNumber<10>("[00000000123456789123456789123456789]$", >+ chars_format::general, 1234567891234567891, >+ /* adjusted exponent */ 8, >+ /* literal exponent */ 0); >+ >+ ExpectNumber<10>("00000000123456789123456789100000000$", >+ chars_format::general, 1234567891234567891, >+ /* adjusted exponent */ 8); >+ >+ // Truncated digits after the decimal point should not cause a further >+ // exponent adjustment. >+ ExpectNumber<10>("1.234567891234567891e123$", chars_format::general, >+ 1234567891234567891, 105); >+ ExpectNumber<10>("[1.23456789123456789123456789]e123$", chars_format::general, >+ 1234567891234567891, >+ /* adjusted exponent */ 105, >+ /* literal exponent */ 123); >+ >+ // Ensure we truncate, and not round. (The from_chars algorithm we use >+ // depends on our guess missing low, if it misses, so we need the rounding >+ // error to be downward.) >+ ExpectNumber<10>("[1999999999999999999999]$", chars_format::general, >+ 1999999999999999999, >+ /* adjusted exponent */ 3, >+ /* literal exponent */ 0); >+} >+ >+TEST(ParseFloat, LargeHexadecimalMantissa) { >+ // After 15 significant hex digits in the mantissa, ParsedFloat will treat >+ // additional digits as sticky, We need to test that: >+ // 1) The truncation to 15 digits happens >+ // 2) The returned exponent reflects the dropped significant digits >+ // 3) If a nonzero digit is dropped, the low bit of mantissa is set. >+ >+ ExpectNumber<16>("123456789abcdef123456789abcdef$", chars_format::general, >+ 0x123456789abcdef, 60); >+ >+ // Leading zeroes should not count towards the 15 significant digit limit >+ ExpectNumber<16>("000000123456789abcdef123456789abcdef$", >+ chars_format::general, 0x123456789abcdef, 60); >+ >+ // Truncated digits after the radix point should not cause a further >+ // exponent adjustment. >+ ExpectNumber<16>("1.23456789abcdefp100$", chars_format::general, >+ 0x123456789abcdef, 44); >+ ExpectNumber<16>("1.23456789abcdef123456789abcdefp100$", >+ chars_format::general, 0x123456789abcdef, 44); >+ >+ // test sticky digit behavior. The low bit should be set iff any dropped >+ // digit is nonzero. >+ ExpectNumber<16>("123456789abcdee123456789abcdee$", chars_format::general, >+ 0x123456789abcdef, 60); >+ ExpectNumber<16>("123456789abcdee000000000000001$", chars_format::general, >+ 0x123456789abcdef, 60); >+ ExpectNumber<16>("123456789abcdee000000000000000$", chars_format::general, >+ 0x123456789abcdee, 60); >+} >+ >+TEST(ParseFloat, ScientificVsFixed) { >+ // In fixed mode, an exponent is never matched (but the remainder of the >+ // number will be matched.) >+ ExpectNumber<10>("1.23456789$e5", chars_format::fixed, 123456789, -8); >+ ExpectNumber<10>("123456.789$", chars_format::fixed, 123456789, -3); >+ ExpectNumber<16>("1.234abcdef$p28", chars_format::fixed, 0x1234abcdef, -36); >+ ExpectNumber<16>("1234abcd.ef$", chars_format::fixed, 0x1234abcdef, -8); >+ >+ // In scientific mode, numbers don't match *unless* they have an exponent. >+ ExpectNumber<10>("1.23456789e5$", chars_format::scientific, 123456789, -3); >+ ExpectFailedParse<10>("-123456.789$", chars_format::scientific); >+ ExpectNumber<16>("1.234abcdefp28$", chars_format::scientific, 0x1234abcdef, >+ -8); >+ ExpectFailedParse<16>("1234abcd.ef$", chars_format::scientific); >+} >+ >+TEST(ParseFloat, Infinity) { >+ ExpectFailedParse<10>("in", chars_format::general); >+ ExpectFailedParse<16>("in", chars_format::general); >+ ExpectFailedParse<10>("inx", chars_format::general); >+ ExpectFailedParse<16>("inx", chars_format::general); >+ ExpectSpecial("inf$", chars_format::general, FloatType::kInfinity); >+ ExpectSpecial("Inf$", chars_format::general, FloatType::kInfinity); >+ ExpectSpecial("INF$", chars_format::general, FloatType::kInfinity); >+ ExpectSpecial("inf$inite", chars_format::general, FloatType::kInfinity); >+ ExpectSpecial("iNfInItY$", chars_format::general, FloatType::kInfinity); >+ ExpectSpecial("infinity$!!!", chars_format::general, FloatType::kInfinity); >+} >+ >+TEST(ParseFloat, NaN) { >+ ExpectFailedParse<10>("na", chars_format::general); >+ ExpectFailedParse<16>("na", chars_format::general); >+ ExpectFailedParse<10>("nah", chars_format::general); >+ ExpectFailedParse<16>("nah", chars_format::general); >+ ExpectSpecial("nan$", chars_format::general, FloatType::kNan); >+ ExpectSpecial("NaN$", chars_format::general, FloatType::kNan); >+ ExpectSpecial("nAn$", chars_format::general, FloatType::kNan); >+ ExpectSpecial("NAN$", chars_format::general, FloatType::kNan); >+ ExpectSpecial("NaN$aNaNaNaNaBatman!", chars_format::general, FloatType::kNan); >+ >+ // A parenthesized sequence of the characters [a-zA-Z0-9_] is allowed to >+ // appear after an NaN. Check that this is allowed, and that the correct >+ // characters are grouped. >+ // >+ // (The characters [ and ] in the pattern below delimit the expected matched >+ // subgroup; they are not part of the input passed to ParseFloat.) >+ ExpectSpecial("nan([0xabcdef])$", chars_format::general, FloatType::kNan); >+ ExpectSpecial("nan([0xabcdef])$...", chars_format::general, FloatType::kNan); >+ ExpectSpecial("nan([0xabcdef])$)...", chars_format::general, FloatType::kNan); >+ ExpectSpecial("nan([])$", chars_format::general, FloatType::kNan); >+ ExpectSpecial("nan([aAzZ09_])$", chars_format::general, FloatType::kNan); >+ // If the subgroup contains illegal characters, don't match it at all. >+ ExpectSpecial("nan$(bad-char)", chars_format::general, FloatType::kNan); >+ // Also cope with a missing close paren. >+ ExpectSpecial("nan$(0xabcdef", chars_format::general, FloatType::kNan); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h >new file mode 100644 >index 0000000000000000000000000000000000000000..cc41f4312c7c1306e79100a911b347a99c0b24c1 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h >@@ -0,0 +1,131 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// This test contains common things needed by both escaping_test.cc and >+// escaping_benchmark.cc. >+ >+#ifndef ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_ >+#define ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_ >+ >+#include <array> >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+struct base64_testcase { >+ absl::string_view plaintext; >+ absl::string_view cyphertext; >+}; >+ >+inline const std::array<base64_testcase, 5>& base64_strings() { >+ static const std::array<base64_testcase, 5> testcase{{ >+ // Some google quotes >+ // Cyphertext created with "uuencode (GNU sharutils) 4.6.3" >+ // (Note that we're testing the websafe encoding, though, so if >+ // you add messages, be sure to run "tr -- '+/' '-_'" on the output) >+ { "I was always good at math and science, and I never realized " >+ "that was unusual or somehow undesirable. So one of the things " >+ "I care a lot about is helping to remove that stigma, " >+ "to show girls that you can be feminine, you can like the things " >+ "that girls like, but you can also be really good at technology. " >+ "You can be really good at building things." >+ " - Marissa Meyer, Newsweek, 2010-12-22" "\n", >+ >+ "SSB3YXMgYWx3YXlzIGdvb2QgYXQgbWF0aCBhbmQgc2NpZW5jZSwgYW5kIEkg" >+ "bmV2ZXIgcmVhbGl6ZWQgdGhhdCB3YXMgdW51c3VhbCBvciBzb21laG93IHVu" >+ "ZGVzaXJhYmxlLiBTbyBvbmUgb2YgdGhlIHRoaW5ncyBJIGNhcmUgYSBsb3Qg" >+ "YWJvdXQgaXMgaGVscGluZyB0byByZW1vdmUgdGhhdCBzdGlnbWEsIHRvIHNo" >+ "b3cgZ2lybHMgdGhhdCB5b3UgY2FuIGJlIGZlbWluaW5lLCB5b3UgY2FuIGxp" >+ "a2UgdGhlIHRoaW5ncyB0aGF0IGdpcmxzIGxpa2UsIGJ1dCB5b3UgY2FuIGFs" >+ "c28gYmUgcmVhbGx5IGdvb2QgYXQgdGVjaG5vbG9neS4gWW91IGNhbiBiZSBy" >+ "ZWFsbHkgZ29vZCBhdCBidWlsZGluZyB0aGluZ3MuIC0gTWFyaXNzYSBNZXll" >+ "ciwgTmV3c3dlZWssIDIwMTAtMTItMjIK" }, >+ >+ { "Typical first year for a new cluster: " >+ "~0.5 overheating " >+ "~1 PDU failure " >+ "~1 rack-move " >+ "~1 network rewiring " >+ "~20 rack failures " >+ "~5 racks go wonky " >+ "~8 network maintenances " >+ "~12 router reloads " >+ "~3 router failures " >+ "~dozens of minor 30-second blips for dns " >+ "~1000 individual machine failures " >+ "~thousands of hard drive failures " >+ "slow disks, bad memory, misconfigured machines, flaky machines, etc." >+ " - Jeff Dean, The Joys of Real Hardware" "\n", >+ >+ "VHlwaWNhbCBmaXJzdCB5ZWFyIGZvciBhIG5ldyBjbHVzdGVyOiB-MC41IG92" >+ "ZXJoZWF0aW5nIH4xIFBEVSBmYWlsdXJlIH4xIHJhY2stbW92ZSB-MSBuZXR3" >+ "b3JrIHJld2lyaW5nIH4yMCByYWNrIGZhaWx1cmVzIH41IHJhY2tzIGdvIHdv" >+ "bmt5IH44IG5ldHdvcmsgbWFpbnRlbmFuY2VzIH4xMiByb3V0ZXIgcmVsb2Fk" >+ "cyB-MyByb3V0ZXIgZmFpbHVyZXMgfmRvemVucyBvZiBtaW5vciAzMC1zZWNv" >+ "bmQgYmxpcHMgZm9yIGRucyB-MTAwMCBpbmRpdmlkdWFsIG1hY2hpbmUgZmFp" >+ "bHVyZXMgfnRob3VzYW5kcyBvZiBoYXJkIGRyaXZlIGZhaWx1cmVzIHNsb3cg" >+ "ZGlza3MsIGJhZCBtZW1vcnksIG1pc2NvbmZpZ3VyZWQgbWFjaGluZXMsIGZs" >+ "YWt5IG1hY2hpbmVzLCBldGMuIC0gSmVmZiBEZWFuLCBUaGUgSm95cyBvZiBS" >+ "ZWFsIEhhcmR3YXJlCg" }, >+ >+ { "I'm the head of the webspam team at Google. " >+ "That means that if you type your name into Google and get porn back, " >+ "it's my fault. Unless you're a porn star, in which case porn is a " >+ "completely reasonable response." >+ " - Matt Cutts, Google Plus" "\n", >+ >+ "SSdtIHRoZSBoZWFkIG9mIHRoZSB3ZWJzcGFtIHRlYW0gYXQgR29vZ2xlLiAg" >+ "VGhhdCBtZWFucyB0aGF0IGlmIHlvdSB0eXBlIHlvdXIgbmFtZSBpbnRvIEdv" >+ "b2dsZSBhbmQgZ2V0IHBvcm4gYmFjaywgaXQncyBteSBmYXVsdC4gVW5sZXNz" >+ "IHlvdSdyZSBhIHBvcm4gc3RhciwgaW4gd2hpY2ggY2FzZSBwb3JuIGlzIGEg" >+ "Y29tcGxldGVseSByZWFzb25hYmxlIHJlc3BvbnNlLiAtIE1hdHQgQ3V0dHMs" >+ "IEdvb2dsZSBQbHVzCg" }, >+ >+ { "It will still be a long time before machines approach human " >+ "intelligence. " >+ "But luckily, machines don't actually have to be intelligent; " >+ "they just have to fake it. Access to a wealth of information, " >+ "combined with a rudimentary decision-making capacity, " >+ "can often be almost as useful. Of course, the results are better yet " >+ "when coupled with intelligence. A reference librarian with access to " >+ "a good search engine is a formidable tool." >+ " - Craig Silverstein, Siemens Pictures of the Future, Spring 2004" >+ "\n", >+ >+ "SXQgd2lsbCBzdGlsbCBiZSBhIGxvbmcgdGltZSBiZWZvcmUgbWFjaGluZXMg" >+ "YXBwcm9hY2ggaHVtYW4gaW50ZWxsaWdlbmNlLiBCdXQgbHVja2lseSwgbWFj" >+ "aGluZXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSB0byBiZSBpbnRlbGxpZ2VudDsg" >+ "dGhleSBqdXN0IGhhdmUgdG8gZmFrZSBpdC4gQWNjZXNzIHRvIGEgd2VhbHRo" >+ "IG9mIGluZm9ybWF0aW9uLCBjb21iaW5lZCB3aXRoIGEgcnVkaW1lbnRhcnkg" >+ "ZGVjaXNpb24tbWFraW5nIGNhcGFjaXR5LCBjYW4gb2Z0ZW4gYmUgYWxtb3N0" >+ "IGFzIHVzZWZ1bC4gT2YgY291cnNlLCB0aGUgcmVzdWx0cyBhcmUgYmV0dGVy" >+ "IHlldCB3aGVuIGNvdXBsZWQgd2l0aCBpbnRlbGxpZ2VuY2UuIEEgcmVmZXJl" >+ "bmNlIGxpYnJhcmlhbiB3aXRoIGFjY2VzcyB0byBhIGdvb2Qgc2VhcmNoIGVu" >+ "Z2luZSBpcyBhIGZvcm1pZGFibGUgdG9vbC4gLSBDcmFpZyBTaWx2ZXJzdGVp" >+ "biwgU2llbWVucyBQaWN0dXJlcyBvZiB0aGUgRnV0dXJlLCBTcHJpbmcgMjAw" >+ "NAo" }, >+ >+ // Degenerate edge case >+ { "", >+ "" }, >+ }}; >+ >+ return testcase; >+} >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..a0de70dffdbdc0273a20c81781b94faa87233351 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil.cc >@@ -0,0 +1,110 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/memutil.h" >+ >+#include <cstdlib> >+ >+namespace absl { >+namespace strings_internal { >+ >+int memcasecmp(const char* s1, const char* s2, size_t len) { >+ const unsigned char* us1 = reinterpret_cast<const unsigned char*>(s1); >+ const unsigned char* us2 = reinterpret_cast<const unsigned char*>(s2); >+ >+ for (size_t i = 0; i < len; i++) { >+ const int diff = >+ int{static_cast<unsigned char>(absl::ascii_tolower(us1[i]))} - >+ int{static_cast<unsigned char>(absl::ascii_tolower(us2[i]))}; >+ if (diff != 0) return diff; >+ } >+ return 0; >+} >+ >+char* memdup(const char* s, size_t slen) { >+ void* copy; >+ if ((copy = malloc(slen)) == nullptr) return nullptr; >+ memcpy(copy, s, slen); >+ return reinterpret_cast<char*>(copy); >+} >+ >+char* memrchr(const char* s, int c, size_t slen) { >+ for (const char* e = s + slen - 1; e >= s; e--) { >+ if (*e == c) return const_cast<char*>(e); >+ } >+ return nullptr; >+} >+ >+size_t memspn(const char* s, size_t slen, const char* accept) { >+ const char* p = s; >+ const char* spanp; >+ char c, sc; >+ >+cont: >+ c = *p++; >+ if (slen-- == 0) return p - 1 - s; >+ for (spanp = accept; (sc = *spanp++) != '\0';) >+ if (sc == c) goto cont; >+ return p - 1 - s; >+} >+ >+size_t memcspn(const char* s, size_t slen, const char* reject) { >+ const char* p = s; >+ const char* spanp; >+ char c, sc; >+ >+ while (slen-- != 0) { >+ c = *p++; >+ for (spanp = reject; (sc = *spanp++) != '\0';) >+ if (sc == c) return p - 1 - s; >+ } >+ return p - s; >+} >+ >+char* mempbrk(const char* s, size_t slen, const char* accept) { >+ const char* scanp; >+ int sc; >+ >+ for (; slen; ++s, --slen) { >+ for (scanp = accept; (sc = *scanp++) != '\0';) >+ if (sc == *s) return const_cast<char*>(s); >+ } >+ return nullptr; >+} >+ >+// This is significantly faster for case-sensitive matches with very >+// few possible matches. See unit test for benchmarks. >+const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle, >+ size_t neelen) { >+ if (0 == neelen) { >+ return phaystack; // even if haylen is 0 >+ } >+ if (haylen < neelen) return nullptr; >+ >+ const char* match; >+ const char* hayend = phaystack + haylen - neelen + 1; >+ // A static cast is used here to work around the fact that memchr returns >+ // a void* on Posix-compliant systems and const void* on Windows. >+ while ((match = static_cast<const char*>( >+ memchr(phaystack, pneedle[0], hayend - phaystack)))) { >+ if (memcmp(match, pneedle, neelen) == 0) >+ return match; >+ else >+ phaystack = match + 1; >+ } >+ return nullptr; >+} >+ >+} // namespace strings_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil.h >new file mode 100644 >index 0000000000000000000000000000000000000000..a6f1c69138e3872f127e70aeb26e159a82925a0c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil.h >@@ -0,0 +1,146 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+// These routines provide mem versions of standard C std::string routines, >+// such as strpbrk. They function exactly the same as the str versions, >+// so if you wonder what they are, replace the word "mem" by >+// "str" and check out the man page. I could return void*, as the >+// strutil.h mem*() routines tend to do, but I return char* instead >+// since this is by far the most common way these functions are called. >+// >+// The difference between the mem and str versions is the mem version >+// takes a pointer and a length, rather than a '\0'-terminated std::string. >+// The memcase* routines defined here assume the locale is "C" >+// (they use absl::ascii_tolower instead of tolower). >+// >+// These routines are based on the BSD library. >+// >+// Here's a list of routines from std::string.h, and their mem analogues. >+// Functions in lowercase are defined in std::string.h; those in UPPERCASE >+// are defined here: >+// >+// strlen -- >+// strcat strncat MEMCAT >+// strcpy strncpy memcpy >+// -- memccpy (very cool function, btw) >+// -- memmove >+// -- memset >+// strcmp strncmp memcmp >+// strcasecmp strncasecmp MEMCASECMP >+// strchr memchr >+// strcoll -- >+// strxfrm -- >+// strdup strndup MEMDUP >+// strrchr MEMRCHR >+// strspn MEMSPN >+// strcspn MEMCSPN >+// strpbrk MEMPBRK >+// strstr MEMSTR MEMMEM >+// (g)strcasestr MEMCASESTR MEMCASEMEM >+// strtok -- >+// strprefix MEMPREFIX (strprefix is from strutil.h) >+// strcaseprefix MEMCASEPREFIX (strcaseprefix is from strutil.h) >+// strsuffix MEMSUFFIX (strsuffix is from strutil.h) >+// strcasesuffix MEMCASESUFFIX (strcasesuffix is from strutil.h) >+// -- MEMIS >+// -- MEMCASEIS >+// strcount MEMCOUNT (strcount is from strutil.h) >+ >+#ifndef ABSL_STRINGS_INTERNAL_MEMUTIL_H_ >+#define ABSL_STRINGS_INTERNAL_MEMUTIL_H_ >+ >+#include <cstddef> >+#include <cstring> >+ >+#include "absl/base/port.h" // disable some warnings on Windows >+#include "absl/strings/ascii.h" // for absl::ascii_tolower >+ >+namespace absl { >+namespace strings_internal { >+ >+inline char* memcat(char* dest, size_t destlen, const char* src, >+ size_t srclen) { >+ return reinterpret_cast<char*>(memcpy(dest + destlen, src, srclen)); >+} >+ >+int memcasecmp(const char* s1, const char* s2, size_t len); >+char* memdup(const char* s, size_t slen); >+char* memrchr(const char* s, int c, size_t slen); >+size_t memspn(const char* s, size_t slen, const char* accept); >+size_t memcspn(const char* s, size_t slen, const char* reject); >+char* mempbrk(const char* s, size_t slen, const char* accept); >+ >+// This is for internal use only. Don't call this directly >+template <bool case_sensitive> >+const char* int_memmatch(const char* haystack, size_t haylen, >+ const char* needle, size_t neelen) { >+ if (0 == neelen) { >+ return haystack; // even if haylen is 0 >+ } >+ const char* hayend = haystack + haylen; >+ const char* needlestart = needle; >+ const char* needleend = needlestart + neelen; >+ >+ for (; haystack < hayend; ++haystack) { >+ char hay = case_sensitive >+ ? *haystack >+ : absl::ascii_tolower(static_cast<unsigned char>(*haystack)); >+ char nee = case_sensitive >+ ? *needle >+ : absl::ascii_tolower(static_cast<unsigned char>(*needle)); >+ if (hay == nee) { >+ if (++needle == needleend) { >+ return haystack + 1 - neelen; >+ } >+ } else if (needle != needlestart) { >+ // must back up haystack in case a prefix matched (find "aab" in "aaab") >+ haystack -= needle - needlestart; // for loop will advance one more >+ needle = needlestart; >+ } >+ } >+ return nullptr; >+} >+ >+// These are the guys you can call directly >+inline const char* memstr(const char* phaystack, size_t haylen, >+ const char* pneedle) { >+ return int_memmatch<true>(phaystack, haylen, pneedle, strlen(pneedle)); >+} >+ >+inline const char* memcasestr(const char* phaystack, size_t haylen, >+ const char* pneedle) { >+ return int_memmatch<false>(phaystack, haylen, pneedle, strlen(pneedle)); >+} >+ >+inline const char* memmem(const char* phaystack, size_t haylen, >+ const char* pneedle, size_t needlelen) { >+ return int_memmatch<true>(phaystack, haylen, pneedle, needlelen); >+} >+ >+inline const char* memcasemem(const char* phaystack, size_t haylen, >+ const char* pneedle, size_t needlelen) { >+ return int_memmatch<false>(phaystack, haylen, pneedle, needlelen); >+} >+ >+// This is significantly faster for case-sensitive matches with very >+// few possible matches. See unit test for benchmarks. >+const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle, >+ size_t neelen); >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_MEMUTIL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..77915adb958ee58b5f5c5825cd87a4c97144da2d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc >@@ -0,0 +1,323 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/memutil.h" >+ >+#include <algorithm> >+#include <cstdlib> >+ >+#include "benchmark/benchmark.h" >+#include "absl/strings/ascii.h" >+ >+// We fill the haystack with aaaaaaaaaaaaaaaaaa...aaaab. >+// That gives us: >+// - an easy search: 'b' >+// - a medium search: 'ab'. That means every letter is a possible match. >+// - a pathological search: 'aaaaaa.......aaaaab' (half as many a's as haytack) >+// We benchmark case-sensitive and case-insensitive versions of >+// three memmem implementations: >+// - memmem() from memutil.h >+// - search() from STL >+// - memmatch(), a custom implementation using memchr and memcmp. >+// Here are sample results: >+// >+// Run on (12 X 3800 MHz CPU s) >+// CPU Caches: >+// L1 Data 32K (x6) >+// L1 Instruction 32K (x6) >+// L2 Unified 256K (x6) >+// L3 Unified 15360K (x1) >+// ---------------------------------------------------------------- >+// Benchmark Time CPU Iterations >+// ---------------------------------------------------------------- >+// BM_Memmem 3583 ns 3582 ns 196469 2.59966GB/s >+// BM_MemmemMedium 13743 ns 13742 ns 50901 693.986MB/s >+// BM_MemmemPathological 13695030 ns 13693977 ns 51 713.133kB/s >+// BM_Memcasemem 3299 ns 3299 ns 212942 2.82309GB/s >+// BM_MemcasememMedium 16407 ns 16406 ns 42170 581.309MB/s >+// BM_MemcasememPathological 17267745 ns 17266030 ns 41 565.598kB/s >+// BM_Search 1610 ns 1609 ns 431321 5.78672GB/s >+// BM_SearchMedium 11111 ns 11110 ns 63001 858.414MB/s >+// BM_SearchPathological 12117390 ns 12116397 ns 58 805.984kB/s >+// BM_Searchcase 3081 ns 3081 ns 229949 3.02313GB/s >+// BM_SearchcaseMedium 16003 ns 16001 ns 44170 595.998MB/s >+// BM_SearchcasePathological 15823413 ns 15821909 ns 44 617.222kB/s >+// BM_Memmatch 197 ns 197 ns 3584225 47.2951GB/s >+// BM_MemmatchMedium 52333 ns 52329 ns 13280 182.244MB/s >+// BM_MemmatchPathological 659799 ns 659727 ns 1058 14.4556MB/s >+// BM_Memcasematch 5460 ns 5460 ns 127606 1.70586GB/s >+// BM_MemcasematchMedium 32861 ns 32857 ns 21258 290.248MB/s >+// BM_MemcasematchPathological 15154243 ns 15153089 ns 46 644.464kB/s >+// BM_MemmemStartup 5 ns 5 ns 150821500 >+// BM_SearchStartup 5 ns 5 ns 150644203 >+// BM_MemmatchStartup 7 ns 7 ns 97068802 >+// >+// Conclusions: >+// >+// The following recommendations are based on the sample results above. However, >+// we have found that the performance of STL search can vary significantly >+// depending on compiler and standard library implementation. We recommend you >+// run the benchmarks for yourself on relevant platforms. >+// >+// If you need case-insensitive, STL search is slightly better than memmem for >+// all cases. >+// >+// Case-sensitive is more subtle: >+// Custom memmatch is _very_ fast at scanning, so if you have very few possible >+// matches in your haystack, that's the way to go. Performance drops >+// significantly with more matches. >+// >+// STL search is slightly faster than memmem in the medium and pathological >+// benchmarks. However, the performance of memmem is currently more dependable >+// across platforms and build configurations. >+ >+namespace { >+ >+constexpr int kHaystackSize = 10000; >+constexpr int64_t kHaystackSize64 = kHaystackSize; >+const char* MakeHaystack() { >+ char* haystack = new char[kHaystackSize]; >+ for (int i = 0; i < kHaystackSize - 1; ++i) haystack[i] = 'a'; >+ haystack[kHaystackSize - 1] = 'b'; >+ return haystack; >+} >+const char* const kHaystack = MakeHaystack(); >+ >+void BM_Memmem(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::strings_internal::memmem(kHaystack, kHaystackSize, "b", 1)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_Memmem); >+ >+void BM_MemmemMedium(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::strings_internal::memmem(kHaystack, kHaystackSize, "ab", 2)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_MemmemMedium); >+ >+void BM_MemmemPathological(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(absl::strings_internal::memmem( >+ kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2, >+ kHaystackSize - kHaystackSize / 2)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_MemmemPathological); >+ >+void BM_Memcasemem(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::strings_internal::memcasemem(kHaystack, kHaystackSize, "b", 1)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_Memcasemem); >+ >+void BM_MemcasememMedium(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::strings_internal::memcasemem(kHaystack, kHaystackSize, "ab", 2)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_MemcasememMedium); >+ >+void BM_MemcasememPathological(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(absl::strings_internal::memcasemem( >+ kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2, >+ kHaystackSize - kHaystackSize / 2)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_MemcasememPathological); >+ >+bool case_eq(const char a, const char b) { >+ return absl::ascii_tolower(a) == absl::ascii_tolower(b); >+} >+ >+void BM_Search(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, >+ kHaystack + kHaystackSize - 1, >+ kHaystack + kHaystackSize)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_Search); >+ >+void BM_SearchMedium(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, >+ kHaystack + kHaystackSize - 2, >+ kHaystack + kHaystackSize)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_SearchMedium); >+ >+void BM_SearchPathological(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, >+ kHaystack + kHaystackSize / 2, >+ kHaystack + kHaystackSize)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_SearchPathological); >+ >+void BM_Searchcase(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, >+ kHaystack + kHaystackSize - 1, >+ kHaystack + kHaystackSize, case_eq)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_Searchcase); >+ >+void BM_SearchcaseMedium(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, >+ kHaystack + kHaystackSize - 2, >+ kHaystack + kHaystackSize, case_eq)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_SearchcaseMedium); >+ >+void BM_SearchcasePathological(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, >+ kHaystack + kHaystackSize / 2, >+ kHaystack + kHaystackSize, case_eq)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_SearchcasePathological); >+ >+char* memcasechr(const char* s, int c, size_t slen) { >+ c = absl::ascii_tolower(c); >+ for (; slen; ++s, --slen) { >+ if (absl::ascii_tolower(*s) == c) return const_cast<char*>(s); >+ } >+ return nullptr; >+} >+ >+const char* memcasematch(const char* phaystack, size_t haylen, >+ const char* pneedle, size_t neelen) { >+ if (0 == neelen) { >+ return phaystack; // even if haylen is 0 >+ } >+ if (haylen < neelen) return nullptr; >+ >+ const char* match; >+ const char* hayend = phaystack + haylen - neelen + 1; >+ while ((match = static_cast<char*>( >+ memcasechr(phaystack, pneedle[0], hayend - phaystack)))) { >+ if (absl::strings_internal::memcasecmp(match, pneedle, neelen) == 0) >+ return match; >+ else >+ phaystack = match + 1; >+ } >+ return nullptr; >+} >+ >+void BM_Memmatch(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::strings_internal::memmatch(kHaystack, kHaystackSize, "b", 1)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_Memmatch); >+ >+void BM_MemmatchMedium(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::strings_internal::memmatch(kHaystack, kHaystackSize, "ab", 2)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_MemmatchMedium); >+ >+void BM_MemmatchPathological(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(absl::strings_internal::memmatch( >+ kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2, >+ kHaystackSize - kHaystackSize / 2)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_MemmatchPathological); >+ >+void BM_Memcasematch(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize, "b", 1)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_Memcasematch); >+ >+void BM_MemcasematchMedium(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize, "ab", 2)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_MemcasematchMedium); >+ >+void BM_MemcasematchPathological(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize, >+ kHaystack + kHaystackSize / 2, >+ kHaystackSize - kHaystackSize / 2)); >+ } >+ state.SetBytesProcessed(kHaystackSize64 * state.iterations()); >+} >+BENCHMARK(BM_MemcasematchPathological); >+ >+void BM_MemmemStartup(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(absl::strings_internal::memmem( >+ kHaystack + kHaystackSize - 10, 10, kHaystack + kHaystackSize - 1, 1)); >+ } >+} >+BENCHMARK(BM_MemmemStartup); >+ >+void BM_SearchStartup(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ std::search(kHaystack + kHaystackSize - 10, kHaystack + kHaystackSize, >+ kHaystack + kHaystackSize - 1, kHaystack + kHaystackSize)); >+ } >+} >+BENCHMARK(BM_SearchStartup); >+ >+void BM_MemmatchStartup(benchmark::State& state) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(absl::strings_internal::memmatch( >+ kHaystack + kHaystackSize - 10, 10, kHaystack + kHaystackSize - 1, 1)); >+ } >+} >+BENCHMARK(BM_MemmatchStartup); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..09424de9a477f4e8a9a3821d9ef052d2f0c2b19d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/memutil_test.cc >@@ -0,0 +1,179 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Unit test for memutil.cc >+ >+#include "absl/strings/internal/memutil.h" >+ >+#include <cstdlib> >+ >+#include "gtest/gtest.h" >+#include "absl/strings/ascii.h" >+ >+namespace { >+ >+static char* memcasechr(const char* s, int c, size_t slen) { >+ c = absl::ascii_tolower(c); >+ for (; slen; ++s, --slen) { >+ if (absl::ascii_tolower(*s) == c) return const_cast<char*>(s); >+ } >+ return nullptr; >+} >+ >+static const char* memcasematch(const char* phaystack, size_t haylen, >+ const char* pneedle, size_t neelen) { >+ if (0 == neelen) { >+ return phaystack; // even if haylen is 0 >+ } >+ if (haylen < neelen) return nullptr; >+ >+ const char* match; >+ const char* hayend = phaystack + haylen - neelen + 1; >+ while ((match = static_cast<char*>( >+ memcasechr(phaystack, pneedle[0], hayend - phaystack)))) { >+ if (absl::strings_internal::memcasecmp(match, pneedle, neelen) == 0) >+ return match; >+ else >+ phaystack = match + 1; >+ } >+ return nullptr; >+} >+ >+TEST(MemUtilTest, AllTests) { >+ // check memutil functions >+ char a[1000]; >+ absl::strings_internal::memcat(a, 0, "hello", sizeof("hello") - 1); >+ absl::strings_internal::memcat(a, 5, " there", sizeof(" there") - 1); >+ >+ EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO there", >+ sizeof("hello there") - 1), >+ 0); >+ EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO therf", >+ sizeof("hello there") - 1), >+ -1); >+ EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO therf", >+ sizeof("hello there") - 2), >+ 0); >+ EXPECT_EQ(absl::strings_internal::memcasecmp(a, "whatever", 0), 0); >+ >+ char* p = absl::strings_internal::memdup("hello", 5); >+ free(p); >+ >+ p = absl::strings_internal::memrchr("hello there", 'e', >+ sizeof("hello there") - 1); >+ EXPECT_TRUE(p && p[-1] == 'r'); >+ p = absl::strings_internal::memrchr("hello there", 'e', >+ sizeof("hello there") - 2); >+ EXPECT_TRUE(p && p[-1] == 'h'); >+ p = absl::strings_internal::memrchr("hello there", 'u', >+ sizeof("hello there") - 1); >+ EXPECT_TRUE(p == nullptr); >+ >+ int len = absl::strings_internal::memspn("hello there", >+ sizeof("hello there") - 1, "hole"); >+ EXPECT_EQ(len, sizeof("hello") - 1); >+ len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1, >+ "u"); >+ EXPECT_EQ(len, 0); >+ len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1, >+ ""); >+ EXPECT_EQ(len, 0); >+ len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1, >+ "trole h"); >+ EXPECT_EQ(len, sizeof("hello there") - 1); >+ len = absl::strings_internal::memspn("hello there!", >+ sizeof("hello there!") - 1, "trole h"); >+ EXPECT_EQ(len, sizeof("hello there") - 1); >+ len = absl::strings_internal::memspn("hello there!", >+ sizeof("hello there!") - 2, "trole h!"); >+ EXPECT_EQ(len, sizeof("hello there!") - 2); >+ >+ len = absl::strings_internal::memcspn("hello there", >+ sizeof("hello there") - 1, "leho"); >+ EXPECT_EQ(len, 0); >+ len = absl::strings_internal::memcspn("hello there", >+ sizeof("hello there") - 1, "u"); >+ EXPECT_EQ(len, sizeof("hello there") - 1); >+ len = absl::strings_internal::memcspn("hello there", >+ sizeof("hello there") - 1, ""); >+ EXPECT_EQ(len, sizeof("hello there") - 1); >+ len = absl::strings_internal::memcspn("hello there", >+ sizeof("hello there") - 1, " "); >+ EXPECT_EQ(len, 5); >+ >+ p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1, >+ "leho"); >+ EXPECT_TRUE(p && p[1] == 'e' && p[2] == 'l'); >+ p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1, >+ "nu"); >+ EXPECT_TRUE(p == nullptr); >+ p = absl::strings_internal::mempbrk("hello there!", >+ sizeof("hello there!") - 2, "!"); >+ EXPECT_TRUE(p == nullptr); >+ p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1, >+ " t "); >+ EXPECT_TRUE(p && p[-1] == 'o' && p[1] == 't'); >+ >+ { >+ const char kHaystack[] = "0123456789"; >+ EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 0, "", 0), kHaystack); >+ EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "012", 3), >+ kHaystack); >+ EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "0xx", 1), >+ kHaystack); >+ EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "789", 3), >+ kHaystack + 7); >+ EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "9xx", 1), >+ kHaystack + 9); >+ EXPECT_TRUE(absl::strings_internal::memmem(kHaystack, 10, "9xx", 3) == >+ nullptr); >+ EXPECT_TRUE(absl::strings_internal::memmem(kHaystack, 10, "xxx", 1) == >+ nullptr); >+ } >+ { >+ const char kHaystack[] = "aBcDeFgHiJ"; >+ EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 0, "", 0), >+ kHaystack); >+ EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "Abc", 3), >+ kHaystack); >+ EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "Axx", 1), >+ kHaystack); >+ EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "hIj", 3), >+ kHaystack + 7); >+ EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "jxx", 1), >+ kHaystack + 9); >+ EXPECT_TRUE(absl::strings_internal::memcasemem(kHaystack, 10, "jxx", 3) == >+ nullptr); >+ EXPECT_TRUE(absl::strings_internal::memcasemem(kHaystack, 10, "xxx", 1) == >+ nullptr); >+ } >+ { >+ const char kHaystack[] = "0123456789"; >+ EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 0, "", 0), kHaystack); >+ EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "012", 3), >+ kHaystack); >+ EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "0xx", 1), >+ kHaystack); >+ EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "789", 3), >+ kHaystack + 7); >+ EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "9xx", 1), >+ kHaystack + 9); >+ EXPECT_TRUE(absl::strings_internal::memmatch(kHaystack, 10, "9xx", 3) == >+ nullptr); >+ EXPECT_TRUE(absl::strings_internal::memmatch(kHaystack, 10, "xxx", 1) == >+ nullptr); >+ } >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/numbers_test_common.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/numbers_test_common.h >new file mode 100644 >index 0000000000000000000000000000000000000000..20e3af51141efbed0589f544060eaae6958b1590 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/numbers_test_common.h >@@ -0,0 +1,178 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// This file contains common things needed by numbers_test.cc, >+// numbers_legacy_test.cc and numbers_benchmark.cc. >+ >+#ifndef ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_ >+#define ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_ >+ >+#include <array> >+#include <cstdint> >+#include <limits> >+#include <string> >+ >+namespace absl { >+namespace strings_internal { >+ >+template <typename IntType> >+inline bool Itoa(IntType value, int base, std::string* destination) { >+ destination->clear(); >+ if (base <= 1 || base > 36) { >+ return false; >+ } >+ >+ if (value == 0) { >+ destination->push_back('0'); >+ return true; >+ } >+ >+ bool negative = value < 0; >+ while (value != 0) { >+ const IntType next_value = value / base; >+ // Can't use std::abs here because of problems when IntType is unsigned. >+ int remainder = value > next_value * base ? value - next_value * base >+ : next_value * base - value; >+ char c = remainder < 10 ? '0' + remainder : 'A' + remainder - 10; >+ destination->insert(0, 1, c); >+ value = next_value; >+ } >+ >+ if (negative) { >+ destination->insert(0, 1, '-'); >+ } >+ return true; >+} >+ >+struct uint32_test_case { >+ const char* str; >+ bool expect_ok; >+ int base; // base to pass to the conversion function >+ uint32_t expected; >+}; >+ >+inline const std::array<uint32_test_case, 27>& strtouint32_test_cases() { >+ static const std::array<uint32_test_case, 27> test_cases{{ >+ {"0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()}, >+ {"0x34234324", true, 16, 0x34234324}, >+ {"34234324", true, 16, 0x34234324}, >+ {"0", true, 16, 0}, >+ {" \t\n 0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()}, >+ {" \f\v 46", true, 10, 46}, // must accept weird whitespace >+ {" \t\n 72717222", true, 8, 072717222}, >+ {" \t\n 072717222", true, 8, 072717222}, >+ {" \t\n 072717228", false, 8, 07271722}, >+ {"0", true, 0, 0}, >+ >+ // Base-10 version. >+ {"34234324", true, 0, 34234324}, >+ {"4294967295", true, 0, std::numeric_limits<uint32_t>::max()}, >+ {"34234324 \n\t", true, 10, 34234324}, >+ >+ // Unusual base >+ {"0", true, 3, 0}, >+ {"2", true, 3, 2}, >+ {"11", true, 3, 4}, >+ >+ // Invalid uints. >+ {"", false, 0, 0}, >+ {" ", false, 0, 0}, >+ {"abc", false, 0, 0}, // would be valid hex, but prefix is missing >+ {"34234324a", false, 0, 34234324}, >+ {"34234.3", false, 0, 34234}, >+ {"-1", false, 0, 0}, >+ {" -123", false, 0, 0}, >+ {" \t\n -123", false, 0, 0}, >+ >+ // Out of bounds. >+ {"4294967296", false, 0, std::numeric_limits<uint32_t>::max()}, >+ {"0x100000000", false, 0, std::numeric_limits<uint32_t>::max()}, >+ {nullptr, false, 0, 0}, >+ }}; >+ return test_cases; >+} >+ >+struct uint64_test_case { >+ const char* str; >+ bool expect_ok; >+ int base; >+ uint64_t expected; >+}; >+ >+inline const std::array<uint64_test_case, 34>& strtouint64_test_cases() { >+ static const std::array<uint64_test_case, 34> test_cases{{ >+ {"0x3423432448783446", true, 16, int64_t{0x3423432448783446}}, >+ {"3423432448783446", true, 16, int64_t{0x3423432448783446}}, >+ >+ {"0", true, 16, 0}, >+ {"000", true, 0, 0}, >+ {"0", true, 0, 0}, >+ {" \t\n 0xffffffffffffffff", true, 16, >+ std::numeric_limits<uint64_t>::max()}, >+ >+ {"012345670123456701234", true, 8, int64_t{012345670123456701234}}, >+ {"12345670123456701234", true, 8, int64_t{012345670123456701234}}, >+ >+ {"12845670123456701234", false, 8, 0}, >+ >+ // Base-10 version. >+ {"34234324487834466", true, 0, int64_t{34234324487834466}}, >+ >+ {" \t\n 18446744073709551615", true, 0, >+ std::numeric_limits<uint64_t>::max()}, >+ >+ {"34234324487834466 \n\t ", true, 0, int64_t{34234324487834466}}, >+ >+ {" \f\v 46", true, 10, 46}, // must accept weird whitespace >+ >+ // Unusual base >+ {"0", true, 3, 0}, >+ {"2", true, 3, 2}, >+ {"11", true, 3, 4}, >+ >+ {"0", true, 0, 0}, >+ >+ // Invalid uints. >+ {"", false, 0, 0}, >+ {" ", false, 0, 0}, >+ {"abc", false, 0, 0}, >+ {"34234324487834466a", false, 0, 0}, >+ {"34234487834466.3", false, 0, 0}, >+ {"-1", false, 0, 0}, >+ {" -123", false, 0, 0}, >+ {" \t\n -123", false, 0, 0}, >+ >+ // Out of bounds. >+ {"18446744073709551616", false, 10, 0}, >+ {"18446744073709551616", false, 0, 0}, >+ {"0x10000000000000000", false, 16, std::numeric_limits<uint64_t>::max()}, >+ {"0X10000000000000000", false, 16, >+ std::numeric_limits<uint64_t>::max()}, // 0X versus 0x. >+ {"0x10000000000000000", false, 0, std::numeric_limits<uint64_t>::max()}, >+ {"0X10000000000000000", false, 0, >+ std::numeric_limits<uint64_t>::max()}, // 0X versus 0x. >+ >+ {"0x1234", true, 16, 0x1234}, >+ >+ // Base-10 std::string version. >+ {"1234", true, 0, 1234}, >+ {nullptr, false, 0, 0}, >+ }}; >+ return test_cases; >+} >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..6ee2b109088722024d4f448b273c6057deea7eab >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc >@@ -0,0 +1,34 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/ostringstream.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+OStringStream::Buf::int_type OStringStream::overflow(int c) { >+ assert(s_); >+ if (!Buf::traits_type::eq_int_type(c, Buf::traits_type::eof())) >+ s_->push_back(static_cast<char>(c)); >+ return 1; >+} >+ >+std::streamsize OStringStream::xsputn(const char* s, std::streamsize n) { >+ assert(s_); >+ s_->append(s, n); >+ return n; >+} >+ >+} // namespace strings_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream.h >new file mode 100644 >index 0000000000000000000000000000000000000000..6e1325b9140f8a0c3eedb6f5a13e21d8d6e0aaf6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream.h >@@ -0,0 +1,87 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_ >+#define ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_ >+ >+#include <cassert> >+#include <ostream> >+#include <streambuf> >+#include <string> >+ >+#include "absl/base/port.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+// The same as std::ostringstream but appends to a user-specified std::string, >+// and is faster. It is ~70% faster to create, ~50% faster to write to, and >+// completely free to extract the result std::string. >+// >+// std::string s; >+// OStringStream strm(&s); >+// strm << 42 << ' ' << 3.14; // appends to `s` >+// >+// The stream object doesn't have to be named. Starting from C++11 operator<< >+// works with rvalues of std::ostream. >+// >+// std::string s; >+// OStringStream(&s) << 42 << ' ' << 3.14; // appends to `s` >+// >+// OStringStream is faster to create than std::ostringstream but it's still >+// relatively slow. Avoid creating multiple streams where a single stream will >+// do. >+// >+// Creates unnecessary instances of OStringStream: slow. >+// >+// std::string s; >+// OStringStream(&s) << 42; >+// OStringStream(&s) << ' '; >+// OStringStream(&s) << 3.14; >+// >+// Creates a single instance of OStringStream and reuses it: fast. >+// >+// std::string s; >+// OStringStream strm(&s); >+// strm << 42; >+// strm << ' '; >+// strm << 3.14; >+// >+// Note: flush() has no effect. No reason to call it. >+class OStringStream : private std::basic_streambuf<char>, public std::ostream { >+ public: >+ // The argument can be null, in which case you'll need to call str(p) with a >+ // non-null argument before you can write to the stream. >+ // >+ // The destructor of OStringStream doesn't use the std::string. It's OK to destroy >+ // the std::string before the stream. >+ explicit OStringStream(std::string* s) : std::ostream(this), s_(s) {} >+ >+ std::string* str() { return s_; } >+ const std::string* str() const { return s_; } >+ void str(std::string* s) { s_ = s; } >+ >+ private: >+ using Buf = std::basic_streambuf<char>; >+ >+ Buf::int_type overflow(int c) override; >+ std::streamsize xsputn(const char* s, std::streamsize n) override; >+ >+ std::string* s_; >+}; >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..c93f96909d8b65434204d010646f58f4623e4ad1 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream_benchmark.cc >@@ -0,0 +1,106 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/ostringstream.h" >+ >+#include <sstream> >+#include <string> >+ >+#include "benchmark/benchmark.h" >+ >+namespace { >+ >+enum StringType { >+ kNone, >+ kStdString, >+}; >+ >+// Benchmarks for std::ostringstream. >+template <StringType kOutput> >+void BM_StdStream(benchmark::State& state) { >+ const int num_writes = state.range(0); >+ const int bytes_per_write = state.range(1); >+ const std::string payload(bytes_per_write, 'x'); >+ for (auto _ : state) { >+ std::ostringstream strm; >+ benchmark::DoNotOptimize(strm); >+ for (int i = 0; i != num_writes; ++i) { >+ strm << payload; >+ } >+ switch (kOutput) { >+ case kNone: { >+ break; >+ } >+ case kStdString: { >+ std::string s = strm.str(); >+ benchmark::DoNotOptimize(s); >+ break; >+ } >+ } >+ } >+} >+ >+// Create the stream, optionally write to it, then destroy it. >+BENCHMARK_TEMPLATE(BM_StdStream, kNone) >+ ->ArgPair(0, 0) >+ ->ArgPair(1, 16) // 16 bytes is small enough for SSO >+ ->ArgPair(1, 256) // 256 bytes requires heap allocation >+ ->ArgPair(1024, 256); >+// Create the stream, write to it, get std::string out, then destroy. >+BENCHMARK_TEMPLATE(BM_StdStream, kStdString) >+ ->ArgPair(1, 16) // 16 bytes is small enough for SSO >+ ->ArgPair(1, 256) // 256 bytes requires heap allocation >+ ->ArgPair(1024, 256); >+ >+// Benchmarks for OStringStream. >+template <StringType kOutput> >+void BM_CustomStream(benchmark::State& state) { >+ const int num_writes = state.range(0); >+ const int bytes_per_write = state.range(1); >+ const std::string payload(bytes_per_write, 'x'); >+ for (auto _ : state) { >+ std::string out; >+ absl::strings_internal::OStringStream strm(&out); >+ benchmark::DoNotOptimize(strm); >+ for (int i = 0; i != num_writes; ++i) { >+ strm << payload; >+ } >+ switch (kOutput) { >+ case kNone: { >+ break; >+ } >+ case kStdString: { >+ std::string s = out; >+ benchmark::DoNotOptimize(s); >+ break; >+ } >+ } >+ } >+} >+ >+// Create the stream, optionally write to it, then destroy it. >+BENCHMARK_TEMPLATE(BM_CustomStream, kNone) >+ ->ArgPair(0, 0) >+ ->ArgPair(1, 16) // 16 bytes is small enough for SSO >+ ->ArgPair(1, 256) // 256 bytes requires heap allocation >+ ->ArgPair(1024, 256); >+// Create the stream, write to it, get std::string out, then destroy. >+// It's not useful in practice to extract std::string from OStringStream; we >+// measure it for completeness. >+BENCHMARK_TEMPLATE(BM_CustomStream, kStdString) >+ ->ArgPair(1, 16) // 16 bytes is small enough for SSO >+ ->ArgPair(1, 256) // 256 bytes requires heap allocation >+ ->ArgPair(1024, 256); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..069a0e1fbbb114522ed22b91cbb1992060192ce1 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/ostringstream_test.cc >@@ -0,0 +1,102 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/ostringstream.h" >+ >+#include <memory> >+#include <ostream> >+#include <string> >+#include <type_traits> >+ >+#include "gtest/gtest.h" >+ >+namespace { >+ >+TEST(OStringStream, IsOStream) { >+ static_assert( >+ std::is_base_of<std::ostream, absl::strings_internal::OStringStream>(), >+ ""); >+} >+ >+TEST(OStringStream, ConstructDestroy) { >+ { >+ absl::strings_internal::OStringStream strm(nullptr); >+ EXPECT_EQ(nullptr, strm.str()); >+ } >+ { >+ std::string s = "abc"; >+ { >+ absl::strings_internal::OStringStream strm(&s); >+ EXPECT_EQ(&s, strm.str()); >+ } >+ EXPECT_EQ("abc", s); >+ } >+ { >+ std::unique_ptr<std::string> s(new std::string); >+ absl::strings_internal::OStringStream strm(s.get()); >+ s.reset(); >+ } >+} >+ >+TEST(OStringStream, Str) { >+ std::string s1; >+ absl::strings_internal::OStringStream strm(&s1); >+ const absl::strings_internal::OStringStream& c_strm(strm); >+ >+ static_assert(std::is_same<decltype(strm.str()), std::string*>(), ""); >+ static_assert(std::is_same<decltype(c_strm.str()), const std::string*>(), ""); >+ >+ EXPECT_EQ(&s1, strm.str()); >+ EXPECT_EQ(&s1, c_strm.str()); >+ >+ strm.str(&s1); >+ EXPECT_EQ(&s1, strm.str()); >+ EXPECT_EQ(&s1, c_strm.str()); >+ >+ std::string s2; >+ strm.str(&s2); >+ EXPECT_EQ(&s2, strm.str()); >+ EXPECT_EQ(&s2, c_strm.str()); >+ >+ strm.str(nullptr); >+ EXPECT_EQ(nullptr, strm.str()); >+ EXPECT_EQ(nullptr, c_strm.str()); >+} >+ >+TEST(OStreamStream, WriteToLValue) { >+ std::string s = "abc"; >+ { >+ absl::strings_internal::OStringStream strm(&s); >+ EXPECT_EQ("abc", s); >+ strm << ""; >+ EXPECT_EQ("abc", s); >+ strm << 42; >+ EXPECT_EQ("abc42", s); >+ strm << 'x' << 'y'; >+ EXPECT_EQ("abc42xy", s); >+ } >+ EXPECT_EQ("abc42xy", s); >+} >+ >+TEST(OStreamStream, WriteToRValue) { >+ std::string s = "abc"; >+ absl::strings_internal::OStringStream(&s) << ""; >+ EXPECT_EQ("abc", s); >+ absl::strings_internal::OStringStream(&s) << 42; >+ EXPECT_EQ("abc42", s); >+ absl::strings_internal::OStringStream(&s) << 'x' << 'y'; >+ EXPECT_EQ("abc42xy", s); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h >new file mode 100644 >index 0000000000000000000000000000000000000000..0157ca0245f350bece6dcbe1987bdb80b4a54551 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h >@@ -0,0 +1,69 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ >+#define ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ >+ >+#include <string> >+#include <utility> >+ >+#include "absl/base/port.h" >+#include "absl/meta/type_traits.h" // for void_t >+ >+namespace absl { >+namespace strings_internal { >+ >+// Is a subclass of true_type or false_type, depending on whether or not >+// T has a resize_uninitialized member. >+template <typename T, typename = void> >+struct HasResizeUninitialized : std::false_type {}; >+template <typename T> >+struct HasResizeUninitialized< >+ T, absl::void_t<decltype(std::declval<T>().resize_uninitialized(237))>> >+ : std::true_type {}; >+ >+template <typename string_type> >+void ResizeUninit(string_type* s, size_t new_size, std::true_type) { >+ s->resize_uninitialized(new_size); >+} >+template <typename string_type> >+void ResizeUninit(string_type* s, size_t new_size, std::false_type) { >+ s->resize(new_size); >+} >+ >+// Returns true if the std::string implementation supports a resize where >+// the new characters added to the std::string are left untouched. >+// >+// (A better name might be "STLStringSupportsUninitializedResize", alluding to >+// the previous function.) >+template <typename string_type> >+inline constexpr bool STLStringSupportsNontrashingResize(string_type*) { >+ return HasResizeUninitialized<string_type>(); >+} >+ >+// Like str->resize(new_size), except any new characters added to "*str" as a >+// result of resizing may be left uninitialized, rather than being filled with >+// '0' bytes. Typically used when code is then going to overwrite the backing >+// store of the std::string with known data. Uses a Google extension to std::string. >+template <typename string_type, typename = void> >+inline void STLStringResizeUninitialized(string_type* s, size_t new_size) { >+ ResizeUninit(s, new_size, HasResizeUninitialized<string_type>()); >+} >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..ad282efcd9bb89f885db0f3e4fab8e4df253399a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc >@@ -0,0 +1,68 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/resize_uninitialized.h" >+ >+#include "gtest/gtest.h" >+ >+namespace { >+ >+int resize_call_count = 0; >+ >+struct resizable_string { >+ void resize(size_t) { resize_call_count += 1; } >+}; >+ >+int resize_uninitialized_call_count = 0; >+ >+struct resize_uninitializable_string { >+ void resize(size_t) { resize_call_count += 1; } >+ void resize_uninitialized(size_t) { resize_uninitialized_call_count += 1; } >+}; >+ >+TEST(ResizeUninit, WithAndWithout) { >+ resize_call_count = 0; >+ resize_uninitialized_call_count = 0; >+ { >+ resizable_string rs; >+ >+ EXPECT_EQ(resize_call_count, 0); >+ EXPECT_EQ(resize_uninitialized_call_count, 0); >+ EXPECT_FALSE( >+ absl::strings_internal::STLStringSupportsNontrashingResize(&rs)); >+ EXPECT_EQ(resize_call_count, 0); >+ EXPECT_EQ(resize_uninitialized_call_count, 0); >+ absl::strings_internal::STLStringResizeUninitialized(&rs, 237); >+ EXPECT_EQ(resize_call_count, 1); >+ EXPECT_EQ(resize_uninitialized_call_count, 0); >+ } >+ >+ resize_call_count = 0; >+ resize_uninitialized_call_count = 0; >+ { >+ resize_uninitializable_string rus; >+ >+ EXPECT_EQ(resize_call_count, 0); >+ EXPECT_EQ(resize_uninitialized_call_count, 0); >+ EXPECT_TRUE( >+ absl::strings_internal::STLStringSupportsNontrashingResize(&rus)); >+ EXPECT_EQ(resize_call_count, 0); >+ EXPECT_EQ(resize_uninitialized_call_count, 0); >+ absl::strings_internal::STLStringResizeUninitialized(&rus, 237); >+ EXPECT_EQ(resize_call_count, 0); >+ EXPECT_EQ(resize_uninitialized_call_count, 1); >+ } >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h >new file mode 100644 >index 0000000000000000000000000000000000000000..04c4a5323b86215770a5c931282ac7bac352e76e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h >@@ -0,0 +1,246 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+// Thie file provides the IsStrictlyBaseOfAndConvertibleToSTLContainer type >+// trait metafunction to assist in working with the _GLIBCXX_DEBUG debug >+// wrappers of STL containers. >+// >+// DO NOT INCLUDE THIS FILE DIRECTLY. Use this file by including >+// absl/strings/str_split.h. >+// >+// IWYU pragma: private, include "absl/strings/str_split.h" >+ >+#ifndef ABSL_STRINGS_INTERNAL_STL_TYPE_TRAITS_H_ >+#define ABSL_STRINGS_INTERNAL_STL_TYPE_TRAITS_H_ >+ >+#include <array> >+#include <bitset> >+#include <deque> >+#include <forward_list> >+#include <list> >+#include <map> >+#include <set> >+#include <type_traits> >+#include <unordered_map> >+#include <unordered_set> >+#include <vector> >+ >+#include "absl/meta/type_traits.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+template <typename C, template <typename...> class T> >+struct IsSpecializationImpl : std::false_type {}; >+template <template <typename...> class T, typename... Args> >+struct IsSpecializationImpl<T<Args...>, T> : std::true_type {}; >+template <typename C, template <typename...> class T> >+using IsSpecialization = IsSpecializationImpl<absl::decay_t<C>, T>; >+ >+template <typename C> >+struct IsArrayImpl : std::false_type {}; >+template <template <typename, size_t> class A, typename T, size_t N> >+struct IsArrayImpl<A<T, N>> : std::is_same<A<T, N>, std::array<T, N>> {}; >+template <typename C> >+using IsArray = IsArrayImpl<absl::decay_t<C>>; >+ >+template <typename C> >+struct IsBitsetImpl : std::false_type {}; >+template <template <size_t> class B, size_t N> >+struct IsBitsetImpl<B<N>> : std::is_same<B<N>, std::bitset<N>> {}; >+template <typename C> >+using IsBitset = IsBitsetImpl<absl::decay_t<C>>; >+ >+template <typename C> >+struct IsSTLContainer >+ : absl::disjunction< >+ IsArray<C>, IsBitset<C>, IsSpecialization<C, std::deque>, >+ IsSpecialization<C, std::forward_list>, >+ IsSpecialization<C, std::list>, IsSpecialization<C, std::map>, >+ IsSpecialization<C, std::multimap>, IsSpecialization<C, std::set>, >+ IsSpecialization<C, std::multiset>, >+ IsSpecialization<C, std::unordered_map>, >+ IsSpecialization<C, std::unordered_multimap>, >+ IsSpecialization<C, std::unordered_set>, >+ IsSpecialization<C, std::unordered_multiset>, >+ IsSpecialization<C, std::vector>> {}; >+ >+template <typename C, template <typename...> class T, typename = void> >+struct IsBaseOfSpecializationImpl : std::false_type {}; >+// IsBaseOfSpecializationImpl needs multiple partial specializations to SFINAE >+// on the existence of container dependent types and plug them into the STL >+// template. >+template <typename C, template <typename, typename> class T> >+struct IsBaseOfSpecializationImpl< >+ C, T, absl::void_t<typename C::value_type, typename C::allocator_type>> >+ : std::is_base_of<C, >+ T<typename C::value_type, typename C::allocator_type>> {}; >+template <typename C, template <typename, typename, typename> class T> >+struct IsBaseOfSpecializationImpl< >+ C, T, >+ absl::void_t<typename C::key_type, typename C::key_compare, >+ typename C::allocator_type>> >+ : std::is_base_of<C, T<typename C::key_type, typename C::key_compare, >+ typename C::allocator_type>> {}; >+template <typename C, template <typename, typename, typename, typename> class T> >+struct IsBaseOfSpecializationImpl< >+ C, T, >+ absl::void_t<typename C::key_type, typename C::mapped_type, >+ typename C::key_compare, typename C::allocator_type>> >+ : std::is_base_of<C, >+ T<typename C::key_type, typename C::mapped_type, >+ typename C::key_compare, typename C::allocator_type>> { >+}; >+template <typename C, template <typename, typename, typename, typename> class T> >+struct IsBaseOfSpecializationImpl< >+ C, T, >+ absl::void_t<typename C::key_type, typename C::hasher, >+ typename C::key_equal, typename C::allocator_type>> >+ : std::is_base_of<C, T<typename C::key_type, typename C::hasher, >+ typename C::key_equal, typename C::allocator_type>> { >+}; >+template <typename C, >+ template <typename, typename, typename, typename, typename> class T> >+struct IsBaseOfSpecializationImpl< >+ C, T, >+ absl::void_t<typename C::key_type, typename C::mapped_type, >+ typename C::hasher, typename C::key_equal, >+ typename C::allocator_type>> >+ : std::is_base_of<C, T<typename C::key_type, typename C::mapped_type, >+ typename C::hasher, typename C::key_equal, >+ typename C::allocator_type>> {}; >+template <typename C, template <typename...> class T> >+using IsBaseOfSpecialization = IsBaseOfSpecializationImpl<absl::decay_t<C>, T>; >+ >+template <typename C> >+struct IsBaseOfArrayImpl : std::false_type {}; >+template <template <typename, size_t> class A, typename T, size_t N> >+struct IsBaseOfArrayImpl<A<T, N>> : std::is_base_of<A<T, N>, std::array<T, N>> { >+}; >+template <typename C> >+using IsBaseOfArray = IsBaseOfArrayImpl<absl::decay_t<C>>; >+ >+template <typename C> >+struct IsBaseOfBitsetImpl : std::false_type {}; >+template <template <size_t> class B, size_t N> >+struct IsBaseOfBitsetImpl<B<N>> : std::is_base_of<B<N>, std::bitset<N>> {}; >+template <typename C> >+using IsBaseOfBitset = IsBaseOfBitsetImpl<absl::decay_t<C>>; >+ >+template <typename C> >+struct IsBaseOfSTLContainer >+ : absl::disjunction<IsBaseOfArray<C>, IsBaseOfBitset<C>, >+ IsBaseOfSpecialization<C, std::deque>, >+ IsBaseOfSpecialization<C, std::forward_list>, >+ IsBaseOfSpecialization<C, std::list>, >+ IsBaseOfSpecialization<C, std::map>, >+ IsBaseOfSpecialization<C, std::multimap>, >+ IsBaseOfSpecialization<C, std::set>, >+ IsBaseOfSpecialization<C, std::multiset>, >+ IsBaseOfSpecialization<C, std::unordered_map>, >+ IsBaseOfSpecialization<C, std::unordered_multimap>, >+ IsBaseOfSpecialization<C, std::unordered_set>, >+ IsBaseOfSpecialization<C, std::unordered_multiset>, >+ IsBaseOfSpecialization<C, std::vector>> {}; >+ >+template <typename C, template <typename...> class T, typename = void> >+struct IsConvertibleToSpecializationImpl : std::false_type {}; >+// IsConvertibleToSpecializationImpl needs multiple partial specializations to >+// SFINAE on the existence of container dependent types and plug them into the >+// STL template. >+template <typename C, template <typename, typename> class T> >+struct IsConvertibleToSpecializationImpl< >+ C, T, absl::void_t<typename C::value_type, typename C::allocator_type>> >+ : std::is_convertible< >+ C, T<typename C::value_type, typename C::allocator_type>> {}; >+template <typename C, template <typename, typename, typename> class T> >+struct IsConvertibleToSpecializationImpl< >+ C, T, >+ absl::void_t<typename C::key_type, typename C::key_compare, >+ typename C::allocator_type>> >+ : std::is_convertible<C, T<typename C::key_type, typename C::key_compare, >+ typename C::allocator_type>> {}; >+template <typename C, template <typename, typename, typename, typename> class T> >+struct IsConvertibleToSpecializationImpl< >+ C, T, >+ absl::void_t<typename C::key_type, typename C::mapped_type, >+ typename C::key_compare, typename C::allocator_type>> >+ : std::is_convertible< >+ C, T<typename C::key_type, typename C::mapped_type, >+ typename C::key_compare, typename C::allocator_type>> {}; >+template <typename C, template <typename, typename, typename, typename> class T> >+struct IsConvertibleToSpecializationImpl< >+ C, T, >+ absl::void_t<typename C::key_type, typename C::hasher, >+ typename C::key_equal, typename C::allocator_type>> >+ : std::is_convertible< >+ C, T<typename C::key_type, typename C::hasher, typename C::key_equal, >+ typename C::allocator_type>> {}; >+template <typename C, >+ template <typename, typename, typename, typename, typename> class T> >+struct IsConvertibleToSpecializationImpl< >+ C, T, >+ absl::void_t<typename C::key_type, typename C::mapped_type, >+ typename C::hasher, typename C::key_equal, >+ typename C::allocator_type>> >+ : std::is_convertible<C, T<typename C::key_type, typename C::mapped_type, >+ typename C::hasher, typename C::key_equal, >+ typename C::allocator_type>> {}; >+template <typename C, template <typename...> class T> >+using IsConvertibleToSpecialization = >+ IsConvertibleToSpecializationImpl<absl::decay_t<C>, T>; >+ >+template <typename C> >+struct IsConvertibleToArrayImpl : std::false_type {}; >+template <template <typename, size_t> class A, typename T, size_t N> >+struct IsConvertibleToArrayImpl<A<T, N>> >+ : std::is_convertible<A<T, N>, std::array<T, N>> {}; >+template <typename C> >+using IsConvertibleToArray = IsConvertibleToArrayImpl<absl::decay_t<C>>; >+ >+template <typename C> >+struct IsConvertibleToBitsetImpl : std::false_type {}; >+template <template <size_t> class B, size_t N> >+struct IsConvertibleToBitsetImpl<B<N>> >+ : std::is_convertible<B<N>, std::bitset<N>> {}; >+template <typename C> >+using IsConvertibleToBitset = IsConvertibleToBitsetImpl<absl::decay_t<C>>; >+ >+template <typename C> >+struct IsConvertibleToSTLContainer >+ : absl::disjunction< >+ IsConvertibleToArray<C>, IsConvertibleToBitset<C>, >+ IsConvertibleToSpecialization<C, std::deque>, >+ IsConvertibleToSpecialization<C, std::forward_list>, >+ IsConvertibleToSpecialization<C, std::list>, >+ IsConvertibleToSpecialization<C, std::map>, >+ IsConvertibleToSpecialization<C, std::multimap>, >+ IsConvertibleToSpecialization<C, std::set>, >+ IsConvertibleToSpecialization<C, std::multiset>, >+ IsConvertibleToSpecialization<C, std::unordered_map>, >+ IsConvertibleToSpecialization<C, std::unordered_multimap>, >+ IsConvertibleToSpecialization<C, std::unordered_set>, >+ IsConvertibleToSpecialization<C, std::unordered_multiset>, >+ IsConvertibleToSpecialization<C, std::vector>> {}; >+ >+template <typename C> >+struct IsStrictlyBaseOfAndConvertibleToSTLContainer >+ : absl::conjunction<absl::negation<IsSTLContainer<C>>, >+ IsBaseOfSTLContainer<C>, >+ IsConvertibleToSTLContainer<C>> {}; >+ >+} // namespace strings_internal >+} // namespace absl >+#endif // ABSL_STRINGS_INTERNAL_STL_TYPE_TRAITS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..eafb068fe2867446270f228a6449e0db5a4ccab5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc >@@ -0,0 +1,399 @@ >+// >+// POSIX spec: >+// http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html >+// >+#include "absl/strings/internal/str_format/arg.h" >+ >+#include <cassert> >+#include <cerrno> >+#include <cstdlib> >+#include <string> >+#include <type_traits> >+ >+#include "absl/base/port.h" >+#include "absl/strings/internal/str_format/float_conversion.h" >+ >+namespace absl { >+namespace str_format_internal { >+namespace { >+ >+const char kDigit[2][32] = { "0123456789abcdef", "0123456789ABCDEF" }; >+ >+// Reduce *capacity by s.size(), clipped to a 0 minimum. >+void ReducePadding(string_view s, size_t *capacity) { >+ *capacity = Excess(s.size(), *capacity); >+} >+ >+// Reduce *capacity by n, clipped to a 0 minimum. >+void ReducePadding(size_t n, size_t *capacity) { >+ *capacity = Excess(n, *capacity); >+} >+ >+template <typename T> >+struct MakeUnsigned : std::make_unsigned<T> {}; >+template <> >+struct MakeUnsigned<absl::uint128> { >+ using type = absl::uint128; >+}; >+ >+template <typename T> >+struct IsSigned : std::is_signed<T> {}; >+template <> >+struct IsSigned<absl::uint128> : std::false_type {}; >+ >+class ConvertedIntInfo { >+ public: >+ template <typename T> >+ ConvertedIntInfo(T v, ConversionChar conv) { >+ using Unsigned = typename MakeUnsigned<T>::type; >+ auto u = static_cast<Unsigned>(v); >+ if (IsNeg(v)) { >+ is_neg_ = true; >+ u = Unsigned{} - u; >+ } else { >+ is_neg_ = false; >+ } >+ UnsignedToStringRight(u, conv); >+ } >+ >+ string_view digits() const { >+ return {end() - size_, static_cast<size_t>(size_)}; >+ } >+ bool is_neg() const { return is_neg_; } >+ >+ private: >+ template <typename T, bool IsSigned> >+ struct IsNegImpl { >+ static bool Eval(T v) { return v < 0; } >+ }; >+ template <typename T> >+ struct IsNegImpl<T, false> { >+ static bool Eval(T) { >+ return false; >+ } >+ }; >+ >+ template <typename T> >+ bool IsNeg(T v) { >+ return IsNegImpl<T, IsSigned<T>::value>::Eval(v); >+ } >+ >+ template <typename T> >+ void UnsignedToStringRight(T u, ConversionChar conv) { >+ char *p = end(); >+ switch (conv.radix()) { >+ default: >+ case 10: >+ for (; u; u /= 10) >+ *--p = static_cast<char>('0' + static_cast<size_t>(u % 10)); >+ break; >+ case 8: >+ for (; u; u /= 8) >+ *--p = static_cast<char>('0' + static_cast<size_t>(u % 8)); >+ break; >+ case 16: { >+ const char *digits = kDigit[conv.upper() ? 1 : 0]; >+ for (; u; u /= 16) *--p = digits[static_cast<size_t>(u % 16)]; >+ break; >+ } >+ } >+ size_ = static_cast<int>(end() - p); >+ } >+ >+ const char *end() const { return storage_ + sizeof(storage_); } >+ char *end() { return storage_ + sizeof(storage_); } >+ >+ bool is_neg_; >+ int size_; >+ // Max size: 128 bit value as octal -> 43 digits >+ char storage_[128 / 3 + 1]; >+}; >+ >+// Note: 'o' conversions do not have a base indicator, it's just that >+// the '#' flag is specified to modify the precision for 'o' conversions. >+string_view BaseIndicator(const ConvertedIntInfo &info, >+ const ConversionSpec &conv) { >+ bool alt = conv.flags().alt; >+ int radix = conv.conv().radix(); >+ if (conv.conv().id() == ConversionChar::p) >+ alt = true; // always show 0x for %p. >+ // From the POSIX description of '#' flag: >+ // "For x or X conversion specifiers, a non-zero result shall have >+ // 0x (or 0X) prefixed to it." >+ if (alt && radix == 16 && !info.digits().empty()) { >+ if (conv.conv().upper()) return "0X"; >+ return "0x"; >+ } >+ return {}; >+} >+ >+string_view SignColumn(bool neg, const ConversionSpec &conv) { >+ if (conv.conv().is_signed()) { >+ if (neg) return "-"; >+ if (conv.flags().show_pos) return "+"; >+ if (conv.flags().sign_col) return " "; >+ } >+ return {}; >+} >+ >+bool ConvertCharImpl(unsigned char v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ size_t fill = 0; >+ if (conv.width() >= 0) fill = conv.width(); >+ ReducePadding(1, &fill); >+ if (!conv.flags().left) sink->Append(fill, ' '); >+ sink->Append(1, v); >+ if (conv.flags().left) sink->Append(fill, ' '); >+ return true; >+} >+ >+bool ConvertIntImplInner(const ConvertedIntInfo &info, >+ const ConversionSpec &conv, FormatSinkImpl *sink) { >+ // Print as a sequence of Substrings: >+ // [left_spaces][sign][base_indicator][zeroes][formatted][right_spaces] >+ size_t fill = 0; >+ if (conv.width() >= 0) fill = conv.width(); >+ >+ string_view formatted = info.digits(); >+ ReducePadding(formatted, &fill); >+ >+ string_view sign = SignColumn(info.is_neg(), conv); >+ ReducePadding(sign, &fill); >+ >+ string_view base_indicator = BaseIndicator(info, conv); >+ ReducePadding(base_indicator, &fill); >+ >+ int precision = conv.precision(); >+ bool precision_specified = precision >= 0; >+ if (!precision_specified) >+ precision = 1; >+ >+ if (conv.flags().alt && conv.conv().id() == ConversionChar::o) { >+ // From POSIX description of the '#' (alt) flag: >+ // "For o conversion, it increases the precision (if necessary) to >+ // force the first digit of the result to be zero." >+ if (formatted.empty() || *formatted.begin() != '0') { >+ int needed = static_cast<int>(formatted.size()) + 1; >+ precision = std::max(precision, needed); >+ } >+ } >+ >+ size_t num_zeroes = Excess(formatted.size(), precision); >+ ReducePadding(num_zeroes, &fill); >+ >+ size_t num_left_spaces = !conv.flags().left ? fill : 0; >+ size_t num_right_spaces = conv.flags().left ? fill : 0; >+ >+ // From POSIX description of the '0' (zero) flag: >+ // "For d, i, o, u, x, and X conversion specifiers, if a precision >+ // is specified, the '0' flag is ignored." >+ if (!precision_specified && conv.flags().zero) { >+ num_zeroes += num_left_spaces; >+ num_left_spaces = 0; >+ } >+ >+ sink->Append(num_left_spaces, ' '); >+ sink->Append(sign); >+ sink->Append(base_indicator); >+ sink->Append(num_zeroes, '0'); >+ sink->Append(formatted); >+ sink->Append(num_right_spaces, ' '); >+ return true; >+} >+ >+template <typename T> >+bool ConvertIntImplInner(T v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ ConvertedIntInfo info(v, conv.conv()); >+ if (conv.flags().basic && conv.conv().id() != ConversionChar::p) { >+ if (info.is_neg()) sink->Append(1, '-'); >+ if (info.digits().empty()) { >+ sink->Append(1, '0'); >+ } else { >+ sink->Append(info.digits()); >+ } >+ return true; >+ } >+ return ConvertIntImplInner(info, conv, sink); >+} >+ >+template <typename T> >+bool ConvertIntArg(T v, const ConversionSpec &conv, FormatSinkImpl *sink) { >+ if (conv.conv().is_float()) { >+ return FormatConvertImpl(static_cast<double>(v), conv, sink).value; >+ } >+ if (conv.conv().id() == ConversionChar::c) >+ return ConvertCharImpl(static_cast<unsigned char>(v), conv, sink); >+ if (!conv.conv().is_integral()) >+ return false; >+ if (!conv.conv().is_signed() && IsSigned<T>::value) { >+ using U = typename MakeUnsigned<T>::type; >+ return FormatConvertImpl(static_cast<U>(v), conv, sink).value; >+ } >+ return ConvertIntImplInner(v, conv, sink); >+} >+ >+template <typename T> >+bool ConvertFloatArg(T v, const ConversionSpec &conv, FormatSinkImpl *sink) { >+ return conv.conv().is_float() && ConvertFloatImpl(v, conv, sink); >+} >+ >+inline bool ConvertStringArg(string_view v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ if (conv.conv().id() != ConversionChar::s) >+ return false; >+ if (conv.flags().basic) { >+ sink->Append(v); >+ return true; >+ } >+ return sink->PutPaddedString(v, conv.width(), conv.precision(), >+ conv.flags().left); >+} >+ >+} // namespace >+ >+// ==================== Strings ==================== >+ConvertResult<Conv::s> FormatConvertImpl(const std::string &v, >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertStringArg(v, conv, sink)}; >+} >+ >+ConvertResult<Conv::s> FormatConvertImpl(string_view v, >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertStringArg(v, conv, sink)}; >+} >+ >+ConvertResult<Conv::s | Conv::p> FormatConvertImpl(const char *v, >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ if (conv.conv().id() == ConversionChar::p) >+ return {FormatConvertImpl(VoidPtr(v), conv, sink).value}; >+ size_t len; >+ if (v == nullptr) { >+ len = 0; >+ } else if (conv.precision() < 0) { >+ len = std::strlen(v); >+ } else { >+ // If precision is set, we look for the null terminator on the valid range. >+ len = std::find(v, v + conv.precision(), '\0') - v; >+ } >+ return {ConvertStringArg(string_view(v, len), conv, sink)}; >+} >+ >+// ==================== Raw pointers ==================== >+ConvertResult<Conv::p> FormatConvertImpl(VoidPtr v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ if (conv.conv().id() != ConversionChar::p) >+ return {false}; >+ if (!v.value) { >+ sink->Append("(nil)"); >+ return {true}; >+ } >+ return {ConvertIntImplInner(v.value, conv, sink)}; >+} >+ >+// ==================== Floats ==================== >+FloatingConvertResult FormatConvertImpl(float v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertFloatArg(v, conv, sink)}; >+} >+FloatingConvertResult FormatConvertImpl(double v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertFloatArg(v, conv, sink)}; >+} >+FloatingConvertResult FormatConvertImpl(long double v, >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertFloatArg(v, conv, sink)}; >+} >+ >+// ==================== Chars ==================== >+IntegralConvertResult FormatConvertImpl(char v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+IntegralConvertResult FormatConvertImpl(signed char v, >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+IntegralConvertResult FormatConvertImpl(unsigned char v, >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+ >+// ==================== Ints ==================== >+IntegralConvertResult FormatConvertImpl(short v, // NOLINT >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+IntegralConvertResult FormatConvertImpl(unsigned short v, // NOLINT >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+IntegralConvertResult FormatConvertImpl(int v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+IntegralConvertResult FormatConvertImpl(unsigned v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+IntegralConvertResult FormatConvertImpl(long v, // NOLINT >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+IntegralConvertResult FormatConvertImpl(unsigned long v, // NOLINT >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+IntegralConvertResult FormatConvertImpl(long long v, // NOLINT >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+IntegralConvertResult FormatConvertImpl(unsigned long long v, // NOLINT >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+IntegralConvertResult FormatConvertImpl(absl::uint128 v, >+ const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return {ConvertIntArg(v, conv, sink)}; >+} >+ >+template struct FormatArgImpl::TypedVTable<str_format_internal::VoidPtr>; >+ >+template struct FormatArgImpl::TypedVTable<bool>; >+template struct FormatArgImpl::TypedVTable<char>; >+template struct FormatArgImpl::TypedVTable<signed char>; >+template struct FormatArgImpl::TypedVTable<unsigned char>; >+template struct FormatArgImpl::TypedVTable<short>; // NOLINT >+template struct FormatArgImpl::TypedVTable<unsigned short>; // NOLINT >+template struct FormatArgImpl::TypedVTable<int>; >+template struct FormatArgImpl::TypedVTable<unsigned>; >+template struct FormatArgImpl::TypedVTable<long>; // NOLINT >+template struct FormatArgImpl::TypedVTable<unsigned long>; // NOLINT >+template struct FormatArgImpl::TypedVTable<long long>; // NOLINT >+template struct FormatArgImpl::TypedVTable<unsigned long long>; // NOLINT >+template struct FormatArgImpl::TypedVTable<absl::uint128>; >+ >+template struct FormatArgImpl::TypedVTable<float>; >+template struct FormatArgImpl::TypedVTable<double>; >+template struct FormatArgImpl::TypedVTable<long double>; >+ >+template struct FormatArgImpl::TypedVTable<const char *>; >+template struct FormatArgImpl::TypedVTable<std::string>; >+template struct FormatArgImpl::TypedVTable<string_view>; >+ >+} // namespace str_format_internal >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h >new file mode 100644 >index 0000000000000000000000000000000000000000..a9562188ea91973a629828e0dec82bd470c9c07a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h >@@ -0,0 +1,434 @@ >+#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_ >+#define ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_ >+ >+#include <string.h> >+#include <wchar.h> >+ >+#include <cstdio> >+#include <iomanip> >+#include <limits> >+#include <sstream> >+#include <string> >+#include <type_traits> >+ >+#include "absl/base/port.h" >+#include "absl/meta/type_traits.h" >+#include "absl/numeric/int128.h" >+#include "absl/strings/internal/str_format/extension.h" >+#include "absl/strings/string_view.h" >+ >+class Cord; >+class CordReader; >+ >+namespace absl { >+ >+class FormatCountCapture; >+class FormatSink; >+ >+namespace str_format_internal { >+ >+template <typename T, typename = void> >+struct HasUserDefinedConvert : std::false_type {}; >+ >+template <typename T> >+struct HasUserDefinedConvert< >+ T, void_t<decltype(AbslFormatConvert( >+ std::declval<const T&>(), std::declval<const ConversionSpec&>(), >+ std::declval<FormatSink*>()))>> : std::true_type {}; >+template <typename T> >+class StreamedWrapper; >+ >+// If 'v' can be converted (in the printf sense) according to 'conv', >+// then convert it, appending to `sink` and return `true`. >+// Otherwise fail and return `false`. >+// Raw pointers. >+struct VoidPtr { >+ VoidPtr() = default; >+ template <typename T, >+ decltype(reinterpret_cast<uintptr_t>(std::declval<T*>())) = 0> >+ VoidPtr(T* ptr) // NOLINT >+ : value(ptr ? reinterpret_cast<uintptr_t>(ptr) : 0) {} >+ uintptr_t value; >+}; >+ConvertResult<Conv::p> FormatConvertImpl(VoidPtr v, const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+ >+// Strings. >+ConvertResult<Conv::s> FormatConvertImpl(const std::string& v, >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+ConvertResult<Conv::s> FormatConvertImpl(string_view v, >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+ConvertResult<Conv::s | Conv::p> FormatConvertImpl(const char* v, >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+template <class AbslCord, >+ typename std::enable_if< >+ std::is_same<AbslCord, ::Cord>::value>::type* = nullptr, >+ class AbslCordReader = ::CordReader> >+ConvertResult<Conv::s> FormatConvertImpl(const AbslCord& value, >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink) { >+ if (conv.conv().id() != ConversionChar::s) return {false}; >+ >+ bool is_left = conv.flags().left; >+ size_t space_remaining = 0; >+ >+ int width = conv.width(); >+ if (width >= 0) space_remaining = width; >+ >+ size_t to_write = value.size(); >+ >+ int precision = conv.precision(); >+ if (precision >= 0) >+ to_write = std::min(to_write, static_cast<size_t>(precision)); >+ >+ space_remaining = Excess(to_write, space_remaining); >+ >+ if (space_remaining > 0 && !is_left) sink->Append(space_remaining, ' '); >+ >+ string_view piece; >+ for (AbslCordReader reader(value); >+ to_write > 0 && reader.ReadFragment(&piece); to_write -= piece.size()) { >+ if (piece.size() > to_write) piece.remove_suffix(piece.size() - to_write); >+ sink->Append(piece); >+ } >+ >+ if (space_remaining > 0 && is_left) sink->Append(space_remaining, ' '); >+ return {true}; >+} >+ >+using IntegralConvertResult = >+ ConvertResult<Conv::c | Conv::numeric | Conv::star>; >+using FloatingConvertResult = ConvertResult<Conv::floating>; >+ >+// Floats. >+FloatingConvertResult FormatConvertImpl(float v, const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+FloatingConvertResult FormatConvertImpl(double v, const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+FloatingConvertResult FormatConvertImpl(long double v, >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+ >+// Chars. >+IntegralConvertResult FormatConvertImpl(char v, const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+IntegralConvertResult FormatConvertImpl(signed char v, >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+IntegralConvertResult FormatConvertImpl(unsigned char v, >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+ >+// Ints. >+IntegralConvertResult FormatConvertImpl(short v, // NOLINT >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+IntegralConvertResult FormatConvertImpl(unsigned short v, // NOLINT >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+IntegralConvertResult FormatConvertImpl(int v, const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+IntegralConvertResult FormatConvertImpl(unsigned v, const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+IntegralConvertResult FormatConvertImpl(long v, // NOLINT >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+IntegralConvertResult FormatConvertImpl(unsigned long v, // NOLINT >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+IntegralConvertResult FormatConvertImpl(long long v, // NOLINT >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+IntegralConvertResult FormatConvertImpl(unsigned long long v, // NOLINT >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+IntegralConvertResult FormatConvertImpl(uint128 v, const ConversionSpec& conv, >+ FormatSinkImpl* sink); >+template <typename T, enable_if_t<std::is_same<T, bool>::value, int> = 0> >+IntegralConvertResult FormatConvertImpl(T v, const ConversionSpec& conv, >+ FormatSinkImpl* sink) { >+ return FormatConvertImpl(static_cast<int>(v), conv, sink); >+} >+ >+// We provide this function to help the checker, but it is never defined. >+// FormatArgImpl will use the underlying Convert functions instead. >+template <typename T> >+typename std::enable_if<std::is_enum<T>::value && >+ !HasUserDefinedConvert<T>::value, >+ IntegralConvertResult>::type >+FormatConvertImpl(T v, const ConversionSpec& conv, FormatSinkImpl* sink); >+ >+template <typename T> >+ConvertResult<Conv::s> FormatConvertImpl(const StreamedWrapper<T>& v, >+ const ConversionSpec& conv, >+ FormatSinkImpl* out) { >+ std::ostringstream oss; >+ oss << v.v_; >+ if (!oss) return {false}; >+ return str_format_internal::FormatConvertImpl(oss.str(), conv, out); >+} >+ >+// Use templates and dependent types to delay evaluation of the function >+// until after FormatCountCapture is fully defined. >+struct FormatCountCaptureHelper { >+ template <class T = int> >+ static ConvertResult<Conv::n> ConvertHelper(const FormatCountCapture& v, >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink) { >+ const absl::enable_if_t<sizeof(T) != 0, FormatCountCapture>& v2 = v; >+ >+ if (conv.conv().id() != str_format_internal::ConversionChar::n) >+ return {false}; >+ *v2.p_ = static_cast<int>(sink->size()); >+ return {true}; >+ } >+}; >+ >+template <class T = int> >+ConvertResult<Conv::n> FormatConvertImpl(const FormatCountCapture& v, >+ const ConversionSpec& conv, >+ FormatSinkImpl* sink) { >+ return FormatCountCaptureHelper::ConvertHelper(v, conv, sink); >+} >+ >+// Helper friend struct to hide implementation details from the public API of >+// FormatArgImpl. >+struct FormatArgImplFriend { >+ template <typename Arg> >+ static bool ToInt(Arg arg, int* out) { >+ if (!arg.vtbl_->to_int) return false; >+ *out = arg.vtbl_->to_int(arg.data_); >+ return true; >+ } >+ >+ template <typename Arg> >+ static bool Convert(Arg arg, const str_format_internal::ConversionSpec& conv, >+ FormatSinkImpl* out) { >+ return arg.vtbl_->convert(arg.data_, conv, out); >+ } >+ >+ template <typename Arg> >+ static const void* GetVTablePtrForTest(Arg arg) { >+ return arg.vtbl_; >+ } >+}; >+ >+// A type-erased handle to a format argument. >+class FormatArgImpl { >+ private: >+ enum { kInlinedSpace = 8 }; >+ >+ using VoidPtr = str_format_internal::VoidPtr; >+ >+ union Data { >+ const void* ptr; >+ const volatile void* volatile_ptr; >+ char buf[kInlinedSpace]; >+ }; >+ >+ struct VTable { >+ bool (*convert)(Data, const str_format_internal::ConversionSpec& conv, >+ FormatSinkImpl* out); >+ int (*to_int)(Data); >+ }; >+ >+ template <typename T> >+ struct store_by_value >+ : std::integral_constant<bool, (sizeof(T) <= kInlinedSpace) && >+ (std::is_integral<T>::value || >+ std::is_floating_point<T>::value || >+ std::is_pointer<T>::value || >+ std::is_same<VoidPtr, T>::value)> {}; >+ >+ enum StoragePolicy { ByPointer, ByVolatilePointer, ByValue }; >+ template <typename T> >+ struct storage_policy >+ : std::integral_constant<StoragePolicy, >+ (std::is_volatile<T>::value >+ ? ByVolatilePointer >+ : (store_by_value<T>::value ? ByValue >+ : ByPointer))> { >+ }; >+ >+ // An instance of an FormatArgImpl::VTable suitable for 'T'. >+ template <typename T> >+ struct TypedVTable; >+ >+ // To reduce the number of vtables we will decay values before hand. >+ // Anything with a user-defined Convert will get its own vtable. >+ // For everything else: >+ // - Decay char* and char arrays into `const char*` >+ // - Decay any other pointer to `const void*` >+ // - Decay all enums to their underlying type. >+ // - Decay function pointers to void*. >+ template <typename T, typename = void> >+ struct DecayType { >+ static constexpr bool kHasUserDefined = >+ str_format_internal::HasUserDefinedConvert<T>::value; >+ using type = typename std::conditional< >+ !kHasUserDefined && std::is_convertible<T, const char*>::value, >+ const char*, >+ typename std::conditional<!kHasUserDefined && >+ std::is_convertible<T, VoidPtr>::value, >+ VoidPtr, const T&>::type>::type; >+ }; >+ template <typename T> >+ struct DecayType<T, >+ typename std::enable_if< >+ !str_format_internal::HasUserDefinedConvert<T>::value && >+ std::is_enum<T>::value>::type> { >+ using type = typename std::underlying_type<T>::type; >+ }; >+ >+ public: >+ template <typename T> >+ explicit FormatArgImpl(const T& value) { >+ using D = typename DecayType<T>::type; >+ static_assert( >+ std::is_same<D, const T&>::value || storage_policy<D>::value == ByValue, >+ "Decayed types must be stored by value"); >+ Init(static_cast<D>(value)); >+ } >+ >+ private: >+ friend struct str_format_internal::FormatArgImplFriend; >+ template <typename T, StoragePolicy = storage_policy<T>::value> >+ struct Manager; >+ >+ template <typename T> >+ struct Manager<T, ByPointer> { >+ static Data SetValue(const T& value) { >+ Data data; >+ data.ptr = &value; >+ return data; >+ } >+ >+ static const T& Value(Data arg) { return *static_cast<const T*>(arg.ptr); } >+ }; >+ >+ template <typename T> >+ struct Manager<T, ByVolatilePointer> { >+ static Data SetValue(const T& value) { >+ Data data; >+ data.volatile_ptr = &value; >+ return data; >+ } >+ >+ static const T& Value(Data arg) { >+ return *static_cast<const T*>(arg.volatile_ptr); >+ } >+ }; >+ >+ template <typename T> >+ struct Manager<T, ByValue> { >+ static Data SetValue(const T& value) { >+ Data data; >+ memcpy(data.buf, &value, sizeof(value)); >+ return data; >+ } >+ >+ static T Value(Data arg) { >+ T value; >+ memcpy(&value, arg.buf, sizeof(T)); >+ return value; >+ } >+ }; >+ >+ template <typename T> >+ void Init(const T& value); >+ >+ template <typename T> >+ static int ToIntVal(const T& val) { >+ using CommonType = typename std::conditional<std::is_signed<T>::value, >+ int64_t, uint64_t>::type; >+ if (static_cast<CommonType>(val) > >+ static_cast<CommonType>(std::numeric_limits<int>::max())) { >+ return std::numeric_limits<int>::max(); >+ } else if (std::is_signed<T>::value && >+ static_cast<CommonType>(val) < >+ static_cast<CommonType>(std::numeric_limits<int>::min())) { >+ return std::numeric_limits<int>::min(); >+ } >+ return static_cast<int>(val); >+ } >+ >+ Data data_; >+ const VTable* vtbl_; >+}; >+ >+template <typename T> >+struct FormatArgImpl::TypedVTable { >+ private: >+ static bool ConvertImpl(Data arg, >+ const str_format_internal::ConversionSpec& conv, >+ FormatSinkImpl* out) { >+ return str_format_internal::FormatConvertImpl(Manager<T>::Value(arg), conv, >+ out) >+ .value; >+ } >+ >+ template <typename U = T, typename = void> >+ struct ToIntImpl { >+ static constexpr int (*value)(Data) = nullptr; >+ }; >+ >+ template <typename U> >+ struct ToIntImpl<U, >+ typename std::enable_if<std::is_integral<U>::value>::type> { >+ static int Invoke(Data arg) { return ToIntVal(Manager<T>::Value(arg)); } >+ static constexpr int (*value)(Data) = &Invoke; >+ }; >+ >+ template <typename U> >+ struct ToIntImpl<U, typename std::enable_if<std::is_enum<U>::value>::type> { >+ static int Invoke(Data arg) { >+ return ToIntVal(static_cast<typename std::underlying_type<T>::type>( >+ Manager<T>::Value(arg))); >+ } >+ static constexpr int (*value)(Data) = &Invoke; >+ }; >+ >+ public: >+ static constexpr VTable value{&ConvertImpl, ToIntImpl<>::value}; >+}; >+ >+template <typename T> >+constexpr FormatArgImpl::VTable FormatArgImpl::TypedVTable<T>::value; >+ >+template <typename T> >+void FormatArgImpl::Init(const T& value) { >+ data_ = Manager<T>::SetValue(value); >+ vtbl_ = &TypedVTable<T>::value; >+} >+ >+extern template struct FormatArgImpl::TypedVTable<str_format_internal::VoidPtr>; >+ >+extern template struct FormatArgImpl::TypedVTable<bool>; >+extern template struct FormatArgImpl::TypedVTable<char>; >+extern template struct FormatArgImpl::TypedVTable<signed char>; >+extern template struct FormatArgImpl::TypedVTable<unsigned char>; >+extern template struct FormatArgImpl::TypedVTable<short>; // NOLINT >+extern template struct FormatArgImpl::TypedVTable<unsigned short>; // NOLINT >+extern template struct FormatArgImpl::TypedVTable<int>; >+extern template struct FormatArgImpl::TypedVTable<unsigned>; >+extern template struct FormatArgImpl::TypedVTable<long>; // NOLINT >+extern template struct FormatArgImpl::TypedVTable<unsigned long>; // NOLINT >+extern template struct FormatArgImpl::TypedVTable<long long>; // NOLINT >+extern template struct FormatArgImpl::TypedVTable< >+ unsigned long long>; // NOLINT >+extern template struct FormatArgImpl::TypedVTable<uint128>; >+ >+extern template struct FormatArgImpl::TypedVTable<float>; >+extern template struct FormatArgImpl::TypedVTable<double>; >+extern template struct FormatArgImpl::TypedVTable<long double>; >+ >+extern template struct FormatArgImpl::TypedVTable<const char*>; >+extern template struct FormatArgImpl::TypedVTable<std::string>; >+extern template struct FormatArgImpl::TypedVTable<string_view>; >+} // namespace str_format_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/arg_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/arg_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..83d59048ea27a4f5d802bd6d6f84a1823ff6e209 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/arg_test.cc >@@ -0,0 +1,111 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+#include "absl/strings/internal/str_format/arg.h" >+ >+#include <ostream> >+#include <string> >+#include "gtest/gtest.h" >+#include "absl/strings/str_format.h" >+ >+namespace absl { >+namespace str_format_internal { >+namespace { >+ >+class FormatArgImplTest : public ::testing::Test { >+ public: >+ enum Color { kRed, kGreen, kBlue }; >+ >+ static const char *hi() { return "hi"; } >+}; >+ >+TEST_F(FormatArgImplTest, ToInt) { >+ int out = 0; >+ EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(1), &out)); >+ EXPECT_EQ(1, out); >+ EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(-1), &out)); >+ EXPECT_EQ(-1, out); >+ EXPECT_TRUE( >+ FormatArgImplFriend::ToInt(FormatArgImpl(static_cast<char>(64)), &out)); >+ EXPECT_EQ(64, out); >+ EXPECT_TRUE(FormatArgImplFriend::ToInt( >+ FormatArgImpl(static_cast<unsigned long long>(123456)), &out)); // NOLINT >+ EXPECT_EQ(123456, out); >+ EXPECT_TRUE(FormatArgImplFriend::ToInt( >+ FormatArgImpl(static_cast<unsigned long long>( // NOLINT >+ std::numeric_limits<int>::max()) + >+ 1), >+ &out)); >+ EXPECT_EQ(std::numeric_limits<int>::max(), out); >+ EXPECT_TRUE(FormatArgImplFriend::ToInt( >+ FormatArgImpl(static_cast<long long>( // NOLINT >+ std::numeric_limits<int>::min()) - >+ 10), >+ &out)); >+ EXPECT_EQ(std::numeric_limits<int>::min(), out); >+ EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(false), &out)); >+ EXPECT_EQ(0, out); >+ EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(true), &out)); >+ EXPECT_EQ(1, out); >+ EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(2.2), &out)); >+ EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(3.2f), &out)); >+ EXPECT_FALSE(FormatArgImplFriend::ToInt( >+ FormatArgImpl(static_cast<int *>(nullptr)), &out)); >+ EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(hi()), &out)); >+ EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl("hi"), &out)); >+ EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(kBlue), &out)); >+ EXPECT_EQ(2, out); >+} >+ >+extern const char kMyArray[]; >+ >+TEST_F(FormatArgImplTest, CharArraysDecayToCharPtr) { >+ const char* a = ""; >+ EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)), >+ FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(""))); >+ EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)), >+ FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("A"))); >+ EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)), >+ FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("ABC"))); >+ EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)), >+ FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(kMyArray))); >+} >+ >+TEST_F(FormatArgImplTest, OtherPtrDecayToVoidPtr) { >+ auto expected = FormatArgImplFriend::GetVTablePtrForTest( >+ FormatArgImpl(static_cast<void *>(nullptr))); >+ EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest( >+ FormatArgImpl(static_cast<int *>(nullptr))), >+ expected); >+ EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest( >+ FormatArgImpl(static_cast<volatile int *>(nullptr))), >+ expected); >+ >+ auto p = static_cast<void (*)()>([] {}); >+ EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(p)), >+ expected); >+} >+ >+TEST_F(FormatArgImplTest, WorksWithCharArraysOfUnknownSize) { >+ std::string s; >+ FormatSinkImpl sink(&s); >+ ConversionSpec conv; >+ conv.set_conv(ConversionChar::FromChar('s')); >+ conv.set_flags(Flags()); >+ conv.set_width(-1); >+ conv.set_precision(-1); >+ EXPECT_TRUE( >+ FormatArgImplFriend::Convert(FormatArgImpl(kMyArray), conv, &sink)); >+ sink.Flush(); >+ EXPECT_EQ("ABCDE", s); >+} >+const char kMyArray[] = "ABCDE"; >+ >+} // namespace >+} // namespace str_format_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..33e8641558ab86f3e892addeecd9a6def8b40a97 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc >@@ -0,0 +1,232 @@ >+#include "absl/strings/internal/str_format/bind.h" >+ >+#include <cerrno> >+#include <limits> >+#include <sstream> >+#include <string> >+ >+namespace absl { >+namespace str_format_internal { >+ >+namespace { >+ >+inline bool BindFromPosition(int position, int* value, >+ absl::Span<const FormatArgImpl> pack) { >+ assert(position > 0); >+ if (static_cast<size_t>(position) > pack.size()) { >+ return false; >+ } >+ // -1 because positions are 1-based >+ return FormatArgImplFriend::ToInt(pack[position - 1], value); >+} >+ >+class ArgContext { >+ public: >+ explicit ArgContext(absl::Span<const FormatArgImpl> pack) : pack_(pack) {} >+ >+ // Fill 'bound' with the results of applying the context's argument pack >+ // to the specified 'props'. We synthesize a BoundConversion by >+ // lining up a UnboundConversion with a user argument. We also >+ // resolve any '*' specifiers for width and precision, so after >+ // this call, 'bound' has all the information it needs to be formatted. >+ // Returns false on failure. >+ bool Bind(const UnboundConversion *props, BoundConversion *bound); >+ >+ private: >+ absl::Span<const FormatArgImpl> pack_; >+}; >+ >+inline bool ArgContext::Bind(const UnboundConversion* unbound, >+ BoundConversion* bound) { >+ const FormatArgImpl* arg = nullptr; >+ int arg_position = unbound->arg_position; >+ if (static_cast<size_t>(arg_position - 1) >= pack_.size()) return false; >+ arg = &pack_[arg_position - 1]; // 1-based >+ >+ if (!unbound->flags.basic) { >+ int width = unbound->width.value(); >+ bool force_left = false; >+ if (unbound->width.is_from_arg()) { >+ if (!BindFromPosition(unbound->width.get_from_arg(), &width, pack_)) >+ return false; >+ if (width < 0) { >+ // "A negative field width is taken as a '-' flag followed by a >+ // positive field width." >+ force_left = true; >+ width = -width; >+ } >+ } >+ >+ int precision = unbound->precision.value(); >+ if (unbound->precision.is_from_arg()) { >+ if (!BindFromPosition(unbound->precision.get_from_arg(), &precision, >+ pack_)) >+ return false; >+ } >+ >+ bound->set_width(width); >+ bound->set_precision(precision); >+ bound->set_flags(unbound->flags); >+ if (force_left) >+ bound->set_left(true); >+ } else { >+ bound->set_flags(unbound->flags); >+ bound->set_width(-1); >+ bound->set_precision(-1); >+ } >+ >+ bound->set_length_mod(unbound->length_mod); >+ bound->set_conv(unbound->conv); >+ bound->set_arg(arg); >+ return true; >+} >+ >+template <typename Converter> >+class ConverterConsumer { >+ public: >+ ConverterConsumer(Converter converter, absl::Span<const FormatArgImpl> pack) >+ : converter_(converter), arg_context_(pack) {} >+ >+ bool Append(string_view s) { >+ converter_.Append(s); >+ return true; >+ } >+ bool ConvertOne(const UnboundConversion& conv, string_view conv_string) { >+ BoundConversion bound; >+ if (!arg_context_.Bind(&conv, &bound)) return false; >+ return converter_.ConvertOne(bound, conv_string); >+ } >+ >+ private: >+ Converter converter_; >+ ArgContext arg_context_; >+}; >+ >+template <typename Converter> >+bool ConvertAll(const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args, >+ const Converter& converter) { >+ const ParsedFormatBase* pc = format.parsed_conversion(); >+ if (pc) >+ return pc->ProcessFormat(ConverterConsumer<Converter>(converter, args)); >+ >+ return ParseFormatString(format.str(), >+ ConverterConsumer<Converter>(converter, args)); >+} >+ >+class DefaultConverter { >+ public: >+ explicit DefaultConverter(FormatSinkImpl* sink) : sink_(sink) {} >+ >+ void Append(string_view s) const { sink_->Append(s); } >+ >+ bool ConvertOne(const BoundConversion& bound, string_view /*conv*/) const { >+ return FormatArgImplFriend::Convert(*bound.arg(), bound, sink_); >+ } >+ >+ private: >+ FormatSinkImpl* sink_; >+}; >+ >+class SummarizingConverter { >+ public: >+ explicit SummarizingConverter(FormatSinkImpl* sink) : sink_(sink) {} >+ >+ void Append(string_view s) const { sink_->Append(s); } >+ >+ bool ConvertOne(const BoundConversion& bound, string_view /*conv*/) const { >+ UntypedFormatSpecImpl spec("%d"); >+ >+ std::ostringstream ss; >+ ss << "{" << Streamable(spec, {*bound.arg()}) << ":" << bound.flags(); >+ if (bound.width() >= 0) ss << bound.width(); >+ if (bound.precision() >= 0) ss << "." << bound.precision(); >+ ss << bound.length_mod() << bound.conv() << "}"; >+ Append(ss.str()); >+ return true; >+ } >+ >+ private: >+ FormatSinkImpl* sink_; >+}; >+ >+} // namespace >+ >+bool BindWithPack(const UnboundConversion* props, >+ absl::Span<const FormatArgImpl> pack, >+ BoundConversion* bound) { >+ return ArgContext(pack).Bind(props, bound); >+} >+ >+std::string Summarize(const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args) { >+ typedef SummarizingConverter Converter; >+ std::string out; >+ { >+ // inner block to destroy sink before returning out. It ensures a last >+ // flush. >+ FormatSinkImpl sink(&out); >+ if (!ConvertAll(format, args, Converter(&sink))) { >+ sink.Flush(); >+ out.clear(); >+ } >+ } >+ return out; >+} >+ >+bool FormatUntyped(FormatRawSinkImpl raw_sink, >+ const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args) { >+ FormatSinkImpl sink(raw_sink); >+ using Converter = DefaultConverter; >+ if (!ConvertAll(format, args, Converter(&sink))) { >+ sink.Flush(); >+ return false; >+ } >+ return true; >+} >+ >+std::ostream& Streamable::Print(std::ostream& os) const { >+ if (!FormatUntyped(&os, format_, args_)) os.setstate(std::ios::failbit); >+ return os; >+} >+ >+std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args) { >+ size_t orig = out->size(); >+ if (!FormatUntyped(out, format, args)) out->resize(orig); >+ return *out; >+} >+ >+int FprintF(std::FILE* output, const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args) { >+ FILERawSink sink(output); >+ if (!FormatUntyped(&sink, format, args)) { >+ errno = EINVAL; >+ return -1; >+ } >+ if (sink.error()) { >+ errno = sink.error(); >+ return -1; >+ } >+ if (sink.count() > std::numeric_limits<int>::max()) { >+ errno = EFBIG; >+ return -1; >+ } >+ return static_cast<int>(sink.count()); >+} >+ >+int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args) { >+ BufferRawSink sink(output, size ? size - 1 : 0); >+ if (!FormatUntyped(&sink, format, args)) { >+ errno = EINVAL; >+ return -1; >+ } >+ size_t total = sink.total_written(); >+ if (size) output[std::min(total, size - 1)] = 0; >+ return static_cast<int>(total); >+} >+ >+} // namespace str_format_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h >new file mode 100644 >index 0000000000000000000000000000000000000000..4008611211cfe6053c51af0648a051354bdf81a2 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h >@@ -0,0 +1,189 @@ >+#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_ >+#define ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_ >+ >+#include <array> >+#include <cstdio> >+#include <sstream> >+#include <string> >+ >+#include "absl/base/port.h" >+#include "absl/container/inlined_vector.h" >+#include "absl/strings/internal/str_format/arg.h" >+#include "absl/strings/internal/str_format/checker.h" >+#include "absl/strings/internal/str_format/parser.h" >+#include "absl/types/span.h" >+ >+namespace absl { >+ >+class UntypedFormatSpec; >+ >+namespace str_format_internal { >+ >+class BoundConversion : public ConversionSpec { >+ public: >+ const FormatArgImpl* arg() const { return arg_; } >+ void set_arg(const FormatArgImpl* a) { arg_ = a; } >+ >+ private: >+ const FormatArgImpl* arg_; >+}; >+ >+// This is the type-erased class that the implementation uses. >+class UntypedFormatSpecImpl { >+ public: >+ UntypedFormatSpecImpl() = delete; >+ >+ explicit UntypedFormatSpecImpl(string_view s) : str_(s), pc_() {} >+ explicit UntypedFormatSpecImpl( >+ const str_format_internal::ParsedFormatBase* pc) >+ : pc_(pc) {} >+ string_view str() const { return str_; } >+ const str_format_internal::ParsedFormatBase* parsed_conversion() const { >+ return pc_; >+ } >+ >+ template <typename T> >+ static const UntypedFormatSpecImpl& Extract(const T& s) { >+ return s.spec_; >+ } >+ >+ private: >+ string_view str_; >+ const str_format_internal::ParsedFormatBase* pc_; >+}; >+ >+template <typename T, typename...> >+struct MakeDependent { >+ using type = T; >+}; >+ >+// Implicitly convertible from `const char*`, `string_view`, and the >+// `ExtendedParsedFormat` type. This abstraction allows all format functions to >+// operate on any without providing too many overloads. >+template <typename... Args> >+class FormatSpecTemplate >+ : public MakeDependent<UntypedFormatSpec, Args...>::type { >+ using Base = typename MakeDependent<UntypedFormatSpec, Args...>::type; >+ >+ public: >+#if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+ >+ // Honeypot overload for when the std::string is not constexpr. >+ // We use the 'unavailable' attribute to give a better compiler error than >+ // just 'method is deleted'. >+ FormatSpecTemplate(...) // NOLINT >+ __attribute__((unavailable("Format std::string is not constexpr."))); >+ >+ // Honeypot overload for when the format is constexpr and invalid. >+ // We use the 'unavailable' attribute to give a better compiler error than >+ // just 'method is deleted'. >+ // To avoid checking the format twice, we just check that the format is >+ // constexpr. If is it valid, then the overload below will kick in. >+ // We add the template here to make this overload have lower priority. >+ template <typename = void> >+ FormatSpecTemplate(const char* s) // NOLINT >+ __attribute__(( >+ enable_if(str_format_internal::EnsureConstexpr(s), "constexpr trap"), >+ unavailable( >+ "Format specified does not match the arguments passed."))); >+ >+ template <typename T = void> >+ FormatSpecTemplate(string_view s) // NOLINT >+ __attribute__((enable_if(str_format_internal::EnsureConstexpr(s), >+ "constexpr trap"))) { >+ static_assert(sizeof(T*) == 0, >+ "Format specified does not match the arguments passed."); >+ } >+ >+ // Good format overload. >+ FormatSpecTemplate(const char* s) // NOLINT >+ __attribute__((enable_if(ValidFormatImpl<ArgumentToConv<Args>()...>(s), >+ "bad format trap"))) >+ : Base(s) {} >+ >+ FormatSpecTemplate(string_view s) // NOLINT >+ __attribute__((enable_if(ValidFormatImpl<ArgumentToConv<Args>()...>(s), >+ "bad format trap"))) >+ : Base(s) {} >+ >+#else // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+ >+ FormatSpecTemplate(const char* s) : Base(s) {} // NOLINT >+ FormatSpecTemplate(string_view s) : Base(s) {} // NOLINT >+ >+#endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+ >+ template <Conv... C, typename = typename std::enable_if< >+ sizeof...(C) == sizeof...(Args) && >+ AllOf(Contains(ArgumentToConv<Args>(), >+ C)...)>::type> >+ FormatSpecTemplate(const ExtendedParsedFormat<C...>& pc) // NOLINT >+ : Base(&pc) {} >+}; >+ >+template <typename... Args> >+struct FormatSpecDeductionBarrier { >+ using type = FormatSpecTemplate<Args...>; >+}; >+ >+class Streamable { >+ public: >+ Streamable(const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args) >+ : format_(format), args_(args.begin(), args.end()) {} >+ >+ std::ostream& Print(std::ostream& os) const; >+ >+ friend std::ostream& operator<<(std::ostream& os, const Streamable& l) { >+ return l.Print(os); >+ } >+ >+ private: >+ const UntypedFormatSpecImpl& format_; >+ absl::InlinedVector<FormatArgImpl, 4> args_; >+}; >+ >+// for testing >+std::string Summarize(const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args); >+bool BindWithPack(const UnboundConversion* props, >+ absl::Span<const FormatArgImpl> pack, BoundConversion* bound); >+ >+bool FormatUntyped(FormatRawSinkImpl raw_sink, >+ const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args); >+ >+std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args); >+ >+inline std::string FormatPack(const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args) { >+ std::string out; >+ AppendPack(&out, format, args); >+ return out; >+} >+ >+int FprintF(std::FILE* output, const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args); >+int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl& format, >+ absl::Span<const FormatArgImpl> args); >+ >+// Returned by Streamed(v). Converts via '%s' to the std::string created >+// by std::ostream << v. >+template <typename T> >+class StreamedWrapper { >+ public: >+ explicit StreamedWrapper(const T& v) : v_(v) { } >+ >+ private: >+ template <typename S> >+ friend ConvertResult<Conv::s> FormatConvertImpl(const StreamedWrapper<S>& v, >+ const ConversionSpec& conv, >+ FormatSinkImpl* out); >+ const T& v_; >+}; >+ >+} // namespace str_format_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/bind_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/bind_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..47575739ba130024bdff076ff0388cfb3a687740 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/bind_test.cc >@@ -0,0 +1,131 @@ >+#include "absl/strings/internal/str_format/bind.h" >+ >+#include <string.h> >+ >+#include "gtest/gtest.h" >+ >+namespace absl { >+namespace str_format_internal { >+namespace { >+ >+template <typename T, size_t N> >+size_t ArraySize(T (&)[N]) { >+ return N; >+} >+ >+class FormatBindTest : public ::testing::Test { >+ public: >+ bool Extract(const char *s, UnboundConversion *props, int *next) const { >+ absl::string_view src = s; >+ return ConsumeUnboundConversion(&src, props, next) && src.empty(); >+ } >+}; >+ >+TEST_F(FormatBindTest, BindSingle) { >+ struct Expectation { >+ int line; >+ const char *fmt; >+ int ok_phases; >+ const FormatArgImpl *arg; >+ int width; >+ int precision; >+ int next_arg; >+ }; >+ const int no = -1; >+ const int ia[] = { 10, 20, 30, 40}; >+ const FormatArgImpl args[] = {FormatArgImpl(ia[0]), FormatArgImpl(ia[1]), >+ FormatArgImpl(ia[2]), FormatArgImpl(ia[3])}; >+#pragma GCC diagnostic push >+#pragma GCC diagnostic ignored "-Wmissing-field-initializers" >+ const Expectation kExpect[] = { >+ {__LINE__, "d", 2, &args[0], no, no, 2}, >+ {__LINE__, "4d", 2, &args[0], 4, no, 2}, >+ {__LINE__, ".5d", 2, &args[0], no, 5, 2}, >+ {__LINE__, "4.5d", 2, &args[0], 4, 5, 2}, >+ {__LINE__, "*d", 2, &args[1], 10, no, 3}, >+ {__LINE__, ".*d", 2, &args[1], no, 10, 3}, >+ {__LINE__, "*.*d", 2, &args[2], 10, 20, 4}, >+ {__LINE__, "1$d", 2, &args[0], no, no, 0}, >+ {__LINE__, "2$d", 2, &args[1], no, no, 0}, >+ {__LINE__, "3$d", 2, &args[2], no, no, 0}, >+ {__LINE__, "4$d", 2, &args[3], no, no, 0}, >+ {__LINE__, "2$*1$d", 2, &args[1], 10, no, 0}, >+ {__LINE__, "2$*2$d", 2, &args[1], 20, no, 0}, >+ {__LINE__, "2$*3$d", 2, &args[1], 30, no, 0}, >+ {__LINE__, "2$.*1$d", 2, &args[1], no, 10, 0}, >+ {__LINE__, "2$.*2$d", 2, &args[1], no, 20, 0}, >+ {__LINE__, "2$.*3$d", 2, &args[1], no, 30, 0}, >+ {__LINE__, "2$*3$.*1$d", 2, &args[1], 30, 10, 0}, >+ {__LINE__, "2$*2$.*2$d", 2, &args[1], 20, 20, 0}, >+ {__LINE__, "2$*1$.*3$d", 2, &args[1], 10, 30, 0}, >+ {__LINE__, "2$*3$.*1$d", 2, &args[1], 30, 10, 0}, >+ {__LINE__, "1$*d", 0}, // indexed, then positional >+ {__LINE__, "*2$d", 0}, // positional, then indexed >+ {__LINE__, "6$d", 1}, // arg position out of bounds >+ {__LINE__, "1$6$d", 0}, // width position incorrectly specified >+ {__LINE__, "1$.6$d", 0}, // precision position incorrectly specified >+ {__LINE__, "1$*6$d", 1}, // width position out of bounds >+ {__LINE__, "1$.*6$d", 1}, // precision position out of bounds >+ }; >+#pragma GCC diagnostic pop >+ for (const Expectation &e : kExpect) { >+ SCOPED_TRACE(e.line); >+ SCOPED_TRACE(e.fmt); >+ UnboundConversion props; >+ BoundConversion bound; >+ int ok_phases = 0; >+ int next = 0; >+ if (Extract(e.fmt, &props, &next)) { >+ ++ok_phases; >+ if (BindWithPack(&props, args, &bound)) { >+ ++ok_phases; >+ } >+ } >+ EXPECT_EQ(e.ok_phases, ok_phases); >+ if (e.ok_phases < 2) continue; >+ if (e.arg != nullptr) { >+ EXPECT_EQ(e.arg, bound.arg()); >+ } >+ EXPECT_EQ(e.width, bound.width()); >+ EXPECT_EQ(e.precision, bound.precision()); >+ } >+} >+ >+TEST_F(FormatBindTest, FormatPack) { >+ struct Expectation { >+ int line; >+ const char *fmt; >+ const char *summary; >+ }; >+ const int ia[] = { 10, 20, 30, 40, -10 }; >+ const FormatArgImpl args[] = {FormatArgImpl(ia[0]), FormatArgImpl(ia[1]), >+ FormatArgImpl(ia[2]), FormatArgImpl(ia[3]), >+ FormatArgImpl(ia[4])}; >+ const Expectation kExpect[] = { >+ {__LINE__, "a%4db%dc", "a{10:4d}b{20:d}c"}, >+ {__LINE__, "a%.4db%dc", "a{10:.4d}b{20:d}c"}, >+ {__LINE__, "a%4.5db%dc", "a{10:4.5d}b{20:d}c"}, >+ {__LINE__, "a%db%4.5dc", "a{10:d}b{20:4.5d}c"}, >+ {__LINE__, "a%db%*.*dc", "a{10:d}b{40:20.30d}c"}, >+ {__LINE__, "a%.*fb", "a{20:.10f}b"}, >+ {__LINE__, "a%1$db%2$*3$.*4$dc", "a{10:d}b{20:30.40d}c"}, >+ {__LINE__, "a%4$db%3$*2$.*1$dc", "a{40:d}b{30:20.10d}c"}, >+ {__LINE__, "a%04ldb", "a{10:04ld}b"}, >+ {__LINE__, "a%-#04lldb", "a{10:-#04lld}b"}, >+ {__LINE__, "a%1$*5$db", "a{10:-10d}b"}, >+ {__LINE__, "a%1$.*5$db", "a{10:d}b"}, >+ }; >+ for (const Expectation &e : kExpect) { >+ absl::string_view fmt = e.fmt; >+ SCOPED_TRACE(e.line); >+ SCOPED_TRACE(e.fmt); >+ UntypedFormatSpecImpl format(fmt); >+ EXPECT_EQ(e.summary, >+ str_format_internal::Summarize(format, absl::MakeSpan(args))) >+ << "line:" << e.line; >+ } >+} >+ >+} // namespace >+} // namespace str_format_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8b594f2d5cc6ffcc322d99c775bdd1f3b5da2eb8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h >@@ -0,0 +1,325 @@ >+#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ >+#define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ >+ >+#include "absl/strings/internal/str_format/arg.h" >+#include "absl/strings/internal/str_format/extension.h" >+ >+// Compile time check support for entry points. >+ >+#ifndef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+#if defined(__clang__) && !defined(__native_client__) >+#if __has_attribute(enable_if) >+#define ABSL_INTERNAL_ENABLE_FORMAT_CHECKER 1 >+#endif // __has_attribute(enable_if) >+#endif // defined(__clang__) && !defined(__native_client__) >+#endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+ >+namespace absl { >+namespace str_format_internal { >+ >+constexpr bool AllOf() { return true; } >+ >+template <typename... T> >+constexpr bool AllOf(bool b, T... t) { >+ return b && AllOf(t...); >+} >+ >+template <typename Arg> >+constexpr Conv ArgumentToConv() { >+ return decltype(str_format_internal::FormatConvertImpl( >+ std::declval<const Arg&>(), std::declval<const ConversionSpec&>(), >+ std::declval<FormatSinkImpl*>()))::kConv; >+} >+ >+#if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+ >+constexpr bool ContainsChar(const char* chars, char c) { >+ return *chars == c || (*chars && ContainsChar(chars + 1, c)); >+} >+ >+// A constexpr compatible list of Convs. >+struct ConvList { >+ const Conv* array; >+ int count; >+ >+ // We do the bound check here to avoid having to do it on the callers. >+ // Returning an empty Conv has the same effect as short circuiting because it >+ // will never match any conversion. >+ constexpr Conv operator[](int i) const { >+ return i < count ? array[i] : Conv{}; >+ } >+ >+ constexpr ConvList without_front() const { >+ return count != 0 ? ConvList{array + 1, count - 1} : *this; >+ } >+}; >+ >+template <size_t count> >+struct ConvListT { >+ // Make sure the array has size > 0. >+ Conv list[count ? count : 1]; >+}; >+ >+constexpr char GetChar(string_view str, size_t index) { >+ return index < str.size() ? str[index] : char{}; >+} >+ >+constexpr string_view ConsumeFront(string_view str, size_t len = 1) { >+ return len <= str.size() ? string_view(str.data() + len, str.size() - len) >+ : string_view(); >+} >+ >+constexpr string_view ConsumeAnyOf(string_view format, const char* chars) { >+ return ContainsChar(chars, GetChar(format, 0)) >+ ? ConsumeAnyOf(ConsumeFront(format), chars) >+ : format; >+} >+ >+constexpr bool IsDigit(char c) { return c >= '0' && c <= '9'; } >+ >+// Helper class for the ParseDigits function. >+// It encapsulates the two return values we need there. >+struct Integer { >+ string_view format; >+ int value; >+ >+ // If the next character is a '$', consume it. >+ // Otherwise, make `this` an invalid positional argument. >+ constexpr Integer ConsumePositionalDollar() const { >+ return GetChar(format, 0) == '$' ? Integer{ConsumeFront(format), value} >+ : Integer{format, 0}; >+ } >+}; >+ >+constexpr Integer ParseDigits(string_view format, int value = 0) { >+ return IsDigit(GetChar(format, 0)) >+ ? ParseDigits(ConsumeFront(format), >+ 10 * value + GetChar(format, 0) - '0') >+ : Integer{format, value}; >+} >+ >+// Parse digits for a positional argument. >+// The parsing also consumes the '$'. >+constexpr Integer ParsePositional(string_view format) { >+ return ParseDigits(format).ConsumePositionalDollar(); >+} >+ >+// Parses a single conversion specifier. >+// See ConvParser::Run() for post conditions. >+class ConvParser { >+ constexpr ConvParser SetFormat(string_view format) const { >+ return ConvParser(format, args_, error_, arg_position_, is_positional_); >+ } >+ >+ constexpr ConvParser SetArgs(ConvList args) const { >+ return ConvParser(format_, args, error_, arg_position_, is_positional_); >+ } >+ >+ constexpr ConvParser SetError(bool error) const { >+ return ConvParser(format_, args_, error_ || error, arg_position_, >+ is_positional_); >+ } >+ >+ constexpr ConvParser SetArgPosition(int arg_position) const { >+ return ConvParser(format_, args_, error_, arg_position, is_positional_); >+ } >+ >+ // Consumes the next arg and verifies that it matches `conv`. >+ // `error_` is set if there is no next arg or if it doesn't match `conv`. >+ constexpr ConvParser ConsumeNextArg(char conv) const { >+ return SetArgs(args_.without_front()).SetError(!Contains(args_[0], conv)); >+ } >+ >+ // Verify that positional argument `i.value` matches `conv`. >+ // `error_` is set if `i.value` is not a valid argument or if it doesn't >+ // match. >+ constexpr ConvParser VerifyPositional(Integer i, char conv) const { >+ return SetFormat(i.format).SetError(!Contains(args_[i.value - 1], conv)); >+ } >+ >+ // Parse the position of the arg and store it in `arg_position_`. >+ constexpr ConvParser ParseArgPosition(Integer arg) const { >+ return SetFormat(arg.format).SetArgPosition(arg.value); >+ } >+ >+ // Consume the flags. >+ constexpr ConvParser ParseFlags() const { >+ return SetFormat(ConsumeAnyOf(format_, "-+ #0")); >+ } >+ >+ // Consume the width. >+ // If it is '*', we verify that it matches `args_`. `error_` is set if it >+ // doesn't match. >+ constexpr ConvParser ParseWidth() const { >+ return IsDigit(GetChar(format_, 0)) >+ ? SetFormat(ParseDigits(format_).format) >+ : GetChar(format_, 0) == '*' >+ ? is_positional_ >+ ? VerifyPositional( >+ ParsePositional(ConsumeFront(format_)), '*') >+ : SetFormat(ConsumeFront(format_)) >+ .ConsumeNextArg('*') >+ : *this; >+ } >+ >+ // Consume the precision. >+ // If it is '*', we verify that it matches `args_`. `error_` is set if it >+ // doesn't match. >+ constexpr ConvParser ParsePrecision() const { >+ return GetChar(format_, 0) != '.' >+ ? *this >+ : GetChar(format_, 1) == '*' >+ ? is_positional_ >+ ? VerifyPositional( >+ ParsePositional(ConsumeFront(format_, 2)), '*') >+ : SetFormat(ConsumeFront(format_, 2)) >+ .ConsumeNextArg('*') >+ : SetFormat(ParseDigits(ConsumeFront(format_)).format); >+ } >+ >+ // Consume the length characters. >+ constexpr ConvParser ParseLength() const { >+ return SetFormat(ConsumeAnyOf(format_, "lLhjztq")); >+ } >+ >+ // Consume the conversion character and verify that it matches `args_`. >+ // `error_` is set if it doesn't match. >+ constexpr ConvParser ParseConversion() const { >+ return is_positional_ >+ ? VerifyPositional({ConsumeFront(format_), arg_position_}, >+ GetChar(format_, 0)) >+ : ConsumeNextArg(GetChar(format_, 0)) >+ .SetFormat(ConsumeFront(format_)); >+ } >+ >+ constexpr ConvParser(string_view format, ConvList args, bool error, >+ int arg_position, bool is_positional) >+ : format_(format), >+ args_(args), >+ error_(error), >+ arg_position_(arg_position), >+ is_positional_(is_positional) {} >+ >+ public: >+ constexpr ConvParser(string_view format, ConvList args, bool is_positional) >+ : format_(format), >+ args_(args), >+ error_(false), >+ arg_position_(0), >+ is_positional_(is_positional) {} >+ >+ // Consume the whole conversion specifier. >+ // `format()` will be set to the character after the conversion character. >+ // `error()` will be set if any of the arguments do not match. >+ constexpr ConvParser Run() const { >+ return (is_positional_ ? ParseArgPosition(ParsePositional(format_)) : *this) >+ .ParseFlags() >+ .ParseWidth() >+ .ParsePrecision() >+ .ParseLength() >+ .ParseConversion(); >+ } >+ >+ constexpr string_view format() const { return format_; } >+ constexpr ConvList args() const { return args_; } >+ constexpr bool error() const { return error_; } >+ constexpr bool is_positional() const { return is_positional_; } >+ >+ private: >+ string_view format_; >+ // Current list of arguments. If we are not in positional mode we will consume >+ // from the front. >+ ConvList args_; >+ bool error_; >+ // Holds the argument position of the conversion character, if we are in >+ // positional mode. Otherwise, it is unspecified. >+ int arg_position_; >+ // Whether we are in positional mode. >+ // It changes the behavior of '*' and where to find the converted argument. >+ bool is_positional_; >+}; >+ >+// Parses a whole format expression. >+// See FormatParser::Run(). >+class FormatParser { >+ static constexpr bool FoundPercent(string_view format) { >+ return format.empty() || >+ (GetChar(format, 0) == '%' && GetChar(format, 1) != '%'); >+ } >+ >+ // We use an inner function to increase the recursion limit. >+ // The inner function consumes up to `limit` characters on every run. >+ // This increases the limit from 512 to ~512*limit. >+ static constexpr string_view ConsumeNonPercentInner(string_view format, >+ int limit = 20) { >+ return FoundPercent(format) || !limit >+ ? format >+ : ConsumeNonPercentInner( >+ ConsumeFront(format, GetChar(format, 0) == '%' && >+ GetChar(format, 1) == '%' >+ ? 2 >+ : 1), >+ limit - 1); >+ } >+ >+ // Consume characters until the next conversion spec %. >+ // It skips %%. >+ static constexpr string_view ConsumeNonPercent(string_view format) { >+ return FoundPercent(format) >+ ? format >+ : ConsumeNonPercent(ConsumeNonPercentInner(format)); >+ } >+ >+ static constexpr bool IsPositional(string_view format) { >+ return IsDigit(GetChar(format, 0)) ? IsPositional(ConsumeFront(format)) >+ : GetChar(format, 0) == '$'; >+ } >+ >+ constexpr bool RunImpl(bool is_positional) const { >+ // In non-positional mode we require all arguments to be consumed. >+ // In positional mode just reaching the end of the format without errors is >+ // enough. >+ return (format_.empty() && (is_positional || args_.count == 0)) || >+ (!format_.empty() && >+ ValidateArg( >+ ConvParser(ConsumeFront(format_), args_, is_positional).Run())); >+ } >+ >+ constexpr bool ValidateArg(ConvParser conv) const { >+ return !conv.error() && FormatParser(conv.format(), conv.args()) >+ .RunImpl(conv.is_positional()); >+ } >+ >+ public: >+ constexpr FormatParser(string_view format, ConvList args) >+ : format_(ConsumeNonPercent(format)), args_(args) {} >+ >+ // Runs the parser for `format` and `args`. >+ // It verifies that the format is valid and that all conversion specifiers >+ // match the arguments passed. >+ // In non-positional mode it also verfies that all arguments are consumed. >+ constexpr bool Run() const { >+ return RunImpl(!format_.empty() && IsPositional(ConsumeFront(format_))); >+ } >+ >+ private: >+ string_view format_; >+ // Current list of arguments. >+ // If we are not in positional mode we will consume from the front and will >+ // have to be empty in the end. >+ ConvList args_; >+}; >+ >+template <Conv... C> >+constexpr bool ValidFormatImpl(string_view format) { >+ return FormatParser(format, >+ {ConvListT<sizeof...(C)>{{C...}}.list, sizeof...(C)}) >+ .Run(); >+} >+ >+#endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+ >+} // namespace str_format_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/checker_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/checker_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..14d11ea8bd306a4eafe326aca9eb377a6aef93ba >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/checker_test.cc >@@ -0,0 +1,150 @@ >+#include <string> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/strings/str_format.h" >+ >+namespace absl { >+namespace str_format_internal { >+namespace { >+ >+std::string ConvToString(Conv conv) { >+ std::string out; >+#define CONV_SET_CASE(c) \ >+ if (Contains(conv, Conv::c)) out += #c; >+ ABSL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, ) >+#undef CONV_SET_CASE >+ if (Contains(conv, Conv::star)) out += "*"; >+ return out; >+} >+ >+TEST(StrFormatChecker, ArgumentToConv) { >+ Conv conv = ArgumentToConv<std::string>(); >+ EXPECT_EQ(ConvToString(conv), "s"); >+ >+ conv = ArgumentToConv<const char*>(); >+ EXPECT_EQ(ConvToString(conv), "sp"); >+ >+ conv = ArgumentToConv<double>(); >+ EXPECT_EQ(ConvToString(conv), "fFeEgGaA"); >+ >+ conv = ArgumentToConv<int>(); >+ EXPECT_EQ(ConvToString(conv), "cdiouxXfFeEgGaA*"); >+ >+ conv = ArgumentToConv<std::string*>(); >+ EXPECT_EQ(ConvToString(conv), "p"); >+} >+ >+#if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+ >+struct Case { >+ bool result; >+ const char* format; >+}; >+ >+template <typename... Args> >+constexpr Case ValidFormat(const char* format) { >+ return {ValidFormatImpl<ArgumentToConv<Args>()...>(format), format}; >+} >+ >+TEST(StrFormatChecker, ValidFormat) { >+ // We want to make sure these expressions are constexpr and they have the >+ // expected value. >+ // If they are not constexpr the attribute will just ignore them and not give >+ // a compile time error. >+ enum e {}; >+ enum class e2 {}; >+ constexpr Case trues[] = { >+ ValidFormat<>("abc"), // >+ >+ ValidFormat<e>("%d"), // >+ ValidFormat<e2>("%d"), // >+ ValidFormat<int>("%% %d"), // >+ ValidFormat<int>("%ld"), // >+ ValidFormat<int>("%lld"), // >+ ValidFormat<std::string>("%s"), // >+ ValidFormat<std::string>("%10s"), // >+ ValidFormat<int>("%.10x"), // >+ ValidFormat<int, int>("%*.3x"), // >+ ValidFormat<int>("%1.d"), // >+ ValidFormat<int>("%.d"), // >+ ValidFormat<int, double>("%d %g"), // >+ ValidFormat<int, std::string>("%*s"), // >+ ValidFormat<int, double>("%.*f"), // >+ ValidFormat<void (*)(), volatile int*>("%p %p"), // >+ ValidFormat<string_view, const char*, double, void*>( >+ "string_view=%s const char*=%s double=%f void*=%p)"), >+ >+ ValidFormat<int>("%% %1$d"), // >+ ValidFormat<int>("%1$ld"), // >+ ValidFormat<int>("%1$lld"), // >+ ValidFormat<std::string>("%1$s"), // >+ ValidFormat<std::string>("%1$10s"), // >+ ValidFormat<int>("%1$.10x"), // >+ ValidFormat<int>("%1$*1$.*1$d"), // >+ ValidFormat<int, int>("%1$*2$.3x"), // >+ ValidFormat<int>("%1$1.d"), // >+ ValidFormat<int>("%1$.d"), // >+ ValidFormat<double, int>("%2$d %1$g"), // >+ ValidFormat<int, std::string>("%2$*1$s"), // >+ ValidFormat<int, double>("%2$.*1$f"), // >+ ValidFormat<void*, string_view, const char*, double>( >+ "string_view=%2$s const char*=%3$s double=%4$f void*=%1$p " >+ "repeat=%3$s)")}; >+ >+ for (Case c : trues) { >+ EXPECT_TRUE(c.result) << c.format; >+ } >+ >+ constexpr Case falses[] = { >+ ValidFormat<int>(""), // >+ >+ ValidFormat<e>("%s"), // >+ ValidFormat<e2>("%s"), // >+ ValidFormat<>("%s"), // >+ ValidFormat<>("%r"), // >+ ValidFormat<int>("%s"), // >+ ValidFormat<int>("%.1.d"), // >+ ValidFormat<int>("%*1d"), // >+ ValidFormat<int>("%1-d"), // >+ ValidFormat<std::string, int>("%*s"), // >+ ValidFormat<int>("%*d"), // >+ ValidFormat<std::string>("%p"), // >+ ValidFormat<int (*)(int)>("%d"), // >+ >+ ValidFormat<>("%3$d"), // >+ ValidFormat<>("%1$r"), // >+ ValidFormat<int>("%1$s"), // >+ ValidFormat<int>("%1$.1.d"), // >+ ValidFormat<int>("%1$*2$1d"), // >+ ValidFormat<int>("%1$1-d"), // >+ ValidFormat<std::string, int>("%2$*1$s"), // >+ ValidFormat<std::string>("%1$p"), >+ >+ ValidFormat<int, int>("%d %2$d"), // >+ }; >+ >+ for (Case c : falses) { >+ EXPECT_FALSE(c.result) << c.format; >+ } >+} >+ >+TEST(StrFormatChecker, LongFormat) { >+#define CHARS_X_40 "1234567890123456789012345678901234567890" >+#define CHARS_X_400 \ >+ CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 \ >+ CHARS_X_40 CHARS_X_40 CHARS_X_40 >+#define CHARS_X_4000 \ >+ CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 \ >+ CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 >+ constexpr char long_format[] = >+ CHARS_X_4000 "%d" CHARS_X_4000 "%s" CHARS_X_4000; >+ constexpr bool is_valid = ValidFormat<int, std::string>(long_format).result; >+ EXPECT_TRUE(is_valid); >+} >+ >+#endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+ >+} // namespace >+} // namespace str_format_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..32f8a0f9ad1a482f038df622d4fb3760ebe6e57c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc >@@ -0,0 +1,575 @@ >+#include <errno.h> >+#include <stdarg.h> >+#include <stdio.h> >+#include <cmath> >+#include <string> >+ >+#include "gtest/gtest.h" >+#include "absl/strings/internal/str_format/bind.h" >+ >+namespace absl { >+namespace str_format_internal { >+namespace { >+ >+template <typename T, size_t N> >+size_t ArraySize(T (&)[N]) { >+ return N; >+} >+ >+std::string LengthModFor(float) { return ""; } >+std::string LengthModFor(double) { return ""; } >+std::string LengthModFor(long double) { return "L"; } >+std::string LengthModFor(char) { return "hh"; } >+std::string LengthModFor(signed char) { return "hh"; } >+std::string LengthModFor(unsigned char) { return "hh"; } >+std::string LengthModFor(short) { return "h"; } // NOLINT >+std::string LengthModFor(unsigned short) { return "h"; } // NOLINT >+std::string LengthModFor(int) { return ""; } >+std::string LengthModFor(unsigned) { return ""; } >+std::string LengthModFor(long) { return "l"; } // NOLINT >+std::string LengthModFor(unsigned long) { return "l"; } // NOLINT >+std::string LengthModFor(long long) { return "ll"; } // NOLINT >+std::string LengthModFor(unsigned long long) { return "ll"; } // NOLINT >+ >+std::string EscCharImpl(int v) { >+ if (isprint(v)) return std::string(1, static_cast<char>(v)); >+ char buf[64]; >+ int n = snprintf(buf, sizeof(buf), "\\%#.2x", >+ static_cast<unsigned>(v & 0xff)); >+ assert(n > 0 && n < sizeof(buf)); >+ return std::string(buf, n); >+} >+ >+std::string Esc(char v) { return EscCharImpl(v); } >+std::string Esc(signed char v) { return EscCharImpl(v); } >+std::string Esc(unsigned char v) { return EscCharImpl(v); } >+ >+template <typename T> >+std::string Esc(const T &v) { >+ std::ostringstream oss; >+ oss << v; >+ return oss.str(); >+} >+ >+void StrAppend(std::string *dst, const char *format, va_list ap) { >+ // First try with a small fixed size buffer >+ static const int kSpaceLength = 1024; >+ char space[kSpaceLength]; >+ >+ // It's possible for methods that use a va_list to invalidate >+ // the data in it upon use. The fix is to make a copy >+ // of the structure before using it and use that copy instead. >+ va_list backup_ap; >+ va_copy(backup_ap, ap); >+ int result = vsnprintf(space, kSpaceLength, format, backup_ap); >+ va_end(backup_ap); >+ if (result < kSpaceLength) { >+ if (result >= 0) { >+ // Normal case -- everything fit. >+ dst->append(space, result); >+ return; >+ } >+ if (result < 0) { >+ // Just an error. >+ return; >+ } >+ } >+ >+ // Increase the buffer size to the size requested by vsnprintf, >+ // plus one for the closing \0. >+ int length = result + 1; >+ char *buf = new char[length]; >+ >+ // Restore the va_list before we use it again >+ va_copy(backup_ap, ap); >+ result = vsnprintf(buf, length, format, backup_ap); >+ va_end(backup_ap); >+ >+ if (result >= 0 && result < length) { >+ // It fit >+ dst->append(buf, result); >+ } >+ delete[] buf; >+} >+ >+std::string StrPrint(const char *format, ...) { >+ va_list ap; >+ va_start(ap, format); >+ std::string result; >+ StrAppend(&result, format, ap); >+ va_end(ap); >+ return result; >+} >+ >+class FormatConvertTest : public ::testing::Test { }; >+ >+template <typename T> >+void TestStringConvert(const T& str) { >+ const FormatArgImpl args[] = {FormatArgImpl(str)}; >+ struct Expectation { >+ const char *out; >+ const char *fmt; >+ }; >+ const Expectation kExpect[] = { >+ {"hello", "%1$s" }, >+ {"", "%1$.s" }, >+ {"", "%1$.0s" }, >+ {"h", "%1$.1s" }, >+ {"he", "%1$.2s" }, >+ {"hello", "%1$.10s" }, >+ {" hello", "%1$6s" }, >+ {" he", "%1$5.2s" }, >+ {"he ", "%1$-5.2s" }, >+ {"hello ", "%1$-6.10s" }, >+ }; >+ for (const Expectation &e : kExpect) { >+ UntypedFormatSpecImpl format(e.fmt); >+ EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args))); >+ } >+} >+ >+TEST_F(FormatConvertTest, BasicString) { >+ TestStringConvert("hello"); // As char array. >+ TestStringConvert(static_cast<const char*>("hello")); >+ TestStringConvert(std::string("hello")); >+ TestStringConvert(string_view("hello")); >+} >+ >+TEST_F(FormatConvertTest, NullString) { >+ const char* p = nullptr; >+ UntypedFormatSpecImpl format("%s"); >+ EXPECT_EQ("", FormatPack(format, {FormatArgImpl(p)})); >+} >+ >+TEST_F(FormatConvertTest, StringPrecision) { >+ // We cap at the precision. >+ char c = 'a'; >+ const char* p = &c; >+ UntypedFormatSpecImpl format("%.1s"); >+ EXPECT_EQ("a", FormatPack(format, {FormatArgImpl(p)})); >+ >+ // We cap at the nul terminator. >+ p = "ABC"; >+ UntypedFormatSpecImpl format2("%.10s"); >+ EXPECT_EQ("ABC", FormatPack(format2, {FormatArgImpl(p)})); >+} >+ >+TEST_F(FormatConvertTest, Pointer) { >+#if _MSC_VER >+ // MSVC's printf implementation prints pointers differently. We can't easily >+ // compare our implementation to theirs. >+ return; >+#endif >+ static int x = 0; >+ const int *xp = &x; >+ char c = 'h'; >+ char *mcp = &c; >+ const char *cp = "hi"; >+ const char *cnil = nullptr; >+ const int *inil = nullptr; >+ using VoidF = void (*)(); >+ VoidF fp = [] {}, fnil = nullptr; >+ volatile char vc; >+ volatile char* vcp = &vc; >+ volatile char* vcnil = nullptr; >+ const FormatArgImpl args[] = { >+ FormatArgImpl(xp), FormatArgImpl(cp), FormatArgImpl(inil), >+ FormatArgImpl(cnil), FormatArgImpl(mcp), FormatArgImpl(fp), >+ FormatArgImpl(fnil), FormatArgImpl(vcp), FormatArgImpl(vcnil), >+ }; >+ struct Expectation { >+ std::string out; >+ const char *fmt; >+ }; >+ const Expectation kExpect[] = { >+ {StrPrint("%p", &x), "%p"}, >+ {StrPrint("%20p", &x), "%20p"}, >+ {StrPrint("%.1p", &x), "%.1p"}, >+ {StrPrint("%.20p", &x), "%.20p"}, >+ {StrPrint("%30.20p", &x), "%30.20p"}, >+ >+ {StrPrint("%-p", &x), "%-p"}, >+ {StrPrint("%-20p", &x), "%-20p"}, >+ {StrPrint("%-.1p", &x), "%-.1p"}, >+ {StrPrint("%.20p", &x), "%.20p"}, >+ {StrPrint("%-30.20p", &x), "%-30.20p"}, >+ >+ {StrPrint("%p", cp), "%2$p"}, // const char* >+ {"(nil)", "%3$p"}, // null const char * >+ {"(nil)", "%4$p"}, // null const int * >+ {StrPrint("%p", mcp), "%5$p"}, // nonconst char* >+ >+ {StrPrint("%p", fp), "%6$p"}, // function pointer >+ {StrPrint("%p", vcp), "%8$p"}, // function pointer >+ >+#ifndef __APPLE__ >+ // Apple's printf differs here (0x0 vs. nil) >+ {StrPrint("%p", fnil), "%7$p"}, // null function pointer >+ {StrPrint("%p", vcnil), "%9$p"}, // null function pointer >+#endif >+ }; >+ for (const Expectation &e : kExpect) { >+ UntypedFormatSpecImpl format(e.fmt); >+ EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args))) << e.fmt; >+ } >+} >+ >+struct Cardinal { >+ enum Pos { k1 = 1, k2 = 2, k3 = 3 }; >+ enum Neg { kM1 = -1, kM2 = -2, kM3 = -3 }; >+}; >+ >+TEST_F(FormatConvertTest, Enum) { >+ const Cardinal::Pos k3 = Cardinal::k3; >+ const Cardinal::Neg km3 = Cardinal::kM3; >+ const FormatArgImpl args[] = {FormatArgImpl(k3), FormatArgImpl(km3)}; >+ UntypedFormatSpecImpl format("%1$d"); >+ UntypedFormatSpecImpl format2("%2$d"); >+ EXPECT_EQ("3", FormatPack(format, absl::MakeSpan(args))); >+ EXPECT_EQ("-3", FormatPack(format2, absl::MakeSpan(args))); >+} >+ >+template <typename T> >+class TypedFormatConvertTest : public FormatConvertTest { }; >+ >+TYPED_TEST_CASE_P(TypedFormatConvertTest); >+ >+std::vector<std::string> AllFlagCombinations() { >+ const char kFlags[] = {'-', '#', '0', '+', ' '}; >+ std::vector<std::string> result; >+ for (size_t fsi = 0; fsi < (1ull << ArraySize(kFlags)); ++fsi) { >+ std::string flag_set; >+ for (size_t fi = 0; fi < ArraySize(kFlags); ++fi) >+ if (fsi & (1ull << fi)) >+ flag_set += kFlags[fi]; >+ result.push_back(flag_set); >+ } >+ return result; >+} >+ >+TYPED_TEST_P(TypedFormatConvertTest, AllIntsWithFlags) { >+ typedef TypeParam T; >+ typedef typename std::make_unsigned<T>::type UnsignedT; >+ using remove_volatile_t = typename std::remove_volatile<T>::type; >+ const T kMin = std::numeric_limits<remove_volatile_t>::min(); >+ const T kMax = std::numeric_limits<remove_volatile_t>::max(); >+ const T kVals[] = { >+ remove_volatile_t(1), >+ remove_volatile_t(2), >+ remove_volatile_t(3), >+ remove_volatile_t(123), >+ remove_volatile_t(-1), >+ remove_volatile_t(-2), >+ remove_volatile_t(-3), >+ remove_volatile_t(-123), >+ remove_volatile_t(0), >+ kMax - remove_volatile_t(1), >+ kMax, >+ kMin + remove_volatile_t(1), >+ kMin, >+ }; >+ const char kConvChars[] = {'d', 'i', 'u', 'o', 'x', 'X'}; >+ const std::string kWid[] = {"", "4", "10"}; >+ const std::string kPrec[] = {"", ".", ".0", ".4", ".10"}; >+ >+ const std::vector<std::string> flag_sets = AllFlagCombinations(); >+ >+ for (size_t vi = 0; vi < ArraySize(kVals); ++vi) { >+ const T val = kVals[vi]; >+ SCOPED_TRACE(Esc(val)); >+ const FormatArgImpl args[] = {FormatArgImpl(val)}; >+ for (size_t ci = 0; ci < ArraySize(kConvChars); ++ci) { >+ const char conv_char = kConvChars[ci]; >+ for (size_t fsi = 0; fsi < flag_sets.size(); ++fsi) { >+ const std::string &flag_set = flag_sets[fsi]; >+ for (size_t wi = 0; wi < ArraySize(kWid); ++wi) { >+ const std::string &wid = kWid[wi]; >+ for (size_t pi = 0; pi < ArraySize(kPrec); ++pi) { >+ const std::string &prec = kPrec[pi]; >+ >+ const bool is_signed_conv = (conv_char == 'd' || conv_char == 'i'); >+ const bool is_unsigned_to_signed = >+ !std::is_signed<T>::value && is_signed_conv; >+ // Don't consider sign-related flags '+' and ' ' when doing >+ // unsigned to signed conversions. >+ if (is_unsigned_to_signed && >+ flag_set.find_first_of("+ ") != std::string::npos) { >+ continue; >+ } >+ >+ std::string new_fmt("%"); >+ new_fmt += flag_set; >+ new_fmt += wid; >+ new_fmt += prec; >+ // old and new always agree up to here. >+ std::string old_fmt = new_fmt; >+ new_fmt += conv_char; >+ std::string old_result; >+ if (is_unsigned_to_signed) { >+ // don't expect agreement on unsigned formatted as signed, >+ // as printf can't do that conversion properly. For those >+ // cases, we do expect agreement with printf with a "%u" >+ // and the unsigned equivalent of 'val'. >+ UnsignedT uval = val; >+ old_fmt += LengthModFor(uval); >+ old_fmt += "u"; >+ old_result = StrPrint(old_fmt.c_str(), uval); >+ } else { >+ old_fmt += LengthModFor(val); >+ old_fmt += conv_char; >+ old_result = StrPrint(old_fmt.c_str(), val); >+ } >+ >+ SCOPED_TRACE(std::string() + " old_fmt: \"" + old_fmt + >+ "\"'" >+ " new_fmt: \"" + >+ new_fmt + "\""); >+ UntypedFormatSpecImpl format(new_fmt); >+ EXPECT_EQ(old_result, FormatPack(format, absl::MakeSpan(args))); >+ } >+ } >+ } >+ } >+ } >+} >+ >+TYPED_TEST_P(TypedFormatConvertTest, Char) { >+ typedef TypeParam T; >+ using remove_volatile_t = typename std::remove_volatile<T>::type; >+ static const T kMin = std::numeric_limits<remove_volatile_t>::min(); >+ static const T kMax = std::numeric_limits<remove_volatile_t>::max(); >+ T kVals[] = { >+ remove_volatile_t(1), remove_volatile_t(2), remove_volatile_t(10), >+ remove_volatile_t(-1), remove_volatile_t(-2), remove_volatile_t(-10), >+ remove_volatile_t(0), >+ kMin + remove_volatile_t(1), kMin, >+ kMax - remove_volatile_t(1), kMax >+ }; >+ for (const T &c : kVals) { >+ const FormatArgImpl args[] = {FormatArgImpl(c)}; >+ UntypedFormatSpecImpl format("%c"); >+ EXPECT_EQ(StrPrint("%c", c), FormatPack(format, absl::MakeSpan(args))); >+ } >+} >+ >+REGISTER_TYPED_TEST_CASE_P(TypedFormatConvertTest, AllIntsWithFlags, Char); >+ >+typedef ::testing::Types< >+ int, unsigned, volatile int, >+ short, unsigned short, >+ long, unsigned long, >+ long long, unsigned long long, >+ signed char, unsigned char, char> >+ AllIntTypes; >+INSTANTIATE_TYPED_TEST_CASE_P(TypedFormatConvertTestWithAllIntTypes, >+ TypedFormatConvertTest, AllIntTypes); >+TEST_F(FormatConvertTest, Uint128) { >+ absl::uint128 v = static_cast<absl::uint128>(0x1234567890abcdef) * 1979; >+ absl::uint128 max = absl::Uint128Max(); >+ const FormatArgImpl args[] = {FormatArgImpl(v), FormatArgImpl(max)}; >+ >+ struct Case { >+ const char* format; >+ const char* expected; >+ } cases[] = { >+ {"%1$d", "2595989796776606496405"}, >+ {"%1$30d", " 2595989796776606496405"}, >+ {"%1$-30d", "2595989796776606496405 "}, >+ {"%1$u", "2595989796776606496405"}, >+ {"%1$x", "8cba9876066020f695"}, >+ {"%2$d", "340282366920938463463374607431768211455"}, >+ {"%2$u", "340282366920938463463374607431768211455"}, >+ {"%2$x", "ffffffffffffffffffffffffffffffff"}, >+ }; >+ >+ for (auto c : cases) { >+ UntypedFormatSpecImpl format(c.format); >+ EXPECT_EQ(c.expected, FormatPack(format, absl::MakeSpan(args))); >+ } >+} >+ >+TEST_F(FormatConvertTest, Float) { >+#if _MSC_VER >+ // MSVC has a different rounding policy than us so we can't test our >+ // implementation against the native one there. >+ return; >+#endif // _MSC_VER >+ >+ const char *const kFormats[] = { >+ "%", "%.3", "%8.5", "%9", "%.60", "%.30", "%03", "%+", >+ "% ", "%-10", "%#15.3", "%#.0", "%.0", "%1$*2$", "%1$.*2$"}; >+ >+ std::vector<double> doubles = {0.0, >+ -0.0, >+ .99999999999999, >+ 99999999999999., >+ std::numeric_limits<double>::max(), >+ -std::numeric_limits<double>::max(), >+ std::numeric_limits<double>::min(), >+ -std::numeric_limits<double>::min(), >+ std::numeric_limits<double>::lowest(), >+ -std::numeric_limits<double>::lowest(), >+ std::numeric_limits<double>::epsilon(), >+ std::numeric_limits<double>::epsilon() + 1, >+ std::numeric_limits<double>::infinity(), >+ -std::numeric_limits<double>::infinity()}; >+ >+#ifndef __APPLE__ >+ // Apple formats NaN differently (+nan) vs. (nan) >+ doubles.push_back(std::nan("")); >+#endif >+ >+ // Some regression tests. >+ doubles.push_back(0.99999999999999989); >+ >+ if (std::numeric_limits<double>::has_denorm != std::denorm_absent) { >+ doubles.push_back(std::numeric_limits<double>::denorm_min()); >+ doubles.push_back(-std::numeric_limits<double>::denorm_min()); >+ } >+ >+ for (double base : >+ {1., 12., 123., 1234., 12345., 123456., 1234567., 12345678., 123456789., >+ 1234567890., 12345678901., 123456789012., 1234567890123.}) { >+ for (int exp = -123; exp <= 123; ++exp) { >+ for (int sign : {1, -1}) { >+ doubles.push_back(sign * std::ldexp(base, exp)); >+ } >+ } >+ } >+ >+ for (const char *fmt : kFormats) { >+ for (char f : {'f', 'F', // >+ 'g', 'G', // >+ 'a', 'A', // >+ 'e', 'E'}) { >+ std::string fmt_str = std::string(fmt) + f; >+ for (double d : doubles) { >+ int i = -10; >+ FormatArgImpl args[2] = {FormatArgImpl(d), FormatArgImpl(i)}; >+ UntypedFormatSpecImpl format(fmt_str); >+ // We use ASSERT_EQ here because failures are usually correlated and a >+ // bug would print way too many failed expectations causing the test to >+ // time out. >+ ASSERT_EQ(StrPrint(fmt_str.c_str(), d, i), >+ FormatPack(format, absl::MakeSpan(args))) >+ << fmt_str << " " << StrPrint("%.18g", d) << " " >+ << StrPrint("%.999f", d); >+ } >+ } >+ } >+} >+ >+TEST_F(FormatConvertTest, LongDouble) { >+ const char *const kFormats[] = {"%", "%.3", "%8.5", "%9", >+ "%.60", "%+", "% ", "%-10"}; >+ >+ // This value is not representable in double, but it is in long double that >+ // uses the extended format. >+ // This is to verify that we are not truncating the value mistakenly through a >+ // double. >+ long double very_precise = 10000000000000000.25L; >+ >+ std::vector<long double> doubles = { >+ 0.0, >+ -0.0, >+ very_precise, >+ 1 / very_precise, >+ std::numeric_limits<long double>::max(), >+ -std::numeric_limits<long double>::max(), >+ std::numeric_limits<long double>::min(), >+ -std::numeric_limits<long double>::min(), >+ std::numeric_limits<long double>::infinity(), >+ -std::numeric_limits<long double>::infinity()}; >+ >+ for (const char *fmt : kFormats) { >+ for (char f : {'f', 'F', // >+ 'g', 'G', // >+ 'a', 'A', // >+ 'e', 'E'}) { >+ std::string fmt_str = std::string(fmt) + 'L' + f; >+ for (auto d : doubles) { >+ FormatArgImpl arg(d); >+ UntypedFormatSpecImpl format(fmt_str); >+ // We use ASSERT_EQ here because failures are usually correlated and a >+ // bug would print way too many failed expectations causing the test to >+ // time out. >+ ASSERT_EQ(StrPrint(fmt_str.c_str(), d), >+ FormatPack(format, {&arg, 1})) >+ << fmt_str << " " << StrPrint("%.18Lg", d) << " " >+ << StrPrint("%.999Lf", d); >+ } >+ } >+ } >+} >+ >+TEST_F(FormatConvertTest, IntAsFloat) { >+ const int kMin = std::numeric_limits<int>::min(); >+ const int kMax = std::numeric_limits<int>::max(); >+ const int ia[] = { >+ 1, 2, 3, 123, >+ -1, -2, -3, -123, >+ 0, kMax - 1, kMax, kMin + 1, kMin }; >+ for (const int fx : ia) { >+ SCOPED_TRACE(fx); >+ const FormatArgImpl args[] = {FormatArgImpl(fx)}; >+ struct Expectation { >+ int line; >+ std::string out; >+ const char *fmt; >+ }; >+ const double dx = static_cast<double>(fx); >+ const Expectation kExpect[] = { >+ { __LINE__, StrPrint("%f", dx), "%f" }, >+ { __LINE__, StrPrint("%12f", dx), "%12f" }, >+ { __LINE__, StrPrint("%.12f", dx), "%.12f" }, >+ { __LINE__, StrPrint("%12a", dx), "%12a" }, >+ { __LINE__, StrPrint("%.12a", dx), "%.12a" }, >+ }; >+ for (const Expectation &e : kExpect) { >+ SCOPED_TRACE(e.line); >+ SCOPED_TRACE(e.fmt); >+ UntypedFormatSpecImpl format(e.fmt); >+ EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args))); >+ } >+ } >+} >+ >+template <typename T> >+bool FormatFails(const char* test_format, T value) { >+ std::string format_string = std::string("<<") + test_format + ">>"; >+ UntypedFormatSpecImpl format(format_string); >+ >+ int one = 1; >+ const FormatArgImpl args[] = {FormatArgImpl(value), FormatArgImpl(one)}; >+ EXPECT_EQ(FormatPack(format, absl::MakeSpan(args)), "") >+ << "format=" << test_format << " value=" << value; >+ return FormatPack(format, absl::MakeSpan(args)).empty(); >+} >+ >+TEST_F(FormatConvertTest, ExpectedFailures) { >+ // Int input >+ EXPECT_TRUE(FormatFails("%p", 1)); >+ EXPECT_TRUE(FormatFails("%s", 1)); >+ EXPECT_TRUE(FormatFails("%n", 1)); >+ >+ // Double input >+ EXPECT_TRUE(FormatFails("%p", 1.)); >+ EXPECT_TRUE(FormatFails("%s", 1.)); >+ EXPECT_TRUE(FormatFails("%n", 1.)); >+ EXPECT_TRUE(FormatFails("%c", 1.)); >+ EXPECT_TRUE(FormatFails("%d", 1.)); >+ EXPECT_TRUE(FormatFails("%x", 1.)); >+ EXPECT_TRUE(FormatFails("%*d", 1.)); >+ >+ // String input >+ EXPECT_TRUE(FormatFails("%n", "")); >+ EXPECT_TRUE(FormatFails("%c", "")); >+ EXPECT_TRUE(FormatFails("%d", "")); >+ EXPECT_TRUE(FormatFails("%x", "")); >+ EXPECT_TRUE(FormatFails("%f", "")); >+ EXPECT_TRUE(FormatFails("%*d", "")); >+} >+ >+} // namespace >+} // namespace str_format_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..c2174703c3e8b3f37bd12c64dd92025e3a74a960 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc >@@ -0,0 +1,84 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/str_format/extension.h" >+ >+#include <errno.h> >+#include <algorithm> >+#include <string> >+ >+namespace absl { >+namespace str_format_internal { >+namespace { >+// clang-format off >+#define ABSL_LENGTH_MODS_EXPAND_ \ >+ X_VAL(h) X_SEP \ >+ X_VAL(hh) X_SEP \ >+ X_VAL(l) X_SEP \ >+ X_VAL(ll) X_SEP \ >+ X_VAL(L) X_SEP \ >+ X_VAL(j) X_SEP \ >+ X_VAL(z) X_SEP \ >+ X_VAL(t) X_SEP \ >+ X_VAL(q) >+// clang-format on >+} // namespace >+ >+const LengthMod::Spec LengthMod::kSpecs[] = { >+#define X_VAL(id) { LengthMod::id, #id, strlen(#id) } >+#define X_SEP , >+ ABSL_LENGTH_MODS_EXPAND_, {LengthMod::none, "", 0} >+#undef X_VAL >+#undef X_SEP >+}; >+ >+const ConversionChar::Spec ConversionChar::kSpecs[] = { >+#define X_VAL(id) { ConversionChar::id, #id[0] } >+#define X_SEP , >+ ABSL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP), >+ {ConversionChar::none, '\0'}, >+#undef X_VAL >+#undef X_SEP >+}; >+ >+std::string Flags::ToString() const { >+ std::string s; >+ s.append(left ? "-" : ""); >+ s.append(show_pos ? "+" : ""); >+ s.append(sign_col ? " " : ""); >+ s.append(alt ? "#" : ""); >+ s.append(zero ? "0" : ""); >+ return s; >+} >+ >+const size_t LengthMod::kNumValues; >+ >+const size_t ConversionChar::kNumValues; >+ >+bool FormatSinkImpl::PutPaddedString(string_view v, int w, int p, bool l) { >+ size_t space_remaining = 0; >+ if (w >= 0) space_remaining = w; >+ size_t n = v.size(); >+ if (p >= 0) n = std::min(n, static_cast<size_t>(p)); >+ string_view shown(v.data(), n); >+ space_remaining = Excess(shown.size(), space_remaining); >+ if (!l) Append(space_remaining, ' '); >+ Append(shown); >+ if (l) Append(space_remaining, ' '); >+ return true; >+} >+ >+} // namespace str_format_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h >new file mode 100644 >index 0000000000000000000000000000000000000000..810330b9d71bd188c26eae215abd61d48ed4bd78 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h >@@ -0,0 +1,406 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// >+#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_ >+#define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_ >+ >+#include <limits.h> >+#include <cstring> >+#include <ostream> >+ >+#include "absl/base/port.h" >+#include "absl/strings/internal/str_format/output.h" >+#include "absl/strings/string_view.h" >+ >+class Cord; >+ >+namespace absl { >+ >+namespace str_format_internal { >+ >+class FormatRawSinkImpl { >+ public: >+ // Implicitly convert from any type that provides the hook function as >+ // described above. >+ template <typename T, decltype(str_format_internal::InvokeFlush( >+ std::declval<T*>(), string_view()))* = nullptr> >+ FormatRawSinkImpl(T* raw) // NOLINT >+ : sink_(raw), write_(&FormatRawSinkImpl::Flush<T>) {} >+ >+ void Write(string_view s) { write_(sink_, s); } >+ >+ template <typename T> >+ static FormatRawSinkImpl Extract(T s) { >+ return s.sink_; >+ } >+ >+ private: >+ template <typename T> >+ static void Flush(void* r, string_view s) { >+ str_format_internal::InvokeFlush(static_cast<T*>(r), s); >+ } >+ >+ void* sink_; >+ void (*write_)(void*, string_view); >+}; >+ >+// An abstraction to which conversions write their std::string data. >+class FormatSinkImpl { >+ public: >+ explicit FormatSinkImpl(FormatRawSinkImpl raw) : raw_(raw) {} >+ >+ ~FormatSinkImpl() { Flush(); } >+ >+ void Flush() { >+ raw_.Write(string_view(buf_, pos_ - buf_)); >+ pos_ = buf_; >+ } >+ >+ void Append(size_t n, char c) { >+ if (n == 0) return; >+ size_ += n; >+ auto raw_append = [&](size_t count) { >+ memset(pos_, c, count); >+ pos_ += count; >+ }; >+ while (n > Avail()) { >+ n -= Avail(); >+ if (Avail() > 0) { >+ raw_append(Avail()); >+ } >+ Flush(); >+ } >+ raw_append(n); >+ } >+ >+ void Append(string_view v) { >+ size_t n = v.size(); >+ if (n == 0) return; >+ size_ += n; >+ if (n >= Avail()) { >+ Flush(); >+ raw_.Write(v); >+ return; >+ } >+ memcpy(pos_, v.data(), n); >+ pos_ += n; >+ } >+ >+ size_t size() const { return size_; } >+ >+ // Put 'v' to 'sink' with specified width, precision, and left flag. >+ bool PutPaddedString(string_view v, int w, int p, bool l); >+ >+ template <typename T> >+ T Wrap() { >+ return T(this); >+ } >+ >+ template <typename T> >+ static FormatSinkImpl* Extract(T* s) { >+ return s->sink_; >+ } >+ >+ private: >+ size_t Avail() const { return buf_ + sizeof(buf_) - pos_; } >+ >+ FormatRawSinkImpl raw_; >+ size_t size_ = 0; >+ char* pos_ = buf_; >+ char buf_[1024]; >+}; >+ >+struct Flags { >+ bool basic : 1; // fastest conversion: no flags, width, or precision >+ bool left : 1; // "-" >+ bool show_pos : 1; // "+" >+ bool sign_col : 1; // " " >+ bool alt : 1; // "#" >+ bool zero : 1; // "0" >+ std::string ToString() const; >+ friend std::ostream& operator<<(std::ostream& os, const Flags& v) { >+ return os << v.ToString(); >+ } >+}; >+ >+struct LengthMod { >+ public: >+ enum Id : uint8_t { >+ h, hh, l, ll, L, j, z, t, q, none >+ }; >+ static const size_t kNumValues = none + 1; >+ >+ LengthMod() : id_(none) {} >+ >+ // Index into the opaque array of LengthMod enums. >+ // Requires: i < kNumValues >+ static LengthMod FromIndex(size_t i) { >+ return LengthMod(kSpecs[i].value); >+ } >+ >+ static LengthMod FromId(Id id) { return LengthMod(id); } >+ >+ // The length modifier std::string associated with a specified LengthMod. >+ string_view name() const { >+ const Spec& spec = kSpecs[id_]; >+ return {spec.name, spec.name_length}; >+ } >+ >+ Id id() const { return id_; } >+ >+ friend bool operator==(const LengthMod& a, const LengthMod& b) { >+ return a.id() == b.id(); >+ } >+ friend bool operator!=(const LengthMod& a, const LengthMod& b) { >+ return !(a == b); >+ } >+ friend std::ostream& operator<<(std::ostream& os, const LengthMod& v) { >+ return os << v.name(); >+ } >+ >+ private: >+ struct Spec { >+ Id value; >+ const char *name; >+ size_t name_length; >+ }; >+ static const Spec kSpecs[]; >+ >+ explicit LengthMod(Id id) : id_(id) {} >+ >+ Id id_; >+}; >+ >+// clang-format off >+#define ABSL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \ >+ /* text */ \ >+ X_VAL(c) X_SEP X_VAL(C) X_SEP X_VAL(s) X_SEP X_VAL(S) X_SEP \ >+ /* ints */ \ >+ X_VAL(d) X_SEP X_VAL(i) X_SEP X_VAL(o) X_SEP \ >+ X_VAL(u) X_SEP X_VAL(x) X_SEP X_VAL(X) X_SEP \ >+ /* floats */ \ >+ X_VAL(f) X_SEP X_VAL(F) X_SEP X_VAL(e) X_SEP X_VAL(E) X_SEP \ >+ X_VAL(g) X_SEP X_VAL(G) X_SEP X_VAL(a) X_SEP X_VAL(A) X_SEP \ >+ /* misc */ \ >+ X_VAL(n) X_SEP X_VAL(p) >+// clang-format on >+ >+struct ConversionChar { >+ public: >+ enum Id : uint8_t { >+ c, C, s, S, // text >+ d, i, o, u, x, X, // int >+ f, F, e, E, g, G, a, A, // float >+ n, p, // misc >+ none >+ }; >+ static const size_t kNumValues = none + 1; >+ >+ ConversionChar() : id_(none) {} >+ >+ public: >+ // Index into the opaque array of ConversionChar enums. >+ // Requires: i < kNumValues >+ static ConversionChar FromIndex(size_t i) { >+ return ConversionChar(kSpecs[i].value); >+ } >+ >+ static ConversionChar FromChar(char c) { >+ ConversionChar::Id out_id = ConversionChar::none; >+ switch (c) { >+#define X_VAL(id) \ >+ case #id[0]: \ >+ out_id = ConversionChar::id; \ >+ break; >+ ABSL_CONVERSION_CHARS_EXPAND_(X_VAL, ) >+#undef X_VAL >+ default: >+ break; >+ } >+ return ConversionChar(out_id); >+ } >+ >+ static ConversionChar FromId(Id id) { return ConversionChar(id); } >+ Id id() const { return id_; } >+ >+ int radix() const { >+ switch (id()) { >+ case x: case X: case a: case A: case p: return 16; >+ case o: return 8; >+ default: return 10; >+ } >+ } >+ >+ bool upper() const { >+ switch (id()) { >+ case X: case F: case E: case G: case A: return true; >+ default: return false; >+ } >+ } >+ >+ bool is_signed() const { >+ switch (id()) { >+ case d: case i: return true; >+ default: return false; >+ } >+ } >+ >+ bool is_integral() const { >+ switch (id()) { >+ case d: case i: case u: case o: case x: case X: >+ return true; >+ default: return false; >+ } >+ } >+ >+ bool is_float() const { >+ switch (id()) { >+ case a: case e: case f: case g: case A: case E: case F: case G: >+ return true; >+ default: return false; >+ } >+ } >+ >+ bool IsValid() const { return id() != none; } >+ >+ // The associated char. >+ char Char() const { return kSpecs[id_].name; } >+ >+ friend bool operator==(const ConversionChar& a, const ConversionChar& b) { >+ return a.id() == b.id(); >+ } >+ friend bool operator!=(const ConversionChar& a, const ConversionChar& b) { >+ return !(a == b); >+ } >+ friend std::ostream& operator<<(std::ostream& os, const ConversionChar& v) { >+ char c = v.Char(); >+ if (!c) c = '?'; >+ return os << c; >+ } >+ >+ private: >+ struct Spec { >+ Id value; >+ char name; >+ }; >+ static const Spec kSpecs[]; >+ >+ explicit ConversionChar(Id id) : id_(id) {} >+ >+ Id id_; >+}; >+ >+class ConversionSpec { >+ public: >+ Flags flags() const { return flags_; } >+ LengthMod length_mod() const { return length_mod_; } >+ ConversionChar conv() const { return conv_; } >+ >+ // Returns the specified width. If width is unspecfied, it returns a negative >+ // value. >+ int width() const { return width_; } >+ // Returns the specified precision. If precision is unspecfied, it returns a >+ // negative value. >+ int precision() const { return precision_; } >+ >+ void set_flags(Flags f) { flags_ = f; } >+ void set_length_mod(LengthMod lm) { length_mod_ = lm; } >+ void set_conv(ConversionChar c) { conv_ = c; } >+ void set_width(int w) { width_ = w; } >+ void set_precision(int p) { precision_ = p; } >+ void set_left(bool b) { flags_.left = b; } >+ >+ private: >+ Flags flags_; >+ LengthMod length_mod_; >+ ConversionChar conv_; >+ int width_; >+ int precision_; >+}; >+ >+constexpr uint64_t ConversionCharToConvValue(char conv) { >+ return >+#define CONV_SET_CASE(c) \ >+ conv == #c[0] ? (uint64_t{1} << (1 + ConversionChar::Id::c)): >+ ABSL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, ) >+#undef CONV_SET_CASE >+ conv == '*' >+ ? 1 >+ : 0; >+} >+ >+enum class Conv : uint64_t { >+#define CONV_SET_CASE(c) c = ConversionCharToConvValue(#c[0]), >+ ABSL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, ) >+#undef CONV_SET_CASE >+ >+ // Used for width/precision '*' specification. >+ star = ConversionCharToConvValue('*'), >+ >+ // Some predefined values: >+ integral = d | i | u | o | x | X, >+ floating = a | e | f | g | A | E | F | G, >+ numeric = integral | floating, >+ string = s, // absl:ignore(std::string) >+ pointer = p >+}; >+ >+// Type safe OR operator. >+// We need this for two reasons: >+// 1. operator| on enums makes them decay to integers and the result is an >+// integer. We need the result to stay as an enum. >+// 2. We use "enum class" which would not work even if we accepted the decay. >+constexpr Conv operator|(Conv a, Conv b) { >+ return Conv(static_cast<uint64_t>(a) | static_cast<uint64_t>(b)); >+} >+ >+// Get a conversion with a single character in it. >+constexpr Conv ConversionCharToConv(char c) { >+ return Conv(ConversionCharToConvValue(c)); >+} >+ >+// Checks whether `c` exists in `set`. >+constexpr bool Contains(Conv set, char c) { >+ return (static_cast<uint64_t>(set) & ConversionCharToConvValue(c)) != 0; >+} >+ >+// Checks whether all the characters in `c` are contained in `set` >+constexpr bool Contains(Conv set, Conv c) { >+ return (static_cast<uint64_t>(set) & static_cast<uint64_t>(c)) == >+ static_cast<uint64_t>(c); >+} >+ >+// Return type of the AbslFormatConvert() functions. >+// The Conv template parameter is used to inform the framework of what >+// conversion characters are supported by that AbslFormatConvert routine. >+template <Conv C> >+struct ConvertResult { >+ static constexpr Conv kConv = C; >+ bool value; >+}; >+template <Conv C> >+constexpr Conv ConvertResult<C>::kConv; >+ >+// Return capacity - used, clipped to a minimum of 0. >+inline size_t Excess(size_t used, size_t capacity) { >+ return used < capacity ? capacity - used : 0; >+} >+ >+} // namespace str_format_internal >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_STR_FORMAT_EXTENSION_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/extension_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/extension_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..224fc923d3e3dbaa34170a47c6f8133c8444ab39 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/extension_test.cc >@@ -0,0 +1,65 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#include "absl/strings/internal/str_format/extension.h" >+ >+#include <random> >+#include <string> >+#include "absl/strings/str_format.h" >+ >+#include "gtest/gtest.h" >+ >+namespace { >+ >+std::string MakeRandomString(size_t len) { >+ std::random_device rd; >+ std::mt19937 gen(rd()); >+ std::uniform_int_distribution<> dis('a', 'z'); >+ std::string s(len, '0'); >+ for (char& c : s) { >+ c = dis(gen); >+ } >+ return s; >+} >+ >+TEST(FormatExtensionTest, SinkAppendSubstring) { >+ for (size_t chunk_size : {1, 10, 100, 1000, 10000}) { >+ std::string expected, actual; >+ absl::str_format_internal::FormatSinkImpl sink(&actual); >+ for (size_t chunks = 0; chunks < 10; ++chunks) { >+ std::string rand = MakeRandomString(chunk_size); >+ expected += rand; >+ sink.Append(rand); >+ } >+ sink.Flush(); >+ EXPECT_EQ(actual, expected); >+ } >+} >+ >+TEST(FormatExtensionTest, SinkAppendChars) { >+ for (size_t chunk_size : {1, 10, 100, 1000, 10000}) { >+ std::string expected, actual; >+ absl::str_format_internal::FormatSinkImpl sink(&actual); >+ for (size_t chunks = 0; chunks < 10; ++chunks) { >+ std::string rand = MakeRandomString(1); >+ expected.append(chunk_size, rand[0]); >+ sink.Append(chunk_size, rand[0]); >+ } >+ sink.Flush(); >+ EXPECT_EQ(actual, expected); >+ } >+} >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..6176db9cb5a22dc1133aadcb6c959593b0199617 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc >@@ -0,0 +1,483 @@ >+#include "absl/strings/internal/str_format/float_conversion.h" >+ >+#include <string.h> >+#include <algorithm> >+#include <cassert> >+#include <cmath> >+#include <string> >+ >+namespace absl { >+namespace str_format_internal { >+ >+namespace { >+ >+char *CopyStringTo(string_view v, char *out) { >+ std::memcpy(out, v.data(), v.size()); >+ return out + v.size(); >+} >+ >+template <typename Float> >+bool FallbackToSnprintf(const Float v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ int w = conv.width() >= 0 ? conv.width() : 0; >+ int p = conv.precision() >= 0 ? conv.precision() : -1; >+ char fmt[32]; >+ { >+ char *fp = fmt; >+ *fp++ = '%'; >+ fp = CopyStringTo(conv.flags().ToString(), fp); >+ fp = CopyStringTo("*.*", fp); >+ if (std::is_same<long double, Float>()) { >+ *fp++ = 'L'; >+ } >+ *fp++ = conv.conv().Char(); >+ *fp = 0; >+ assert(fp < fmt + sizeof(fmt)); >+ } >+ std::string space(512, '\0'); >+ string_view result; >+ while (true) { >+ int n = snprintf(&space[0], space.size(), fmt, w, p, v); >+ if (n < 0) return false; >+ if (static_cast<size_t>(n) < space.size()) { >+ result = string_view(space.data(), n); >+ break; >+ } >+ space.resize(n + 1); >+ } >+ sink->Append(result); >+ return true; >+} >+ >+// 128-bits in decimal: ceil(128*log(2)/log(10)) >+// or std::numeric_limits<__uint128_t>::digits10 >+constexpr int kMaxFixedPrecision = 39; >+ >+constexpr int kBufferLength = /*sign*/ 1 + >+ /*integer*/ kMaxFixedPrecision + >+ /*point*/ 1 + >+ /*fraction*/ kMaxFixedPrecision + >+ /*exponent e+123*/ 5; >+ >+struct Buffer { >+ void push_front(char c) { >+ assert(begin > data); >+ *--begin = c; >+ } >+ void push_back(char c) { >+ assert(end < data + sizeof(data)); >+ *end++ = c; >+ } >+ void pop_back() { >+ assert(begin < end); >+ --end; >+ } >+ >+ char &back() { >+ assert(begin < end); >+ return end[-1]; >+ } >+ >+ char last_digit() const { return end[-1] == '.' ? end[-2] : end[-1]; } >+ >+ int size() const { return static_cast<int>(end - begin); } >+ >+ char data[kBufferLength]; >+ char *begin; >+ char *end; >+}; >+ >+enum class FormatStyle { Fixed, Precision }; >+ >+// If the value is Inf or Nan, print it and return true. >+// Otherwise, return false. >+template <typename Float> >+bool ConvertNonNumericFloats(char sign_char, Float v, >+ const ConversionSpec &conv, FormatSinkImpl *sink) { >+ char text[4], *ptr = text; >+ if (sign_char) *ptr++ = sign_char; >+ if (std::isnan(v)) { >+ ptr = std::copy_n(conv.conv().upper() ? "NAN" : "nan", 3, ptr); >+ } else if (std::isinf(v)) { >+ ptr = std::copy_n(conv.conv().upper() ? "INF" : "inf", 3, ptr); >+ } else { >+ return false; >+ } >+ >+ return sink->PutPaddedString(string_view(text, ptr - text), conv.width(), -1, >+ conv.flags().left); >+} >+ >+// Round up the last digit of the value. >+// It will carry over and potentially overflow. 'exp' will be adjusted in that >+// case. >+template <FormatStyle mode> >+void RoundUp(Buffer *buffer, int *exp) { >+ char *p = &buffer->back(); >+ while (p >= buffer->begin && (*p == '9' || *p == '.')) { >+ if (*p == '9') *p = '0'; >+ --p; >+ } >+ >+ if (p < buffer->begin) { >+ *p = '1'; >+ buffer->begin = p; >+ if (mode == FormatStyle::Precision) { >+ std::swap(p[1], p[2]); // move the . >+ ++*exp; >+ buffer->pop_back(); >+ } >+ } else { >+ ++*p; >+ } >+} >+ >+void PrintExponent(int exp, char e, Buffer *out) { >+ out->push_back(e); >+ if (exp < 0) { >+ out->push_back('-'); >+ exp = -exp; >+ } else { >+ out->push_back('+'); >+ } >+ // Exponent digits. >+ if (exp > 99) { >+ out->push_back(exp / 100 + '0'); >+ out->push_back(exp / 10 % 10 + '0'); >+ out->push_back(exp % 10 + '0'); >+ } else { >+ out->push_back(exp / 10 + '0'); >+ out->push_back(exp % 10 + '0'); >+ } >+} >+ >+template <typename Float, typename Int> >+constexpr bool CanFitMantissa() { >+ return >+#if defined(__clang__) && !defined(__SSE3__) >+ // Workaround for clang bug: https://bugs.llvm.org/show_bug.cgi?id=38289 >+ // Casting from long double to uint64_t is miscompiled and drops bits. >+ (!std::is_same<Float, long double>::value || >+ !std::is_same<Int, uint64_t>::value) && >+#endif >+ std::numeric_limits<Float>::digits <= std::numeric_limits<Int>::digits; >+} >+ >+template <typename Float> >+struct Decomposed { >+ Float mantissa; >+ int exponent; >+}; >+ >+// Decompose the double into an integer mantissa and an exponent. >+template <typename Float> >+Decomposed<Float> Decompose(Float v) { >+ int exp; >+ Float m = std::frexp(v, &exp); >+ m = std::ldexp(m, std::numeric_limits<Float>::digits); >+ exp -= std::numeric_limits<Float>::digits; >+ return {m, exp}; >+} >+ >+// Print 'digits' as decimal. >+// In Fixed mode, we add a '.' at the end. >+// In Precision mode, we add a '.' after the first digit. >+template <FormatStyle mode, typename Int> >+int PrintIntegralDigits(Int digits, Buffer *out) { >+ int printed = 0; >+ if (digits) { >+ for (; digits; digits /= 10) out->push_front(digits % 10 + '0'); >+ printed = out->size(); >+ if (mode == FormatStyle::Precision) { >+ out->push_front(*out->begin); >+ out->begin[1] = '.'; >+ } else { >+ out->push_back('.'); >+ } >+ } else if (mode == FormatStyle::Fixed) { >+ out->push_front('0'); >+ out->push_back('.'); >+ printed = 1; >+ } >+ return printed; >+} >+ >+// Back out 'extra_digits' digits and round up if necessary. >+bool RemoveExtraPrecision(int extra_digits, bool has_leftover_value, >+ Buffer *out, int *exp_out) { >+ if (extra_digits <= 0) return false; >+ >+ // Back out the extra digits >+ out->end -= extra_digits; >+ >+ bool needs_to_round_up = [&] { >+ // We look at the digit just past the end. >+ // There must be 'extra_digits' extra valid digits after end. >+ if (*out->end > '5') return true; >+ if (*out->end < '5') return false; >+ if (has_leftover_value || std::any_of(out->end + 1, out->end + extra_digits, >+ [](char c) { return c != '0'; })) >+ return true; >+ >+ // Ends in ...50*, round to even. >+ return out->last_digit() % 2 == 1; >+ }(); >+ >+ if (needs_to_round_up) { >+ RoundUp<FormatStyle::Precision>(out, exp_out); >+ } >+ return true; >+} >+ >+// Print the value into the buffer. >+// This will not include the exponent, which will be returned in 'exp_out' for >+// Precision mode. >+template <typename Int, typename Float, FormatStyle mode> >+bool FloatToBufferImpl(Int int_mantissa, int exp, int precision, Buffer *out, >+ int *exp_out) { >+ assert((CanFitMantissa<Float, Int>())); >+ >+ const int int_bits = std::numeric_limits<Int>::digits; >+ >+ // In precision mode, we start printing one char to the right because it will >+ // also include the '.' >+ // In fixed mode we put the dot afterwards on the right. >+ out->begin = out->end = >+ out->data + 1 + kMaxFixedPrecision + (mode == FormatStyle::Precision); >+ >+ if (exp >= 0) { >+ if (std::numeric_limits<Float>::digits + exp > int_bits) { >+ // The value will overflow the Int >+ return false; >+ } >+ int digits_printed = PrintIntegralDigits<mode>(int_mantissa << exp, out); >+ int digits_to_zero_pad = precision; >+ if (mode == FormatStyle::Precision) { >+ *exp_out = digits_printed - 1; >+ digits_to_zero_pad -= digits_printed - 1; >+ if (RemoveExtraPrecision(-digits_to_zero_pad, false, out, exp_out)) { >+ return true; >+ } >+ } >+ for (; digits_to_zero_pad-- > 0;) out->push_back('0'); >+ return true; >+ } >+ >+ exp = -exp; >+ // We need at least 4 empty bits for the next decimal digit. >+ // We will multiply by 10. >+ if (exp > int_bits - 4) return false; >+ >+ const Int mask = (Int{1} << exp) - 1; >+ >+ // Print the integral part first. >+ int digits_printed = PrintIntegralDigits<mode>(int_mantissa >> exp, out); >+ int_mantissa &= mask; >+ >+ int fractional_count = precision; >+ if (mode == FormatStyle::Precision) { >+ if (digits_printed == 0) { >+ // Find the first non-zero digit, when in Precision mode. >+ *exp_out = 0; >+ if (int_mantissa) { >+ while (int_mantissa <= mask) { >+ int_mantissa *= 10; >+ --*exp_out; >+ } >+ } >+ out->push_front(static_cast<char>(int_mantissa >> exp) + '0'); >+ out->push_back('.'); >+ int_mantissa &= mask; >+ } else { >+ // We already have a digit, and a '.' >+ *exp_out = digits_printed - 1; >+ fractional_count -= *exp_out; >+ if (RemoveExtraPrecision(-fractional_count, int_mantissa != 0, out, >+ exp_out)) { >+ // If we had enough digits, return right away. >+ // The code below will try to round again otherwise. >+ return true; >+ } >+ } >+ } >+ >+ auto get_next_digit = [&] { >+ int_mantissa *= 10; >+ int digit = static_cast<int>(int_mantissa >> exp); >+ int_mantissa &= mask; >+ return digit; >+ }; >+ >+ // Print fractional_count more digits, if available. >+ for (; fractional_count > 0; --fractional_count) { >+ out->push_back(get_next_digit() + '0'); >+ } >+ >+ int next_digit = get_next_digit(); >+ if (next_digit > 5 || >+ (next_digit == 5 && (int_mantissa || out->last_digit() % 2 == 1))) { >+ RoundUp<mode>(out, exp_out); >+ } >+ >+ return true; >+} >+ >+template <FormatStyle mode, typename Float> >+bool FloatToBuffer(Decomposed<Float> decomposed, int precision, Buffer *out, >+ int *exp) { >+ if (precision > kMaxFixedPrecision) return false; >+ >+ // Try with uint64_t. >+ if (CanFitMantissa<Float, std::uint64_t>() && >+ FloatToBufferImpl<std::uint64_t, Float, mode>( >+ static_cast<std::uint64_t>(decomposed.mantissa), >+ static_cast<std::uint64_t>(decomposed.exponent), precision, out, exp)) >+ return true; >+ >+#if defined(__SIZEOF_INT128__) >+ // If that is not enough, try with __uint128_t. >+ return CanFitMantissa<Float, __uint128_t>() && >+ FloatToBufferImpl<__uint128_t, Float, mode>( >+ static_cast<__uint128_t>(decomposed.mantissa), >+ static_cast<__uint128_t>(decomposed.exponent), precision, out, >+ exp); >+#endif >+ return false; >+} >+ >+void WriteBufferToSink(char sign_char, string_view str, >+ const ConversionSpec &conv, FormatSinkImpl *sink) { >+ int left_spaces = 0, zeros = 0, right_spaces = 0; >+ int missing_chars = >+ conv.width() >= 0 ? std::max(conv.width() - static_cast<int>(str.size()) - >+ static_cast<int>(sign_char != 0), >+ 0) >+ : 0; >+ if (conv.flags().left) { >+ right_spaces = missing_chars; >+ } else if (conv.flags().zero) { >+ zeros = missing_chars; >+ } else { >+ left_spaces = missing_chars; >+ } >+ >+ sink->Append(left_spaces, ' '); >+ if (sign_char) sink->Append(1, sign_char); >+ sink->Append(zeros, '0'); >+ sink->Append(str); >+ sink->Append(right_spaces, ' '); >+} >+ >+template <typename Float> >+bool FloatToSink(const Float v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ // Print the sign or the sign column. >+ Float abs_v = v; >+ char sign_char = 0; >+ if (std::signbit(abs_v)) { >+ sign_char = '-'; >+ abs_v = -abs_v; >+ } else if (conv.flags().show_pos) { >+ sign_char = '+'; >+ } else if (conv.flags().sign_col) { >+ sign_char = ' '; >+ } >+ >+ // Print nan/inf. >+ if (ConvertNonNumericFloats(sign_char, abs_v, conv, sink)) { >+ return true; >+ } >+ >+ int precision = conv.precision() < 0 ? 6 : conv.precision(); >+ >+ int exp = 0; >+ >+ auto decomposed = Decompose(abs_v); >+ >+ Buffer buffer; >+ >+ switch (conv.conv().id()) { >+ case ConversionChar::f: >+ case ConversionChar::F: >+ if (!FloatToBuffer<FormatStyle::Fixed>(decomposed, precision, &buffer, >+ nullptr)) { >+ return FallbackToSnprintf(v, conv, sink); >+ } >+ if (!conv.flags().alt && buffer.back() == '.') buffer.pop_back(); >+ break; >+ >+ case ConversionChar::e: >+ case ConversionChar::E: >+ if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer, >+ &exp)) { >+ return FallbackToSnprintf(v, conv, sink); >+ } >+ if (!conv.flags().alt && buffer.back() == '.') buffer.pop_back(); >+ PrintExponent(exp, conv.conv().upper() ? 'E' : 'e', &buffer); >+ break; >+ >+ case ConversionChar::g: >+ case ConversionChar::G: >+ precision = std::max(0, precision - 1); >+ if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer, >+ &exp)) { >+ return FallbackToSnprintf(v, conv, sink); >+ } >+ if (precision + 1 > exp && exp >= -4) { >+ if (exp < 0) { >+ // Have 1.23456, needs 0.00123456 >+ // Move the first digit >+ buffer.begin[1] = *buffer.begin; >+ // Add some zeros >+ for (; exp < -1; ++exp) *buffer.begin-- = '0'; >+ *buffer.begin-- = '.'; >+ *buffer.begin = '0'; >+ } else if (exp > 0) { >+ // Have 1.23456, needs 1234.56 >+ // Move the '.' exp positions to the right. >+ std::rotate(buffer.begin + 1, buffer.begin + 2, >+ buffer.begin + exp + 2); >+ } >+ exp = 0; >+ } >+ if (!conv.flags().alt) { >+ while (buffer.back() == '0') buffer.pop_back(); >+ if (buffer.back() == '.') buffer.pop_back(); >+ } >+ if (exp) PrintExponent(exp, conv.conv().upper() ? 'E' : 'e', &buffer); >+ break; >+ >+ case ConversionChar::a: >+ case ConversionChar::A: >+ return FallbackToSnprintf(v, conv, sink); >+ >+ default: >+ return false; >+ } >+ >+ WriteBufferToSink(sign_char, >+ string_view(buffer.begin, buffer.end - buffer.begin), conv, >+ sink); >+ >+ return true; >+} >+ >+} // namespace >+ >+bool ConvertFloatImpl(long double v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return FloatToSink(v, conv, sink); >+} >+ >+bool ConvertFloatImpl(float v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return FloatToSink(v, conv, sink); >+} >+ >+bool ConvertFloatImpl(double v, const ConversionSpec &conv, >+ FormatSinkImpl *sink) { >+ return FloatToSink(v, conv, sink); >+} >+ >+} // namespace str_format_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8ba5566d3eefa28e085f53c6ff74c500ababa47d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.h >@@ -0,0 +1,21 @@ >+#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_ >+#define ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_ >+ >+#include "absl/strings/internal/str_format/extension.h" >+ >+namespace absl { >+namespace str_format_internal { >+ >+bool ConvertFloatImpl(float v, const ConversionSpec &conv, >+ FormatSinkImpl *sink); >+ >+bool ConvertFloatImpl(double v, const ConversionSpec &conv, >+ FormatSinkImpl *sink); >+ >+bool ConvertFloatImpl(long double v, const ConversionSpec &conv, >+ FormatSinkImpl *sink); >+ >+} // namespace str_format_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..5c3795b737ca1bccc5de9bba753c34ab6c62073e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc >@@ -0,0 +1,47 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/str_format/output.h" >+ >+#include <errno.h> >+#include <cstring> >+ >+namespace absl { >+namespace str_format_internal { >+ >+void BufferRawSink::Write(string_view v) { >+ size_t to_write = std::min(v.size(), size_); >+ std::memcpy(buffer_, v.data(), to_write); >+ buffer_ += to_write; >+ size_ -= to_write; >+ total_written_ += v.size(); >+} >+ >+void FILERawSink::Write(string_view v) { >+ while (!v.empty() && !error_) { >+ if (size_t result = std::fwrite(v.data(), 1, v.size(), output_)) { >+ // Some progress was made. >+ count_ += result; >+ v.remove_prefix(result); >+ } else { >+ // Some error occurred. >+ if (errno != EINTR) { >+ error_ = errno; >+ } >+ } >+ } >+} >+ >+} // namespace str_format_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/output.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/output.h >new file mode 100644 >index 0000000000000000000000000000000000000000..3b0aa5e7157ecbdaf8f243e44a13a751638b575d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/output.h >@@ -0,0 +1,101 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Output extension hooks for the Format library. >+// `internal::InvokeFlush` calls the appropriate flush function for the >+// specified output argument. >+// `BufferRawSink` is a simple output sink for a char buffer. Used by SnprintF. >+// `FILERawSink` is a std::FILE* based sink. Used by PrintF and FprintF. >+ >+#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_ >+#define ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_ >+ >+#include <cstdio> >+#include <ostream> >+#include <string> >+ >+#include "absl/base/port.h" >+#include "absl/strings/string_view.h" >+ >+class Cord; >+ >+namespace absl { >+namespace str_format_internal { >+ >+// RawSink implementation that writes into a char* buffer. >+// It will not overflow the buffer, but will keep the total count of chars >+// that would have been written. >+class BufferRawSink { >+ public: >+ BufferRawSink(char* buffer, size_t size) : buffer_(buffer), size_(size) {} >+ >+ size_t total_written() const { return total_written_; } >+ void Write(string_view v); >+ >+ private: >+ char* buffer_; >+ size_t size_; >+ size_t total_written_ = 0; >+}; >+ >+// RawSink implementation that writes into a FILE*. >+// It keeps track of the total number of bytes written and any error encountered >+// during the writes. >+class FILERawSink { >+ public: >+ explicit FILERawSink(std::FILE* output) : output_(output) {} >+ >+ void Write(string_view v); >+ >+ size_t count() const { return count_; } >+ int error() const { return error_; } >+ >+ private: >+ std::FILE* output_; >+ int error_ = 0; >+ size_t count_ = 0; >+}; >+ >+// Provide RawSink integration with common types from the STL. >+inline void AbslFormatFlush(std::string* out, string_view s) { >+ out->append(s.begin(), s.size()); >+} >+inline void AbslFormatFlush(std::ostream* out, string_view s) { >+ out->write(s.begin(), s.size()); >+} >+ >+template <class AbslCord, typename = typename std::enable_if< >+ std::is_same<AbslCord, ::Cord>::value>::type> >+inline void AbslFormatFlush(AbslCord* out, string_view s) { >+ out->Append(s); >+} >+ >+inline void AbslFormatFlush(FILERawSink* sink, string_view v) { >+ sink->Write(v); >+} >+ >+inline void AbslFormatFlush(BufferRawSink* sink, string_view v) { >+ sink->Write(v); >+} >+ >+template <typename T> >+auto InvokeFlush(T* out, string_view s) >+ -> decltype(str_format_internal::AbslFormatFlush(out, s)) { >+ str_format_internal::AbslFormatFlush(out, s); >+} >+ >+} // namespace str_format_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/output_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/output_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..cc3c615557fef44bf813911f7bde8e0c8c8061f4 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/output_test.cc >@@ -0,0 +1,78 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/str_format/output.h" >+ >+#include <sstream> >+#include <string> >+ >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+ >+namespace absl { >+namespace { >+ >+TEST(InvokeFlush, String) { >+ std::string str = "ABC"; >+ str_format_internal::InvokeFlush(&str, "DEF"); >+ EXPECT_EQ(str, "ABCDEF"); >+ >+#if UTIL_FORMAT_HAS_GLOBAL_STRING >+ std::string str2 = "ABC"; >+ str_format_internal::InvokeFlush(&str2, "DEF"); >+ EXPECT_EQ(str2, "ABCDEF"); >+#endif // UTIL_FORMAT_HAS_GLOBAL_STRING >+} >+ >+TEST(InvokeFlush, Stream) { >+ std::stringstream str; >+ str << "ABC"; >+ str_format_internal::InvokeFlush(&str, "DEF"); >+ EXPECT_EQ(str.str(), "ABCDEF"); >+} >+ >+TEST(BufferRawSink, Limits) { >+ char buf[16]; >+ { >+ std::fill(std::begin(buf), std::end(buf), 'x'); >+ str_format_internal::BufferRawSink bufsink(buf, sizeof(buf) - 1); >+ str_format_internal::InvokeFlush(&bufsink, "Hello World237"); >+ EXPECT_EQ(std::string(buf, sizeof(buf)), "Hello World237xx"); >+ } >+ { >+ std::fill(std::begin(buf), std::end(buf), 'x'); >+ str_format_internal::BufferRawSink bufsink(buf, sizeof(buf) - 1); >+ str_format_internal::InvokeFlush(&bufsink, "Hello World237237"); >+ EXPECT_EQ(std::string(buf, sizeof(buf)), "Hello World2372x"); >+ } >+ { >+ std::fill(std::begin(buf), std::end(buf), 'x'); >+ str_format_internal::BufferRawSink bufsink(buf, sizeof(buf) - 1); >+ str_format_internal::InvokeFlush(&bufsink, "Hello World"); >+ str_format_internal::InvokeFlush(&bufsink, "237"); >+ EXPECT_EQ(std::string(buf, sizeof(buf)), "Hello World237xx"); >+ } >+ { >+ std::fill(std::begin(buf), std::end(buf), 'x'); >+ str_format_internal::BufferRawSink bufsink(buf, sizeof(buf) - 1); >+ str_format_internal::InvokeFlush(&bufsink, "Hello World"); >+ str_format_internal::InvokeFlush(&bufsink, "237237"); >+ EXPECT_EQ(std::string(buf, sizeof(buf)), "Hello World2372x"); >+ } >+} >+ >+} // namespace >+} // namespace absl >+ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..10114f489c0189f0586149685378e13a8df94684 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc >@@ -0,0 +1,294 @@ >+#include "absl/strings/internal/str_format/parser.h" >+ >+#include <assert.h> >+#include <string.h> >+#include <wchar.h> >+#include <cctype> >+#include <cstdint> >+ >+#include <algorithm> >+#include <initializer_list> >+#include <limits> >+#include <ostream> >+#include <string> >+#include <unordered_set> >+ >+namespace absl { >+namespace str_format_internal { >+namespace { >+ >+bool CheckFastPathSetting(const UnboundConversion& conv) { >+ bool should_be_basic = !conv.flags.left && // >+ !conv.flags.show_pos && // >+ !conv.flags.sign_col && // >+ !conv.flags.alt && // >+ !conv.flags.zero && // >+ (conv.width.value() == -1) && >+ (conv.precision.value() == -1); >+ if (should_be_basic != conv.flags.basic) { >+ fprintf(stderr, >+ "basic=%d left=%d show_pos=%d sign_col=%d alt=%d zero=%d " >+ "width=%d precision=%d\n", >+ conv.flags.basic, conv.flags.left, conv.flags.show_pos, >+ conv.flags.sign_col, conv.flags.alt, conv.flags.zero, >+ conv.width.value(), conv.precision.value()); >+ } >+ return should_be_basic == conv.flags.basic; >+} >+ >+// Keep a single table for all the conversion chars and length modifiers. >+// We invert the length modifiers to make them negative so that we can easily >+// test for them. >+// Everything else is `none`, which is a negative constant. >+using CC = ConversionChar::Id; >+using LM = LengthMod::Id; >+static constexpr std::int8_t none = -128; >+static constexpr std::int8_t kIds[] = { >+ none, none, none, none, none, none, none, none, // 00-07 >+ none, none, none, none, none, none, none, none, // 08-0f >+ none, none, none, none, none, none, none, none, // 10-17 >+ none, none, none, none, none, none, none, none, // 18-1f >+ none, none, none, none, none, none, none, none, // 20-27 >+ none, none, none, none, none, none, none, none, // 28-2f >+ none, none, none, none, none, none, none, none, // 30-37 >+ none, none, none, none, none, none, none, none, // 38-3f >+ none, CC::A, none, CC::C, none, CC::E, CC::F, CC::G, // @ABCDEFG >+ none, none, none, none, ~LM::L, none, none, none, // HIJKLMNO >+ none, none, none, CC::S, none, none, none, none, // PQRSTUVW >+ CC::X, none, none, none, none, none, none, none, // XYZ[\]^_ >+ none, CC::a, none, CC::c, CC::d, CC::e, CC::f, CC::g, // `abcdefg >+ ~LM::h, CC::i, ~LM::j, none, ~LM::l, none, CC::n, CC::o, // hijklmno >+ CC::p, ~LM::q, none, CC::s, ~LM::t, CC::u, none, none, // pqrstuvw >+ CC::x, none, ~LM::z, none, none, none, none, none, // xyz{|}~! >+ none, none, none, none, none, none, none, none, // 80-87 >+ none, none, none, none, none, none, none, none, // 88-8f >+ none, none, none, none, none, none, none, none, // 90-97 >+ none, none, none, none, none, none, none, none, // 98-9f >+ none, none, none, none, none, none, none, none, // a0-a7 >+ none, none, none, none, none, none, none, none, // a8-af >+ none, none, none, none, none, none, none, none, // b0-b7 >+ none, none, none, none, none, none, none, none, // b8-bf >+ none, none, none, none, none, none, none, none, // c0-c7 >+ none, none, none, none, none, none, none, none, // c8-cf >+ none, none, none, none, none, none, none, none, // d0-d7 >+ none, none, none, none, none, none, none, none, // d8-df >+ none, none, none, none, none, none, none, none, // e0-e7 >+ none, none, none, none, none, none, none, none, // e8-ef >+ none, none, none, none, none, none, none, none, // f0-f7 >+ none, none, none, none, none, none, none, none, // f8-ff >+}; >+ >+template <bool is_positional> >+bool ConsumeConversion(string_view *src, UnboundConversion *conv, >+ int *next_arg) { >+ const char *pos = src->begin(); >+ const char *const end = src->end(); >+ char c; >+ // Read the next char into `c` and update `pos`. Reads '\0' if at end. >+ const auto get_char = [&] { c = pos == end ? '\0' : *pos++; }; >+ >+ const auto parse_digits = [&] { >+ int digits = c - '0'; >+ // We do not want to overflow `digits` so we consume at most digits10-1 >+ // digits. If there are more digits the parsing will fail later on when the >+ // digit doesn't match the expected characters. >+ int num_digits = std::numeric_limits<int>::digits10 - 2; >+ for (get_char(); num_digits && std::isdigit(c); get_char()) { >+ --num_digits; >+ digits = 10 * digits + c - '0'; >+ } >+ return digits; >+ }; >+ >+ if (is_positional) { >+ get_char(); >+ if (c < '1' || c > '9') return false; >+ conv->arg_position = parse_digits(); >+ assert(conv->arg_position > 0); >+ if (c != '$') return false; >+ } >+ >+ get_char(); >+ >+ // We should start with the basic flag on. >+ assert(conv->flags.basic); >+ >+ // Any non alpha character makes this conversion not basic. >+ // This includes flags (-+ #0), width (1-9, *) or precision (.). >+ // All conversion characters and length modifiers are alpha characters. >+ if (c < 'A') { >+ conv->flags.basic = false; >+ >+ for (; c <= '0'; get_char()) { >+ switch (c) { >+ case '-': >+ conv->flags.left = true; >+ continue; >+ case '+': >+ conv->flags.show_pos = true; >+ continue; >+ case ' ': >+ conv->flags.sign_col = true; >+ continue; >+ case '#': >+ conv->flags.alt = true; >+ continue; >+ case '0': >+ conv->flags.zero = true; >+ continue; >+ } >+ break; >+ } >+ >+ if (c <= '9') { >+ if (c >= '0') { >+ int maybe_width = parse_digits(); >+ if (!is_positional && c == '$') { >+ if (*next_arg != 0) return false; >+ // Positional conversion. >+ *next_arg = -1; >+ conv->flags = Flags(); >+ conv->flags.basic = true; >+ return ConsumeConversion<true>(src, conv, next_arg); >+ } >+ conv->width.set_value(maybe_width); >+ } else if (c == '*') { >+ get_char(); >+ if (is_positional) { >+ if (c < '1' || c > '9') return false; >+ conv->width.set_from_arg(parse_digits()); >+ if (c != '$') return false; >+ get_char(); >+ } else { >+ conv->width.set_from_arg(++*next_arg); >+ } >+ } >+ } >+ >+ if (c == '.') { >+ get_char(); >+ if (std::isdigit(c)) { >+ conv->precision.set_value(parse_digits()); >+ } else if (c == '*') { >+ get_char(); >+ if (is_positional) { >+ if (c < '1' || c > '9') return false; >+ conv->precision.set_from_arg(parse_digits()); >+ if (c != '$') return false; >+ get_char(); >+ } else { >+ conv->precision.set_from_arg(++*next_arg); >+ } >+ } else { >+ conv->precision.set_value(0); >+ } >+ } >+ } >+ >+ std::int8_t id = kIds[static_cast<unsigned char>(c)]; >+ >+ if (id < 0) { >+ if (id == none) return false; >+ >+ // It is a length modifier. >+ using str_format_internal::LengthMod; >+ LengthMod length_mod = LengthMod::FromId(static_cast<LM>(~id)); >+ get_char(); >+ if (c == 'h' && length_mod.id() == LengthMod::h) { >+ conv->length_mod = LengthMod::FromId(LengthMod::hh); >+ get_char(); >+ } else if (c == 'l' && length_mod.id() == LengthMod::l) { >+ conv->length_mod = LengthMod::FromId(LengthMod::ll); >+ get_char(); >+ } else { >+ conv->length_mod = length_mod; >+ } >+ id = kIds[static_cast<unsigned char>(c)]; >+ if (id < 0) return false; >+ } >+ >+ assert(CheckFastPathSetting(*conv)); >+ (void)(&CheckFastPathSetting); >+ >+ conv->conv = ConversionChar::FromId(static_cast<CC>(id)); >+ if (!is_positional) conv->arg_position = ++*next_arg; >+ *src = string_view(pos, end - pos); >+ return true; >+} >+ >+} // namespace >+ >+bool ConsumeUnboundConversion(string_view *src, UnboundConversion *conv, >+ int *next_arg) { >+ if (*next_arg < 0) return ConsumeConversion<true>(src, conv, next_arg); >+ return ConsumeConversion<false>(src, conv, next_arg); >+} >+ >+struct ParsedFormatBase::ParsedFormatConsumer { >+ explicit ParsedFormatConsumer(ParsedFormatBase *parsedformat) >+ : parsed(parsedformat), data_pos(parsedformat->data_.get()) {} >+ >+ bool Append(string_view s) { >+ if (s.empty()) return true; >+ >+ size_t text_end = AppendText(s); >+ >+ if (!parsed->items_.empty() && !parsed->items_.back().is_conversion) { >+ // Let's extend the existing text run. >+ parsed->items_.back().text_end = text_end; >+ } else { >+ // Let's make a new text run. >+ parsed->items_.push_back({false, text_end, {}}); >+ } >+ return true; >+ } >+ >+ bool ConvertOne(const UnboundConversion &conv, string_view s) { >+ size_t text_end = AppendText(s); >+ parsed->items_.push_back({true, text_end, conv}); >+ return true; >+ } >+ >+ size_t AppendText(string_view s) { >+ memcpy(data_pos, s.data(), s.size()); >+ data_pos += s.size(); >+ return static_cast<size_t>(data_pos - parsed->data_.get()); >+ } >+ >+ ParsedFormatBase *parsed; >+ char* data_pos; >+}; >+ >+ParsedFormatBase::ParsedFormatBase(string_view format, bool allow_ignored, >+ std::initializer_list<Conv> convs) >+ : data_(format.empty() ? nullptr : new char[format.size()]) { >+ has_error_ = !ParseFormatString(format, ParsedFormatConsumer(this)) || >+ !MatchesConversions(allow_ignored, convs); >+} >+ >+bool ParsedFormatBase::MatchesConversions( >+ bool allow_ignored, std::initializer_list<Conv> convs) const { >+ std::unordered_set<int> used; >+ auto add_if_valid_conv = [&](int pos, char c) { >+ if (static_cast<size_t>(pos) > convs.size() || >+ !Contains(convs.begin()[pos - 1], c)) >+ return false; >+ used.insert(pos); >+ return true; >+ }; >+ for (const ConversionItem &item : items_) { >+ if (!item.is_conversion) continue; >+ auto &conv = item.conv; >+ if (conv.precision.is_from_arg() && >+ !add_if_valid_conv(conv.precision.get_from_arg(), '*')) >+ return false; >+ if (conv.width.is_from_arg() && >+ !add_if_valid_conv(conv.width.get_from_arg(), '*')) >+ return false; >+ if (!add_if_valid_conv(conv.arg_position, conv.conv.Char())) return false; >+ } >+ return used.size() == convs.size() || allow_ignored; >+} >+ >+} // namespace str_format_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h >new file mode 100644 >index 0000000000000000000000000000000000000000..5bebc95540e6c28d39d0847305366742ced9edfa >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h >@@ -0,0 +1,291 @@ >+#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_ >+#define ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_ >+ >+#include <limits.h> >+#include <stddef.h> >+#include <stdlib.h> >+ >+#include <cassert> >+#include <initializer_list> >+#include <iosfwd> >+#include <iterator> >+#include <memory> >+#include <vector> >+ >+#include "absl/strings/internal/str_format/checker.h" >+#include "absl/strings/internal/str_format/extension.h" >+ >+namespace absl { >+namespace str_format_internal { >+ >+// The analyzed properties of a single specified conversion. >+struct UnboundConversion { >+ UnboundConversion() >+ : flags() /* This is required to zero all the fields of flags. */ { >+ flags.basic = true; >+ } >+ >+ class InputValue { >+ public: >+ void set_value(int value) { >+ assert(value >= 0); >+ value_ = value; >+ } >+ int value() const { return value_; } >+ >+ // Marks the value as "from arg". aka the '*' format. >+ // Requires `value >= 1`. >+ // When set, is_from_arg() return true and get_from_arg() returns the >+ // original value. >+ // `value()`'s return value is unspecfied in this state. >+ void set_from_arg(int value) { >+ assert(value > 0); >+ value_ = -value - 1; >+ } >+ bool is_from_arg() const { return value_ < -1; } >+ int get_from_arg() const { >+ assert(is_from_arg()); >+ return -value_ - 1; >+ } >+ >+ private: >+ int value_ = -1; >+ }; >+ >+ // No need to initialize. It will always be set in the parser. >+ int arg_position; >+ >+ InputValue width; >+ InputValue precision; >+ >+ Flags flags; >+ LengthMod length_mod; >+ ConversionChar conv; >+}; >+ >+// Consume conversion spec prefix (not including '%') of '*src' if valid. >+// Examples of valid specs would be e.g.: "s", "d", "-12.6f". >+// If valid, the front of src is advanced such that src becomes the >+// part following the conversion spec, and the spec part is broken down and >+// returned in 'conv'. >+// If invalid, returns false and leaves 'src' unmodified. >+// For example: >+// Given "d9", returns "d", and leaves src="9", >+// Given "!", returns "" and leaves src="!". >+bool ConsumeUnboundConversion(string_view* src, UnboundConversion* conv, >+ int* next_arg); >+ >+// Parse the format std::string provided in 'src' and pass the identified items into >+// 'consumer'. >+// Text runs will be passed by calling >+// Consumer::Append(string_view); >+// ConversionItems will be passed by calling >+// Consumer::ConvertOne(UnboundConversion, string_view); >+// In the case of ConvertOne, the string_view that is passed is the >+// portion of the format std::string corresponding to the conversion, not including >+// the leading %. On success, it returns true. On failure, it stops and returns >+// false. >+template <typename Consumer> >+bool ParseFormatString(string_view src, Consumer consumer) { >+ int next_arg = 0; >+ while (!src.empty()) { >+ const char* percent = >+ static_cast<const char*>(memchr(src.begin(), '%', src.size())); >+ if (!percent) { >+ // We found the last substring. >+ return consumer.Append(src); >+ } >+ // We found a percent, so push the text run then process the percent. >+ size_t percent_loc = percent - src.data(); >+ if (!consumer.Append(string_view(src.data(), percent_loc))) return false; >+ if (percent + 1 >= src.end()) return false; >+ >+ UnboundConversion conv; >+ >+ switch (percent[1]) { >+ case '%': >+ if (!consumer.Append("%")) return false; >+ src.remove_prefix(percent_loc + 2); >+ continue; >+ >+#define PARSER_CASE(ch) \ >+ case #ch[0]: \ >+ src.remove_prefix(percent_loc + 2); \ >+ conv.conv = ConversionChar::FromId(ConversionChar::ch); \ >+ conv.arg_position = ++next_arg; \ >+ break; >+ ABSL_CONVERSION_CHARS_EXPAND_(PARSER_CASE, ); >+#undef PARSER_CASE >+ >+ default: >+ src.remove_prefix(percent_loc + 1); >+ if (!ConsumeUnboundConversion(&src, &conv, &next_arg)) return false; >+ break; >+ } >+ if (next_arg == 0) { >+ // This indicates an error in the format std::string. >+ // The only way to get next_arg == 0 is to have a positional argument >+ // first which sets next_arg to -1 and then a non-positional argument >+ // which does ++next_arg. >+ // Checking here seems to be the cheapeast place to do it. >+ return false; >+ } >+ if (!consumer.ConvertOne( >+ conv, string_view(percent + 1, src.data() - (percent + 1)))) { >+ return false; >+ } >+ } >+ return true; >+} >+ >+// Always returns true, or fails to compile in a constexpr context if s does not >+// point to a constexpr char array. >+constexpr bool EnsureConstexpr(string_view s) { >+ return s.empty() || s[0] == s[0]; >+} >+ >+class ParsedFormatBase { >+ public: >+ explicit ParsedFormatBase(string_view format, bool allow_ignored, >+ std::initializer_list<Conv> convs); >+ >+ ParsedFormatBase(const ParsedFormatBase& other) { *this = other; } >+ >+ ParsedFormatBase(ParsedFormatBase&& other) { *this = std::move(other); } >+ >+ ParsedFormatBase& operator=(const ParsedFormatBase& other) { >+ if (this == &other) return *this; >+ has_error_ = other.has_error_; >+ items_ = other.items_; >+ size_t text_size = items_.empty() ? 0 : items_.back().text_end; >+ data_.reset(new char[text_size]); >+ memcpy(data_.get(), other.data_.get(), text_size); >+ return *this; >+ } >+ >+ ParsedFormatBase& operator=(ParsedFormatBase&& other) { >+ if (this == &other) return *this; >+ has_error_ = other.has_error_; >+ data_ = std::move(other.data_); >+ items_ = std::move(other.items_); >+ // Reset the vector to make sure the invariants hold. >+ other.items_.clear(); >+ return *this; >+ } >+ >+ template <typename Consumer> >+ bool ProcessFormat(Consumer consumer) const { >+ const char* const base = data_.get(); >+ string_view text(base, 0); >+ for (const auto& item : items_) { >+ text = string_view(text.end(), (base + item.text_end) - text.end()); >+ if (item.is_conversion) { >+ if (!consumer.ConvertOne(item.conv, text)) return false; >+ } else { >+ if (!consumer.Append(text)) return false; >+ } >+ } >+ return !has_error_; >+ } >+ >+ bool has_error() const { return has_error_; } >+ >+ private: >+ // Returns whether the conversions match and if !allow_ignored it verifies >+ // that all conversions are used by the format. >+ bool MatchesConversions(bool allow_ignored, >+ std::initializer_list<Conv> convs) const; >+ >+ struct ParsedFormatConsumer; >+ >+ struct ConversionItem { >+ bool is_conversion; >+ // Points to the past-the-end location of this element in the data_ array. >+ size_t text_end; >+ UnboundConversion conv; >+ }; >+ >+ bool has_error_; >+ std::unique_ptr<char[]> data_; >+ std::vector<ConversionItem> items_; >+}; >+ >+ >+// A value type representing a preparsed format. These can be created, copied >+// around, and reused to speed up formatting loops. >+// The user must specify through the template arguments the conversion >+// characters used in the format. This will be checked at compile time. >+// >+// This class uses Conv enum values to specify each argument. >+// This allows for more flexibility as you can specify multiple possible >+// conversion characters for each argument. >+// ParsedFormat<char...> is a simplified alias for when the user only >+// needs to specify a single conversion character for each argument. >+// >+// Example: >+// // Extended format supports multiple characters per argument: >+// using MyFormat = ExtendedParsedFormat<Conv::d | Conv::x>; >+// MyFormat GetFormat(bool use_hex) { >+// if (use_hex) return MyFormat("foo %x bar"); >+// return MyFormat("foo %d bar"); >+// } >+// // 'format' can be used with any value that supports 'd' and 'x', >+// // like `int`. >+// auto format = GetFormat(use_hex); >+// value = StringF(format, i); >+// >+// This class also supports runtime format checking with the ::New() and >+// ::NewAllowIgnored() factory functions. >+// This is the only API that allows the user to pass a runtime specified format >+// std::string. These factory functions will return NULL if the format does not match >+// the conversions requested by the user. >+template <str_format_internal::Conv... C> >+class ExtendedParsedFormat : public str_format_internal::ParsedFormatBase { >+ public: >+ explicit ExtendedParsedFormat(string_view format) >+#if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+ __attribute__(( >+ enable_if(str_format_internal::EnsureConstexpr(format), >+ "Format std::string is not constexpr."), >+ enable_if(str_format_internal::ValidFormatImpl<C...>(format), >+ "Format specified does not match the template arguments."))) >+#endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER >+ : ExtendedParsedFormat(format, false) { >+ } >+ >+ // ExtendedParsedFormat factory function. >+ // The user still has to specify the conversion characters, but they will not >+ // be checked at compile time. Instead, it will be checked at runtime. >+ // This delays the checking to runtime, but allows the user to pass >+ // dynamically sourced formats. >+ // It returns NULL if the format does not match the conversion characters. >+ // The user is responsible for checking the return value before using it. >+ // >+ // The 'New' variant will check that all the specified arguments are being >+ // consumed by the format and return NULL if any argument is being ignored. >+ // The 'NewAllowIgnored' variant will not verify this and will allow formats >+ // that ignore arguments. >+ static std::unique_ptr<ExtendedParsedFormat> New(string_view format) { >+ return New(format, false); >+ } >+ static std::unique_ptr<ExtendedParsedFormat> NewAllowIgnored( >+ string_view format) { >+ return New(format, true); >+ } >+ >+ private: >+ static std::unique_ptr<ExtendedParsedFormat> New(string_view format, >+ bool allow_ignored) { >+ std::unique_ptr<ExtendedParsedFormat> conv( >+ new ExtendedParsedFormat(format, allow_ignored)); >+ if (conv->has_error()) return nullptr; >+ return conv; >+ } >+ >+ ExtendedParsedFormat(string_view s, bool allow_ignored) >+ : ParsedFormatBase(s, allow_ignored, {C...}) {} >+}; >+} // namespace str_format_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e698020b1aba38452c7b8899fd3ed2769b0c3e51 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc >@@ -0,0 +1,379 @@ >+#include "absl/strings/internal/str_format/parser.h" >+ >+#include <string.h> >+#include "gtest/gtest.h" >+#include "absl/base/macros.h" >+ >+namespace absl { >+namespace str_format_internal { >+ >+namespace { >+ >+TEST(LengthModTest, Names) { >+ struct Expectation { >+ int line; >+ LengthMod::Id id; >+ const char *name; >+ }; >+ const Expectation kExpect[] = { >+ {__LINE__, LengthMod::none, "" }, >+ {__LINE__, LengthMod::h, "h" }, >+ {__LINE__, LengthMod::hh, "hh"}, >+ {__LINE__, LengthMod::l, "l" }, >+ {__LINE__, LengthMod::ll, "ll"}, >+ {__LINE__, LengthMod::L, "L" }, >+ {__LINE__, LengthMod::j, "j" }, >+ {__LINE__, LengthMod::z, "z" }, >+ {__LINE__, LengthMod::t, "t" }, >+ {__LINE__, LengthMod::q, "q" }, >+ }; >+ EXPECT_EQ(ABSL_ARRAYSIZE(kExpect), LengthMod::kNumValues); >+ for (auto e : kExpect) { >+ SCOPED_TRACE(e.line); >+ LengthMod mod = LengthMod::FromId(e.id); >+ EXPECT_EQ(e.id, mod.id()); >+ EXPECT_EQ(e.name, mod.name()); >+ } >+} >+ >+TEST(ConversionCharTest, Names) { >+ struct Expectation { >+ ConversionChar::Id id; >+ char name; >+ }; >+ // clang-format off >+ const Expectation kExpect[] = { >+#define X(c) {ConversionChar::c, #c[0]} >+ X(c), X(C), X(s), X(S), // text >+ X(d), X(i), X(o), X(u), X(x), X(X), // int >+ X(f), X(F), X(e), X(E), X(g), X(G), X(a), X(A), // float >+ X(n), X(p), // misc >+#undef X >+ {ConversionChar::none, '\0'}, >+ }; >+ // clang-format on >+ EXPECT_EQ(ABSL_ARRAYSIZE(kExpect), ConversionChar::kNumValues); >+ for (auto e : kExpect) { >+ SCOPED_TRACE(e.name); >+ ConversionChar v = ConversionChar::FromId(e.id); >+ EXPECT_EQ(e.id, v.id()); >+ EXPECT_EQ(e.name, v.Char()); >+ } >+} >+ >+class ConsumeUnboundConversionTest : public ::testing::Test { >+ public: >+ typedef UnboundConversion Props; >+ string_view Consume(string_view* src) { >+ int next = 0; >+ const char* prev_begin = src->begin(); >+ o = UnboundConversion(); // refresh >+ ConsumeUnboundConversion(src, &o, &next); >+ return {prev_begin, static_cast<size_t>(src->begin() - prev_begin)}; >+ } >+ >+ bool Run(const char *fmt, bool force_positional = false) { >+ string_view src = fmt; >+ int next = force_positional ? -1 : 0; >+ o = UnboundConversion(); // refresh >+ return ConsumeUnboundConversion(&src, &o, &next) && src.empty(); >+ } >+ UnboundConversion o; >+}; >+ >+TEST_F(ConsumeUnboundConversionTest, ConsumeSpecification) { >+ struct Expectation { >+ int line; >+ const char *src; >+ const char *out; >+ const char *src_post; >+ }; >+ const Expectation kExpect[] = { >+ {__LINE__, "", "", "" }, >+ {__LINE__, "b", "", "b" }, // 'b' is invalid >+ {__LINE__, "ba", "", "ba"}, // 'b' is invalid >+ {__LINE__, "l", "", "l" }, // just length mod isn't okay >+ {__LINE__, "d", "d", "" }, // basic >+ {__LINE__, "d ", "d", " " }, // leave suffix >+ {__LINE__, "dd", "d", "d" }, // don't be greedy >+ {__LINE__, "d9", "d", "9" }, // leave non-space suffix >+ {__LINE__, "dzz", "d", "zz"}, // length mod as suffix >+ {__LINE__, "1$*2$d", "1$*2$d", "" }, // arg indexing and * allowed. >+ {__LINE__, "0-14.3hhd", "0-14.3hhd", ""}, // precision, width >+ {__LINE__, " 0-+#14.3hhd", " 0-+#14.3hhd", ""}, // flags >+ }; >+ for (const auto& e : kExpect) { >+ SCOPED_TRACE(e.line); >+ string_view src = e.src; >+ EXPECT_EQ(e.src, src); >+ string_view out = Consume(&src); >+ EXPECT_EQ(e.out, out); >+ EXPECT_EQ(e.src_post, src); >+ } >+} >+ >+TEST_F(ConsumeUnboundConversionTest, BasicConversion) { >+ EXPECT_FALSE(Run("")); >+ EXPECT_FALSE(Run("z")); >+ >+ EXPECT_FALSE(Run("dd")); // no excess allowed >+ >+ EXPECT_TRUE(Run("d")); >+ EXPECT_EQ('d', o.conv.Char()); >+ EXPECT_FALSE(o.width.is_from_arg()); >+ EXPECT_LT(o.width.value(), 0); >+ EXPECT_FALSE(o.precision.is_from_arg()); >+ EXPECT_LT(o.precision.value(), 0); >+ EXPECT_EQ(1, o.arg_position); >+ EXPECT_EQ(LengthMod::none, o.length_mod.id()); >+} >+ >+TEST_F(ConsumeUnboundConversionTest, ArgPosition) { >+ EXPECT_TRUE(Run("d")); >+ EXPECT_EQ(1, o.arg_position); >+ EXPECT_TRUE(Run("3$d")); >+ EXPECT_EQ(3, o.arg_position); >+ EXPECT_TRUE(Run("1$d")); >+ EXPECT_EQ(1, o.arg_position); >+ EXPECT_TRUE(Run("1$d", true)); >+ EXPECT_EQ(1, o.arg_position); >+ EXPECT_TRUE(Run("123$d")); >+ EXPECT_EQ(123, o.arg_position); >+ EXPECT_TRUE(Run("123$d", true)); >+ EXPECT_EQ(123, o.arg_position); >+ EXPECT_TRUE(Run("10$d")); >+ EXPECT_EQ(10, o.arg_position); >+ EXPECT_TRUE(Run("10$d", true)); >+ EXPECT_EQ(10, o.arg_position); >+ >+ // Position can't be zero. >+ EXPECT_FALSE(Run("0$d")); >+ EXPECT_FALSE(Run("0$d", true)); >+ EXPECT_FALSE(Run("1$*0$d")); >+ EXPECT_FALSE(Run("1$.*0$d")); >+ >+ // Position can't start with a zero digit at all. That is not a 'decimal'. >+ EXPECT_FALSE(Run("01$p")); >+ EXPECT_FALSE(Run("01$p", true)); >+ EXPECT_FALSE(Run("1$*01$p")); >+ EXPECT_FALSE(Run("1$.*01$p")); >+} >+ >+TEST_F(ConsumeUnboundConversionTest, WidthAndPrecision) { >+ EXPECT_TRUE(Run("14d")); >+ EXPECT_EQ('d', o.conv.Char()); >+ EXPECT_FALSE(o.width.is_from_arg()); >+ EXPECT_EQ(14, o.width.value()); >+ EXPECT_FALSE(o.precision.is_from_arg()); >+ EXPECT_LT(o.precision.value(), 0); >+ >+ EXPECT_TRUE(Run("14.d")); >+ EXPECT_FALSE(o.width.is_from_arg()); >+ EXPECT_FALSE(o.precision.is_from_arg()); >+ EXPECT_EQ(14, o.width.value()); >+ EXPECT_EQ(0, o.precision.value()); >+ >+ EXPECT_TRUE(Run(".d")); >+ EXPECT_FALSE(o.width.is_from_arg()); >+ EXPECT_LT(o.width.value(), 0); >+ EXPECT_FALSE(o.precision.is_from_arg()); >+ EXPECT_EQ(0, o.precision.value()); >+ >+ EXPECT_TRUE(Run(".5d")); >+ EXPECT_FALSE(o.width.is_from_arg()); >+ EXPECT_LT(o.width.value(), 0); >+ EXPECT_FALSE(o.precision.is_from_arg()); >+ EXPECT_EQ(5, o.precision.value()); >+ >+ EXPECT_TRUE(Run(".0d")); >+ EXPECT_FALSE(o.width.is_from_arg()); >+ EXPECT_LT(o.width.value(), 0); >+ EXPECT_FALSE(o.precision.is_from_arg()); >+ EXPECT_EQ(0, o.precision.value()); >+ >+ EXPECT_TRUE(Run("14.5d")); >+ EXPECT_FALSE(o.width.is_from_arg()); >+ EXPECT_FALSE(o.precision.is_from_arg()); >+ EXPECT_EQ(14, o.width.value()); >+ EXPECT_EQ(5, o.precision.value()); >+ >+ EXPECT_TRUE(Run("*.*d")); >+ EXPECT_TRUE(o.width.is_from_arg()); >+ EXPECT_EQ(1, o.width.get_from_arg()); >+ EXPECT_TRUE(o.precision.is_from_arg()); >+ EXPECT_EQ(2, o.precision.get_from_arg()); >+ EXPECT_EQ(3, o.arg_position); >+ >+ EXPECT_TRUE(Run("*d")); >+ EXPECT_TRUE(o.width.is_from_arg()); >+ EXPECT_EQ(1, o.width.get_from_arg()); >+ EXPECT_FALSE(o.precision.is_from_arg()); >+ EXPECT_LT(o.precision.value(), 0); >+ EXPECT_EQ(2, o.arg_position); >+ >+ EXPECT_TRUE(Run(".*d")); >+ EXPECT_FALSE(o.width.is_from_arg()); >+ EXPECT_LT(o.width.value(), 0); >+ EXPECT_TRUE(o.precision.is_from_arg()); >+ EXPECT_EQ(1, o.precision.get_from_arg()); >+ EXPECT_EQ(2, o.arg_position); >+ >+ // mixed implicit and explicit: didn't specify arg position. >+ EXPECT_FALSE(Run("*23$.*34$d")); >+ >+ EXPECT_TRUE(Run("12$*23$.*34$d")); >+ EXPECT_EQ(12, o.arg_position); >+ EXPECT_TRUE(o.width.is_from_arg()); >+ EXPECT_EQ(23, o.width.get_from_arg()); >+ EXPECT_TRUE(o.precision.is_from_arg()); >+ EXPECT_EQ(34, o.precision.get_from_arg()); >+ >+ EXPECT_TRUE(Run("2$*5$.*9$d")); >+ EXPECT_EQ(2, o.arg_position); >+ EXPECT_TRUE(o.width.is_from_arg()); >+ EXPECT_EQ(5, o.width.get_from_arg()); >+ EXPECT_TRUE(o.precision.is_from_arg()); >+ EXPECT_EQ(9, o.precision.get_from_arg()); >+ >+ EXPECT_FALSE(Run(".*0$d")) << "no arg 0"; >+} >+ >+TEST_F(ConsumeUnboundConversionTest, Flags) { >+ static const char kAllFlags[] = "-+ #0"; >+ static const int kNumFlags = ABSL_ARRAYSIZE(kAllFlags) - 1; >+ for (int rev = 0; rev < 2; ++rev) { >+ for (int i = 0; i < 1 << kNumFlags; ++i) { >+ std::string fmt; >+ for (int k = 0; k < kNumFlags; ++k) >+ if ((i >> k) & 1) fmt += kAllFlags[k]; >+ // flag order shouldn't matter >+ if (rev == 1) { std::reverse(fmt.begin(), fmt.end()); } >+ fmt += 'd'; >+ SCOPED_TRACE(fmt); >+ EXPECT_TRUE(Run(fmt.c_str())); >+ EXPECT_EQ(fmt.find('-') == std::string::npos, !o.flags.left); >+ EXPECT_EQ(fmt.find('+') == std::string::npos, !o.flags.show_pos); >+ EXPECT_EQ(fmt.find(' ') == std::string::npos, !o.flags.sign_col); >+ EXPECT_EQ(fmt.find('#') == std::string::npos, !o.flags.alt); >+ EXPECT_EQ(fmt.find('0') == std::string::npos, !o.flags.zero); >+ } >+ } >+} >+ >+TEST_F(ConsumeUnboundConversionTest, BasicFlag) { >+ // Flag is on >+ for (const char* fmt : {"d", "llx", "G", "1$X"}) { >+ SCOPED_TRACE(fmt); >+ EXPECT_TRUE(Run(fmt)); >+ EXPECT_TRUE(o.flags.basic); >+ } >+ >+ // Flag is off >+ for (const char* fmt : {"3d", ".llx", "-G", "1$#X"}) { >+ SCOPED_TRACE(fmt); >+ EXPECT_TRUE(Run(fmt)); >+ EXPECT_FALSE(o.flags.basic); >+ } >+} >+ >+struct SummarizeConsumer { >+ std::string* out; >+ explicit SummarizeConsumer(std::string* out) : out(out) {} >+ >+ bool Append(string_view s) { >+ *out += "[" + std::string(s) + "]"; >+ return true; >+ } >+ >+ bool ConvertOne(const UnboundConversion& conv, string_view s) { >+ *out += "{"; >+ *out += std::string(s); >+ *out += ":"; >+ *out += std::to_string(conv.arg_position) + "$"; >+ if (conv.width.is_from_arg()) { >+ *out += std::to_string(conv.width.get_from_arg()) + "$*"; >+ } >+ if (conv.precision.is_from_arg()) { >+ *out += "." + std::to_string(conv.precision.get_from_arg()) + "$*"; >+ } >+ *out += conv.conv.Char(); >+ *out += "}"; >+ return true; >+ } >+}; >+ >+std::string SummarizeParsedFormat(const ParsedFormatBase& pc) { >+ std::string out; >+ if (!pc.ProcessFormat(SummarizeConsumer(&out))) out += "!"; >+ return out; >+} >+ >+class ParsedFormatTest : public testing::Test {}; >+ >+TEST_F(ParsedFormatTest, ValueSemantics) { >+ ParsedFormatBase p1({}, true, {}); // empty format >+ EXPECT_EQ("", SummarizeParsedFormat(p1)); >+ >+ ParsedFormatBase p2 = p1; // copy construct (empty) >+ EXPECT_EQ(SummarizeParsedFormat(p1), SummarizeParsedFormat(p2)); >+ >+ p1 = ParsedFormatBase("hello%s", true, {Conv::s}); // move assign >+ EXPECT_EQ("[hello]{s:1$s}", SummarizeParsedFormat(p1)); >+ >+ ParsedFormatBase p3 = p1; // copy construct (nonempty) >+ EXPECT_EQ(SummarizeParsedFormat(p1), SummarizeParsedFormat(p3)); >+ >+ using std::swap; >+ swap(p1, p2); >+ EXPECT_EQ("", SummarizeParsedFormat(p1)); >+ EXPECT_EQ("[hello]{s:1$s}", SummarizeParsedFormat(p2)); >+ swap(p1, p2); // undo >+ >+ p2 = p1; // copy assign >+ EXPECT_EQ(SummarizeParsedFormat(p1), SummarizeParsedFormat(p2)); >+} >+ >+struct ExpectParse { >+ const char* in; >+ std::initializer_list<Conv> conv_set; >+ const char* out; >+}; >+ >+TEST_F(ParsedFormatTest, Parsing) { >+ // Parse should be equivalent to that obtained by ConversionParseIterator. >+ // No need to retest the parsing edge cases here. >+ const ExpectParse kExpect[] = { >+ {"", {}, ""}, >+ {"ab", {}, "[ab]"}, >+ {"a%d", {Conv::d}, "[a]{d:1$d}"}, >+ {"a%+d", {Conv::d}, "[a]{+d:1$d}"}, >+ {"a% d", {Conv::d}, "[a]{ d:1$d}"}, >+ {"a%b %d", {}, "[a]!"}, // stop after error >+ }; >+ for (const auto& e : kExpect) { >+ SCOPED_TRACE(e.in); >+ EXPECT_EQ(e.out, >+ SummarizeParsedFormat(ParsedFormatBase(e.in, false, e.conv_set))); >+ } >+} >+ >+TEST_F(ParsedFormatTest, ParsingFlagOrder) { >+ const ExpectParse kExpect[] = { >+ {"a%+ 0d", {Conv::d}, "[a]{+ 0d:1$d}"}, >+ {"a%+0 d", {Conv::d}, "[a]{+0 d:1$d}"}, >+ {"a%0+ d", {Conv::d}, "[a]{0+ d:1$d}"}, >+ {"a% +0d", {Conv::d}, "[a]{ +0d:1$d}"}, >+ {"a%0 +d", {Conv::d}, "[a]{0 +d:1$d}"}, >+ {"a% 0+d", {Conv::d}, "[a]{ 0+d:1$d}"}, >+ {"a%+ 0+d", {Conv::d}, "[a]{+ 0+d:1$d}"}, >+ }; >+ for (const auto& e : kExpect) { >+ SCOPED_TRACE(e.in); >+ EXPECT_EQ(e.out, >+ SummarizeParsedFormat(ParsedFormatBase(e.in, false, e.conv_set))); >+ } >+} >+ >+} // namespace >+} // namespace str_format_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h >new file mode 100644 >index 0000000000000000000000000000000000000000..a734758c21ee30951f77a2c69c96ec75d71ee96a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h >@@ -0,0 +1,311 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+// This file declares INTERNAL parts of the Join API that are inlined/templated >+// or otherwise need to be available at compile time. The main abstractions >+// defined in this file are: >+// >+// - A handful of default Formatters >+// - JoinAlgorithm() overloads >+// - JoinRange() overloads >+// - JoinTuple() >+// >+// DO NOT INCLUDE THIS FILE DIRECTLY. Use this file by including >+// absl/strings/str_join.h >+// >+// IWYU pragma: private, include "absl/strings/str_join.h" >+ >+#ifndef ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_ >+#define ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_ >+ >+#include <cstring> >+#include <iterator> >+#include <memory> >+#include <string> >+#include <type_traits> >+#include <utility> >+ >+#include "absl/strings/internal/ostringstream.h" >+#include "absl/strings/internal/resize_uninitialized.h" >+#include "absl/strings/str_cat.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+// >+// Formatter objects >+// >+// The following are implementation classes for standard Formatter objects. The >+// factory functions that users will call to create and use these formatters are >+// defined and documented in strings/join.h. >+// >+ >+// The default formatter. Converts alpha-numeric types to strings. >+struct AlphaNumFormatterImpl { >+ // This template is needed in order to support passing in a dereferenced >+ // vector<bool>::iterator >+ template <typename T> >+ void operator()(std::string* out, const T& t) const { >+ StrAppend(out, AlphaNum(t)); >+ } >+ >+ void operator()(std::string* out, const AlphaNum& t) const { >+ StrAppend(out, t); >+ } >+}; >+ >+// A type that's used to overload the JoinAlgorithm() function (defined below) >+// for ranges that do not require additional formatting (e.g., a range of >+// strings). >+ >+struct NoFormatter : public AlphaNumFormatterImpl {}; >+ >+// Formats types to strings using the << operator. >+class StreamFormatterImpl { >+ public: >+ // The method isn't const because it mutates state. Making it const will >+ // render StreamFormatterImpl thread-hostile. >+ template <typename T> >+ void operator()(std::string* out, const T& t) { >+ // The stream is created lazily to avoid paying the relatively high cost >+ // of its construction when joining an empty range. >+ if (strm_) { >+ strm_->clear(); // clear the bad, fail and eof bits in case they were set >+ strm_->str(out); >+ } else { >+ strm_.reset(new strings_internal::OStringStream(out)); >+ } >+ *strm_ << t; >+ } >+ >+ private: >+ std::unique_ptr<strings_internal::OStringStream> strm_; >+}; >+ >+// Formats a std::pair<>. The 'first' member is formatted using f1_ and the >+// 'second' member is formatted using f2_. sep_ is the separator. >+template <typename F1, typename F2> >+class PairFormatterImpl { >+ public: >+ PairFormatterImpl(F1 f1, absl::string_view sep, F2 f2) >+ : f1_(std::move(f1)), sep_(sep), f2_(std::move(f2)) {} >+ >+ template <typename T> >+ void operator()(std::string* out, const T& p) { >+ f1_(out, p.first); >+ out->append(sep_); >+ f2_(out, p.second); >+ } >+ >+ template <typename T> >+ void operator()(std::string* out, const T& p) const { >+ f1_(out, p.first); >+ out->append(sep_); >+ f2_(out, p.second); >+ } >+ >+ private: >+ F1 f1_; >+ std::string sep_; >+ F2 f2_; >+}; >+ >+// Wraps another formatter and dereferences the argument to operator() then >+// passes the dereferenced argument to the wrapped formatter. This can be >+// useful, for example, to join a std::vector<int*>. >+template <typename Formatter> >+class DereferenceFormatterImpl { >+ public: >+ DereferenceFormatterImpl() : f_() {} >+ explicit DereferenceFormatterImpl(Formatter&& f) >+ : f_(std::forward<Formatter>(f)) {} >+ >+ template <typename T> >+ void operator()(std::string* out, const T& t) { >+ f_(out, *t); >+ } >+ >+ template <typename T> >+ void operator()(std::string* out, const T& t) const { >+ f_(out, *t); >+ } >+ >+ private: >+ Formatter f_; >+}; >+ >+// DefaultFormatter<T> is a traits class that selects a default Formatter to use >+// for the given type T. The ::Type member names the Formatter to use. This is >+// used by the strings::Join() functions that do NOT take a Formatter argument, >+// in which case a default Formatter must be chosen. >+// >+// AlphaNumFormatterImpl is the default in the base template, followed by >+// specializations for other types. >+template <typename ValueType> >+struct DefaultFormatter { >+ typedef AlphaNumFormatterImpl Type; >+}; >+template <> >+struct DefaultFormatter<const char*> { >+ typedef AlphaNumFormatterImpl Type; >+}; >+template <> >+struct DefaultFormatter<char*> { >+ typedef AlphaNumFormatterImpl Type; >+}; >+template <> >+struct DefaultFormatter<std::string> { >+ typedef NoFormatter Type; >+}; >+template <> >+struct DefaultFormatter<absl::string_view> { >+ typedef NoFormatter Type; >+}; >+template <typename ValueType> >+struct DefaultFormatter<ValueType*> { >+ typedef DereferenceFormatterImpl<typename DefaultFormatter<ValueType>::Type> >+ Type; >+}; >+ >+template <typename ValueType> >+struct DefaultFormatter<std::unique_ptr<ValueType>> >+ : public DefaultFormatter<ValueType*> {}; >+ >+// >+// JoinAlgorithm() functions >+// >+ >+// The main joining algorithm. This simply joins the elements in the given >+// iterator range, each separated by the given separator, into an output std::string, >+// and formats each element using the provided Formatter object. >+template <typename Iterator, typename Formatter> >+std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s, >+ Formatter&& f) { >+ std::string result; >+ absl::string_view sep(""); >+ for (Iterator it = start; it != end; ++it) { >+ result.append(sep.data(), sep.size()); >+ f(&result, *it); >+ sep = s; >+ } >+ return result; >+} >+ >+// A joining algorithm that's optimized for a forward iterator range of >+// std::string-like objects that do not need any additional formatting. This is to >+// optimize the common case of joining, say, a std::vector<std::string> or a >+// std::vector<absl::string_view>. >+// >+// This is an overload of the previous JoinAlgorithm() function. Here the >+// Formatter argument is of type NoFormatter. Since NoFormatter is an internal >+// type, this overload is only invoked when strings::Join() is called with a >+// range of std::string-like objects (e.g., std::string, absl::string_view), and an >+// explicit Formatter argument was NOT specified. >+// >+// The optimization is that the needed space will be reserved in the output >+// std::string to avoid the need to resize while appending. To do this, the iterator >+// range will be traversed twice: once to calculate the total needed size, and >+// then again to copy the elements and delimiters to the output std::string. >+template <typename Iterator, >+ typename = typename std::enable_if<std::is_convertible< >+ typename std::iterator_traits<Iterator>::iterator_category, >+ std::forward_iterator_tag>::value>::type> >+std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s, >+ NoFormatter) { >+ std::string result; >+ if (start != end) { >+ // Sums size >+ size_t result_size = start->size(); >+ for (Iterator it = start; ++it != end;) { >+ result_size += s.size(); >+ result_size += it->size(); >+ } >+ >+ if (result_size > 0) { >+ STLStringResizeUninitialized(&result, result_size); >+ >+ // Joins strings >+ char* result_buf = &*result.begin(); >+ memcpy(result_buf, start->data(), start->size()); >+ result_buf += start->size(); >+ for (Iterator it = start; ++it != end;) { >+ memcpy(result_buf, s.data(), s.size()); >+ result_buf += s.size(); >+ memcpy(result_buf, it->data(), it->size()); >+ result_buf += it->size(); >+ } >+ } >+ } >+ >+ return result; >+} >+ >+// JoinTupleLoop implements a loop over the elements of a std::tuple, which >+// are heterogeneous. The primary template matches the tuple interior case. It >+// continues the iteration after appending a separator (for nonzero indices) >+// and formatting an element of the tuple. The specialization for the I=N case >+// matches the end-of-tuple, and terminates the iteration. >+template <size_t I, size_t N> >+struct JoinTupleLoop { >+ template <typename Tup, typename Formatter> >+ void operator()(std::string* out, const Tup& tup, absl::string_view sep, >+ Formatter&& fmt) { >+ if (I > 0) out->append(sep.data(), sep.size()); >+ fmt(out, std::get<I>(tup)); >+ JoinTupleLoop<I + 1, N>()(out, tup, sep, fmt); >+ } >+}; >+template <size_t N> >+struct JoinTupleLoop<N, N> { >+ template <typename Tup, typename Formatter> >+ void operator()(std::string*, const Tup&, absl::string_view, Formatter&&) {} >+}; >+ >+template <typename... T, typename Formatter> >+std::string JoinAlgorithm(const std::tuple<T...>& tup, absl::string_view sep, >+ Formatter&& fmt) { >+ std::string result; >+ JoinTupleLoop<0, sizeof...(T)>()(&result, tup, sep, fmt); >+ return result; >+} >+ >+template <typename Iterator> >+std::string JoinRange(Iterator first, Iterator last, absl::string_view separator) { >+ // No formatter was explicitly given, so a default must be chosen. >+ typedef typename std::iterator_traits<Iterator>::value_type ValueType; >+ typedef typename DefaultFormatter<ValueType>::Type Formatter; >+ return JoinAlgorithm(first, last, separator, Formatter()); >+} >+ >+template <typename Range, typename Formatter> >+std::string JoinRange(const Range& range, absl::string_view separator, >+ Formatter&& fmt) { >+ using std::begin; >+ using std::end; >+ return JoinAlgorithm(begin(range), end(range), separator, fmt); >+} >+ >+template <typename Range> >+std::string JoinRange(const Range& range, absl::string_view separator) { >+ using std::begin; >+ using std::end; >+ return JoinRange(begin(range), end(range), separator); >+} >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9cf0833f49028ab039c7c422504a996d99e943dc >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h >@@ -0,0 +1,453 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+// This file declares INTERNAL parts of the Split API that are inline/templated >+// or otherwise need to be available at compile time. The main abstractions >+// defined in here are >+// >+// - ConvertibleToStringView >+// - SplitIterator<> >+// - Splitter<> >+// >+// DO NOT INCLUDE THIS FILE DIRECTLY. Use this file by including >+// absl/strings/str_split.h. >+// >+// IWYU pragma: private, include "absl/strings/str_split.h" >+ >+#ifndef ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_ >+#define ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_ >+ >+#include <array> >+#include <initializer_list> >+#include <iterator> >+#include <map> >+#include <type_traits> >+#include <utility> >+#include <vector> >+ >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+#include "absl/meta/type_traits.h" >+#include "absl/strings/string_view.h" >+ >+#ifdef _GLIBCXX_DEBUG >+#include "absl/strings/internal/stl_type_traits.h" >+#endif // _GLIBCXX_DEBUG >+ >+namespace absl { >+namespace strings_internal { >+ >+// This class is implicitly constructible from everything that absl::string_view >+// is implicitly constructible from. If it's constructed from a temporary >+// std::string, the data is moved into a data member so its lifetime matches that of >+// the ConvertibleToStringView instance. >+class ConvertibleToStringView { >+ public: >+ ConvertibleToStringView(const char* s) // NOLINT(runtime/explicit) >+ : value_(s) {} >+ ConvertibleToStringView(char* s) : value_(s) {} // NOLINT(runtime/explicit) >+ ConvertibleToStringView(absl::string_view s) // NOLINT(runtime/explicit) >+ : value_(s) {} >+ ConvertibleToStringView(const std::string& s) // NOLINT(runtime/explicit) >+ : value_(s) {} >+ >+ // Matches rvalue strings and moves their data to a member. >+ConvertibleToStringView(std::string&& s) // NOLINT(runtime/explicit) >+ : copy_(std::move(s)), value_(copy_) {} >+ >+ ConvertibleToStringView(const ConvertibleToStringView& other) >+ : copy_(other.copy_), >+ value_(other.IsSelfReferential() ? copy_ : other.value_) {} >+ >+ ConvertibleToStringView(ConvertibleToStringView&& other) { >+ StealMembers(std::move(other)); >+ } >+ >+ ConvertibleToStringView& operator=(ConvertibleToStringView other) { >+ StealMembers(std::move(other)); >+ return *this; >+ } >+ >+ absl::string_view value() const { return value_; } >+ >+ private: >+ // Returns true if ctsp's value refers to its internal copy_ member. >+ bool IsSelfReferential() const { return value_.data() == copy_.data(); } >+ >+ void StealMembers(ConvertibleToStringView&& other) { >+ if (other.IsSelfReferential()) { >+ copy_ = std::move(other.copy_); >+ value_ = copy_; >+ other.value_ = other.copy_; >+ } else { >+ value_ = other.value_; >+ } >+ } >+ >+ // Holds the data moved from temporary std::string arguments. Declared first so >+ // that 'value' can refer to 'copy_'. >+ std::string copy_; >+ absl::string_view value_; >+}; >+ >+// An iterator that enumerates the parts of a std::string from a Splitter. The text >+// to be split, the Delimiter, and the Predicate are all taken from the given >+// Splitter object. Iterators may only be compared if they refer to the same >+// Splitter instance. >+// >+// This class is NOT part of the public splitting API. >+template <typename Splitter> >+class SplitIterator { >+ public: >+ using iterator_category = std::input_iterator_tag; >+ using value_type = absl::string_view; >+ using difference_type = ptrdiff_t; >+ using pointer = const value_type*; >+ using reference = const value_type&; >+ >+ enum State { kInitState, kLastState, kEndState }; >+ SplitIterator(State state, const Splitter* splitter) >+ : pos_(0), >+ state_(state), >+ splitter_(splitter), >+ delimiter_(splitter->delimiter()), >+ predicate_(splitter->predicate()) { >+ // Hack to maintain backward compatibility. This one block makes it so an >+ // empty absl::string_view whose .data() happens to be nullptr behaves >+ // *differently* from an otherwise empty absl::string_view whose .data() is >+ // not nullptr. This is an undesirable difference in general, but this >+ // behavior is maintained to avoid breaking existing code that happens to >+ // depend on this old behavior/bug. Perhaps it will be fixed one day. The >+ // difference in behavior is as follows: >+ // Split(absl::string_view(""), '-'); // {""} >+ // Split(absl::string_view(), '-'); // {} >+ if (splitter_->text().data() == nullptr) { >+ state_ = kEndState; >+ pos_ = splitter_->text().size(); >+ return; >+ } >+ >+ if (state_ == kEndState) { >+ pos_ = splitter_->text().size(); >+ } else { >+ ++(*this); >+ } >+ } >+ >+ bool at_end() const { return state_ == kEndState; } >+ >+ reference operator*() const { return curr_; } >+ pointer operator->() const { return &curr_; } >+ >+ SplitIterator& operator++() { >+ do { >+ if (state_ == kLastState) { >+ state_ = kEndState; >+ return *this; >+ } >+ const absl::string_view text = splitter_->text(); >+ const absl::string_view d = delimiter_.Find(text, pos_); >+ if (d.data() == text.end()) state_ = kLastState; >+ curr_ = text.substr(pos_, d.data() - (text.data() + pos_)); >+ pos_ += curr_.size() + d.size(); >+ } while (!predicate_(curr_)); >+ return *this; >+ } >+ >+ SplitIterator operator++(int) { >+ SplitIterator old(*this); >+ ++(*this); >+ return old; >+ } >+ >+ friend bool operator==(const SplitIterator& a, const SplitIterator& b) { >+ return a.state_ == b.state_ && a.pos_ == b.pos_; >+ } >+ >+ friend bool operator!=(const SplitIterator& a, const SplitIterator& b) { >+ return !(a == b); >+ } >+ >+ private: >+ size_t pos_; >+ State state_; >+ absl::string_view curr_; >+ const Splitter* splitter_; >+ typename Splitter::DelimiterType delimiter_; >+ typename Splitter::PredicateType predicate_; >+}; >+ >+// HasMappedType<T>::value is true iff there exists a type T::mapped_type. >+template <typename T, typename = void> >+struct HasMappedType : std::false_type {}; >+template <typename T> >+struct HasMappedType<T, absl::void_t<typename T::mapped_type>> >+ : std::true_type {}; >+ >+// HasValueType<T>::value is true iff there exists a type T::value_type. >+template <typename T, typename = void> >+struct HasValueType : std::false_type {}; >+template <typename T> >+struct HasValueType<T, absl::void_t<typename T::value_type>> : std::true_type { >+}; >+ >+// HasConstIterator<T>::value is true iff there exists a type T::const_iterator. >+template <typename T, typename = void> >+struct HasConstIterator : std::false_type {}; >+template <typename T> >+struct HasConstIterator<T, absl::void_t<typename T::const_iterator>> >+ : std::true_type {}; >+ >+// IsInitializerList<T>::value is true iff T is an std::initializer_list. More >+// details below in Splitter<> where this is used. >+std::false_type IsInitializerListDispatch(...); // default: No >+template <typename T> >+std::true_type IsInitializerListDispatch(std::initializer_list<T>*); >+template <typename T> >+struct IsInitializerList >+ : decltype(IsInitializerListDispatch(static_cast<T*>(nullptr))) {}; >+ >+// A SplitterIsConvertibleTo<C>::type alias exists iff the specified condition >+// is true for type 'C'. >+// >+// Restricts conversion to container-like types (by testing for the presence of >+// a const_iterator member type) and also to disable conversion to an >+// std::initializer_list (which also has a const_iterator). Otherwise, code >+// compiled in C++11 will get an error due to ambiguous conversion paths (in >+// C++11 std::vector<T>::operator= is overloaded to take either a std::vector<T> >+// or an std::initializer_list<T>). >+ >+template <typename C, bool has_value_type, bool has_mapped_type> >+struct SplitterIsConvertibleToImpl : std::false_type {}; >+ >+template <typename C> >+struct SplitterIsConvertibleToImpl<C, true, false> >+ : std::is_constructible<typename C::value_type, absl::string_view> {}; >+ >+template <typename C> >+struct SplitterIsConvertibleToImpl<C, true, true> >+ : absl::conjunction< >+ std::is_constructible<typename C::key_type, absl::string_view>, >+ std::is_constructible<typename C::mapped_type, absl::string_view>> {}; >+ >+template <typename C> >+struct SplitterIsConvertibleTo >+ : SplitterIsConvertibleToImpl< >+ C, >+#ifdef _GLIBCXX_DEBUG >+ !IsStrictlyBaseOfAndConvertibleToSTLContainer<C>::value && >+#endif // _GLIBCXX_DEBUG >+ !IsInitializerList< >+ typename std::remove_reference<C>::type>::value && >+ HasValueType<C>::value && HasConstIterator<C>::value, >+ HasMappedType<C>::value> { >+}; >+ >+// This class implements the range that is returned by absl::StrSplit(). This >+// class has templated conversion operators that allow it to be implicitly >+// converted to a variety of types that the caller may have specified on the >+// left-hand side of an assignment. >+// >+// The main interface for interacting with this class is through its implicit >+// conversion operators. However, this class may also be used like a container >+// in that it has .begin() and .end() member functions. It may also be used >+// within a range-for loop. >+// >+// Output containers can be collections of any type that is constructible from >+// an absl::string_view. >+// >+// An Predicate functor may be supplied. This predicate will be used to filter >+// the split strings: only strings for which the predicate returns true will be >+// kept. A Predicate object is any unary functor that takes an absl::string_view >+// and returns bool. >+template <typename Delimiter, typename Predicate> >+class Splitter { >+ public: >+ using DelimiterType = Delimiter; >+ using PredicateType = Predicate; >+ using const_iterator = strings_internal::SplitIterator<Splitter>; >+ using value_type = typename std::iterator_traits<const_iterator>::value_type; >+ >+ Splitter(ConvertibleToStringView input_text, Delimiter d, Predicate p) >+ : text_(std::move(input_text)), >+ delimiter_(std::move(d)), >+ predicate_(std::move(p)) {} >+ >+ absl::string_view text() const { return text_.value(); } >+ const Delimiter& delimiter() const { return delimiter_; } >+ const Predicate& predicate() const { return predicate_; } >+ >+ // Range functions that iterate the split substrings as absl::string_view >+ // objects. These methods enable a Splitter to be used in a range-based for >+ // loop. >+ const_iterator begin() const { return {const_iterator::kInitState, this}; } >+ const_iterator end() const { return {const_iterator::kEndState, this}; } >+ >+ // An implicit conversion operator that is restricted to only those containers >+ // that the splitter is convertible to. >+ template <typename Container, >+ typename = typename std::enable_if< >+ SplitterIsConvertibleTo<Container>::value>::type> >+ operator Container() const { // NOLINT(runtime/explicit) >+ return ConvertToContainer<Container, typename Container::value_type, >+ HasMappedType<Container>::value>()(*this); >+ } >+ >+ // Returns a pair with its .first and .second members set to the first two >+ // strings returned by the begin() iterator. Either/both of .first and .second >+ // will be constructed with empty strings if the iterator doesn't have a >+ // corresponding value. >+ template <typename First, typename Second> >+ operator std::pair<First, Second>() const { // NOLINT(runtime/explicit) >+ absl::string_view first, second; >+ auto it = begin(); >+ if (it != end()) { >+ first = *it; >+ if (++it != end()) { >+ second = *it; >+ } >+ } >+ return {First(first), Second(second)}; >+ } >+ >+ private: >+ // ConvertToContainer is a functor converting a Splitter to the requested >+ // Container of ValueType. It is specialized below to optimize splitting to >+ // certain combinations of Container and ValueType. >+ // >+ // This base template handles the generic case of storing the split results in >+ // the requested non-map-like container and converting the split substrings to >+ // the requested type. >+ template <typename Container, typename ValueType, bool is_map = false> >+ struct ConvertToContainer { >+ Container operator()(const Splitter& splitter) const { >+ Container c; >+ auto it = std::inserter(c, c.end()); >+ for (const auto sp : splitter) { >+ *it++ = ValueType(sp); >+ } >+ return c; >+ } >+ }; >+ >+ // Partial specialization for a std::vector<absl::string_view>. >+ // >+ // Optimized for the common case of splitting to a >+ // std::vector<absl::string_view>. In this case we first split the results to >+ // a small array of absl::string_view on the stack, to reduce reallocations. >+ template <typename A> >+ struct ConvertToContainer<std::vector<absl::string_view, A>, >+ absl::string_view, false> { >+ std::vector<absl::string_view, A> operator()( >+ const Splitter& splitter) const { >+ struct raw_view { >+ const char* data; >+ size_t size; >+ operator absl::string_view() const { // NOLINT(runtime/explicit) >+ return {data, size}; >+ } >+ }; >+ std::vector<absl::string_view, A> v; >+ std::array<raw_view, 16> ar; >+ for (auto it = splitter.begin(); !it.at_end();) { >+ size_t index = 0; >+ do { >+ ar[index].data = it->data(); >+ ar[index].size = it->size(); >+ ++it; >+ } while (++index != ar.size() && !it.at_end()); >+ v.insert(v.end(), ar.begin(), ar.begin() + index); >+ } >+ return v; >+ } >+ }; >+ >+ // Partial specialization for a std::vector<std::string>. >+ // >+ // Optimized for the common case of splitting to a std::vector<std::string>. In >+ // this case we first split the results to a std::vector<absl::string_view> so >+ // the returned std::vector<std::string> can have space reserved to avoid std::string >+ // moves. >+ template <typename A> >+ struct ConvertToContainer<std::vector<std::string, A>, std::string, false> { >+ std::vector<std::string, A> operator()(const Splitter& splitter) const { >+ const std::vector<absl::string_view> v = splitter; >+ return std::vector<std::string, A>(v.begin(), v.end()); >+ } >+ }; >+ >+ // Partial specialization for containers of pairs (e.g., maps). >+ // >+ // The algorithm is to insert a new pair into the map for each even-numbered >+ // item, with the even-numbered item as the key with a default-constructed >+ // value. Each odd-numbered item will then be assigned to the last pair's >+ // value. >+ template <typename Container, typename First, typename Second> >+ struct ConvertToContainer<Container, std::pair<const First, Second>, true> { >+ Container operator()(const Splitter& splitter) const { >+ Container m; >+ typename Container::iterator it; >+ bool insert = true; >+ for (const auto sp : splitter) { >+ if (insert) { >+ it = Inserter<Container>::Insert(&m, First(sp), Second()); >+ } else { >+ it->second = Second(sp); >+ } >+ insert = !insert; >+ } >+ return m; >+ } >+ >+ // Inserts the key and value into the given map, returning an iterator to >+ // the inserted item. Specialized for std::map and std::multimap to use >+ // emplace() and adapt emplace()'s return value. >+ template <typename Map> >+ struct Inserter { >+ using M = Map; >+ template <typename... Args> >+ static typename M::iterator Insert(M* m, Args&&... args) { >+ return m->insert(std::make_pair(std::forward<Args>(args)...)).first; >+ } >+ }; >+ >+ template <typename... Ts> >+ struct Inserter<std::map<Ts...>> { >+ using M = std::map<Ts...>; >+ template <typename... Args> >+ static typename M::iterator Insert(M* m, Args&&... args) { >+ return m->emplace(std::make_pair(std::forward<Args>(args)...)).first; >+ } >+ }; >+ >+ template <typename... Ts> >+ struct Inserter<std::multimap<Ts...>> { >+ using M = std::multimap<Ts...>; >+ template <typename... Args> >+ static typename M::iterator Insert(M* m, Args&&... args) { >+ return m->emplace(std::make_pair(std::forward<Args>(args)...)); >+ } >+ }; >+ }; >+ >+ ConvertibleToStringView text_; >+ Delimiter delimiter_; >+ Predicate predicate_; >+}; >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/utf8.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/utf8.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..2415c2ccc45cd7549e9866d8bb03bd9ad005b363 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/utf8.cc >@@ -0,0 +1,51 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// UTF8 utilities, implemented to reduce dependencies. >+ >+#include "absl/strings/internal/utf8.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+size_t EncodeUTF8Char(char *buffer, char32_t utf8_char) { >+ if (utf8_char <= 0x7F) { >+ *buffer = static_cast<char>(utf8_char); >+ return 1; >+ } else if (utf8_char <= 0x7FF) { >+ buffer[1] = 0x80 | (utf8_char & 0x3F); >+ utf8_char >>= 6; >+ buffer[0] = 0xC0 | utf8_char; >+ return 2; >+ } else if (utf8_char <= 0xFFFF) { >+ buffer[2] = 0x80 | (utf8_char & 0x3F); >+ utf8_char >>= 6; >+ buffer[1] = 0x80 | (utf8_char & 0x3F); >+ utf8_char >>= 6; >+ buffer[0] = 0xE0 | utf8_char; >+ return 3; >+ } else { >+ buffer[3] = 0x80 | (utf8_char & 0x3F); >+ utf8_char >>= 6; >+ buffer[2] = 0x80 | (utf8_char & 0x3F); >+ utf8_char >>= 6; >+ buffer[1] = 0x80 | (utf8_char & 0x3F); >+ utf8_char >>= 6; >+ buffer[0] = 0xF0 | utf8_char; >+ return 4; >+ } >+} >+ >+} // namespace strings_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/utf8.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/utf8.h >new file mode 100644 >index 0000000000000000000000000000000000000000..d2c3c0b01208596b44c79847ea71c627d913c64b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/utf8.h >@@ -0,0 +1,47 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// UTF8 utilities, implemented to reduce dependencies. >+// >+ >+#ifndef ABSL_STRINGS_INTERNAL_UTF8_H_ >+#define ABSL_STRINGS_INTERNAL_UTF8_H_ >+ >+#include <cstddef> >+#include <cstdint> >+ >+namespace absl { >+namespace strings_internal { >+ >+// For Unicode code points 0 through 0x10FFFF, EncodeUTF8Char writes >+// out the UTF-8 encoding into buffer, and returns the number of chars >+// it wrote. >+// >+// As described in https://tools.ietf.org/html/rfc3629#section-3 , the encodings >+// are: >+// 00 - 7F : 0xxxxxxx >+// 80 - 7FF : 110xxxxx 10xxxxxx >+// 800 - FFFF : 1110xxxx 10xxxxxx 10xxxxxx >+// 10000 - 10FFFF : 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx >+// >+// Values greater than 0x10FFFF are not supported and may or may not write >+// characters into buffer, however never will more than kMaxEncodedUTF8Size >+// bytes be written, regardless of the value of utf8_char. >+enum { kMaxEncodedUTF8Size = 4 }; >+size_t EncodeUTF8Char(char *buffer, char32_t utf8_char); >+ >+} // namespace strings_internal >+} // namespace absl >+ >+#endif // ABSL_STRINGS_INTERNAL_UTF8_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/utf8_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/utf8_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..64cec70df7e1d8dd53f54d3f8c06f40b084d9f5b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/internal/utf8_test.cc >@@ -0,0 +1,57 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/internal/utf8.h" >+ >+#include <cstdint> >+#include <utility> >+ >+#include "gtest/gtest.h" >+#include "absl/base/port.h" >+ >+namespace { >+ >+TEST(EncodeUTF8Char, BasicFunction) { >+ std::pair<char32_t, std::string> tests[] = {{0x0030, u8"\u0030"}, >+ {0x00A3, u8"\u00A3"}, >+ {0x00010000, u8"\U00010000"}, >+ {0x0000FFFF, u8"\U0000FFFF"}, >+ {0x0010FFFD, u8"\U0010FFFD"}}; >+ for (auto &test : tests) { >+ char buf0[7] = {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}; >+ char buf1[7] = {'\xFF', '\xFF', '\xFF', '\xFF', '\xFF', '\xFF', '\xFF'}; >+ char *buf0_written = >+ &buf0[absl::strings_internal::EncodeUTF8Char(buf0, test.first)]; >+ char *buf1_written = >+ &buf1[absl::strings_internal::EncodeUTF8Char(buf1, test.first)]; >+ int apparent_length = 7; >+ while (buf0[apparent_length - 1] == '\x00' && >+ buf1[apparent_length - 1] == '\xFF') { >+ if (--apparent_length == 0) break; >+ } >+ EXPECT_EQ(apparent_length, buf0_written - buf0); >+ EXPECT_EQ(apparent_length, buf1_written - buf1); >+ EXPECT_EQ(apparent_length, test.second.length()); >+ EXPECT_EQ(std::string(buf0, apparent_length), test.second); >+ EXPECT_EQ(std::string(buf1, apparent_length), test.second); >+ } >+ char buf[32] = "Don't Tread On Me"; >+ EXPECT_LE(absl::strings_internal::EncodeUTF8Char(buf, 0x00110000), >+ absl::strings_internal::kMaxEncodedUTF8Size); >+ char buf2[32] = "Negative is invalid but sane"; >+ EXPECT_LE(absl::strings_internal::EncodeUTF8Char(buf2, -1), >+ absl::strings_internal::kMaxEncodedUTF8Size); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/match.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/match.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..25bd7f0b828bfdec72ca587d4871bffb692862e3 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/match.cc >@@ -0,0 +1,40 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/match.h" >+ >+#include "absl/strings/internal/memutil.h" >+ >+namespace absl { >+ >+namespace { >+bool CaseEqual(absl::string_view piece1, absl::string_view piece2) { >+ return (piece1.size() == piece2.size() && >+ 0 == strings_internal::memcasecmp(piece1.data(), piece2.data(), >+ piece1.size())); >+ // memcasecmp uses ascii_tolower(). >+} >+} // namespace >+ >+bool StartsWithIgnoreCase(absl::string_view text, absl::string_view prefix) { >+ return (text.size() >= prefix.size()) && >+ CaseEqual(text.substr(0, prefix.size()), prefix); >+} >+ >+bool EndsWithIgnoreCase(absl::string_view text, absl::string_view suffix) { >+ return (text.size() >= suffix.size()) && >+ CaseEqual(text.substr(text.size() - suffix.size()), suffix); >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/match.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/match.h >new file mode 100644 >index 0000000000000000000000000000000000000000..108b6048b048ec265f518aa3a6ee04d1019f3436 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/match.h >@@ -0,0 +1,83 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: match.h >+// ----------------------------------------------------------------------------- >+// >+// This file contains simple utilities for performing std::string matching checks. >+// All of these function parameters are specified as `absl::string_view`, >+// meaning that these functions can accept `std::string`, `absl::string_view` or >+// nul-terminated C-style strings. >+// >+// Examples: >+// std::string s = "foo"; >+// absl::string_view sv = "f"; >+// assert(absl::StrContains(s, sv)); >+// >+// Note: The order of parameters in these functions is designed to mimic the >+// order an equivalent member function would exhibit; >+// e.g. `s.Contains(x)` ==> `absl::StrContains(s, x). >+#ifndef ABSL_STRINGS_MATCH_H_ >+#define ABSL_STRINGS_MATCH_H_ >+ >+#include <cstring> >+ >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+ >+// StrContains() >+// >+// Returns whether a given std::string `haystack` contains the substring `needle`. >+inline bool StrContains(absl::string_view haystack, absl::string_view needle) { >+ return haystack.find(needle, 0) != haystack.npos; >+} >+ >+// StartsWith() >+// >+// Returns whether a given std::string `text` begins with `prefix`. >+inline bool StartsWith(absl::string_view text, absl::string_view prefix) { >+ return prefix.empty() || >+ (text.size() >= prefix.size() && >+ memcmp(text.data(), prefix.data(), prefix.size()) == 0); >+} >+ >+// EndsWith() >+// >+// Returns whether a given std::string `text` ends with `suffix`. >+inline bool EndsWith(absl::string_view text, absl::string_view suffix) { >+ return suffix.empty() || >+ (text.size() >= suffix.size() && >+ memcmp(text.data() + (text.size() - suffix.size()), suffix.data(), >+ suffix.size()) == 0 >+ ); >+} >+ >+// StartsWithIgnoreCase() >+// >+// Returns whether a given std::string `text` starts with `starts_with`, ignoring >+// case in the comparison. >+bool StartsWithIgnoreCase(absl::string_view text, absl::string_view prefix); >+ >+// EndsWithIgnoreCase() >+// >+// Returns whether a given std::string `text` ends with `ends_with`, ignoring case >+// in the comparison. >+bool EndsWithIgnoreCase(absl::string_view text, absl::string_view suffix); >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_MATCH_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/match_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/match_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..d194f0e689bf6e001656c52e357b5d778a67b55d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/match_test.cc >@@ -0,0 +1,99 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/match.h" >+ >+#include "gtest/gtest.h" >+ >+namespace { >+ >+TEST(MatchTest, StartsWith) { >+ const std::string s1("123" "\0" "456", 7); >+ const absl::string_view a("foobar"); >+ const absl::string_view b(s1); >+ const absl::string_view e; >+ EXPECT_TRUE(absl::StartsWith(a, a)); >+ EXPECT_TRUE(absl::StartsWith(a, "foo")); >+ EXPECT_TRUE(absl::StartsWith(a, e)); >+ EXPECT_TRUE(absl::StartsWith(b, s1)); >+ EXPECT_TRUE(absl::StartsWith(b, b)); >+ EXPECT_TRUE(absl::StartsWith(b, e)); >+ EXPECT_TRUE(absl::StartsWith(e, "")); >+ EXPECT_FALSE(absl::StartsWith(a, b)); >+ EXPECT_FALSE(absl::StartsWith(b, a)); >+ EXPECT_FALSE(absl::StartsWith(e, a)); >+} >+ >+TEST(MatchTest, EndsWith) { >+ const std::string s1("123" "\0" "456", 7); >+ const absl::string_view a("foobar"); >+ const absl::string_view b(s1); >+ const absl::string_view e; >+ EXPECT_TRUE(absl::EndsWith(a, a)); >+ EXPECT_TRUE(absl::EndsWith(a, "bar")); >+ EXPECT_TRUE(absl::EndsWith(a, e)); >+ EXPECT_TRUE(absl::EndsWith(b, s1)); >+ EXPECT_TRUE(absl::EndsWith(b, b)); >+ EXPECT_TRUE(absl::EndsWith(b, e)); >+ EXPECT_TRUE(absl::EndsWith(e, "")); >+ EXPECT_FALSE(absl::EndsWith(a, b)); >+ EXPECT_FALSE(absl::EndsWith(b, a)); >+ EXPECT_FALSE(absl::EndsWith(e, a)); >+} >+ >+TEST(MatchTest, Contains) { >+ absl::string_view a("abcdefg"); >+ absl::string_view b("abcd"); >+ absl::string_view c("efg"); >+ absl::string_view d("gh"); >+ EXPECT_TRUE(absl::StrContains(a, a)); >+ EXPECT_TRUE(absl::StrContains(a, b)); >+ EXPECT_TRUE(absl::StrContains(a, c)); >+ EXPECT_FALSE(absl::StrContains(a, d)); >+ EXPECT_TRUE(absl::StrContains("", "")); >+ EXPECT_TRUE(absl::StrContains("abc", "")); >+ EXPECT_FALSE(absl::StrContains("", "a")); >+} >+ >+TEST(MatchTest, ContainsNull) { >+ const std::string s = "foo"; >+ const char* cs = "foo"; >+ const absl::string_view sv("foo"); >+ const absl::string_view sv2("foo\0bar", 4); >+ EXPECT_EQ(s, "foo"); >+ EXPECT_EQ(sv, "foo"); >+ EXPECT_NE(sv2, "foo"); >+ EXPECT_TRUE(absl::EndsWith(s, sv)); >+ EXPECT_TRUE(absl::StartsWith(cs, sv)); >+ EXPECT_TRUE(absl::StrContains(cs, sv)); >+ EXPECT_FALSE(absl::StrContains(cs, sv2)); >+} >+ >+TEST(MatchTest, StartsWithIgnoreCase) { >+ EXPECT_TRUE(absl::StartsWithIgnoreCase("foo", "foo")); >+ EXPECT_TRUE(absl::StartsWithIgnoreCase("foo", "Fo")); >+ EXPECT_TRUE(absl::StartsWithIgnoreCase("foo", "")); >+ EXPECT_FALSE(absl::StartsWithIgnoreCase("foo", "fooo")); >+ EXPECT_FALSE(absl::StartsWithIgnoreCase("", "fo")); >+} >+ >+TEST(MatchTest, EndsWithIgnoreCase) { >+ EXPECT_TRUE(absl::EndsWithIgnoreCase("foo", "foo")); >+ EXPECT_TRUE(absl::EndsWithIgnoreCase("foo", "Oo")); >+ EXPECT_TRUE(absl::EndsWithIgnoreCase("foo", "")); >+ EXPECT_FALSE(absl::EndsWithIgnoreCase("foo", "fooo")); >+ EXPECT_FALSE(absl::EndsWithIgnoreCase("", "fo")); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..f842ed85e9f595efb8da1ec050275dd368a26e97 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers.cc >@@ -0,0 +1,912 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// This file contains std::string processing functions related to >+// numeric values. >+ >+#include "absl/strings/numbers.h" >+ >+#include <algorithm> >+#include <cassert> >+#include <cfloat> // for DBL_DIG and FLT_DIG >+#include <cmath> // for HUGE_VAL >+#include <cstdint> >+#include <cstdio> >+#include <cstdlib> >+#include <cstring> >+#include <iterator> >+#include <limits> >+#include <memory> >+#include <utility> >+ >+#include "absl/base/internal/raw_logging.h" >+#include "absl/strings/ascii.h" >+#include "absl/strings/charconv.h" >+#include "absl/strings/internal/bits.h" >+#include "absl/strings/internal/memutil.h" >+#include "absl/strings/str_cat.h" >+ >+namespace absl { >+ >+bool SimpleAtof(absl::string_view str, float* value) { >+ *value = 0.0; >+ str = StripAsciiWhitespace(str); >+ if (!str.empty() && str[0] == '+') { >+ str.remove_prefix(1); >+ } >+ auto result = absl::from_chars(str.data(), str.data() + str.size(), *value); >+ if (result.ec == std::errc::invalid_argument) { >+ return false; >+ } >+ if (result.ptr != str.data() + str.size()) { >+ // not all non-whitespace characters consumed >+ return false; >+ } >+ // from_chars() with DR 3801's current wording will return max() on >+ // overflow. SimpleAtof returns infinity instead. >+ if (result.ec == std::errc::result_out_of_range) { >+ if (*value > 1.0) { >+ *value = std::numeric_limits<float>::infinity(); >+ } else if (*value < -1.0) { >+ *value = -std::numeric_limits<float>::infinity(); >+ } >+ } >+ return true; >+} >+ >+bool SimpleAtod(absl::string_view str, double* value) { >+ *value = 0.0; >+ str = StripAsciiWhitespace(str); >+ if (!str.empty() && str[0] == '+') { >+ str.remove_prefix(1); >+ } >+ auto result = absl::from_chars(str.data(), str.data() + str.size(), *value); >+ if (result.ec == std::errc::invalid_argument) { >+ return false; >+ } >+ if (result.ptr != str.data() + str.size()) { >+ // not all non-whitespace characters consumed >+ return false; >+ } >+ // from_chars() with DR 3801's current wording will return max() on >+ // overflow. SimpleAtod returns infinity instead. >+ if (result.ec == std::errc::result_out_of_range) { >+ if (*value > 1.0) { >+ *value = std::numeric_limits<double>::infinity(); >+ } else if (*value < -1.0) { >+ *value = -std::numeric_limits<double>::infinity(); >+ } >+ } >+ return true; >+} >+ >+namespace { >+ >+// TODO(rogeeff): replace with the real released thing once we figure out what >+// it is. >+inline bool CaseEqual(absl::string_view piece1, absl::string_view piece2) { >+ return (piece1.size() == piece2.size() && >+ 0 == strings_internal::memcasecmp(piece1.data(), piece2.data(), >+ piece1.size())); >+} >+ >+// Writes a two-character representation of 'i' to 'buf'. 'i' must be in the >+// range 0 <= i < 100, and buf must have space for two characters. Example: >+// char buf[2]; >+// PutTwoDigits(42, buf); >+// // buf[0] == '4' >+// // buf[1] == '2' >+inline void PutTwoDigits(size_t i, char* buf) { >+ static const char two_ASCII_digits[100][2] = { >+ {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, >+ {'0', '5'}, {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, >+ {'1', '0'}, {'1', '1'}, {'1', '2'}, {'1', '3'}, {'1', '4'}, >+ {'1', '5'}, {'1', '6'}, {'1', '7'}, {'1', '8'}, {'1', '9'}, >+ {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'}, {'2', '4'}, >+ {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'}, >+ {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, >+ {'3', '5'}, {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, >+ {'4', '0'}, {'4', '1'}, {'4', '2'}, {'4', '3'}, {'4', '4'}, >+ {'4', '5'}, {'4', '6'}, {'4', '7'}, {'4', '8'}, {'4', '9'}, >+ {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'}, {'5', '4'}, >+ {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'}, >+ {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, >+ {'6', '5'}, {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, >+ {'7', '0'}, {'7', '1'}, {'7', '2'}, {'7', '3'}, {'7', '4'}, >+ {'7', '5'}, {'7', '6'}, {'7', '7'}, {'7', '8'}, {'7', '9'}, >+ {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'}, {'8', '4'}, >+ {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'}, >+ {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, >+ {'9', '5'}, {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'} >+ }; >+ assert(i < 100); >+ memcpy(buf, two_ASCII_digits[i], 2); >+} >+ >+} // namespace >+ >+bool SimpleAtob(absl::string_view str, bool* value) { >+ ABSL_RAW_CHECK(value != nullptr, "Output pointer must not be nullptr."); >+ if (CaseEqual(str, "true") || CaseEqual(str, "t") || >+ CaseEqual(str, "yes") || CaseEqual(str, "y") || >+ CaseEqual(str, "1")) { >+ *value = true; >+ return true; >+ } >+ if (CaseEqual(str, "false") || CaseEqual(str, "f") || >+ CaseEqual(str, "no") || CaseEqual(str, "n") || >+ CaseEqual(str, "0")) { >+ *value = false; >+ return true; >+ } >+ return false; >+} >+ >+// ---------------------------------------------------------------------- >+// FastIntToBuffer() overloads >+// >+// Like the Fast*ToBuffer() functions above, these are intended for speed. >+// Unlike the Fast*ToBuffer() functions, however, these functions write >+// their output to the beginning of the buffer. The caller is responsible >+// for ensuring that the buffer has enough space to hold the output. >+// >+// Returns a pointer to the end of the std::string (i.e. the null character >+// terminating the std::string). >+// ---------------------------------------------------------------------- >+ >+namespace { >+ >+// Used to optimize printing a decimal number's final digit. >+const char one_ASCII_final_digits[10][2] { >+ {'0', 0}, {'1', 0}, {'2', 0}, {'3', 0}, {'4', 0}, >+ {'5', 0}, {'6', 0}, {'7', 0}, {'8', 0}, {'9', 0}, >+}; >+ >+} // namespace >+ >+char* numbers_internal::FastIntToBuffer(uint32_t i, char* buffer) { >+ uint32_t digits; >+ // The idea of this implementation is to trim the number of divides to as few >+ // as possible, and also reducing memory stores and branches, by going in >+ // steps of two digits at a time rather than one whenever possible. >+ // The huge-number case is first, in the hopes that the compiler will output >+ // that case in one branch-free block of code, and only output conditional >+ // branches into it from below. >+ if (i >= 1000000000) { // >= 1,000,000,000 >+ digits = i / 100000000; // 100,000,000 >+ i -= digits * 100000000; >+ PutTwoDigits(digits, buffer); >+ buffer += 2; >+ lt100_000_000: >+ digits = i / 1000000; // 1,000,000 >+ i -= digits * 1000000; >+ PutTwoDigits(digits, buffer); >+ buffer += 2; >+ lt1_000_000: >+ digits = i / 10000; // 10,000 >+ i -= digits * 10000; >+ PutTwoDigits(digits, buffer); >+ buffer += 2; >+ lt10_000: >+ digits = i / 100; >+ i -= digits * 100; >+ PutTwoDigits(digits, buffer); >+ buffer += 2; >+ lt100: >+ digits = i; >+ PutTwoDigits(digits, buffer); >+ buffer += 2; >+ *buffer = 0; >+ return buffer; >+ } >+ >+ if (i < 100) { >+ digits = i; >+ if (i >= 10) goto lt100; >+ memcpy(buffer, one_ASCII_final_digits[i], 2); >+ return buffer + 1; >+ } >+ if (i < 10000) { // 10,000 >+ if (i >= 1000) goto lt10_000; >+ digits = i / 100; >+ i -= digits * 100; >+ *buffer++ = '0' + digits; >+ goto lt100; >+ } >+ if (i < 1000000) { // 1,000,000 >+ if (i >= 100000) goto lt1_000_000; >+ digits = i / 10000; // 10,000 >+ i -= digits * 10000; >+ *buffer++ = '0' + digits; >+ goto lt10_000; >+ } >+ if (i < 100000000) { // 100,000,000 >+ if (i >= 10000000) goto lt100_000_000; >+ digits = i / 1000000; // 1,000,000 >+ i -= digits * 1000000; >+ *buffer++ = '0' + digits; >+ goto lt1_000_000; >+ } >+ // we already know that i < 1,000,000,000 >+ digits = i / 100000000; // 100,000,000 >+ i -= digits * 100000000; >+ *buffer++ = '0' + digits; >+ goto lt100_000_000; >+} >+ >+char* numbers_internal::FastIntToBuffer(int32_t i, char* buffer) { >+ uint32_t u = i; >+ if (i < 0) { >+ *buffer++ = '-'; >+ // We need to do the negation in modular (i.e., "unsigned") >+ // arithmetic; MSVC++ apprently warns for plain "-u", so >+ // we write the equivalent expression "0 - u" instead. >+ u = 0 - u; >+ } >+ return numbers_internal::FastIntToBuffer(u, buffer); >+} >+ >+char* numbers_internal::FastIntToBuffer(uint64_t i, char* buffer) { >+ uint32_t u32 = static_cast<uint32_t>(i); >+ if (u32 == i) return numbers_internal::FastIntToBuffer(u32, buffer); >+ >+ // Here we know i has at least 10 decimal digits. >+ uint64_t top_1to11 = i / 1000000000; >+ u32 = static_cast<uint32_t>(i - top_1to11 * 1000000000); >+ uint32_t top_1to11_32 = static_cast<uint32_t>(top_1to11); >+ >+ if (top_1to11_32 == top_1to11) { >+ buffer = numbers_internal::FastIntToBuffer(top_1to11_32, buffer); >+ } else { >+ // top_1to11 has more than 32 bits too; print it in two steps. >+ uint32_t top_8to9 = static_cast<uint32_t>(top_1to11 / 100); >+ uint32_t mid_2 = static_cast<uint32_t>(top_1to11 - top_8to9 * 100); >+ buffer = numbers_internal::FastIntToBuffer(top_8to9, buffer); >+ PutTwoDigits(mid_2, buffer); >+ buffer += 2; >+ } >+ >+ // We have only 9 digits now, again the maximum uint32_t can handle fully. >+ uint32_t digits = u32 / 10000000; // 10,000,000 >+ u32 -= digits * 10000000; >+ PutTwoDigits(digits, buffer); >+ buffer += 2; >+ digits = u32 / 100000; // 100,000 >+ u32 -= digits * 100000; >+ PutTwoDigits(digits, buffer); >+ buffer += 2; >+ digits = u32 / 1000; // 1,000 >+ u32 -= digits * 1000; >+ PutTwoDigits(digits, buffer); >+ buffer += 2; >+ digits = u32 / 10; >+ u32 -= digits * 10; >+ PutTwoDigits(digits, buffer); >+ buffer += 2; >+ memcpy(buffer, one_ASCII_final_digits[u32], 2); >+ return buffer + 1; >+} >+ >+char* numbers_internal::FastIntToBuffer(int64_t i, char* buffer) { >+ uint64_t u = i; >+ if (i < 0) { >+ *buffer++ = '-'; >+ u = 0 - u; >+ } >+ return numbers_internal::FastIntToBuffer(u, buffer); >+} >+ >+// Given a 128-bit number expressed as a pair of uint64_t, high half first, >+// return that number multiplied by the given 32-bit value. If the result is >+// too large to fit in a 128-bit number, divide it by 2 until it fits. >+static std::pair<uint64_t, uint64_t> Mul32(std::pair<uint64_t, uint64_t> num, >+ uint32_t mul) { >+ uint64_t bits0_31 = num.second & 0xFFFFFFFF; >+ uint64_t bits32_63 = num.second >> 32; >+ uint64_t bits64_95 = num.first & 0xFFFFFFFF; >+ uint64_t bits96_127 = num.first >> 32; >+ >+ // The picture so far: each of these 64-bit values has only the lower 32 bits >+ // filled in. >+ // bits96_127: [ 00000000 xxxxxxxx ] >+ // bits64_95: [ 00000000 xxxxxxxx ] >+ // bits32_63: [ 00000000 xxxxxxxx ] >+ // bits0_31: [ 00000000 xxxxxxxx ] >+ >+ bits0_31 *= mul; >+ bits32_63 *= mul; >+ bits64_95 *= mul; >+ bits96_127 *= mul; >+ >+ // Now the top halves may also have value, though all 64 of their bits will >+ // never be set at the same time, since they are a result of a 32x32 bit >+ // multiply. This makes the carry calculation slightly easier. >+ // bits96_127: [ mmmmmmmm | mmmmmmmm ] >+ // bits64_95: [ | mmmmmmmm mmmmmmmm | ] >+ // bits32_63: | [ mmmmmmmm | mmmmmmmm ] >+ // bits0_31: | [ | mmmmmmmm mmmmmmmm ] >+ // eventually: [ bits128_up | ...bits64_127.... | ..bits0_63... ] >+ >+ uint64_t bits0_63 = bits0_31 + (bits32_63 << 32); >+ uint64_t bits64_127 = bits64_95 + (bits96_127 << 32) + (bits32_63 >> 32) + >+ (bits0_63 < bits0_31); >+ uint64_t bits128_up = (bits96_127 >> 32) + (bits64_127 < bits64_95); >+ if (bits128_up == 0) return {bits64_127, bits0_63}; >+ >+ int shift = 64 - strings_internal::CountLeadingZeros64(bits128_up); >+ uint64_t lo = (bits0_63 >> shift) + (bits64_127 << (64 - shift)); >+ uint64_t hi = (bits64_127 >> shift) + (bits128_up << (64 - shift)); >+ return {hi, lo}; >+} >+ >+// Compute num * 5 ^ expfive, and return the first 128 bits of the result, >+// where the first bit is always a one. So PowFive(1, 0) starts 0b100000, >+// PowFive(1, 1) starts 0b101000, PowFive(1, 2) starts 0b110010, etc. >+static std::pair<uint64_t, uint64_t> PowFive(uint64_t num, int expfive) { >+ std::pair<uint64_t, uint64_t> result = {num, 0}; >+ while (expfive >= 13) { >+ // 5^13 is the highest power of five that will fit in a 32-bit integer. >+ result = Mul32(result, 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5); >+ expfive -= 13; >+ } >+ constexpr int powers_of_five[13] = { >+ 1, >+ 5, >+ 5 * 5, >+ 5 * 5 * 5, >+ 5 * 5 * 5 * 5, >+ 5 * 5 * 5 * 5 * 5, >+ 5 * 5 * 5 * 5 * 5 * 5, >+ 5 * 5 * 5 * 5 * 5 * 5 * 5, >+ 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, >+ 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, >+ 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, >+ 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, >+ 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5}; >+ result = Mul32(result, powers_of_five[expfive & 15]); >+ int shift = strings_internal::CountLeadingZeros64(result.first); >+ if (shift != 0) { >+ result.first = (result.first << shift) + (result.second >> (64 - shift)); >+ result.second = (result.second << shift); >+ } >+ return result; >+} >+ >+struct ExpDigits { >+ int32_t exponent; >+ char digits[6]; >+}; >+ >+// SplitToSix converts value, a positive double-precision floating-point number, >+// into a base-10 exponent and 6 ASCII digits, where the first digit is never >+// zero. For example, SplitToSix(1) returns an exponent of zero and a digits >+// array of {'1', '0', '0', '0', '0', '0'}. If value is exactly halfway between >+// two possible representations, e.g. value = 100000.5, then "round to even" is >+// performed. >+static ExpDigits SplitToSix(const double value) { >+ ExpDigits exp_dig; >+ int exp = 5; >+ double d = value; >+ // First step: calculate a close approximation of the output, where the >+ // value d will be between 100,000 and 999,999, representing the digits >+ // in the output ASCII array, and exp is the base-10 exponent. It would be >+ // faster to use a table here, and to look up the base-2 exponent of value, >+ // however value is an IEEE-754 64-bit number, so the table would have 2,000 >+ // entries, which is not cache-friendly. >+ if (d >= 999999.5) { >+ if (d >= 1e+261) exp += 256, d *= 1e-256; >+ if (d >= 1e+133) exp += 128, d *= 1e-128; >+ if (d >= 1e+69) exp += 64, d *= 1e-64; >+ if (d >= 1e+37) exp += 32, d *= 1e-32; >+ if (d >= 1e+21) exp += 16, d *= 1e-16; >+ if (d >= 1e+13) exp += 8, d *= 1e-8; >+ if (d >= 1e+9) exp += 4, d *= 1e-4; >+ if (d >= 1e+7) exp += 2, d *= 1e-2; >+ if (d >= 1e+6) exp += 1, d *= 1e-1; >+ } else { >+ if (d < 1e-250) exp -= 256, d *= 1e256; >+ if (d < 1e-122) exp -= 128, d *= 1e128; >+ if (d < 1e-58) exp -= 64, d *= 1e64; >+ if (d < 1e-26) exp -= 32, d *= 1e32; >+ if (d < 1e-10) exp -= 16, d *= 1e16; >+ if (d < 1e-2) exp -= 8, d *= 1e8; >+ if (d < 1e+2) exp -= 4, d *= 1e4; >+ if (d < 1e+4) exp -= 2, d *= 1e2; >+ if (d < 1e+5) exp -= 1, d *= 1e1; >+ } >+ // At this point, d is in the range [99999.5..999999.5) and exp is in the >+ // range [-324..308]. Since we need to round d up, we want to add a half >+ // and truncate. >+ // However, the technique above may have lost some precision, due to its >+ // repeated multiplication by constants that each may be off by half a bit >+ // of precision. This only matters if we're close to the edge though. >+ // Since we'd like to know if the fractional part of d is close to a half, >+ // we multiply it by 65536 and see if the fractional part is close to 32768. >+ // (The number doesn't have to be a power of two,but powers of two are faster) >+ uint64_t d64k = d * 65536; >+ int dddddd; // A 6-digit decimal integer. >+ if ((d64k % 65536) == 32767 || (d64k % 65536) == 32768) { >+ // OK, it's fairly likely that precision was lost above, which is >+ // not a surprise given only 52 mantissa bits are available. Therefore >+ // redo the calculation using 128-bit numbers. (64 bits are not enough). >+ >+ // Start out with digits rounded down; maybe add one below. >+ dddddd = static_cast<int>(d64k / 65536); >+ >+ // mantissa is a 64-bit integer representing M.mmm... * 2^63. The actual >+ // value we're representing, of course, is M.mmm... * 2^exp2. >+ int exp2; >+ double m = std::frexp(value, &exp2); >+ uint64_t mantissa = m * (32768.0 * 65536.0 * 65536.0 * 65536.0); >+ // std::frexp returns an m value in the range [0.5, 1.0), however we >+ // can't multiply it by 2^64 and convert to an integer because some FPUs >+ // throw an exception when converting an number higher than 2^63 into an >+ // integer - even an unsigned 64-bit integer! Fortunately it doesn't matter >+ // since m only has 52 significant bits anyway. >+ mantissa <<= 1; >+ exp2 -= 64; // not needed, but nice for debugging >+ >+ // OK, we are here to compare: >+ // (dddddd + 0.5) * 10^(exp-5) vs. mantissa * 2^exp2 >+ // so we can round up dddddd if appropriate. Those values span the full >+ // range of 600 orders of magnitude of IEE 64-bit floating-point. >+ // Fortunately, we already know they are very close, so we don't need to >+ // track the base-2 exponent of both sides. This greatly simplifies the >+ // the math since the 2^exp2 calculation is unnecessary and the power-of-10 >+ // calculation can become a power-of-5 instead. >+ >+ std::pair<uint64_t, uint64_t> edge, val; >+ if (exp >= 6) { >+ // Compare (dddddd + 0.5) * 5 ^ (exp - 5) to mantissa >+ // Since we're tossing powers of two, 2 * dddddd + 1 is the >+ // same as dddddd + 0.5 >+ edge = PowFive(2 * dddddd + 1, exp - 5); >+ >+ val.first = mantissa; >+ val.second = 0; >+ } else { >+ // We can't compare (dddddd + 0.5) * 5 ^ (exp - 5) to mantissa as we did >+ // above because (exp - 5) is negative. So we compare (dddddd + 0.5) to >+ // mantissa * 5 ^ (5 - exp) >+ edge = PowFive(2 * dddddd + 1, 0); >+ >+ val = PowFive(mantissa, 5 - exp); >+ } >+ // printf("exp=%d %016lx %016lx vs %016lx %016lx\n", exp, val.first, >+ // val.second, edge.first, edge.second); >+ if (val > edge) { >+ dddddd++; >+ } else if (val == edge) { >+ dddddd += (dddddd & 1); >+ } >+ } else { >+ // Here, we are not close to the edge. >+ dddddd = static_cast<int>((d64k + 32768) / 65536); >+ } >+ if (dddddd == 1000000) { >+ dddddd = 100000; >+ exp += 1; >+ } >+ exp_dig.exponent = exp; >+ >+ int two_digits = dddddd / 10000; >+ dddddd -= two_digits * 10000; >+ PutTwoDigits(two_digits, &exp_dig.digits[0]); >+ >+ two_digits = dddddd / 100; >+ dddddd -= two_digits * 100; >+ PutTwoDigits(two_digits, &exp_dig.digits[2]); >+ >+ PutTwoDigits(dddddd, &exp_dig.digits[4]); >+ return exp_dig; >+} >+ >+// Helper function for fast formatting of floating-point. >+// The result is the same as "%g", a.k.a. "%.6g". >+size_t numbers_internal::SixDigitsToBuffer(double d, char* const buffer) { >+ static_assert(std::numeric_limits<float>::is_iec559, >+ "IEEE-754/IEC-559 support only"); >+ >+ char* out = buffer; // we write data to out, incrementing as we go, but >+ // FloatToBuffer always returns the address of the buffer >+ // passed in. >+ >+ if (std::isnan(d)) { >+ strcpy(out, "nan"); // NOLINT(runtime/printf) >+ return 3; >+ } >+ if (d == 0) { // +0 and -0 are handled here >+ if (std::signbit(d)) *out++ = '-'; >+ *out++ = '0'; >+ *out = 0; >+ return out - buffer; >+ } >+ if (d < 0) { >+ *out++ = '-'; >+ d = -d; >+ } >+ if (std::isinf(d)) { >+ strcpy(out, "inf"); // NOLINT(runtime/printf) >+ return out + 3 - buffer; >+ } >+ >+ auto exp_dig = SplitToSix(d); >+ int exp = exp_dig.exponent; >+ const char* digits = exp_dig.digits; >+ out[0] = '0'; >+ out[1] = '.'; >+ switch (exp) { >+ case 5: >+ memcpy(out, &digits[0], 6), out += 6; >+ *out = 0; >+ return out - buffer; >+ case 4: >+ memcpy(out, &digits[0], 5), out += 5; >+ if (digits[5] != '0') { >+ *out++ = '.'; >+ *out++ = digits[5]; >+ } >+ *out = 0; >+ return out - buffer; >+ case 3: >+ memcpy(out, &digits[0], 4), out += 4; >+ if ((digits[5] | digits[4]) != '0') { >+ *out++ = '.'; >+ *out++ = digits[4]; >+ if (digits[5] != '0') *out++ = digits[5]; >+ } >+ *out = 0; >+ return out - buffer; >+ case 2: >+ memcpy(out, &digits[0], 3), out += 3; >+ *out++ = '.'; >+ memcpy(out, &digits[3], 3); >+ out += 3; >+ while (out[-1] == '0') --out; >+ if (out[-1] == '.') --out; >+ *out = 0; >+ return out - buffer; >+ case 1: >+ memcpy(out, &digits[0], 2), out += 2; >+ *out++ = '.'; >+ memcpy(out, &digits[2], 4); >+ out += 4; >+ while (out[-1] == '0') --out; >+ if (out[-1] == '.') --out; >+ *out = 0; >+ return out - buffer; >+ case 0: >+ memcpy(out, &digits[0], 1), out += 1; >+ *out++ = '.'; >+ memcpy(out, &digits[1], 5); >+ out += 5; >+ while (out[-1] == '0') --out; >+ if (out[-1] == '.') --out; >+ *out = 0; >+ return out - buffer; >+ case -4: >+ out[2] = '0'; >+ ++out; >+ ABSL_FALLTHROUGH_INTENDED; >+ case -3: >+ out[2] = '0'; >+ ++out; >+ ABSL_FALLTHROUGH_INTENDED; >+ case -2: >+ out[2] = '0'; >+ ++out; >+ ABSL_FALLTHROUGH_INTENDED; >+ case -1: >+ out += 2; >+ memcpy(out, &digits[0], 6); >+ out += 6; >+ while (out[-1] == '0') --out; >+ *out = 0; >+ return out - buffer; >+ } >+ assert(exp < -4 || exp >= 6); >+ out[0] = digits[0]; >+ assert(out[1] == '.'); >+ out += 2; >+ memcpy(out, &digits[1], 5), out += 5; >+ while (out[-1] == '0') --out; >+ if (out[-1] == '.') --out; >+ *out++ = 'e'; >+ if (exp > 0) { >+ *out++ = '+'; >+ } else { >+ *out++ = '-'; >+ exp = -exp; >+ } >+ if (exp > 99) { >+ int dig1 = exp / 100; >+ exp -= dig1 * 100; >+ *out++ = '0' + dig1; >+ } >+ PutTwoDigits(exp, out); >+ out += 2; >+ *out = 0; >+ return out - buffer; >+} >+ >+namespace { >+// Represents integer values of digits. >+// Uses 36 to indicate an invalid character since we support >+// bases up to 36. >+static const int8_t kAsciiToInt[256] = { >+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // 16 36s. >+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, >+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 0, 1, 2, 3, 4, 5, >+ 6, 7, 8, 9, 36, 36, 36, 36, 36, 36, 36, 10, 11, 12, 13, 14, 15, 16, 17, >+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, >+ 36, 36, 36, 36, 36, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, >+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36, 36, 36, >+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, >+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, >+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, >+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, >+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, >+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, >+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36}; >+ >+// Parse the sign and optional hex or oct prefix in text. >+inline bool safe_parse_sign_and_base(absl::string_view* text /*inout*/, >+ int* base_ptr /*inout*/, >+ bool* negative_ptr /*output*/) { >+ if (text->data() == nullptr) { >+ return false; >+ } >+ >+ const char* start = text->data(); >+ const char* end = start + text->size(); >+ int base = *base_ptr; >+ >+ // Consume whitespace. >+ while (start < end && absl::ascii_isspace(start[0])) { >+ ++start; >+ } >+ while (start < end && absl::ascii_isspace(end[-1])) { >+ --end; >+ } >+ if (start >= end) { >+ return false; >+ } >+ >+ // Consume sign. >+ *negative_ptr = (start[0] == '-'); >+ if (*negative_ptr || start[0] == '+') { >+ ++start; >+ if (start >= end) { >+ return false; >+ } >+ } >+ >+ // Consume base-dependent prefix. >+ // base 0: "0x" -> base 16, "0" -> base 8, default -> base 10 >+ // base 16: "0x" -> base 16 >+ // Also validate the base. >+ if (base == 0) { >+ if (end - start >= 2 && start[0] == '0' && >+ (start[1] == 'x' || start[1] == 'X')) { >+ base = 16; >+ start += 2; >+ if (start >= end) { >+ // "0x" with no digits after is invalid. >+ return false; >+ } >+ } else if (end - start >= 1 && start[0] == '0') { >+ base = 8; >+ start += 1; >+ } else { >+ base = 10; >+ } >+ } else if (base == 16) { >+ if (end - start >= 2 && start[0] == '0' && >+ (start[1] == 'x' || start[1] == 'X')) { >+ start += 2; >+ if (start >= end) { >+ // "0x" with no digits after is invalid. >+ return false; >+ } >+ } >+ } else if (base >= 2 && base <= 36) { >+ // okay >+ } else { >+ return false; >+ } >+ *text = absl::string_view(start, end - start); >+ *base_ptr = base; >+ return true; >+} >+ >+// Consume digits. >+// >+// The classic loop: >+// >+// for each digit >+// value = value * base + digit >+// value *= sign >+// >+// The classic loop needs overflow checking. It also fails on the most >+// negative integer, -2147483648 in 32-bit two's complement representation. >+// >+// My improved loop: >+// >+// if (!negative) >+// for each digit >+// value = value * base >+// value = value + digit >+// else >+// for each digit >+// value = value * base >+// value = value - digit >+// >+// Overflow checking becomes simple. >+ >+// Lookup tables per IntType: >+// vmax/base and vmin/base are precomputed because division costs at least 8ns. >+// TODO(junyer): Doing this per base instead (i.e. an array of structs, not a >+// struct of arrays) would probably be better in terms of d-cache for the most >+// commonly used bases. >+template <typename IntType> >+struct LookupTables { >+ static const IntType kVmaxOverBase[]; >+ static const IntType kVminOverBase[]; >+}; >+ >+// An array initializer macro for X/base where base in [0, 36]. >+// However, note that lookups for base in [0, 1] should never happen because >+// base has been validated to be in [2, 36] by safe_parse_sign_and_base(). >+#define X_OVER_BASE_INITIALIZER(X) \ >+ { \ >+ 0, 0, X / 2, X / 3, X / 4, X / 5, X / 6, X / 7, X / 8, X / 9, X / 10, \ >+ X / 11, X / 12, X / 13, X / 14, X / 15, X / 16, X / 17, X / 18, \ >+ X / 19, X / 20, X / 21, X / 22, X / 23, X / 24, X / 25, X / 26, \ >+ X / 27, X / 28, X / 29, X / 30, X / 31, X / 32, X / 33, X / 34, \ >+ X / 35, X / 36, \ >+ } >+ >+template <typename IntType> >+const IntType LookupTables<IntType>::kVmaxOverBase[] = >+ X_OVER_BASE_INITIALIZER(std::numeric_limits<IntType>::max()); >+ >+template <typename IntType> >+const IntType LookupTables<IntType>::kVminOverBase[] = >+ X_OVER_BASE_INITIALIZER(std::numeric_limits<IntType>::min()); >+ >+#undef X_OVER_BASE_INITIALIZER >+ >+template <typename IntType> >+inline bool safe_parse_positive_int(absl::string_view text, int base, >+ IntType* value_p) { >+ IntType value = 0; >+ const IntType vmax = std::numeric_limits<IntType>::max(); >+ assert(vmax > 0); >+ assert(base >= 0); >+ assert(vmax >= static_cast<IntType>(base)); >+ const IntType vmax_over_base = LookupTables<IntType>::kVmaxOverBase[base]; >+ const char* start = text.data(); >+ const char* end = start + text.size(); >+ // loop over digits >+ for (; start < end; ++start) { >+ unsigned char c = static_cast<unsigned char>(start[0]); >+ int digit = kAsciiToInt[c]; >+ if (digit >= base) { >+ *value_p = value; >+ return false; >+ } >+ if (value > vmax_over_base) { >+ *value_p = vmax; >+ return false; >+ } >+ value *= base; >+ if (value > vmax - digit) { >+ *value_p = vmax; >+ return false; >+ } >+ value += digit; >+ } >+ *value_p = value; >+ return true; >+} >+ >+template <typename IntType> >+inline bool safe_parse_negative_int(absl::string_view text, int base, >+ IntType* value_p) { >+ IntType value = 0; >+ const IntType vmin = std::numeric_limits<IntType>::min(); >+ assert(vmin < 0); >+ assert(vmin <= 0 - base); >+ IntType vmin_over_base = LookupTables<IntType>::kVminOverBase[base]; >+ // 2003 c++ standard [expr.mul] >+ // "... the sign of the remainder is implementation-defined." >+ // Although (vmin/base)*base + vmin%base is always vmin. >+ // 2011 c++ standard tightens the spec but we cannot rely on it. >+ // TODO(junyer): Handle this in the lookup table generation. >+ if (vmin % base > 0) { >+ vmin_over_base += 1; >+ } >+ const char* start = text.data(); >+ const char* end = start + text.size(); >+ // loop over digits >+ for (; start < end; ++start) { >+ unsigned char c = static_cast<unsigned char>(start[0]); >+ int digit = kAsciiToInt[c]; >+ if (digit >= base) { >+ *value_p = value; >+ return false; >+ } >+ if (value < vmin_over_base) { >+ *value_p = vmin; >+ return false; >+ } >+ value *= base; >+ if (value < vmin + digit) { >+ *value_p = vmin; >+ return false; >+ } >+ value -= digit; >+ } >+ *value_p = value; >+ return true; >+} >+ >+// Input format based on POSIX.1-2008 strtol >+// http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtol.html >+template <typename IntType> >+inline bool safe_int_internal(absl::string_view text, IntType* value_p, >+ int base) { >+ *value_p = 0; >+ bool negative; >+ if (!safe_parse_sign_and_base(&text, &base, &negative)) { >+ return false; >+ } >+ if (!negative) { >+ return safe_parse_positive_int(text, base, value_p); >+ } else { >+ return safe_parse_negative_int(text, base, value_p); >+ } >+} >+ >+template <typename IntType> >+inline bool safe_uint_internal(absl::string_view text, IntType* value_p, >+ int base) { >+ *value_p = 0; >+ bool negative; >+ if (!safe_parse_sign_and_base(&text, &base, &negative) || negative) { >+ return false; >+ } >+ return safe_parse_positive_int(text, base, value_p); >+} >+} // anonymous namespace >+ >+namespace numbers_internal { >+bool safe_strto32_base(absl::string_view text, int32_t* value, int base) { >+ return safe_int_internal<int32_t>(text, value, base); >+} >+ >+bool safe_strto64_base(absl::string_view text, int64_t* value, int base) { >+ return safe_int_internal<int64_t>(text, value, base); >+} >+ >+bool safe_strtou32_base(absl::string_view text, uint32_t* value, int base) { >+ return safe_uint_internal<uint32_t>(text, value, base); >+} >+ >+bool safe_strtou64_base(absl::string_view text, uint64_t* value, int base) { >+ return safe_uint_internal<uint64_t>(text, value, base); >+} >+} // namespace numbers_internal >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers.h >new file mode 100644 >index 0000000000000000000000000000000000000000..cf3c597266cf71474d405dd0cfdea5cdeb58badc >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers.h >@@ -0,0 +1,184 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: numbers.h >+// ----------------------------------------------------------------------------- >+// >+// This package contains functions for converting strings to numbers. For >+// converting numbers to strings, use `StrCat()` or `StrAppend()` in str_cat.h, >+// which automatically detect and convert most number values appropriately. >+ >+#ifndef ABSL_STRINGS_NUMBERS_H_ >+#define ABSL_STRINGS_NUMBERS_H_ >+ >+#include <cstddef> >+#include <cstdlib> >+#include <cstring> >+#include <ctime> >+#include <limits> >+#include <string> >+#include <type_traits> >+ >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+#include "absl/numeric/int128.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+ >+// SimpleAtoi() >+// >+// Converts the given std::string into an integer value, returning `true` if >+// successful. The std::string must reflect a base-10 integer (optionally followed or >+// preceded by ASCII whitespace) whose value falls within the range of the >+// integer type, >+template <typename int_type> >+ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out); >+ >+// SimpleAtof() >+// >+// Converts the given std::string (optionally followed or preceded by ASCII >+// whitespace) into a float, which may be rounded on overflow or underflow. >+// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the >+// allowed formats for `str`. >+ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* value); >+ >+// SimpleAtod() >+// >+// Converts the given std::string (optionally followed or preceded by ASCII >+// whitespace) into a double, which may be rounded on overflow or underflow. >+// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the >+// allowed formats for `str`. >+ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* value); >+ >+// SimpleAtob() >+// >+// Converts the given std::string into a boolean, returning `true` if successful. >+// The following case-insensitive strings are interpreted as boolean `true`: >+// "true", "t", "yes", "y", "1". The following case-insensitive strings >+// are interpreted as boolean `false`: "false", "f", "no", "n", "0". >+ABSL_MUST_USE_RESULT bool SimpleAtob(absl::string_view str, bool* value); >+ >+} // namespace absl >+ >+// End of public API. Implementation details follow. >+ >+namespace absl { >+namespace numbers_internal { >+ >+// safe_strto?() functions for implementing SimpleAtoi() >+bool safe_strto32_base(absl::string_view text, int32_t* value, int base); >+bool safe_strto64_base(absl::string_view text, int64_t* value, int base); >+bool safe_strtou32_base(absl::string_view text, uint32_t* value, int base); >+bool safe_strtou64_base(absl::string_view text, uint64_t* value, int base); >+ >+static const int kFastToBufferSize = 32; >+static const int kSixDigitsToBufferSize = 16; >+ >+// Helper function for fast formatting of floating-point values. >+// The result is the same as printf's "%g", a.k.a. "%.6g"; that is, six >+// significant digits are returned, trailing zeros are removed, and numbers >+// outside the range 0.0001-999999 are output using scientific notation >+// (1.23456e+06). This routine is heavily optimized. >+// Required buffer size is `kSixDigitsToBufferSize`. >+size_t SixDigitsToBuffer(double d, char* buffer); >+ >+// These functions are intended for speed. All functions take an output buffer >+// as an argument and return a pointer to the last byte they wrote, which is the >+// terminating '\0'. At most `kFastToBufferSize` bytes are written. >+char* FastIntToBuffer(int32_t, char*); >+char* FastIntToBuffer(uint32_t, char*); >+char* FastIntToBuffer(int64_t, char*); >+char* FastIntToBuffer(uint64_t, char*); >+ >+// For enums and integer types that are not an exact match for the types above, >+// use templates to call the appropriate one of the four overloads above. >+template <typename int_type> >+char* FastIntToBuffer(int_type i, char* buffer) { >+ static_assert(sizeof(i) <= 64 / 8, >+ "FastIntToBuffer works only with 64-bit-or-less integers."); >+ // TODO(jorg): This signed-ness check is used because it works correctly >+ // with enums, and it also serves to check that int_type is not a pointer. >+ // If one day something like std::is_signed<enum E> works, switch to it. >+ if (static_cast<int_type>(1) - 2 < 0) { // Signed >+ if (sizeof(i) > 32 / 8) { // 33-bit to 64-bit >+ return FastIntToBuffer(static_cast<int64_t>(i), buffer); >+ } else { // 32-bit or less >+ return FastIntToBuffer(static_cast<int32_t>(i), buffer); >+ } >+ } else { // Unsigned >+ if (sizeof(i) > 32 / 8) { // 33-bit to 64-bit >+ return FastIntToBuffer(static_cast<uint64_t>(i), buffer); >+ } else { // 32-bit or less >+ return FastIntToBuffer(static_cast<uint32_t>(i), buffer); >+ } >+ } >+} >+ >+// Implementation of SimpleAtoi, generalized to support arbitrary base (used >+// with base different from 10 elsewhere in Abseil implementation). >+template <typename int_type> >+ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type* out, >+ int base) { >+ static_assert(sizeof(*out) == 4 || sizeof(*out) == 8, >+ "SimpleAtoi works only with 32-bit or 64-bit integers."); >+ static_assert(!std::is_floating_point<int_type>::value, >+ "Use SimpleAtof or SimpleAtod instead."); >+ bool parsed; >+ // TODO(jorg): This signed-ness check is used because it works correctly >+ // with enums, and it also serves to check that int_type is not a pointer. >+ // If one day something like std::is_signed<enum E> works, switch to it. >+ if (static_cast<int_type>(1) - 2 < 0) { // Signed >+ if (sizeof(*out) == 64 / 8) { // 64-bit >+ int64_t val; >+ parsed = numbers_internal::safe_strto64_base(s, &val, base); >+ *out = static_cast<int_type>(val); >+ } else { // 32-bit >+ int32_t val; >+ parsed = numbers_internal::safe_strto32_base(s, &val, base); >+ *out = static_cast<int_type>(val); >+ } >+ } else { // Unsigned >+ if (sizeof(*out) == 64 / 8) { // 64-bit >+ uint64_t val; >+ parsed = numbers_internal::safe_strtou64_base(s, &val, base); >+ *out = static_cast<int_type>(val); >+ } else { // 32-bit >+ uint32_t val; >+ parsed = numbers_internal::safe_strtou32_base(s, &val, base); >+ *out = static_cast<int_type>(val); >+ } >+ } >+ return parsed; >+} >+ >+} // namespace numbers_internal >+ >+// SimpleAtoi() >+// >+// Converts a std::string to an integer, using `safe_strto?()` functions for actual >+// parsing, returning `true` if successful. The `safe_strto?()` functions apply >+// strict checking; the std::string must be a base-10 integer, optionally followed or >+// preceded by ASCII whitespace, with a value in the range of the corresponding >+// integer type. >+template <typename int_type> >+ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out) { >+ return numbers_internal::safe_strtoi_base(s, out, 10); >+} >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_NUMBERS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..8ef650b9a3eccdd79664dc79d2d6f261a6686a32 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers_benchmark.cc >@@ -0,0 +1,263 @@ >+// 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 <cstdint> >+#include <random> >+#include <string> >+#include <type_traits> >+#include <vector> >+ >+#include "benchmark/benchmark.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/strings/numbers.h" >+ >+namespace { >+ >+template <typename T> >+void BM_FastIntToBuffer(benchmark::State& state) { >+ const int inc = state.range(0); >+ char buf[absl::numbers_internal::kFastToBufferSize]; >+ // Use the unsigned type to increment to take advantage of well-defined >+ // modular arithmetic. >+ typename std::make_unsigned<T>::type x = 0; >+ for (auto _ : state) { >+ absl::numbers_internal::FastIntToBuffer(static_cast<T>(x), buf); >+ x += inc; >+ } >+} >+BENCHMARK_TEMPLATE(BM_FastIntToBuffer, int32_t)->Range(0, 1 << 15); >+BENCHMARK_TEMPLATE(BM_FastIntToBuffer, int64_t)->Range(0, 1 << 30); >+ >+// Creates an integer that would be printed as `num_digits` repeated 7s in the >+// given `base`. `base` must be greater than or equal to 8. >+int64_t RepeatedSevens(int num_digits, int base) { >+ ABSL_RAW_CHECK(base >= 8, ""); >+ int64_t num = 7; >+ while (--num_digits) num = base * num + 7; >+ return num; >+} >+ >+void BM_safe_strto32_string(benchmark::State& state) { >+ const int digits = state.range(0); >+ const int base = state.range(1); >+ std::string str(digits, '7'); // valid in octal, decimal and hex >+ int32_t value = 0; >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::numbers_internal::safe_strto32_base(str, &value, base)); >+ } >+ ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), ""); >+} >+BENCHMARK(BM_safe_strto32_string) >+ ->ArgPair(1, 8) >+ ->ArgPair(1, 10) >+ ->ArgPair(1, 16) >+ ->ArgPair(2, 8) >+ ->ArgPair(2, 10) >+ ->ArgPair(2, 16) >+ ->ArgPair(4, 8) >+ ->ArgPair(4, 10) >+ ->ArgPair(4, 16) >+ ->ArgPair(8, 8) >+ ->ArgPair(8, 10) >+ ->ArgPair(8, 16) >+ ->ArgPair(10, 8) >+ ->ArgPair(9, 10); >+ >+void BM_safe_strto64_string(benchmark::State& state) { >+ const int digits = state.range(0); >+ const int base = state.range(1); >+ std::string str(digits, '7'); // valid in octal, decimal and hex >+ int64_t value = 0; >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::numbers_internal::safe_strto64_base(str, &value, base)); >+ } >+ ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), ""); >+} >+BENCHMARK(BM_safe_strto64_string) >+ ->ArgPair(1, 8) >+ ->ArgPair(1, 10) >+ ->ArgPair(1, 16) >+ ->ArgPair(2, 8) >+ ->ArgPair(2, 10) >+ ->ArgPair(2, 16) >+ ->ArgPair(4, 8) >+ ->ArgPair(4, 10) >+ ->ArgPair(4, 16) >+ ->ArgPair(8, 8) >+ ->ArgPair(8, 10) >+ ->ArgPair(8, 16) >+ ->ArgPair(16, 8) >+ ->ArgPair(16, 10) >+ ->ArgPair(16, 16); >+ >+void BM_safe_strtou32_string(benchmark::State& state) { >+ const int digits = state.range(0); >+ const int base = state.range(1); >+ std::string str(digits, '7'); // valid in octal, decimal and hex >+ uint32_t value = 0; >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::numbers_internal::safe_strtou32_base(str, &value, base)); >+ } >+ ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), ""); >+} >+BENCHMARK(BM_safe_strtou32_string) >+ ->ArgPair(1, 8) >+ ->ArgPair(1, 10) >+ ->ArgPair(1, 16) >+ ->ArgPair(2, 8) >+ ->ArgPair(2, 10) >+ ->ArgPair(2, 16) >+ ->ArgPair(4, 8) >+ ->ArgPair(4, 10) >+ ->ArgPair(4, 16) >+ ->ArgPair(8, 8) >+ ->ArgPair(8, 10) >+ ->ArgPair(8, 16) >+ ->ArgPair(10, 8) >+ ->ArgPair(9, 10); >+ >+void BM_safe_strtou64_string(benchmark::State& state) { >+ const int digits = state.range(0); >+ const int base = state.range(1); >+ std::string str(digits, '7'); // valid in octal, decimal and hex >+ uint64_t value = 0; >+ for (auto _ : state) { >+ benchmark::DoNotOptimize( >+ absl::numbers_internal::safe_strtou64_base(str, &value, base)); >+ } >+ ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), ""); >+} >+BENCHMARK(BM_safe_strtou64_string) >+ ->ArgPair(1, 8) >+ ->ArgPair(1, 10) >+ ->ArgPair(1, 16) >+ ->ArgPair(2, 8) >+ ->ArgPair(2, 10) >+ ->ArgPair(2, 16) >+ ->ArgPair(4, 8) >+ ->ArgPair(4, 10) >+ ->ArgPair(4, 16) >+ ->ArgPair(8, 8) >+ ->ArgPair(8, 10) >+ ->ArgPair(8, 16) >+ ->ArgPair(16, 8) >+ ->ArgPair(16, 10) >+ ->ArgPair(16, 16); >+ >+// Returns a vector of `num_strings` strings. Each std::string represents a >+// floating point number with `num_digits` digits before the decimal point and >+// another `num_digits` digits after. >+std::vector<std::string> MakeFloatStrings(int num_strings, int num_digits) { >+ // For convenience, use a random number generator to generate the test data. >+ // We don't actually need random properties, so use a fixed seed. >+ std::minstd_rand0 rng(1); >+ std::uniform_int_distribution<int> random_digit('0', '9'); >+ >+ std::vector<std::string> float_strings(num_strings); >+ for (std::string& s : float_strings) { >+ s.reserve(2 * num_digits + 1); >+ for (int i = 0; i < num_digits; ++i) { >+ s.push_back(static_cast<char>(random_digit(rng))); >+ } >+ s.push_back('.'); >+ for (int i = 0; i < num_digits; ++i) { >+ s.push_back(static_cast<char>(random_digit(rng))); >+ } >+ } >+ return float_strings; >+} >+ >+template <typename StringType> >+StringType GetStringAs(const std::string& s) { >+ return static_cast<StringType>(s); >+} >+template <> >+const char* GetStringAs<const char*>(const std::string& s) { >+ return s.c_str(); >+} >+ >+template <typename StringType> >+std::vector<StringType> GetStringsAs(const std::vector<std::string>& strings) { >+ std::vector<StringType> result; >+ result.reserve(strings.size()); >+ for (const std::string& s : strings) { >+ result.push_back(GetStringAs<StringType>(s)); >+ } >+ return result; >+} >+ >+template <typename T> >+void BM_SimpleAtof(benchmark::State& state) { >+ const int num_strings = state.range(0); >+ const int num_digits = state.range(1); >+ std::vector<std::string> backing_strings = >+ MakeFloatStrings(num_strings, num_digits); >+ std::vector<T> inputs = GetStringsAs<T>(backing_strings); >+ float value; >+ for (auto _ : state) { >+ for (const T& input : inputs) { >+ benchmark::DoNotOptimize(absl::SimpleAtof(input, &value)); >+ } >+ } >+} >+BENCHMARK_TEMPLATE(BM_SimpleAtof, absl::string_view) >+ ->ArgPair(10, 1) >+ ->ArgPair(10, 2) >+ ->ArgPair(10, 4) >+ ->ArgPair(10, 8); >+BENCHMARK_TEMPLATE(BM_SimpleAtof, const char*) >+ ->ArgPair(10, 1) >+ ->ArgPair(10, 2) >+ ->ArgPair(10, 4) >+ ->ArgPair(10, 8); >+BENCHMARK_TEMPLATE(BM_SimpleAtof, std::string) >+ ->ArgPair(10, 1) >+ ->ArgPair(10, 2) >+ ->ArgPair(10, 4) >+ ->ArgPair(10, 8); >+ >+template <typename T> >+void BM_SimpleAtod(benchmark::State& state) { >+ const int num_strings = state.range(0); >+ const int num_digits = state.range(1); >+ std::vector<std::string> backing_strings = >+ MakeFloatStrings(num_strings, num_digits); >+ std::vector<T> inputs = GetStringsAs<T>(backing_strings); >+ double value; >+ for (auto _ : state) { >+ for (const T& input : inputs) { >+ benchmark::DoNotOptimize(absl::SimpleAtod(input, &value)); >+ } >+ } >+} >+BENCHMARK_TEMPLATE(BM_SimpleAtod, absl::string_view) >+ ->ArgPair(10, 1) >+ ->ArgPair(10, 2) >+ ->ArgPair(10, 4) >+ ->ArgPair(10, 8); >+BENCHMARK_TEMPLATE(BM_SimpleAtod, const char*) >+ ->ArgPair(10, 1) >+ ->ArgPair(10, 2) >+ ->ArgPair(10, 4) >+ ->ArgPair(10, 8); >+BENCHMARK_TEMPLATE(BM_SimpleAtod, std::string) >+ ->ArgPair(10, 1) >+ ->ArgPair(10, 2) >+ ->ArgPair(10, 4) >+ ->ArgPair(10, 8); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..27cc0479e3412c838b4785dfafb8895efe096f63 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/numbers_test.cc >@@ -0,0 +1,1185 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// This file tests std::string processing functions related to numeric values. >+ >+#include "absl/strings/numbers.h" >+ >+#include <sys/types.h> >+#include <cfenv> // NOLINT(build/c++11) >+#include <cinttypes> >+#include <climits> >+#include <cmath> >+#include <cstddef> >+#include <cstdint> >+#include <cstdio> >+#include <cstdlib> >+#include <cstring> >+#include <limits> >+#include <numeric> >+#include <random> >+#include <set> >+#include <string> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/strings/str_cat.h" >+ >+#include "absl/strings/internal/numbers_test_common.h" >+ >+namespace { >+ >+using absl::numbers_internal::kSixDigitsToBufferSize; >+using absl::numbers_internal::safe_strto32_base; >+using absl::numbers_internal::safe_strto64_base; >+using absl::numbers_internal::safe_strtou32_base; >+using absl::numbers_internal::safe_strtou64_base; >+using absl::numbers_internal::SixDigitsToBuffer; >+using absl::strings_internal::Itoa; >+using absl::strings_internal::strtouint32_test_cases; >+using absl::strings_internal::strtouint64_test_cases; >+using absl::SimpleAtoi; >+using testing::Eq; >+using testing::MatchesRegex; >+ >+// Number of floats to test with. >+// 5,000,000 is a reasonable default for a test that only takes a few seconds. >+// 1,000,000,000+ triggers checking for all possible mantissa values for >+// double-precision tests. 2,000,000,000+ triggers checking for every possible >+// single-precision float. >+const int kFloatNumCases = 5000000; >+ >+// This is a slow, brute-force routine to compute the exact base-10 >+// representation of a double-precision floating-point number. It >+// is useful for debugging only. >+std::string PerfectDtoa(double d) { >+ if (d == 0) return "0"; >+ if (d < 0) return "-" + PerfectDtoa(-d); >+ >+ // Basic theory: decompose d into mantissa and exp, where >+ // d = mantissa * 2^exp, and exp is as close to zero as possible. >+ int64_t mantissa, exp = 0; >+ while (d >= 1ULL << 63) ++exp, d *= 0.5; >+ while ((mantissa = d) != d) --exp, d *= 2.0; >+ >+ // Then convert mantissa to ASCII, and either double it (if >+ // exp > 0) or halve it (if exp < 0) repeatedly. "halve it" >+ // in this case means multiplying it by five and dividing by 10. >+ constexpr int maxlen = 1100; // worst case is actually 1030 or so. >+ char buf[maxlen + 5]; >+ for (int64_t num = mantissa, pos = maxlen; --pos >= 0;) { >+ buf[pos] = '0' + (num % 10); >+ num /= 10; >+ } >+ char* begin = &buf[0]; >+ char* end = buf + maxlen; >+ for (int i = 0; i != exp; i += (exp > 0) ? 1 : -1) { >+ int carry = 0; >+ for (char* p = end; --p != begin;) { >+ int dig = *p - '0'; >+ dig = dig * (exp > 0 ? 2 : 5) + carry; >+ carry = dig / 10; >+ dig %= 10; >+ *p = '0' + dig; >+ } >+ } >+ if (exp < 0) { >+ // "dividing by 10" above means we have to add the decimal point. >+ memmove(end + 1 + exp, end + exp, 1 - exp); >+ end[exp] = '.'; >+ ++end; >+ } >+ while (*begin == '0' && begin[1] != '.') ++begin; >+ return {begin, end}; >+} >+ >+TEST(ToString, PerfectDtoa) { >+ EXPECT_THAT(PerfectDtoa(1), Eq("1")); >+ EXPECT_THAT(PerfectDtoa(0.1), >+ Eq("0.1000000000000000055511151231257827021181583404541015625")); >+ EXPECT_THAT(PerfectDtoa(1e24), Eq("999999999999999983222784")); >+ EXPECT_THAT(PerfectDtoa(5e-324), MatchesRegex("0.0000.*625")); >+ for (int i = 0; i < 100; ++i) { >+ for (double multiplier : >+ {1e-300, 1e-200, 1e-100, 0.1, 1.0, 10.0, 1e100, 1e300}) { >+ double d = multiplier * i; >+ std::string s = PerfectDtoa(d); >+ EXPECT_DOUBLE_EQ(d, strtod(s.c_str(), nullptr)); >+ } >+ } >+} >+ >+template <typename integer> >+struct MyInteger { >+ integer i; >+ explicit constexpr MyInteger(integer i) : i(i) {} >+ constexpr operator integer() const { return i; } >+ >+ constexpr MyInteger operator+(MyInteger other) const { return i + other.i; } >+ constexpr MyInteger operator-(MyInteger other) const { return i - other.i; } >+ constexpr MyInteger operator*(MyInteger other) const { return i * other.i; } >+ constexpr MyInteger operator/(MyInteger other) const { return i / other.i; } >+ >+ constexpr bool operator<(MyInteger other) const { return i < other.i; } >+ constexpr bool operator<=(MyInteger other) const { return i <= other.i; } >+ constexpr bool operator==(MyInteger other) const { return i == other.i; } >+ constexpr bool operator>=(MyInteger other) const { return i >= other.i; } >+ constexpr bool operator>(MyInteger other) const { return i > other.i; } >+ constexpr bool operator!=(MyInteger other) const { return i != other.i; } >+ >+ integer as_integer() const { return i; } >+}; >+ >+typedef MyInteger<int64_t> MyInt64; >+typedef MyInteger<uint64_t> MyUInt64; >+ >+void CheckInt32(int32_t x) { >+ char buffer[absl::numbers_internal::kFastToBufferSize]; >+ char* actual = absl::numbers_internal::FastIntToBuffer(x, buffer); >+ std::string expected = std::to_string(x); >+ EXPECT_EQ(expected, std::string(buffer, actual)) << " Input " << x; >+ >+ char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, buffer); >+ EXPECT_EQ(expected, std::string(buffer, generic_actual)) << " Input " << x; >+} >+ >+void CheckInt64(int64_t x) { >+ char buffer[absl::numbers_internal::kFastToBufferSize + 3]; >+ buffer[0] = '*'; >+ buffer[23] = '*'; >+ buffer[24] = '*'; >+ char* actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]); >+ std::string expected = std::to_string(x); >+ EXPECT_EQ(expected, std::string(&buffer[1], actual)) << " Input " << x; >+ EXPECT_EQ(buffer[0], '*'); >+ EXPECT_EQ(buffer[23], '*'); >+ EXPECT_EQ(buffer[24], '*'); >+ >+ char* my_actual = >+ absl::numbers_internal::FastIntToBuffer(MyInt64(x), &buffer[1]); >+ EXPECT_EQ(expected, std::string(&buffer[1], my_actual)) << " Input " << x; >+} >+ >+void CheckUInt32(uint32_t x) { >+ char buffer[absl::numbers_internal::kFastToBufferSize]; >+ char* actual = absl::numbers_internal::FastIntToBuffer(x, buffer); >+ std::string expected = std::to_string(x); >+ EXPECT_EQ(expected, std::string(buffer, actual)) << " Input " << x; >+ >+ char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, buffer); >+ EXPECT_EQ(expected, std::string(buffer, generic_actual)) << " Input " << x; >+} >+ >+void CheckUInt64(uint64_t x) { >+ char buffer[absl::numbers_internal::kFastToBufferSize + 1]; >+ char* actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]); >+ std::string expected = std::to_string(x); >+ EXPECT_EQ(expected, std::string(&buffer[1], actual)) << " Input " << x; >+ >+ char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]); >+ EXPECT_EQ(expected, std::string(&buffer[1], generic_actual)) << " Input " << x; >+ >+ char* my_actual = >+ absl::numbers_internal::FastIntToBuffer(MyUInt64(x), &buffer[1]); >+ EXPECT_EQ(expected, std::string(&buffer[1], my_actual)) << " Input " << x; >+} >+ >+void CheckHex64(uint64_t v) { >+ char expected[16 + 1]; >+ std::string actual = absl::StrCat(absl::Hex(v, absl::kZeroPad16)); >+ snprintf(expected, sizeof(expected), "%016" PRIx64, static_cast<uint64_t>(v)); >+ EXPECT_EQ(expected, actual) << " Input " << v; >+} >+ >+TEST(Numbers, TestFastPrints) { >+ for (int i = -100; i <= 100; i++) { >+ CheckInt32(i); >+ CheckInt64(i); >+ } >+ for (int i = 0; i <= 100; i++) { >+ CheckUInt32(i); >+ CheckUInt64(i); >+ } >+ // Test min int to make sure that works >+ CheckInt32(INT_MIN); >+ CheckInt32(INT_MAX); >+ CheckInt64(LONG_MIN); >+ CheckInt64(uint64_t{1000000000}); >+ CheckInt64(uint64_t{9999999999}); >+ CheckInt64(uint64_t{100000000000000}); >+ CheckInt64(uint64_t{999999999999999}); >+ CheckInt64(uint64_t{1000000000000000000}); >+ CheckInt64(uint64_t{1199999999999999999}); >+ CheckInt64(int64_t{-700000000000000000}); >+ CheckInt64(LONG_MAX); >+ CheckUInt32(std::numeric_limits<uint32_t>::max()); >+ CheckUInt64(uint64_t{1000000000}); >+ CheckUInt64(uint64_t{9999999999}); >+ CheckUInt64(uint64_t{100000000000000}); >+ CheckUInt64(uint64_t{999999999999999}); >+ CheckUInt64(uint64_t{1000000000000000000}); >+ CheckUInt64(uint64_t{1199999999999999999}); >+ CheckUInt64(std::numeric_limits<uint64_t>::max()); >+ >+ for (int i = 0; i < 10000; i++) { >+ CheckHex64(i); >+ } >+ CheckHex64(uint64_t{0x123456789abcdef0}); >+} >+ >+template <typename int_type, typename in_val_type> >+void VerifySimpleAtoiGood(in_val_type in_value, int_type exp_value) { >+ std::string s = absl::StrCat(in_value); >+ int_type x = static_cast<int_type>(~exp_value); >+ EXPECT_TRUE(SimpleAtoi(s, &x)) >+ << "in_value=" << in_value << " s=" << s << " x=" << x; >+ EXPECT_EQ(exp_value, x); >+ x = static_cast<int_type>(~exp_value); >+ EXPECT_TRUE(SimpleAtoi(s.c_str(), &x)); >+ EXPECT_EQ(exp_value, x); >+} >+ >+template <typename int_type, typename in_val_type> >+void VerifySimpleAtoiBad(in_val_type in_value) { >+ std::string s = absl::StrCat(in_value); >+ int_type x; >+ EXPECT_FALSE(SimpleAtoi(s, &x)); >+ EXPECT_FALSE(SimpleAtoi(s.c_str(), &x)); >+} >+ >+TEST(NumbersTest, Atoi) { >+ // SimpleAtoi(absl::string_view, int32_t) >+ VerifySimpleAtoiGood<int32_t>(0, 0); >+ VerifySimpleAtoiGood<int32_t>(42, 42); >+ VerifySimpleAtoiGood<int32_t>(-42, -42); >+ >+ VerifySimpleAtoiGood<int32_t>(std::numeric_limits<int32_t>::min(), >+ std::numeric_limits<int32_t>::min()); >+ VerifySimpleAtoiGood<int32_t>(std::numeric_limits<int32_t>::max(), >+ std::numeric_limits<int32_t>::max()); >+ >+ // SimpleAtoi(absl::string_view, uint32_t) >+ VerifySimpleAtoiGood<uint32_t>(0, 0); >+ VerifySimpleAtoiGood<uint32_t>(42, 42); >+ VerifySimpleAtoiBad<uint32_t>(-42); >+ >+ VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int32_t>::min()); >+ VerifySimpleAtoiGood<uint32_t>(std::numeric_limits<int32_t>::max(), >+ std::numeric_limits<int32_t>::max()); >+ VerifySimpleAtoiGood<uint32_t>(std::numeric_limits<uint32_t>::max(), >+ std::numeric_limits<uint32_t>::max()); >+ VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int64_t>::min()); >+ VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int64_t>::max()); >+ VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<uint64_t>::max()); >+ >+ // SimpleAtoi(absl::string_view, int64_t) >+ VerifySimpleAtoiGood<int64_t>(0, 0); >+ VerifySimpleAtoiGood<int64_t>(42, 42); >+ VerifySimpleAtoiGood<int64_t>(-42, -42); >+ >+ VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int32_t>::min(), >+ std::numeric_limits<int32_t>::min()); >+ VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int32_t>::max(), >+ std::numeric_limits<int32_t>::max()); >+ VerifySimpleAtoiGood<int64_t>(std::numeric_limits<uint32_t>::max(), >+ std::numeric_limits<uint32_t>::max()); >+ VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int64_t>::min(), >+ std::numeric_limits<int64_t>::min()); >+ VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int64_t>::max(), >+ std::numeric_limits<int64_t>::max()); >+ VerifySimpleAtoiBad<int64_t>(std::numeric_limits<uint64_t>::max()); >+ >+ // SimpleAtoi(absl::string_view, uint64_t) >+ VerifySimpleAtoiGood<uint64_t>(0, 0); >+ VerifySimpleAtoiGood<uint64_t>(42, 42); >+ VerifySimpleAtoiBad<uint64_t>(-42); >+ >+ VerifySimpleAtoiBad<uint64_t>(std::numeric_limits<int32_t>::min()); >+ VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<int32_t>::max(), >+ std::numeric_limits<int32_t>::max()); >+ VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<uint32_t>::max(), >+ std::numeric_limits<uint32_t>::max()); >+ VerifySimpleAtoiBad<uint64_t>(std::numeric_limits<int64_t>::min()); >+ VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<int64_t>::max(), >+ std::numeric_limits<int64_t>::max()); >+ VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<uint64_t>::max(), >+ std::numeric_limits<uint64_t>::max()); >+ >+ // Some other types >+ VerifySimpleAtoiGood<int>(-42, -42); >+ VerifySimpleAtoiGood<int32_t>(-42, -42); >+ VerifySimpleAtoiGood<uint32_t>(42, 42); >+ VerifySimpleAtoiGood<unsigned int>(42, 42); >+ VerifySimpleAtoiGood<int64_t>(-42, -42); >+ VerifySimpleAtoiGood<long>(-42, -42); // NOLINT(runtime/int) >+ VerifySimpleAtoiGood<uint64_t>(42, 42); >+ VerifySimpleAtoiGood<size_t>(42, 42); >+ VerifySimpleAtoiGood<std::string::size_type>(42, 42); >+} >+ >+TEST(NumbersTest, Atoenum) { >+ enum E01 { >+ E01_zero = 0, >+ E01_one = 1, >+ }; >+ >+ VerifySimpleAtoiGood<E01>(E01_zero, E01_zero); >+ VerifySimpleAtoiGood<E01>(E01_one, E01_one); >+ >+ enum E_101 { >+ E_101_minusone = -1, >+ E_101_zero = 0, >+ E_101_one = 1, >+ }; >+ >+ VerifySimpleAtoiGood<E_101>(E_101_minusone, E_101_minusone); >+ VerifySimpleAtoiGood<E_101>(E_101_zero, E_101_zero); >+ VerifySimpleAtoiGood<E_101>(E_101_one, E_101_one); >+ >+ enum E_bigint { >+ E_bigint_zero = 0, >+ E_bigint_one = 1, >+ E_bigint_max31 = static_cast<int32_t>(0x7FFFFFFF), >+ }; >+ >+ VerifySimpleAtoiGood<E_bigint>(E_bigint_zero, E_bigint_zero); >+ VerifySimpleAtoiGood<E_bigint>(E_bigint_one, E_bigint_one); >+ VerifySimpleAtoiGood<E_bigint>(E_bigint_max31, E_bigint_max31); >+ >+ enum E_fullint { >+ E_fullint_zero = 0, >+ E_fullint_one = 1, >+ E_fullint_max31 = static_cast<int32_t>(0x7FFFFFFF), >+ E_fullint_min32 = INT32_MIN, >+ }; >+ >+ VerifySimpleAtoiGood<E_fullint>(E_fullint_zero, E_fullint_zero); >+ VerifySimpleAtoiGood<E_fullint>(E_fullint_one, E_fullint_one); >+ VerifySimpleAtoiGood<E_fullint>(E_fullint_max31, E_fullint_max31); >+ VerifySimpleAtoiGood<E_fullint>(E_fullint_min32, E_fullint_min32); >+ >+ enum E_biguint { >+ E_biguint_zero = 0, >+ E_biguint_one = 1, >+ E_biguint_max31 = static_cast<uint32_t>(0x7FFFFFFF), >+ E_biguint_max32 = static_cast<uint32_t>(0xFFFFFFFF), >+ }; >+ >+ VerifySimpleAtoiGood<E_biguint>(E_biguint_zero, E_biguint_zero); >+ VerifySimpleAtoiGood<E_biguint>(E_biguint_one, E_biguint_one); >+ VerifySimpleAtoiGood<E_biguint>(E_biguint_max31, E_biguint_max31); >+ VerifySimpleAtoiGood<E_biguint>(E_biguint_max32, E_biguint_max32); >+} >+ >+TEST(stringtest, safe_strto32_base) { >+ int32_t value; >+ EXPECT_TRUE(safe_strto32_base("0x34234324", &value, 16)); >+ EXPECT_EQ(0x34234324, value); >+ >+ EXPECT_TRUE(safe_strto32_base("0X34234324", &value, 16)); >+ EXPECT_EQ(0x34234324, value); >+ >+ EXPECT_TRUE(safe_strto32_base("34234324", &value, 16)); >+ EXPECT_EQ(0x34234324, value); >+ >+ EXPECT_TRUE(safe_strto32_base("0", &value, 16)); >+ EXPECT_EQ(0, value); >+ >+ EXPECT_TRUE(safe_strto32_base(" \t\n -0x34234324", &value, 16)); >+ EXPECT_EQ(-0x34234324, value); >+ >+ EXPECT_TRUE(safe_strto32_base(" \t\n -34234324", &value, 16)); >+ EXPECT_EQ(-0x34234324, value); >+ >+ EXPECT_TRUE(safe_strto32_base("7654321", &value, 8)); >+ EXPECT_EQ(07654321, value); >+ >+ EXPECT_TRUE(safe_strto32_base("-01234", &value, 8)); >+ EXPECT_EQ(-01234, value); >+ >+ EXPECT_FALSE(safe_strto32_base("1834", &value, 8)); >+ >+ // Autodetect base. >+ EXPECT_TRUE(safe_strto32_base("0", &value, 0)); >+ EXPECT_EQ(0, value); >+ >+ EXPECT_TRUE(safe_strto32_base("077", &value, 0)); >+ EXPECT_EQ(077, value); // Octal interpretation >+ >+ // Leading zero indicates octal, but then followed by invalid digit. >+ EXPECT_FALSE(safe_strto32_base("088", &value, 0)); >+ >+ // Leading 0x indicated hex, but then followed by invalid digit. >+ EXPECT_FALSE(safe_strto32_base("0xG", &value, 0)); >+ >+ // Base-10 version. >+ EXPECT_TRUE(safe_strto32_base("34234324", &value, 10)); >+ EXPECT_EQ(34234324, value); >+ >+ EXPECT_TRUE(safe_strto32_base("0", &value, 10)); >+ EXPECT_EQ(0, value); >+ >+ EXPECT_TRUE(safe_strto32_base(" \t\n -34234324", &value, 10)); >+ EXPECT_EQ(-34234324, value); >+ >+ EXPECT_TRUE(safe_strto32_base("34234324 \n\t ", &value, 10)); >+ EXPECT_EQ(34234324, value); >+ >+ // Invalid ints. >+ EXPECT_FALSE(safe_strto32_base("", &value, 10)); >+ EXPECT_FALSE(safe_strto32_base(" ", &value, 10)); >+ EXPECT_FALSE(safe_strto32_base("abc", &value, 10)); >+ EXPECT_FALSE(safe_strto32_base("34234324a", &value, 10)); >+ EXPECT_FALSE(safe_strto32_base("34234.3", &value, 10)); >+ >+ // Out of bounds. >+ EXPECT_FALSE(safe_strto32_base("2147483648", &value, 10)); >+ EXPECT_FALSE(safe_strto32_base("-2147483649", &value, 10)); >+ >+ // String version. >+ EXPECT_TRUE(safe_strto32_base(std::string("0x1234"), &value, 16)); >+ EXPECT_EQ(0x1234, value); >+ >+ // Base-10 std::string version. >+ EXPECT_TRUE(safe_strto32_base("1234", &value, 10)); >+ EXPECT_EQ(1234, value); >+} >+ >+TEST(stringtest, safe_strto32_range) { >+ // These tests verify underflow/overflow behaviour. >+ int32_t value; >+ EXPECT_FALSE(safe_strto32_base("2147483648", &value, 10)); >+ EXPECT_EQ(std::numeric_limits<int32_t>::max(), value); >+ >+ EXPECT_TRUE(safe_strto32_base("-2147483648", &value, 10)); >+ EXPECT_EQ(std::numeric_limits<int32_t>::min(), value); >+ >+ EXPECT_FALSE(safe_strto32_base("-2147483649", &value, 10)); >+ EXPECT_EQ(std::numeric_limits<int32_t>::min(), value); >+} >+ >+TEST(stringtest, safe_strto64_range) { >+ // These tests verify underflow/overflow behaviour. >+ int64_t value; >+ EXPECT_FALSE(safe_strto64_base("9223372036854775808", &value, 10)); >+ EXPECT_EQ(std::numeric_limits<int64_t>::max(), value); >+ >+ EXPECT_TRUE(safe_strto64_base("-9223372036854775808", &value, 10)); >+ EXPECT_EQ(std::numeric_limits<int64_t>::min(), value); >+ >+ EXPECT_FALSE(safe_strto64_base("-9223372036854775809", &value, 10)); >+ EXPECT_EQ(std::numeric_limits<int64_t>::min(), value); >+} >+ >+TEST(stringtest, safe_strto32_leading_substring) { >+ // These tests verify this comment in numbers.h: >+ // On error, returns false, and sets *value to: [...] >+ // conversion of leading substring if available ("123@@@" -> 123) >+ // 0 if no leading substring available >+ int32_t value; >+ EXPECT_FALSE(safe_strto32_base("04069@@@", &value, 10)); >+ EXPECT_EQ(4069, value); >+ >+ EXPECT_FALSE(safe_strto32_base("04069@@@", &value, 8)); >+ EXPECT_EQ(0406, value); >+ >+ EXPECT_FALSE(safe_strto32_base("04069balloons", &value, 10)); >+ EXPECT_EQ(4069, value); >+ >+ EXPECT_FALSE(safe_strto32_base("04069balloons", &value, 16)); >+ EXPECT_EQ(0x4069ba, value); >+ >+ EXPECT_FALSE(safe_strto32_base("@@@", &value, 10)); >+ EXPECT_EQ(0, value); // there was no leading substring >+} >+ >+TEST(stringtest, safe_strto64_leading_substring) { >+ // These tests verify this comment in numbers.h: >+ // On error, returns false, and sets *value to: [...] >+ // conversion of leading substring if available ("123@@@" -> 123) >+ // 0 if no leading substring available >+ int64_t value; >+ EXPECT_FALSE(safe_strto64_base("04069@@@", &value, 10)); >+ EXPECT_EQ(4069, value); >+ >+ EXPECT_FALSE(safe_strto64_base("04069@@@", &value, 8)); >+ EXPECT_EQ(0406, value); >+ >+ EXPECT_FALSE(safe_strto64_base("04069balloons", &value, 10)); >+ EXPECT_EQ(4069, value); >+ >+ EXPECT_FALSE(safe_strto64_base("04069balloons", &value, 16)); >+ EXPECT_EQ(0x4069ba, value); >+ >+ EXPECT_FALSE(safe_strto64_base("@@@", &value, 10)); >+ EXPECT_EQ(0, value); // there was no leading substring >+} >+ >+TEST(stringtest, safe_strto64_base) { >+ int64_t value; >+ EXPECT_TRUE(safe_strto64_base("0x3423432448783446", &value, 16)); >+ EXPECT_EQ(int64_t{0x3423432448783446}, value); >+ >+ EXPECT_TRUE(safe_strto64_base("3423432448783446", &value, 16)); >+ EXPECT_EQ(int64_t{0x3423432448783446}, value); >+ >+ EXPECT_TRUE(safe_strto64_base("0", &value, 16)); >+ EXPECT_EQ(0, value); >+ >+ EXPECT_TRUE(safe_strto64_base(" \t\n -0x3423432448783446", &value, 16)); >+ EXPECT_EQ(int64_t{-0x3423432448783446}, value); >+ >+ EXPECT_TRUE(safe_strto64_base(" \t\n -3423432448783446", &value, 16)); >+ EXPECT_EQ(int64_t{-0x3423432448783446}, value); >+ >+ EXPECT_TRUE(safe_strto64_base("123456701234567012", &value, 8)); >+ EXPECT_EQ(int64_t{0123456701234567012}, value); >+ >+ EXPECT_TRUE(safe_strto64_base("-017777777777777", &value, 8)); >+ EXPECT_EQ(int64_t{-017777777777777}, value); >+ >+ EXPECT_FALSE(safe_strto64_base("19777777777777", &value, 8)); >+ >+ // Autodetect base. >+ EXPECT_TRUE(safe_strto64_base("0", &value, 0)); >+ EXPECT_EQ(0, value); >+ >+ EXPECT_TRUE(safe_strto64_base("077", &value, 0)); >+ EXPECT_EQ(077, value); // Octal interpretation >+ >+ // Leading zero indicates octal, but then followed by invalid digit. >+ EXPECT_FALSE(safe_strto64_base("088", &value, 0)); >+ >+ // Leading 0x indicated hex, but then followed by invalid digit. >+ EXPECT_FALSE(safe_strto64_base("0xG", &value, 0)); >+ >+ // Base-10 version. >+ EXPECT_TRUE(safe_strto64_base("34234324487834466", &value, 10)); >+ EXPECT_EQ(int64_t{34234324487834466}, value); >+ >+ EXPECT_TRUE(safe_strto64_base("0", &value, 10)); >+ EXPECT_EQ(0, value); >+ >+ EXPECT_TRUE(safe_strto64_base(" \t\n -34234324487834466", &value, 10)); >+ EXPECT_EQ(int64_t{-34234324487834466}, value); >+ >+ EXPECT_TRUE(safe_strto64_base("34234324487834466 \n\t ", &value, 10)); >+ EXPECT_EQ(int64_t{34234324487834466}, value); >+ >+ // Invalid ints. >+ EXPECT_FALSE(safe_strto64_base("", &value, 10)); >+ EXPECT_FALSE(safe_strto64_base(" ", &value, 10)); >+ EXPECT_FALSE(safe_strto64_base("abc", &value, 10)); >+ EXPECT_FALSE(safe_strto64_base("34234324487834466a", &value, 10)); >+ EXPECT_FALSE(safe_strto64_base("34234487834466.3", &value, 10)); >+ >+ // Out of bounds. >+ EXPECT_FALSE(safe_strto64_base("9223372036854775808", &value, 10)); >+ EXPECT_FALSE(safe_strto64_base("-9223372036854775809", &value, 10)); >+ >+ // String version. >+ EXPECT_TRUE(safe_strto64_base(std::string("0x1234"), &value, 16)); >+ EXPECT_EQ(0x1234, value); >+ >+ // Base-10 std::string version. >+ EXPECT_TRUE(safe_strto64_base("1234", &value, 10)); >+ EXPECT_EQ(1234, value); >+} >+ >+const size_t kNumRandomTests = 10000; >+ >+template <typename IntType> >+void test_random_integer_parse_base(bool (*parse_func)(absl::string_view, >+ IntType* value, >+ int base)) { >+ using RandomEngine = std::minstd_rand0; >+ std::random_device rd; >+ RandomEngine rng(rd()); >+ std::uniform_int_distribution<IntType> random_int( >+ std::numeric_limits<IntType>::min()); >+ std::uniform_int_distribution<int> random_base(2, 35); >+ for (size_t i = 0; i < kNumRandomTests; i++) { >+ IntType value = random_int(rng); >+ int base = random_base(rng); >+ std::string str_value; >+ EXPECT_TRUE(Itoa<IntType>(value, base, &str_value)); >+ IntType parsed_value; >+ >+ // Test successful parse >+ EXPECT_TRUE(parse_func(str_value, &parsed_value, base)); >+ EXPECT_EQ(parsed_value, value); >+ >+ // Test overflow >+ EXPECT_FALSE( >+ parse_func(absl::StrCat(std::numeric_limits<IntType>::max(), value), >+ &parsed_value, base)); >+ >+ // Test underflow >+ if (std::numeric_limits<IntType>::min() < 0) { >+ EXPECT_FALSE( >+ parse_func(absl::StrCat(std::numeric_limits<IntType>::min(), value), >+ &parsed_value, base)); >+ } else { >+ EXPECT_FALSE(parse_func(absl::StrCat("-", value), &parsed_value, base)); >+ } >+ } >+} >+ >+TEST(stringtest, safe_strto32_random) { >+ test_random_integer_parse_base<int32_t>(&safe_strto32_base); >+} >+TEST(stringtest, safe_strto64_random) { >+ test_random_integer_parse_base<int64_t>(&safe_strto64_base); >+} >+TEST(stringtest, safe_strtou32_random) { >+ test_random_integer_parse_base<uint32_t>(&safe_strtou32_base); >+} >+TEST(stringtest, safe_strtou64_random) { >+ test_random_integer_parse_base<uint64_t>(&safe_strtou64_base); >+} >+ >+TEST(stringtest, safe_strtou32_base) { >+ for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) { >+ const auto& e = strtouint32_test_cases()[i]; >+ uint32_t value; >+ EXPECT_EQ(e.expect_ok, safe_strtou32_base(e.str, &value, e.base)) >+ << "str=\"" << e.str << "\" base=" << e.base; >+ if (e.expect_ok) { >+ EXPECT_EQ(e.expected, value) << "i=" << i << " str=\"" << e.str >+ << "\" base=" << e.base; >+ } >+ } >+} >+ >+TEST(stringtest, safe_strtou32_base_length_delimited) { >+ for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) { >+ const auto& e = strtouint32_test_cases()[i]; >+ std::string tmp(e.str); >+ tmp.append("12"); // Adds garbage at the end. >+ >+ uint32_t value; >+ EXPECT_EQ(e.expect_ok, >+ safe_strtou32_base(absl::string_view(tmp.data(), strlen(e.str)), >+ &value, e.base)) >+ << "str=\"" << e.str << "\" base=" << e.base; >+ if (e.expect_ok) { >+ EXPECT_EQ(e.expected, value) << "i=" << i << " str=" << e.str >+ << " base=" << e.base; >+ } >+ } >+} >+ >+TEST(stringtest, safe_strtou64_base) { >+ for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) { >+ const auto& e = strtouint64_test_cases()[i]; >+ uint64_t value; >+ EXPECT_EQ(e.expect_ok, safe_strtou64_base(e.str, &value, e.base)) >+ << "str=\"" << e.str << "\" base=" << e.base; >+ if (e.expect_ok) { >+ EXPECT_EQ(e.expected, value) << "str=" << e.str << " base=" << e.base; >+ } >+ } >+} >+ >+TEST(stringtest, safe_strtou64_base_length_delimited) { >+ for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) { >+ const auto& e = strtouint64_test_cases()[i]; >+ std::string tmp(e.str); >+ tmp.append("12"); // Adds garbage at the end. >+ >+ uint64_t value; >+ EXPECT_EQ(e.expect_ok, >+ safe_strtou64_base(absl::string_view(tmp.data(), strlen(e.str)), >+ &value, e.base)) >+ << "str=\"" << e.str << "\" base=" << e.base; >+ if (e.expect_ok) { >+ EXPECT_EQ(e.expected, value) << "str=\"" << e.str << "\" base=" << e.base; >+ } >+ } >+} >+ >+// feenableexcept() and fedisableexcept() are missing on Mac OS X, MSVC, >+// and WebAssembly. >+#if defined(_MSC_VER) || defined(__APPLE__) || defined(__EMSCRIPTEN__) >+#define ABSL_MISSING_FEENABLEEXCEPT 1 >+#define ABSL_MISSING_FEDISABLEEXCEPT 1 >+#endif >+ >+class SimpleDtoaTest : public testing::Test { >+ protected: >+ void SetUp() override { >+ // Store the current floating point env & clear away any pending exceptions. >+ feholdexcept(&fp_env_); >+#ifndef ABSL_MISSING_FEENABLEEXCEPT >+ // Turn on floating point exceptions. >+ feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); >+#endif >+ } >+ >+ void TearDown() override { >+ // Restore the floating point environment to the original state. >+ // In theory fedisableexcept is unnecessary; fesetenv will also do it. >+ // In practice, our toolchains have subtle bugs. >+#ifndef ABSL_MISSING_FEDISABLEEXCEPT >+ fedisableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); >+#endif >+ fesetenv(&fp_env_); >+ } >+ >+ std::string ToNineDigits(double value) { >+ char buffer[16]; // more than enough for %.9g >+ snprintf(buffer, sizeof(buffer), "%.9g", value); >+ return buffer; >+ } >+ >+ fenv_t fp_env_; >+}; >+ >+// Run the given runnable functor for "cases" test cases, chosen over the >+// available range of float. pi and e and 1/e are seeded, and then all >+// available integer powers of 2 and 10 are multiplied against them. In >+// addition to trying all those values, we try the next higher and next lower >+// float, and then we add additional test cases evenly distributed between them. >+// Each test case is passed to runnable as both a positive and negative value. >+template <typename R> >+void ExhaustiveFloat(uint32_t cases, R&& runnable) { >+ runnable(0.0f); >+ runnable(-0.0f); >+ if (cases >= 2e9) { // more than 2 billion? Might as well run them all. >+ for (float f = 0; f < std::numeric_limits<float>::max(); ) { >+ f = nextafterf(f, std::numeric_limits<float>::max()); >+ runnable(-f); >+ runnable(f); >+ } >+ return; >+ } >+ std::set<float> floats = {3.4028234e38f}; >+ for (float f : {1.0, 3.14159265, 2.718281828, 1 / 2.718281828}) { >+ for (float testf = f; testf != 0; testf *= 0.1f) floats.insert(testf); >+ for (float testf = f; testf != 0; testf *= 0.5f) floats.insert(testf); >+ for (float testf = f; testf < 3e38f / 2; testf *= 2.0f) >+ floats.insert(testf); >+ for (float testf = f; testf < 3e38f / 10; testf *= 10) floats.insert(testf); >+ } >+ >+ float last = *floats.begin(); >+ >+ runnable(last); >+ runnable(-last); >+ int iters_per_float = cases / floats.size(); >+ if (iters_per_float == 0) iters_per_float = 1; >+ for (float f : floats) { >+ if (f == last) continue; >+ float testf = nextafter(last, std::numeric_limits<float>::max()); >+ runnable(testf); >+ runnable(-testf); >+ last = testf; >+ if (f == last) continue; >+ double step = (double{f} - last) / iters_per_float; >+ for (double d = last + step; d < f; d += step) { >+ testf = d; >+ if (testf != last) { >+ runnable(testf); >+ runnable(-testf); >+ last = testf; >+ } >+ } >+ testf = nextafter(f, 0.0f); >+ if (testf > last) { >+ runnable(testf); >+ runnable(-testf); >+ last = testf; >+ } >+ if (f != last) { >+ runnable(f); >+ runnable(-f); >+ last = f; >+ } >+ } >+} >+ >+TEST_F(SimpleDtoaTest, ExhaustiveDoubleToSixDigits) { >+ uint64_t test_count = 0; >+ std::vector<double> mismatches; >+ auto checker = [&](double d) { >+ if (d != d) return; // rule out NaNs >+ ++test_count; >+ char sixdigitsbuf[kSixDigitsToBufferSize] = {0}; >+ SixDigitsToBuffer(d, sixdigitsbuf); >+ char snprintfbuf[kSixDigitsToBufferSize] = {0}; >+ snprintf(snprintfbuf, kSixDigitsToBufferSize, "%g", d); >+ if (strcmp(sixdigitsbuf, snprintfbuf) != 0) { >+ mismatches.push_back(d); >+ if (mismatches.size() < 10) { >+ ABSL_RAW_LOG(ERROR, "%s", >+ absl::StrCat("Six-digit failure with double. ", "d=", d, >+ "=", d, " sixdigits=", sixdigitsbuf, >+ " printf(%g)=", snprintfbuf) >+ .c_str()); >+ } >+ } >+ }; >+ // Some quick sanity checks... >+ checker(5e-324); >+ checker(1e-308); >+ checker(1.0); >+ checker(1.000005); >+ checker(1.7976931348623157e308); >+ checker(0.00390625); >+#ifndef _MSC_VER >+ // on MSVC, snprintf() rounds it to 0.00195313. SixDigitsToBuffer() rounds it >+ // to 0.00195312 (round half to even). >+ checker(0.001953125); >+#endif >+ checker(0.005859375); >+ // Some cases where the rounding is very very close >+ checker(1.089095e-15); >+ checker(3.274195e-55); >+ checker(6.534355e-146); >+ checker(2.920845e+234); >+ >+ if (mismatches.empty()) { >+ test_count = 0; >+ ExhaustiveFloat(kFloatNumCases, checker); >+ >+ test_count = 0; >+ std::vector<int> digit_testcases{ >+ 100000, 100001, 100002, 100005, 100010, 100020, 100050, 100100, // misc >+ 195312, 195313, // 1.953125 is a case where we round down, just barely. >+ 200000, 500000, 800000, // misc mid-range cases >+ 585937, 585938, // 5.859375 is a case where we round up, just barely. >+ 900000, 990000, 999000, 999900, 999990, 999996, 999997, 999998, 999999}; >+ if (kFloatNumCases >= 1e9) { >+ // If at least 1 billion test cases were requested, user wants an >+ // exhaustive test. So let's test all mantissas, too. >+ constexpr int min_mantissa = 100000, max_mantissa = 999999; >+ digit_testcases.resize(max_mantissa - min_mantissa + 1); >+ std::iota(digit_testcases.begin(), digit_testcases.end(), min_mantissa); >+ } >+ >+ for (int exponent = -324; exponent <= 308; ++exponent) { >+ double powten = pow(10.0, exponent); >+ if (powten == 0) powten = 5e-324; >+ if (kFloatNumCases >= 1e9) { >+ // The exhaustive test takes a very long time, so log progress. >+ char buf[kSixDigitsToBufferSize]; >+ ABSL_RAW_LOG( >+ INFO, "%s", >+ absl::StrCat("Exp ", exponent, " powten=", powten, "(", >+ powten, ") (", >+ std::string(buf, SixDigitsToBuffer(powten, buf)), ")") >+ .c_str()); >+ } >+ for (int digits : digit_testcases) { >+ if (exponent == 308 && digits >= 179769) break; // don't overflow! >+ double digiform = (digits + 0.5) * 0.00001; >+ double testval = digiform * powten; >+ double pretestval = nextafter(testval, 0); >+ double posttestval = nextafter(testval, 1.7976931348623157e308); >+ checker(testval); >+ checker(pretestval); >+ checker(posttestval); >+ } >+ } >+ } else { >+ EXPECT_EQ(mismatches.size(), 0); >+ for (size_t i = 0; i < mismatches.size(); ++i) { >+ if (i > 100) i = mismatches.size() - 1; >+ double d = mismatches[i]; >+ char sixdigitsbuf[kSixDigitsToBufferSize] = {0}; >+ SixDigitsToBuffer(d, sixdigitsbuf); >+ char snprintfbuf[kSixDigitsToBufferSize] = {0}; >+ snprintf(snprintfbuf, kSixDigitsToBufferSize, "%g", d); >+ double before = nextafter(d, 0.0); >+ double after = nextafter(d, 1.7976931348623157e308); >+ char b1[32], b2[kSixDigitsToBufferSize]; >+ ABSL_RAW_LOG( >+ ERROR, "%s", >+ absl::StrCat( >+ "Mismatch #", i, " d=", d, " (", ToNineDigits(d), ")", >+ " sixdigits='", sixdigitsbuf, "'", " snprintf='", snprintfbuf, >+ "'", " Before.=", PerfectDtoa(before), " ", >+ (SixDigitsToBuffer(before, b2), b2), >+ " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", before), b1), >+ " Perfect=", PerfectDtoa(d), " ", (SixDigitsToBuffer(d, b2), b2), >+ " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", d), b1), >+ " After.=.", PerfectDtoa(after), " ", >+ (SixDigitsToBuffer(after, b2), b2), >+ " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", after), b1)) >+ .c_str()); >+ } >+ } >+} >+ >+TEST(StrToInt32, Partial) { >+ struct Int32TestLine { >+ std::string input; >+ bool status; >+ int32_t value; >+ }; >+ const int32_t int32_min = std::numeric_limits<int32_t>::min(); >+ const int32_t int32_max = std::numeric_limits<int32_t>::max(); >+ Int32TestLine int32_test_line[] = { >+ {"", false, 0}, >+ {" ", false, 0}, >+ {"-", false, 0}, >+ {"123@@@", false, 123}, >+ {absl::StrCat(int32_min, int32_max), false, int32_min}, >+ {absl::StrCat(int32_max, int32_max), false, int32_max}, >+ }; >+ >+ for (const Int32TestLine& test_line : int32_test_line) { >+ int32_t value = -2; >+ bool status = safe_strto32_base(test_line.input, &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ value = -2; >+ status = safe_strto32_base(test_line.input, &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ value = -2; >+ status = safe_strto32_base(absl::string_view(test_line.input), &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ } >+} >+ >+TEST(StrToUint32, Partial) { >+ struct Uint32TestLine { >+ std::string input; >+ bool status; >+ uint32_t value; >+ }; >+ const uint32_t uint32_max = std::numeric_limits<uint32_t>::max(); >+ Uint32TestLine uint32_test_line[] = { >+ {"", false, 0}, >+ {" ", false, 0}, >+ {"-", false, 0}, >+ {"123@@@", false, 123}, >+ {absl::StrCat(uint32_max, uint32_max), false, uint32_max}, >+ }; >+ >+ for (const Uint32TestLine& test_line : uint32_test_line) { >+ uint32_t value = 2; >+ bool status = safe_strtou32_base(test_line.input, &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ value = 2; >+ status = safe_strtou32_base(test_line.input, &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ value = 2; >+ status = safe_strtou32_base(absl::string_view(test_line.input), &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ } >+} >+ >+TEST(StrToInt64, Partial) { >+ struct Int64TestLine { >+ std::string input; >+ bool status; >+ int64_t value; >+ }; >+ const int64_t int64_min = std::numeric_limits<int64_t>::min(); >+ const int64_t int64_max = std::numeric_limits<int64_t>::max(); >+ Int64TestLine int64_test_line[] = { >+ {"", false, 0}, >+ {" ", false, 0}, >+ {"-", false, 0}, >+ {"123@@@", false, 123}, >+ {absl::StrCat(int64_min, int64_max), false, int64_min}, >+ {absl::StrCat(int64_max, int64_max), false, int64_max}, >+ }; >+ >+ for (const Int64TestLine& test_line : int64_test_line) { >+ int64_t value = -2; >+ bool status = safe_strto64_base(test_line.input, &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ value = -2; >+ status = safe_strto64_base(test_line.input, &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ value = -2; >+ status = safe_strto64_base(absl::string_view(test_line.input), &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ } >+} >+ >+TEST(StrToUint64, Partial) { >+ struct Uint64TestLine { >+ std::string input; >+ bool status; >+ uint64_t value; >+ }; >+ const uint64_t uint64_max = std::numeric_limits<uint64_t>::max(); >+ Uint64TestLine uint64_test_line[] = { >+ {"", false, 0}, >+ {" ", false, 0}, >+ {"-", false, 0}, >+ {"123@@@", false, 123}, >+ {absl::StrCat(uint64_max, uint64_max), false, uint64_max}, >+ }; >+ >+ for (const Uint64TestLine& test_line : uint64_test_line) { >+ uint64_t value = 2; >+ bool status = safe_strtou64_base(test_line.input, &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ value = 2; >+ status = safe_strtou64_base(test_line.input, &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ value = 2; >+ status = safe_strtou64_base(absl::string_view(test_line.input), &value, 10); >+ EXPECT_EQ(test_line.status, status) << test_line.input; >+ EXPECT_EQ(test_line.value, value) << test_line.input; >+ } >+} >+ >+TEST(StrToInt32Base, PrefixOnly) { >+ struct Int32TestLine { >+ std::string input; >+ bool status; >+ int32_t value; >+ }; >+ Int32TestLine int32_test_line[] = { >+ { "", false, 0 }, >+ { "-", false, 0 }, >+ { "-0", true, 0 }, >+ { "0", true, 0 }, >+ { "0x", false, 0 }, >+ { "-0x", false, 0 }, >+ }; >+ const int base_array[] = { 0, 2, 8, 10, 16 }; >+ >+ for (const Int32TestLine& line : int32_test_line) { >+ for (const int base : base_array) { >+ int32_t value = 2; >+ bool status = safe_strto32_base(line.input.c_str(), &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ value = 2; >+ status = safe_strto32_base(line.input, &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ value = 2; >+ status = safe_strto32_base(absl::string_view(line.input), &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ } >+ } >+} >+ >+TEST(StrToUint32Base, PrefixOnly) { >+ struct Uint32TestLine { >+ std::string input; >+ bool status; >+ uint32_t value; >+ }; >+ Uint32TestLine uint32_test_line[] = { >+ { "", false, 0 }, >+ { "0", true, 0 }, >+ { "0x", false, 0 }, >+ }; >+ const int base_array[] = { 0, 2, 8, 10, 16 }; >+ >+ for (const Uint32TestLine& line : uint32_test_line) { >+ for (const int base : base_array) { >+ uint32_t value = 2; >+ bool status = safe_strtou32_base(line.input.c_str(), &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ value = 2; >+ status = safe_strtou32_base(line.input, &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ value = 2; >+ status = safe_strtou32_base(absl::string_view(line.input), &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ } >+ } >+} >+ >+TEST(StrToInt64Base, PrefixOnly) { >+ struct Int64TestLine { >+ std::string input; >+ bool status; >+ int64_t value; >+ }; >+ Int64TestLine int64_test_line[] = { >+ { "", false, 0 }, >+ { "-", false, 0 }, >+ { "-0", true, 0 }, >+ { "0", true, 0 }, >+ { "0x", false, 0 }, >+ { "-0x", false, 0 }, >+ }; >+ const int base_array[] = { 0, 2, 8, 10, 16 }; >+ >+ for (const Int64TestLine& line : int64_test_line) { >+ for (const int base : base_array) { >+ int64_t value = 2; >+ bool status = safe_strto64_base(line.input.c_str(), &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ value = 2; >+ status = safe_strto64_base(line.input, &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ value = 2; >+ status = safe_strto64_base(absl::string_view(line.input), &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ } >+ } >+} >+ >+TEST(StrToUint64Base, PrefixOnly) { >+ struct Uint64TestLine { >+ std::string input; >+ bool status; >+ uint64_t value; >+ }; >+ Uint64TestLine uint64_test_line[] = { >+ { "", false, 0 }, >+ { "0", true, 0 }, >+ { "0x", false, 0 }, >+ }; >+ const int base_array[] = { 0, 2, 8, 10, 16 }; >+ >+ for (const Uint64TestLine& line : uint64_test_line) { >+ for (const int base : base_array) { >+ uint64_t value = 2; >+ bool status = safe_strtou64_base(line.input.c_str(), &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ value = 2; >+ status = safe_strtou64_base(line.input, &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ value = 2; >+ status = safe_strtou64_base(absl::string_view(line.input), &value, base); >+ EXPECT_EQ(line.status, status) << line.input << " " << base; >+ EXPECT_EQ(line.value, value) << line.input << " " << base; >+ } >+ } >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..3fe8c95eca9ef979491693638900858b08725d0b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat.cc >@@ -0,0 +1,239 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/str_cat.h" >+ >+#include <assert.h> >+#include <algorithm> >+#include <cstdint> >+#include <cstring> >+ >+#include "absl/strings/ascii.h" >+#include "absl/strings/internal/resize_uninitialized.h" >+ >+namespace absl { >+ >+AlphaNum::AlphaNum(Hex hex) { >+ char* const end = &digits_[numbers_internal::kFastToBufferSize]; >+ char* writer = end; >+ uint64_t value = hex.value; >+ static const char hexdigits[] = "0123456789abcdef"; >+ do { >+ *--writer = hexdigits[value & 0xF]; >+ value >>= 4; >+ } while (value != 0); >+ >+ char* beg; >+ if (end - writer < hex.width) { >+ beg = end - hex.width; >+ std::fill_n(beg, writer - beg, hex.fill); >+ } else { >+ beg = writer; >+ } >+ >+ piece_ = absl::string_view(beg, end - beg); >+} >+ >+AlphaNum::AlphaNum(Dec dec) { >+ assert(dec.width <= numbers_internal::kFastToBufferSize); >+ char* const end = &digits_[numbers_internal::kFastToBufferSize]; >+ char* const minfill = end - dec.width; >+ char* writer = end; >+ uint64_t value = dec.value; >+ bool neg = dec.neg; >+ while (value > 9) { >+ *--writer = '0' + (value % 10); >+ value /= 10; >+ } >+ *--writer = '0' + value; >+ if (neg) *--writer = '-'; >+ >+ ptrdiff_t fillers = writer - minfill; >+ if (fillers > 0) { >+ // Tricky: if the fill character is ' ', then it's <fill><+/-><digits> >+ // But...: if the fill character is '0', then it's <+/-><fill><digits> >+ bool add_sign_again = false; >+ if (neg && dec.fill == '0') { // If filling with '0', >+ ++writer; // ignore the sign we just added >+ add_sign_again = true; // and re-add the sign later. >+ } >+ writer -= fillers; >+ std::fill_n(writer, fillers, dec.fill); >+ if (add_sign_again) *--writer = '-'; >+ } >+ >+ piece_ = absl::string_view(writer, end - writer); >+} >+ >+// ---------------------------------------------------------------------- >+// StrCat() >+// This merges the given strings or integers, with no delimiter. This >+// is designed to be the fastest possible way to construct a std::string out >+// of a mix of raw C strings, StringPieces, strings, and integer values. >+// ---------------------------------------------------------------------- >+ >+// Append is merely a version of memcpy that returns the address of the byte >+// after the area just overwritten. >+static char* Append(char* out, const AlphaNum& x) { >+ // memcpy is allowed to overwrite arbitrary memory, so doing this after the >+ // call would force an extra fetch of x.size(). >+ char* after = out + x.size(); >+ memcpy(out, x.data(), x.size()); >+ return after; >+} >+ >+std::string StrCat(const AlphaNum& a, const AlphaNum& b) { >+ std::string result; >+ absl::strings_internal::STLStringResizeUninitialized(&result, >+ a.size() + b.size()); >+ char* const begin = &*result.begin(); >+ char* out = begin; >+ out = Append(out, a); >+ out = Append(out, b); >+ assert(out == begin + result.size()); >+ return result; >+} >+ >+std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c) { >+ std::string result; >+ strings_internal::STLStringResizeUninitialized( >+ &result, a.size() + b.size() + c.size()); >+ char* const begin = &*result.begin(); >+ char* out = begin; >+ out = Append(out, a); >+ out = Append(out, b); >+ out = Append(out, c); >+ assert(out == begin + result.size()); >+ return result; >+} >+ >+std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, >+ const AlphaNum& d) { >+ std::string result; >+ strings_internal::STLStringResizeUninitialized( >+ &result, a.size() + b.size() + c.size() + d.size()); >+ char* const begin = &*result.begin(); >+ char* out = begin; >+ out = Append(out, a); >+ out = Append(out, b); >+ out = Append(out, c); >+ out = Append(out, d); >+ assert(out == begin + result.size()); >+ return result; >+} >+ >+namespace strings_internal { >+ >+// Do not call directly - these are not part of the public API. >+std::string CatPieces(std::initializer_list<absl::string_view> pieces) { >+ std::string result; >+ size_t total_size = 0; >+ for (const absl::string_view piece : pieces) total_size += piece.size(); >+ strings_internal::STLStringResizeUninitialized(&result, total_size); >+ >+ char* const begin = &*result.begin(); >+ char* out = begin; >+ for (const absl::string_view piece : pieces) { >+ const size_t this_size = piece.size(); >+ memcpy(out, piece.data(), this_size); >+ out += this_size; >+ } >+ assert(out == begin + result.size()); >+ return result; >+} >+ >+// It's possible to call StrAppend with an absl::string_view that is itself a >+// fragment of the std::string we're appending to. However the results of this are >+// random. Therefore, check for this in debug mode. Use unsigned math so we >+// only have to do one comparison. Note, there's an exception case: appending an >+// empty std::string is always allowed. >+#define ASSERT_NO_OVERLAP(dest, src) \ >+ assert(((src).size() == 0) || \ >+ (uintptr_t((src).data() - (dest).data()) > uintptr_t((dest).size()))) >+ >+void AppendPieces(std::string* dest, >+ std::initializer_list<absl::string_view> pieces) { >+ size_t old_size = dest->size(); >+ size_t total_size = old_size; >+ for (const absl::string_view piece : pieces) { >+ ASSERT_NO_OVERLAP(*dest, piece); >+ total_size += piece.size(); >+ } >+ strings_internal::STLStringResizeUninitialized(dest, total_size); >+ >+ char* const begin = &*dest->begin(); >+ char* out = begin + old_size; >+ for (const absl::string_view piece : pieces) { >+ const size_t this_size = piece.size(); >+ memcpy(out, piece.data(), this_size); >+ out += this_size; >+ } >+ assert(out == begin + dest->size()); >+} >+ >+} // namespace strings_internal >+ >+void StrAppend(std::string* dest, const AlphaNum& a) { >+ ASSERT_NO_OVERLAP(*dest, a); >+ dest->append(a.data(), a.size()); >+} >+ >+void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b) { >+ ASSERT_NO_OVERLAP(*dest, a); >+ ASSERT_NO_OVERLAP(*dest, b); >+ std::string::size_type old_size = dest->size(); >+ strings_internal::STLStringResizeUninitialized( >+ dest, old_size + a.size() + b.size()); >+ char* const begin = &*dest->begin(); >+ char* out = begin + old_size; >+ out = Append(out, a); >+ out = Append(out, b); >+ assert(out == begin + dest->size()); >+} >+ >+void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, >+ const AlphaNum& c) { >+ ASSERT_NO_OVERLAP(*dest, a); >+ ASSERT_NO_OVERLAP(*dest, b); >+ ASSERT_NO_OVERLAP(*dest, c); >+ std::string::size_type old_size = dest->size(); >+ strings_internal::STLStringResizeUninitialized( >+ dest, old_size + a.size() + b.size() + c.size()); >+ char* const begin = &*dest->begin(); >+ char* out = begin + old_size; >+ out = Append(out, a); >+ out = Append(out, b); >+ out = Append(out, c); >+ assert(out == begin + dest->size()); >+} >+ >+void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, >+ const AlphaNum& c, const AlphaNum& d) { >+ ASSERT_NO_OVERLAP(*dest, a); >+ ASSERT_NO_OVERLAP(*dest, b); >+ ASSERT_NO_OVERLAP(*dest, c); >+ ASSERT_NO_OVERLAP(*dest, d); >+ std::string::size_type old_size = dest->size(); >+ strings_internal::STLStringResizeUninitialized( >+ dest, old_size + a.size() + b.size() + c.size() + d.size()); >+ char* const begin = &*dest->begin(); >+ char* out = begin + old_size; >+ out = Append(out, a); >+ out = Append(out, b); >+ out = Append(out, c); >+ out = Append(out, d); >+ assert(out == begin + dest->size()); >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat.h >new file mode 100644 >index 0000000000000000000000000000000000000000..e5501a5012ee8d9cf79cbe6b50b04756d191bf9e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat.h >@@ -0,0 +1,385 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: str_cat.h >+// ----------------------------------------------------------------------------- >+// >+// This package contains functions for efficiently concatenating and appending >+// strings: `StrCat()` and `StrAppend()`. Most of the work within these routines >+// is actually handled through use of a special AlphaNum type, which was >+// designed to be used as a parameter type that efficiently manages conversion >+// to strings and avoids copies in the above operations. >+// >+// Any routine accepting either a std::string or a number may accept `AlphaNum`. >+// The basic idea is that by accepting a `const AlphaNum &` as an argument >+// to your function, your callers will automagically convert bools, integers, >+// and floating point values to strings for you. >+// >+// NOTE: Use of `AlphaNum` outside of the //absl/strings package is unsupported >+// except for the specific case of function parameters of type `AlphaNum` or >+// `const AlphaNum &`. In particular, instantiating `AlphaNum` directly as a >+// stack variable is not supported. >+// >+// Conversion from 8-bit values is not accepted because, if it were, then an >+// attempt to pass ':' instead of ":" might result in a 58 ending up in your >+// result. >+// >+// Bools convert to "0" or "1". >+// >+// Floating point numbers are formatted with six-digit precision, which is >+// the default for "std::cout <<" or printf "%g" (the same as "%.6g"). >+// >+// >+// You can convert to hexadecimal output rather than decimal output using the >+// `Hex` type contained here. To do so, pass `Hex(my_int)` as a parameter to >+// `StrCat()` or `StrAppend()`. You may specify a minimum hex field width using >+// a `PadSpec` enum. >+// >+// ----------------------------------------------------------------------------- >+ >+#ifndef ABSL_STRINGS_STR_CAT_H_ >+#define ABSL_STRINGS_STR_CAT_H_ >+ >+#include <array> >+#include <cstdint> >+#include <string> >+#include <type_traits> >+ >+#include "absl/base/port.h" >+#include "absl/strings/numbers.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+ >+namespace strings_internal { >+// AlphaNumBuffer allows a way to pass a std::string to StrCat without having to do >+// memory allocation. It is simply a pair of a fixed-size character array, and >+// a size. Please don't use outside of absl, yet. >+template <size_t max_size> >+struct AlphaNumBuffer { >+ std::array<char, max_size> data; >+ size_t size; >+}; >+ >+} // namespace strings_internal >+ >+// Enum that specifies the number of significant digits to return in a `Hex` or >+// `Dec` conversion and fill character to use. A `kZeroPad2` value, for example, >+// would produce hexadecimal strings such as "0A","0F" and a 'kSpacePad5' value >+// would produce hexadecimal strings such as " A"," F". >+enum PadSpec : uint8_t { >+ kNoPad = 1, >+ kZeroPad2, >+ kZeroPad3, >+ kZeroPad4, >+ kZeroPad5, >+ kZeroPad6, >+ kZeroPad7, >+ kZeroPad8, >+ kZeroPad9, >+ kZeroPad10, >+ kZeroPad11, >+ kZeroPad12, >+ kZeroPad13, >+ kZeroPad14, >+ kZeroPad15, >+ kZeroPad16, >+ >+ kSpacePad2 = kZeroPad2 + 64, >+ kSpacePad3, >+ kSpacePad4, >+ kSpacePad5, >+ kSpacePad6, >+ kSpacePad7, >+ kSpacePad8, >+ kSpacePad9, >+ kSpacePad10, >+ kSpacePad11, >+ kSpacePad12, >+ kSpacePad13, >+ kSpacePad14, >+ kSpacePad15, >+ kSpacePad16, >+}; >+ >+// ----------------------------------------------------------------------------- >+// Hex >+// ----------------------------------------------------------------------------- >+// >+// `Hex` stores a set of hexadecimal std::string conversion parameters for use >+// within `AlphaNum` std::string conversions. >+struct Hex { >+ uint64_t value; >+ uint8_t width; >+ char fill; >+ >+ template <typename Int> >+ explicit Hex( >+ Int v, PadSpec spec = absl::kNoPad, >+ typename std::enable_if<sizeof(Int) == 1 && >+ !std::is_pointer<Int>::value>::type* = nullptr) >+ : Hex(spec, static_cast<uint8_t>(v)) {} >+ template <typename Int> >+ explicit Hex( >+ Int v, PadSpec spec = absl::kNoPad, >+ typename std::enable_if<sizeof(Int) == 2 && >+ !std::is_pointer<Int>::value>::type* = nullptr) >+ : Hex(spec, static_cast<uint16_t>(v)) {} >+ template <typename Int> >+ explicit Hex( >+ Int v, PadSpec spec = absl::kNoPad, >+ typename std::enable_if<sizeof(Int) == 4 && >+ !std::is_pointer<Int>::value>::type* = nullptr) >+ : Hex(spec, static_cast<uint32_t>(v)) {} >+ template <typename Int> >+ explicit Hex( >+ Int v, PadSpec spec = absl::kNoPad, >+ typename std::enable_if<sizeof(Int) == 8 && >+ !std::is_pointer<Int>::value>::type* = nullptr) >+ : Hex(spec, static_cast<uint64_t>(v)) {} >+ template <typename Pointee> >+ explicit Hex(Pointee* v, PadSpec spec = absl::kNoPad) >+ : Hex(spec, reinterpret_cast<uintptr_t>(v)) {} >+ >+ private: >+ Hex(PadSpec spec, uint64_t v) >+ : value(v), >+ width(spec == absl::kNoPad >+ ? 1 >+ : spec >= absl::kSpacePad2 ? spec - absl::kSpacePad2 + 2 >+ : spec - absl::kZeroPad2 + 2), >+ fill(spec >= absl::kSpacePad2 ? ' ' : '0') {} >+}; >+ >+// ----------------------------------------------------------------------------- >+// Dec >+// ----------------------------------------------------------------------------- >+// >+// `Dec` stores a set of decimal std::string conversion parameters for use >+// within `AlphaNum` std::string conversions. Dec is slower than the default >+// integer conversion, so use it only if you need padding. >+struct Dec { >+ uint64_t value; >+ uint8_t width; >+ char fill; >+ bool neg; >+ >+ template <typename Int> >+ explicit Dec(Int v, PadSpec spec = absl::kNoPad, >+ typename std::enable_if<(sizeof(Int) <= 8)>::type* = nullptr) >+ : value(v >= 0 ? static_cast<uint64_t>(v) >+ : uint64_t{0} - static_cast<uint64_t>(v)), >+ width(spec == absl::kNoPad >+ ? 1 >+ : spec >= absl::kSpacePad2 ? spec - absl::kSpacePad2 + 2 >+ : spec - absl::kZeroPad2 + 2), >+ fill(spec >= absl::kSpacePad2 ? ' ' : '0'), >+ neg(v < 0) {} >+}; >+ >+// ----------------------------------------------------------------------------- >+// AlphaNum >+// ----------------------------------------------------------------------------- >+// >+// The `AlphaNum` class acts as the main parameter type for `StrCat()` and >+// `StrAppend()`, providing efficient conversion of numeric, boolean, and >+// hexadecimal values (through the `Hex` type) into strings. >+ >+class AlphaNum { >+ public: >+ // No bool ctor -- bools convert to an integral type. >+ // A bool ctor would also convert incoming pointers (bletch). >+ >+ AlphaNum(int x) // NOLINT(runtime/explicit) >+ : piece_(digits_, >+ numbers_internal::FastIntToBuffer(x, digits_) - &digits_[0]) {} >+ AlphaNum(unsigned int x) // NOLINT(runtime/explicit) >+ : piece_(digits_, >+ numbers_internal::FastIntToBuffer(x, digits_) - &digits_[0]) {} >+ AlphaNum(long x) // NOLINT(*) >+ : piece_(digits_, >+ numbers_internal::FastIntToBuffer(x, digits_) - &digits_[0]) {} >+ AlphaNum(unsigned long x) // NOLINT(*) >+ : piece_(digits_, >+ numbers_internal::FastIntToBuffer(x, digits_) - &digits_[0]) {} >+ AlphaNum(long long x) // NOLINT(*) >+ : piece_(digits_, >+ numbers_internal::FastIntToBuffer(x, digits_) - &digits_[0]) {} >+ AlphaNum(unsigned long long x) // NOLINT(*) >+ : piece_(digits_, >+ numbers_internal::FastIntToBuffer(x, digits_) - &digits_[0]) {} >+ >+ AlphaNum(float f) // NOLINT(runtime/explicit) >+ : piece_(digits_, numbers_internal::SixDigitsToBuffer(f, digits_)) {} >+ AlphaNum(double f) // NOLINT(runtime/explicit) >+ : piece_(digits_, numbers_internal::SixDigitsToBuffer(f, digits_)) {} >+ >+ AlphaNum(Hex hex); // NOLINT(runtime/explicit) >+ AlphaNum(Dec dec); // NOLINT(runtime/explicit) >+ >+ template <size_t size> >+ AlphaNum( // NOLINT(runtime/explicit) >+ const strings_internal::AlphaNumBuffer<size>& buf) >+ : piece_(&buf.data[0], buf.size) {} >+ >+ AlphaNum(const char* c_str) : piece_(c_str) {} // NOLINT(runtime/explicit) >+ AlphaNum(absl::string_view pc) : piece_(pc) {} // NOLINT(runtime/explicit) >+ template <typename Allocator> >+ AlphaNum( // NOLINT(runtime/explicit) >+ const std::basic_string<char, std::char_traits<char>, Allocator>& str) >+ : piece_(str) {} >+ >+ // Use std::string literals ":" instead of character literals ':'. >+ AlphaNum(char c) = delete; // NOLINT(runtime/explicit) >+ >+ AlphaNum(const AlphaNum&) = delete; >+ AlphaNum& operator=(const AlphaNum&) = delete; >+ >+ absl::string_view::size_type size() const { return piece_.size(); } >+ const char* data() const { return piece_.data(); } >+ absl::string_view Piece() const { return piece_; } >+ >+ // Normal enums are already handled by the integer formatters. >+ // This overload matches only scoped enums. >+ template <typename T, >+ typename = typename std::enable_if< >+ std::is_enum<T>{} && !std::is_convertible<T, int>{}>::type> >+ AlphaNum(T e) // NOLINT(runtime/explicit) >+ : AlphaNum(static_cast<typename std::underlying_type<T>::type>(e)) {} >+ >+ private: >+ absl::string_view piece_; >+ char digits_[numbers_internal::kFastToBufferSize]; >+}; >+ >+// ----------------------------------------------------------------------------- >+// StrCat() >+// ----------------------------------------------------------------------------- >+// >+// Merges given strings or numbers, using no delimiter(s). >+// >+// `StrCat()` is designed to be the fastest possible way to construct a std::string >+// out of a mix of raw C strings, string_views, strings, bool values, >+// and numeric values. >+// >+// Don't use `StrCat()` for user-visible strings. The localization process >+// works poorly on strings built up out of fragments. >+// >+// For clarity and performance, don't use `StrCat()` when appending to a >+// std::string. Use `StrAppend()` instead. In particular, avoid using any of these >+// (anti-)patterns: >+// >+// str.append(StrCat(...)) >+// str += StrCat(...) >+// str = StrCat(str, ...) >+// >+// The last case is the worst, with a potential to change a loop >+// from a linear time operation with O(1) dynamic allocations into a >+// quadratic time operation with O(n) dynamic allocations. >+// >+// See `StrAppend()` below for more information. >+ >+namespace strings_internal { >+ >+// Do not call directly - this is not part of the public API. >+std::string CatPieces(std::initializer_list<absl::string_view> pieces); >+void AppendPieces(std::string* dest, >+ std::initializer_list<absl::string_view> pieces); >+ >+} // namespace strings_internal >+ >+ABSL_MUST_USE_RESULT inline std::string StrCat() { return std::string(); } >+ >+ABSL_MUST_USE_RESULT inline std::string StrCat(const AlphaNum& a) { >+ return std::string(a.data(), a.size()); >+} >+ >+ABSL_MUST_USE_RESULT std::string StrCat(const AlphaNum& a, const AlphaNum& b); >+ABSL_MUST_USE_RESULT std::string StrCat(const AlphaNum& a, const AlphaNum& b, >+ const AlphaNum& c); >+ABSL_MUST_USE_RESULT std::string StrCat(const AlphaNum& a, const AlphaNum& b, >+ const AlphaNum& c, const AlphaNum& d); >+ >+// Support 5 or more arguments >+template <typename... AV> >+ABSL_MUST_USE_RESULT inline std::string StrCat(const AlphaNum& a, const AlphaNum& b, >+ const AlphaNum& c, const AlphaNum& d, >+ const AlphaNum& e, >+ const AV&... args) { >+ return strings_internal::CatPieces( >+ {a.Piece(), b.Piece(), c.Piece(), d.Piece(), e.Piece(), >+ static_cast<const AlphaNum&>(args).Piece()...}); >+} >+ >+// ----------------------------------------------------------------------------- >+// StrAppend() >+// ----------------------------------------------------------------------------- >+// >+// Appends a std::string or set of strings to an existing std::string, in a similar >+// fashion to `StrCat()`. >+// >+// WARNING: `StrAppend(&str, a, b, c, ...)` requires that none of the >+// a, b, c, parameters be a reference into str. For speed, `StrAppend()` does >+// not try to check each of its input arguments to be sure that they are not >+// a subset of the std::string being appended to. That is, while this will work: >+// >+// std::string s = "foo"; >+// s += s; >+// >+// This output is undefined: >+// >+// std::string s = "foo"; >+// StrAppend(&s, s); >+// >+// This output is undefined as well, since `absl::string_view` does not own its >+// data: >+// >+// std::string s = "foobar"; >+// absl::string_view p = s; >+// StrAppend(&s, p); >+ >+inline void StrAppend(std::string*) {} >+void StrAppend(std::string* dest, const AlphaNum& a); >+void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b); >+void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, >+ const AlphaNum& c); >+void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, >+ const AlphaNum& c, const AlphaNum& d); >+ >+// Support 5 or more arguments >+template <typename... AV> >+inline void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, >+ const AlphaNum& c, const AlphaNum& d, const AlphaNum& e, >+ const AV&... args) { >+ strings_internal::AppendPieces( >+ dest, {a.Piece(), b.Piece(), c.Piece(), d.Piece(), e.Piece(), >+ static_cast<const AlphaNum&>(args).Piece()...}); >+} >+ >+// Helper function for the future StrCat default floating-point format, %.6g >+// This is fast. >+inline strings_internal::AlphaNumBuffer< >+ numbers_internal::kSixDigitsToBufferSize> >+SixDigits(double d) { >+ strings_internal::AlphaNumBuffer<numbers_internal::kSixDigitsToBufferSize> >+ result; >+ result.size = numbers_internal::SixDigitsToBuffer(d, &result.data[0]); >+ return result; >+} >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_STR_CAT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..b6df9e309c4f8372368f00f1e4e3d59a7a9d3e9d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat_benchmark.cc >@@ -0,0 +1,140 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/str_cat.h" >+ >+#include <cstdint> >+#include <string> >+ >+#include "benchmark/benchmark.h" >+#include "absl/strings/substitute.h" >+ >+namespace { >+ >+const char kStringOne[] = "Once Upon A Time, "; >+const char kStringTwo[] = "There was a std::string benchmark"; >+ >+// We want to include negative numbers in the benchmark, so this function >+// is used to count 0, 1, -1, 2, -2, 3, -3, ... >+inline int IncrementAlternatingSign(int i) { >+ return i > 0 ? -i : 1 - i; >+} >+ >+void BM_Sum_By_StrCat(benchmark::State& state) { >+ int i = 0; >+ char foo[100]; >+ for (auto _ : state) { >+ // NOLINTNEXTLINE(runtime/printf) >+ strcpy(foo, absl::StrCat(kStringOne, i, kStringTwo, i * 65536ULL).c_str()); >+ int sum = 0; >+ for (char* f = &foo[0]; *f != 0; ++f) { >+ sum += *f; >+ } >+ benchmark::DoNotOptimize(sum); >+ i = IncrementAlternatingSign(i); >+ } >+} >+BENCHMARK(BM_Sum_By_StrCat); >+ >+void BM_StrCat_By_snprintf(benchmark::State& state) { >+ int i = 0; >+ char on_stack[1000]; >+ for (auto _ : state) { >+ snprintf(on_stack, sizeof(on_stack), "%s %s:%d", kStringOne, kStringTwo, i); >+ i = IncrementAlternatingSign(i); >+ } >+} >+BENCHMARK(BM_StrCat_By_snprintf); >+ >+void BM_StrCat_By_Strings(benchmark::State& state) { >+ int i = 0; >+ for (auto _ : state) { >+ std::string result = >+ std::string(kStringOne) + " " + kStringTwo + ":" + absl::StrCat(i); >+ benchmark::DoNotOptimize(result); >+ i = IncrementAlternatingSign(i); >+ } >+} >+BENCHMARK(BM_StrCat_By_Strings); >+ >+void BM_StrCat_By_StringOpPlus(benchmark::State& state) { >+ int i = 0; >+ for (auto _ : state) { >+ std::string result = kStringOne; >+ result += " "; >+ result += kStringTwo; >+ result += ":"; >+ result += absl::StrCat(i); >+ benchmark::DoNotOptimize(result); >+ i = IncrementAlternatingSign(i); >+ } >+} >+BENCHMARK(BM_StrCat_By_StringOpPlus); >+ >+void BM_StrCat_By_StrCat(benchmark::State& state) { >+ int i = 0; >+ for (auto _ : state) { >+ std::string result = absl::StrCat(kStringOne, " ", kStringTwo, ":", i); >+ benchmark::DoNotOptimize(result); >+ i = IncrementAlternatingSign(i); >+ } >+} >+BENCHMARK(BM_StrCat_By_StrCat); >+ >+void BM_HexCat_By_StrCat(benchmark::State& state) { >+ int i = 0; >+ for (auto _ : state) { >+ std::string result = >+ absl::StrCat(kStringOne, " ", absl::Hex(int64_t{i} + 0x10000000)); >+ benchmark::DoNotOptimize(result); >+ i = IncrementAlternatingSign(i); >+ } >+} >+BENCHMARK(BM_HexCat_By_StrCat); >+ >+void BM_HexCat_By_Substitute(benchmark::State& state) { >+ int i = 0; >+ for (auto _ : state) { >+ std::string result = absl::Substitute( >+ "$0 $1", kStringOne, reinterpret_cast<void*>(int64_t{i} + 0x10000000)); >+ benchmark::DoNotOptimize(result); >+ i = IncrementAlternatingSign(i); >+ } >+} >+BENCHMARK(BM_HexCat_By_Substitute); >+ >+void BM_FloatToString_By_StrCat(benchmark::State& state) { >+ int i = 0; >+ float foo = 0.0f; >+ for (auto _ : state) { >+ std::string result = absl::StrCat(foo += 1.001f, " != ", int64_t{i}); >+ benchmark::DoNotOptimize(result); >+ i = IncrementAlternatingSign(i); >+ } >+} >+BENCHMARK(BM_FloatToString_By_StrCat); >+ >+void BM_DoubleToString_By_SixDigits(benchmark::State& state) { >+ int i = 0; >+ double foo = 0.0; >+ for (auto _ : state) { >+ std::string result = >+ absl::StrCat(absl::SixDigits(foo += 1.001), " != ", int64_t{i}); >+ benchmark::DoNotOptimize(result); >+ i = IncrementAlternatingSign(i); >+ } >+} >+BENCHMARK(BM_DoubleToString_By_SixDigits); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e9d67690638271920d26234d9739053c30b27489 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_cat_test.cc >@@ -0,0 +1,549 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Unit tests for all str_cat.h functions >+ >+#include "absl/strings/str_cat.h" >+ >+#include <cstdint> >+#include <string> >+ >+#include "gtest/gtest.h" >+#include "absl/strings/substitute.h" >+ >+#ifdef __ANDROID__ >+// Android assert messages only go to system log, so death tests cannot inspect >+// the message for matching. >+#define ABSL_EXPECT_DEBUG_DEATH(statement, regex) \ >+ EXPECT_DEBUG_DEATH(statement, ".*") >+#else >+#define ABSL_EXPECT_DEBUG_DEATH EXPECT_DEBUG_DEATH >+#endif >+ >+namespace { >+ >+// Test absl::StrCat of ints and longs of various sizes and signdedness. >+TEST(StrCat, Ints) { >+ const short s = -1; // NOLINT(runtime/int) >+ const uint16_t us = 2; >+ const int i = -3; >+ const unsigned int ui = 4; >+ const long l = -5; // NOLINT(runtime/int) >+ const unsigned long ul = 6; // NOLINT(runtime/int) >+ const long long ll = -7; // NOLINT(runtime/int) >+ const unsigned long long ull = 8; // NOLINT(runtime/int) >+ const ptrdiff_t ptrdiff = -9; >+ const size_t size = 10; >+ const intptr_t intptr = -12; >+ const uintptr_t uintptr = 13; >+ std::string answer; >+ answer = absl::StrCat(s, us); >+ EXPECT_EQ(answer, "-12"); >+ answer = absl::StrCat(i, ui); >+ EXPECT_EQ(answer, "-34"); >+ answer = absl::StrCat(l, ul); >+ EXPECT_EQ(answer, "-56"); >+ answer = absl::StrCat(ll, ull); >+ EXPECT_EQ(answer, "-78"); >+ answer = absl::StrCat(ptrdiff, size); >+ EXPECT_EQ(answer, "-910"); >+ answer = absl::StrCat(ptrdiff, intptr); >+ EXPECT_EQ(answer, "-9-12"); >+ answer = absl::StrCat(uintptr, 0); >+ EXPECT_EQ(answer, "130"); >+} >+ >+TEST(StrCat, Enums) { >+ enum SmallNumbers { One = 1, Ten = 10 } e = Ten; >+ EXPECT_EQ("10", absl::StrCat(e)); >+ EXPECT_EQ("-5", absl::StrCat(SmallNumbers(-5))); >+ >+ enum class Option { Boxers = 1, Briefs = -1 }; >+ >+ EXPECT_EQ("-1", absl::StrCat(Option::Briefs)); >+ >+ enum class Airplane : uint64_t { >+ Airbus = 1, >+ Boeing = 1000, >+ Canary = 10000000000 // too big for "int" >+ }; >+ >+ EXPECT_EQ("10000000000", absl::StrCat(Airplane::Canary)); >+ >+ enum class TwoGig : int32_t { >+ TwoToTheZero = 1, >+ TwoToTheSixteenth = 1 << 16, >+ TwoToTheThirtyFirst = INT32_MIN >+ }; >+ EXPECT_EQ("65536", absl::StrCat(TwoGig::TwoToTheSixteenth)); >+ EXPECT_EQ("-2147483648", absl::StrCat(TwoGig::TwoToTheThirtyFirst)); >+ EXPECT_EQ("-1", absl::StrCat(static_cast<TwoGig>(-1))); >+ >+ enum class FourGig : uint32_t { >+ TwoToTheZero = 1, >+ TwoToTheSixteenth = 1 << 16, >+ TwoToTheThirtyFirst = 1U << 31 // too big for "int" >+ }; >+ EXPECT_EQ("65536", absl::StrCat(FourGig::TwoToTheSixteenth)); >+ EXPECT_EQ("2147483648", absl::StrCat(FourGig::TwoToTheThirtyFirst)); >+ EXPECT_EQ("4294967295", absl::StrCat(static_cast<FourGig>(-1))); >+ >+ EXPECT_EQ("10000000000", absl::StrCat(Airplane::Canary)); >+} >+ >+TEST(StrCat, Basics) { >+ std::string result; >+ >+ std::string strs[] = { >+ "Hello", >+ "Cruel", >+ "World" >+ }; >+ >+ std::string stdstrs[] = { >+ "std::Hello", >+ "std::Cruel", >+ "std::World" >+ }; >+ >+ absl::string_view pieces[] = {"Hello", "Cruel", "World"}; >+ >+ const char* c_strs[] = { >+ "Hello", >+ "Cruel", >+ "World" >+ }; >+ >+ int32_t i32s[] = {'H', 'C', 'W'}; >+ uint64_t ui64s[] = {12345678910LL, 10987654321LL}; >+ >+ EXPECT_EQ(absl::StrCat(), ""); >+ >+ result = absl::StrCat(false, true, 2, 3); >+ EXPECT_EQ(result, "0123"); >+ >+ result = absl::StrCat(-1); >+ EXPECT_EQ(result, "-1"); >+ >+ result = absl::StrCat(absl::SixDigits(0.5)); >+ EXPECT_EQ(result, "0.5"); >+ >+ result = absl::StrCat(strs[1], pieces[2]); >+ EXPECT_EQ(result, "CruelWorld"); >+ >+ result = absl::StrCat(stdstrs[1], " ", stdstrs[2]); >+ EXPECT_EQ(result, "std::Cruel std::World"); >+ >+ result = absl::StrCat(strs[0], ", ", pieces[2]); >+ EXPECT_EQ(result, "Hello, World"); >+ >+ result = absl::StrCat(strs[0], ", ", strs[1], " ", strs[2], "!"); >+ EXPECT_EQ(result, "Hello, Cruel World!"); >+ >+ result = absl::StrCat(pieces[0], ", ", pieces[1], " ", pieces[2]); >+ EXPECT_EQ(result, "Hello, Cruel World"); >+ >+ result = absl::StrCat(c_strs[0], ", ", c_strs[1], " ", c_strs[2]); >+ EXPECT_EQ(result, "Hello, Cruel World"); >+ >+ result = absl::StrCat("ASCII ", i32s[0], ", ", i32s[1], " ", i32s[2], "!"); >+ EXPECT_EQ(result, "ASCII 72, 67 87!"); >+ >+ result = absl::StrCat(ui64s[0], ", ", ui64s[1], "!"); >+ EXPECT_EQ(result, "12345678910, 10987654321!"); >+ >+ std::string one = "1"; // Actually, it's the size of this std::string that we want; a >+ // 64-bit build distinguishes between size_t and uint64_t, >+ // even though they're both unsigned 64-bit values. >+ result = absl::StrCat("And a ", one.size(), " and a ", >+ &result[2] - &result[0], " and a ", one, " 2 3 4", "!"); >+ EXPECT_EQ(result, "And a 1 and a 2 and a 1 2 3 4!"); >+ >+ // result = absl::StrCat("Single chars won't compile", '!'); >+ // result = absl::StrCat("Neither will nullptrs", nullptr); >+ result = >+ absl::StrCat("To output a char by ASCII/numeric value, use +: ", '!' + 0); >+ EXPECT_EQ(result, "To output a char by ASCII/numeric value, use +: 33"); >+ >+ float f = 100000.5; >+ result = absl::StrCat("A hundred K and a half is ", absl::SixDigits(f)); >+ EXPECT_EQ(result, "A hundred K and a half is 100000"); >+ >+ f = 100001.5; >+ result = >+ absl::StrCat("A hundred K and one and a half is ", absl::SixDigits(f)); >+ EXPECT_EQ(result, "A hundred K and one and a half is 100002"); >+ >+ double d = 100000.5; >+ d *= d; >+ result = >+ absl::StrCat("A hundred K and a half squared is ", absl::SixDigits(d)); >+ EXPECT_EQ(result, "A hundred K and a half squared is 1.00001e+10"); >+ >+ result = absl::StrCat(1, 2, 333, 4444, 55555, 666666, 7777777, 88888888, >+ 999999999); >+ EXPECT_EQ(result, "12333444455555666666777777788888888999999999"); >+} >+ >+// A minimal allocator that uses malloc(). >+template <typename T> >+struct Mallocator { >+ typedef T value_type; >+ typedef size_t size_type; >+ typedef ptrdiff_t difference_type; >+ typedef T* pointer; >+ typedef const T* const_pointer; >+ typedef T& reference; >+ typedef const T& const_reference; >+ >+ size_type max_size() const { >+ return size_t(std::numeric_limits<size_type>::max()) / sizeof(value_type); >+ } >+ template <typename U> >+ struct rebind { >+ typedef Mallocator<U> other; >+ }; >+ Mallocator() = default; >+ template <class U> >+ Mallocator(const Mallocator<U>&) {} // NOLINT(runtime/explicit) >+ >+ T* allocate(size_t n) { return static_cast<T*>(std::malloc(n * sizeof(T))); } >+ void deallocate(T* p, size_t) { std::free(p); } >+}; >+template <typename T, typename U> >+bool operator==(const Mallocator<T>&, const Mallocator<U>&) { >+ return true; >+} >+template <typename T, typename U> >+bool operator!=(const Mallocator<T>&, const Mallocator<U>&) { >+ return false; >+} >+ >+TEST(StrCat, CustomAllocator) { >+ using mstring = >+ std::basic_string<char, std::char_traits<char>, Mallocator<char>>; >+ const mstring str1("PARACHUTE OFF A BLIMP INTO MOSCONE!!"); >+ >+ const mstring str2("Read this book about coffee tables"); >+ >+ std::string result = absl::StrCat(str1, str2); >+ EXPECT_EQ(result, >+ "PARACHUTE OFF A BLIMP INTO MOSCONE!!" >+ "Read this book about coffee tables"); >+} >+ >+TEST(StrCat, MaxArgs) { >+ std::string result; >+ // Test 10 up to 26 arguments, the old maximum >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a"); >+ EXPECT_EQ(result, "123456789a"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b"); >+ EXPECT_EQ(result, "123456789ab"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c"); >+ EXPECT_EQ(result, "123456789abc"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d"); >+ EXPECT_EQ(result, "123456789abcd"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e"); >+ EXPECT_EQ(result, "123456789abcde"); >+ result = >+ absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f"); >+ EXPECT_EQ(result, "123456789abcdef"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g"); >+ EXPECT_EQ(result, "123456789abcdefg"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g", "h"); >+ EXPECT_EQ(result, "123456789abcdefgh"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g", "h", "i"); >+ EXPECT_EQ(result, "123456789abcdefghi"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g", "h", "i", "j"); >+ EXPECT_EQ(result, "123456789abcdefghij"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g", "h", "i", "j", "k"); >+ EXPECT_EQ(result, "123456789abcdefghijk"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g", "h", "i", "j", "k", "l"); >+ EXPECT_EQ(result, "123456789abcdefghijkl"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g", "h", "i", "j", "k", "l", "m"); >+ EXPECT_EQ(result, "123456789abcdefghijklm"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g", "h", "i", "j", "k", "l", "m", "n"); >+ EXPECT_EQ(result, "123456789abcdefghijklmn"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g", "h", "i", "j", "k", "l", "m", "n", "o"); >+ EXPECT_EQ(result, "123456789abcdefghijklmno"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"); >+ EXPECT_EQ(result, "123456789abcdefghijklmnop"); >+ result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f", >+ "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q"); >+ EXPECT_EQ(result, "123456789abcdefghijklmnopq"); >+ // No limit thanks to C++11's variadic templates >+ result = absl::StrCat( >+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "a", "b", "c", "d", "e", "f", "g", "h", >+ "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", >+ "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", >+ "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"); >+ EXPECT_EQ(result, >+ "12345678910abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); >+} >+ >+TEST(StrAppend, Basics) { >+ std::string result = "existing text"; >+ >+ std::string strs[] = { >+ "Hello", >+ "Cruel", >+ "World" >+ }; >+ >+ std::string stdstrs[] = { >+ "std::Hello", >+ "std::Cruel", >+ "std::World" >+ }; >+ >+ absl::string_view pieces[] = {"Hello", "Cruel", "World"}; >+ >+ const char* c_strs[] = { >+ "Hello", >+ "Cruel", >+ "World" >+ }; >+ >+ int32_t i32s[] = {'H', 'C', 'W'}; >+ uint64_t ui64s[] = {12345678910LL, 10987654321LL}; >+ >+ std::string::size_type old_size = result.size(); >+ absl::StrAppend(&result); >+ EXPECT_EQ(result.size(), old_size); >+ >+ old_size = result.size(); >+ absl::StrAppend(&result, strs[0]); >+ EXPECT_EQ(result.substr(old_size), "Hello"); >+ >+ old_size = result.size(); >+ absl::StrAppend(&result, strs[1], pieces[2]); >+ EXPECT_EQ(result.substr(old_size), "CruelWorld"); >+ >+ old_size = result.size(); >+ absl::StrAppend(&result, stdstrs[0], ", ", pieces[2]); >+ EXPECT_EQ(result.substr(old_size), "std::Hello, World"); >+ >+ old_size = result.size(); >+ absl::StrAppend(&result, strs[0], ", ", stdstrs[1], " ", strs[2], "!"); >+ EXPECT_EQ(result.substr(old_size), "Hello, std::Cruel World!"); >+ >+ old_size = result.size(); >+ absl::StrAppend(&result, pieces[0], ", ", pieces[1], " ", pieces[2]); >+ EXPECT_EQ(result.substr(old_size), "Hello, Cruel World"); >+ >+ old_size = result.size(); >+ absl::StrAppend(&result, c_strs[0], ", ", c_strs[1], " ", c_strs[2]); >+ EXPECT_EQ(result.substr(old_size), "Hello, Cruel World"); >+ >+ old_size = result.size(); >+ absl::StrAppend(&result, "ASCII ", i32s[0], ", ", i32s[1], " ", i32s[2], "!"); >+ EXPECT_EQ(result.substr(old_size), "ASCII 72, 67 87!"); >+ >+ old_size = result.size(); >+ absl::StrAppend(&result, ui64s[0], ", ", ui64s[1], "!"); >+ EXPECT_EQ(result.substr(old_size), "12345678910, 10987654321!"); >+ >+ std::string one = "1"; // Actually, it's the size of this std::string that we want; a >+ // 64-bit build distinguishes between size_t and uint64_t, >+ // even though they're both unsigned 64-bit values. >+ old_size = result.size(); >+ absl::StrAppend(&result, "And a ", one.size(), " and a ", >+ &result[2] - &result[0], " and a ", one, " 2 3 4", "!"); >+ EXPECT_EQ(result.substr(old_size), "And a 1 and a 2 and a 1 2 3 4!"); >+ >+ // result = absl::StrCat("Single chars won't compile", '!'); >+ // result = absl::StrCat("Neither will nullptrs", nullptr); >+ old_size = result.size(); >+ absl::StrAppend(&result, >+ "To output a char by ASCII/numeric value, use +: ", '!' + 0); >+ EXPECT_EQ(result.substr(old_size), >+ "To output a char by ASCII/numeric value, use +: 33"); >+ >+ // Test 9 arguments, the old maximum >+ old_size = result.size(); >+ absl::StrAppend(&result, 1, 22, 333, 4444, 55555, 666666, 7777777, 88888888, >+ 9); >+ EXPECT_EQ(result.substr(old_size), "1223334444555556666667777777888888889"); >+ >+ // No limit thanks to C++11's variadic templates >+ old_size = result.size(); >+ absl::StrAppend( >+ &result, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // >+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", // >+ "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", // >+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", // >+ "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", // >+ "No limit thanks to C++11's variadic templates"); >+ EXPECT_EQ(result.substr(old_size), >+ "12345678910abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" >+ "No limit thanks to C++11's variadic templates"); >+} >+ >+#ifdef GTEST_HAS_DEATH_TEST >+TEST(StrAppend, Death) { >+ std::string s = "self"; >+ // on linux it's "assertion", on mac it's "Assertion", >+ // on chromiumos it's "Assertion ... failed". >+ ABSL_EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s.c_str() + 1), >+ "ssertion.*failed"); >+ ABSL_EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s), "ssertion.*failed"); >+} >+#endif // GTEST_HAS_DEATH_TEST >+ >+TEST(StrAppend, EmptyString) { >+ std::string s = ""; >+ absl::StrAppend(&s, s); >+ EXPECT_EQ(s, ""); >+} >+ >+template <typename IntType> >+void CheckHex(IntType v, const char* nopad_format, const char* zeropad_format, >+ const char* spacepad_format) { >+ char expected[256]; >+ >+ std::string actual = absl::StrCat(absl::Hex(v, absl::kNoPad)); >+ snprintf(expected, sizeof(expected), nopad_format, v); >+ EXPECT_EQ(expected, actual) << " decimal value " << v; >+ >+ for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad16; ++spec) { >+ std::string actual = >+ absl::StrCat(absl::Hex(v, static_cast<absl::PadSpec>(spec))); >+ snprintf(expected, sizeof(expected), zeropad_format, >+ spec - absl::kZeroPad2 + 2, v); >+ EXPECT_EQ(expected, actual) << " decimal value " << v; >+ } >+ >+ for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad16; ++spec) { >+ std::string actual = >+ absl::StrCat(absl::Hex(v, static_cast<absl::PadSpec>(spec))); >+ snprintf(expected, sizeof(expected), spacepad_format, >+ spec - absl::kSpacePad2 + 2, v); >+ EXPECT_EQ(expected, actual) << " decimal value " << v; >+ } >+} >+ >+template <typename IntType> >+void CheckDec(IntType v, const char* nopad_format, const char* zeropad_format, >+ const char* spacepad_format) { >+ char expected[256]; >+ >+ std::string actual = absl::StrCat(absl::Dec(v, absl::kNoPad)); >+ snprintf(expected, sizeof(expected), nopad_format, v); >+ EXPECT_EQ(expected, actual) << " decimal value " << v; >+ >+ for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad16; ++spec) { >+ std::string actual = >+ absl::StrCat(absl::Dec(v, static_cast<absl::PadSpec>(spec))); >+ snprintf(expected, sizeof(expected), zeropad_format, >+ spec - absl::kZeroPad2 + 2, v); >+ EXPECT_EQ(expected, actual) >+ << " decimal value " << v << " format '" << zeropad_format >+ << "' digits " << (spec - absl::kZeroPad2 + 2); >+ } >+ >+ for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad16; ++spec) { >+ std::string actual = >+ absl::StrCat(absl::Dec(v, static_cast<absl::PadSpec>(spec))); >+ snprintf(expected, sizeof(expected), spacepad_format, >+ spec - absl::kSpacePad2 + 2, v); >+ EXPECT_EQ(expected, actual) >+ << " decimal value " << v << " format '" << spacepad_format >+ << "' digits " << (spec - absl::kSpacePad2 + 2); >+ } >+} >+ >+void CheckHexDec64(uint64_t v) { >+ unsigned long long ullv = v; // NOLINT(runtime/int) >+ >+ CheckHex(ullv, "%llx", "%0*llx", "%*llx"); >+ CheckDec(ullv, "%llu", "%0*llu", "%*llu"); >+ >+ long long llv = static_cast<long long>(ullv); // NOLINT(runtime/int) >+ CheckDec(llv, "%lld", "%0*lld", "%*lld"); >+ >+ if (sizeof(v) == sizeof(&v)) { >+ auto uintptr = static_cast<uintptr_t>(v); >+ void* ptr = reinterpret_cast<void*>(uintptr); >+ CheckHex(ptr, "%llx", "%0*llx", "%*llx"); >+ } >+} >+ >+void CheckHexDec32(uint32_t uv) { >+ CheckHex(uv, "%x", "%0*x", "%*x"); >+ CheckDec(uv, "%u", "%0*u", "%*u"); >+ int32_t v = static_cast<int32_t>(uv); >+ CheckDec(v, "%d", "%0*d", "%*d"); >+ >+ if (sizeof(v) == sizeof(&v)) { >+ auto uintptr = static_cast<uintptr_t>(v); >+ void* ptr = reinterpret_cast<void*>(uintptr); >+ CheckHex(ptr, "%x", "%0*x", "%*x"); >+ } >+} >+ >+void CheckAll(uint64_t v) { >+ CheckHexDec64(v); >+ CheckHexDec32(static_cast<uint32_t>(v)); >+} >+ >+void TestFastPrints() { >+ // Test all small ints; there aren't many and they're common. >+ for (int i = 0; i < 10000; i++) { >+ CheckAll(i); >+ } >+ >+ CheckAll(std::numeric_limits<uint64_t>::max()); >+ CheckAll(std::numeric_limits<uint64_t>::max() - 1); >+ CheckAll(std::numeric_limits<int64_t>::min()); >+ CheckAll(std::numeric_limits<int64_t>::min() + 1); >+ CheckAll(std::numeric_limits<uint32_t>::max()); >+ CheckAll(std::numeric_limits<uint32_t>::max() - 1); >+ CheckAll(std::numeric_limits<int32_t>::min()); >+ CheckAll(std::numeric_limits<int32_t>::min() + 1); >+ CheckAll(999999999); // fits in 32 bits >+ CheckAll(1000000000); // fits in 32 bits >+ CheckAll(9999999999); // doesn't fit in 32 bits >+ CheckAll(10000000000); // doesn't fit in 32 bits >+ CheckAll(999999999999999999); // fits in signed 64-bit >+ CheckAll(9999999999999999999u); // fits in unsigned 64-bit, but not signed. >+ CheckAll(1000000000000000000); // fits in signed 64-bit >+ CheckAll(10000000000000000000u); // fits in unsigned 64-bit, but not signed. >+ >+ CheckAll(999999999876543210); // check all decimal digits, signed >+ CheckAll(9999999999876543210u); // check all decimal digits, unsigned. >+ CheckAll(0x123456789abcdef0); // check all hex digits >+ CheckAll(0x12345678); >+ >+ int8_t minus_one_8bit = -1; >+ EXPECT_EQ("ff", absl::StrCat(absl::Hex(minus_one_8bit))); >+ >+ int16_t minus_one_16bit = -1; >+ EXPECT_EQ("ffff", absl::StrCat(absl::Hex(minus_one_16bit))); >+} >+ >+TEST(Numbers, TestFunctionsMovedOverFromNumbersMain) { >+ TestFastPrints(); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_format.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_format.h >new file mode 100644 >index 0000000000000000000000000000000000000000..70a811b75e2ff8863c9e3687c6c282f90c2317f9 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_format.h >@@ -0,0 +1,512 @@ >+// >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: str_format.h >+// ----------------------------------------------------------------------------- >+// >+// The `str_format` library is a typesafe replacement for the family of >+// `printf()` std::string formatting routines within the `<cstdio>` standard library >+// header. Like the `printf` family, the `str_format` uses a "format string" to >+// perform argument substitutions based on types. >+// >+// Example: >+// >+// std::string s = absl::StrFormat("%s %s You have $%d!", "Hello", name, dollars); >+// >+// The library consists of the following basic utilities: >+// >+// * `absl::StrFormat()`, a type-safe replacement for `std::sprintf()`, to >+// write a format std::string to a `string` value. >+// * `absl::StrAppendFormat()` to append a format std::string to a `string` >+// * `absl::StreamFormat()` to more efficiently write a format std::string to a >+// stream, such as`std::cout`. >+// * `absl::PrintF()`, `absl::FPrintF()` and `absl::SNPrintF()` as >+// replacements for `std::printf()`, `std::fprintf()` and `std::snprintf()`. >+// >+// Note: a version of `std::sprintf()` is not supported as it is >+// generally unsafe due to buffer overflows. >+// >+// Additionally, you can provide a format std::string (and its associated arguments) >+// using one of the following abstractions: >+// >+// * A `FormatSpec` class template fully encapsulates a format std::string and its >+// type arguments and is usually provided to `str_format` functions as a >+// variadic argument of type `FormatSpec<Arg...>`. The `FormatSpec<Args...>` >+// template is evaluated at compile-time, providing type safety. >+// * A `ParsedFormat` instance, which encapsulates a specific, pre-compiled >+// format std::string for a specific set of type(s), and which can be passed >+// between API boundaries. (The `FormatSpec` type should not be used >+// directly.) >+// >+// The `str_format` library provides the ability to output its format strings to >+// arbitrary sink types: >+// >+// * A generic `Format()` function to write outputs to arbitrary sink types, >+// which must implement a `RawSinkFormat` interface. (See >+// `str_format_sink.h` for more information.) >+// >+// * A `FormatUntyped()` function that is similar to `Format()` except it is >+// loosely typed. `FormatUntyped()` is not a template and does not perform >+// any compile-time checking of the format std::string; instead, it returns a >+// boolean from a runtime check. >+// >+// In addition, the `str_format` library provides extension points for >+// augmenting formatting to new types. These extensions are fully documented >+// within the `str_format_extension.h` header file. >+#ifndef ABSL_STRINGS_STR_FORMAT_H_ >+#define ABSL_STRINGS_STR_FORMAT_H_ >+ >+#include <cstdio> >+#include <string> >+ >+#include "absl/strings/internal/str_format/arg.h" // IWYU pragma: export >+#include "absl/strings/internal/str_format/bind.h" // IWYU pragma: export >+#include "absl/strings/internal/str_format/checker.h" // IWYU pragma: export >+#include "absl/strings/internal/str_format/extension.h" // IWYU pragma: export >+#include "absl/strings/internal/str_format/parser.h" // IWYU pragma: export >+ >+namespace absl { >+ >+// UntypedFormatSpec >+// >+// A type-erased class that can be used directly within untyped API entry >+// points. An `UntypedFormatSpec` is specifically used as an argument to >+// `FormatUntyped()`. >+// >+// Example: >+// >+// absl::UntypedFormatSpec format("%d"); >+// std::string out; >+// CHECK(absl::FormatUntyped(&out, format, {absl::FormatArg(1)})); >+class UntypedFormatSpec { >+ public: >+ UntypedFormatSpec() = delete; >+ UntypedFormatSpec(const UntypedFormatSpec&) = delete; >+ UntypedFormatSpec& operator=(const UntypedFormatSpec&) = delete; >+ >+ explicit UntypedFormatSpec(string_view s) : spec_(s) {} >+ >+ protected: >+ explicit UntypedFormatSpec(const str_format_internal::ParsedFormatBase* pc) >+ : spec_(pc) {} >+ >+ private: >+ friend str_format_internal::UntypedFormatSpecImpl; >+ str_format_internal::UntypedFormatSpecImpl spec_; >+}; >+ >+// FormatStreamed() >+// >+// Takes a streamable argument and returns an object that can print it >+// with '%s'. Allows printing of types that have an `operator<<` but no >+// intrinsic type support within `StrFormat()` itself. >+// >+// Example: >+// >+// absl::StrFormat("%s", absl::FormatStreamed(obj)); >+template <typename T> >+str_format_internal::StreamedWrapper<T> FormatStreamed(const T& v) { >+ return str_format_internal::StreamedWrapper<T>(v); >+} >+ >+// FormatCountCapture >+// >+// This class provides a way to safely wrap `StrFormat()` captures of `%n` >+// conversions, which denote the number of characters written by a formatting >+// operation to this point, into an integer value. >+// >+// This wrapper is designed to allow safe usage of `%n` within `StrFormat(); in >+// the `printf()` family of functions, `%n` is not safe to use, as the `int *` >+// buffer can be used to capture arbitrary data. >+// >+// Example: >+// >+// int n = 0; >+// std::string s = absl::StrFormat("%s%d%n", "hello", 123, >+// absl::FormatCountCapture(&n)); >+// EXPECT_EQ(8, n); >+class FormatCountCapture { >+ public: >+ explicit FormatCountCapture(int* p) : p_(p) {} >+ >+ private: >+ // FormatCountCaptureHelper is used to define FormatConvertImpl() for this >+ // class. >+ friend struct str_format_internal::FormatCountCaptureHelper; >+ // Unused() is here because of the false positive from -Wunused-private-field >+ // p_ is used in the templated function of the friend FormatCountCaptureHelper >+ // class. >+ int* Unused() { return p_; } >+ int* p_; >+}; >+ >+// FormatSpec >+// >+// The `FormatSpec` type defines the makeup of a format std::string within the >+// `str_format` library. You should not need to use or manipulate this type >+// directly. A `FormatSpec` is a variadic class template that is evaluated at >+// compile-time, according to the format std::string and arguments that are passed >+// to it. >+// >+// For a `FormatSpec` to be valid at compile-time, it must be provided as >+// either: >+// >+// * A `constexpr` literal or `absl::string_view`, which is how it most often >+// used. >+// * A `ParsedFormat` instantiation, which ensures the format std::string is >+// valid before use. (See below.) >+// >+// Example: >+// >+// // Provided as a std::string literal. >+// absl::StrFormat("Welcome to %s, Number %d!", "The Village", 6); >+// >+// // Provided as a constexpr absl::string_view. >+// constexpr absl::string_view formatString = "Welcome to %s, Number %d!"; >+// absl::StrFormat(formatString, "The Village", 6); >+// >+// // Provided as a pre-compiled ParsedFormat object. >+// // Note that this example is useful only for illustration purposes. >+// absl::ParsedFormat<'s', 'd'> formatString("Welcome to %s, Number %d!"); >+// absl::StrFormat(formatString, "TheVillage", 6); >+// >+// A format std::string generally follows the POSIX syntax as used within the POSIX >+// `printf` specification. >+// >+// (See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html.) >+// >+// In specific, the `FormatSpec` supports the following type specifiers: >+// * `c` for characters >+// * `s` for strings >+// * `d` or `i` for integers >+// * `o` for unsigned integer conversions into octal >+// * `x` or `X` for unsigned integer conversions into hex >+// * `u` for unsigned integers >+// * `f` or `F` for floating point values into decimal notation >+// * `e` or `E` for floating point values into exponential notation >+// * `a` or `A` for floating point values into hex exponential notation >+// * `g` or `G` for floating point values into decimal or exponential >+// notation based on their precision >+// * `p` for pointer address values >+// * `n` for the special case of writing out the number of characters >+// written to this point. The resulting value must be captured within an >+// `absl::FormatCountCapture` type. >+// >+// NOTE: `o`, `x\X` and `u` will convert signed values to their unsigned >+// counterpart before formatting. >+// >+// Examples: >+// "%c", 'a' -> "a" >+// "%c", 32 -> " " >+// "%s", "C" -> "C" >+// "%s", std::string("C++") -> "C++" >+// "%d", -10 -> "-10" >+// "%o", 10 -> "12" >+// "%x", 16 -> "10" >+// "%f", 123456789 -> "123456789.000000" >+// "%e", .01 -> "1.00000e-2" >+// "%a", -3.0 -> "-0x1.8p+1" >+// "%g", .01 -> "1e-2" >+// "%p", *int -> "0x7ffdeb6ad2a4" >+// >+// int n = 0; >+// std::string s = absl::StrFormat( >+// "%s%d%n", "hello", 123, absl::FormatCountCapture(&n)); >+// EXPECT_EQ(8, n); >+// >+// The `FormatSpec` intrinsically supports all of these fundamental C++ types: >+// >+// * Characters: `char`, `signed char`, `unsigned char` >+// * Integers: `int`, `short`, `unsigned short`, `unsigned`, `long`, >+// `unsigned long`, `long long`, `unsigned long long` >+// * Floating-point: `float`, `double`, `long double` >+// >+// However, in the `str_format` library, a format conversion specifies a broader >+// C++ conceptual category instead of an exact type. For example, `%s` binds to >+// any std::string-like argument, so `std::string`, `absl::string_view`, and >+// `const char*` are all accepted. Likewise, `%d` accepts any integer-like >+// argument, etc. >+ >+template <typename... Args> >+using FormatSpec = >+ typename str_format_internal::FormatSpecDeductionBarrier<Args...>::type; >+ >+// ParsedFormat >+// >+// A `ParsedFormat` is a class template representing a preparsed `FormatSpec`, >+// with template arguments specifying the conversion characters used within the >+// format std::string. Such characters must be valid format type specifiers, and >+// these type specifiers are checked at compile-time. >+// >+// Instances of `ParsedFormat` can be created, copied, and reused to speed up >+// formatting loops. A `ParsedFormat` may either be constructed statically, or >+// dynamically through its `New()` factory function, which only constructs a >+// runtime object if the format is valid at that time. >+// >+// Example: >+// >+// // Verified at compile time. >+// absl::ParsedFormat<'s', 'd'> formatString("Welcome to %s, Number %d!"); >+// absl::StrFormat(formatString, "TheVillage", 6); >+// >+// // Verified at runtime. >+// auto format_runtime = absl::ParsedFormat<'d'>::New(format_string); >+// if (format_runtime) { >+// value = absl::StrFormat(*format_runtime, i); >+// } else { >+// ... error case ... >+// } >+template <char... Conv> >+using ParsedFormat = str_format_internal::ExtendedParsedFormat< >+ str_format_internal::ConversionCharToConv(Conv)...>; >+ >+// StrFormat() >+// >+// Returns a `string` given a `printf()`-style format std::string and zero or more >+// additional arguments. Use it as you would `sprintf()`. `StrFormat()` is the >+// primary formatting function within the `str_format` library, and should be >+// used in most cases where you need type-safe conversion of types into >+// formatted strings. >+// >+// The format std::string generally consists of ordinary character data along with >+// one or more format conversion specifiers (denoted by the `%` character). >+// Ordinary character data is returned unchanged into the result std::string, while >+// each conversion specification performs a type substitution from >+// `StrFormat()`'s other arguments. See the comments for `FormatSpec` for full >+// information on the makeup of this format std::string. >+// >+// Example: >+// >+// std::string s = absl::StrFormat( >+// "Welcome to %s, Number %d!", "The Village", 6); >+// EXPECT_EQ("Welcome to The Village, Number 6!", s); >+// >+// Returns an empty std::string in case of error. >+template <typename... Args> >+ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec<Args...>& format, >+ const Args&... args) { >+ return str_format_internal::FormatPack( >+ str_format_internal::UntypedFormatSpecImpl::Extract(format), >+ {str_format_internal::FormatArgImpl(args)...}); >+} >+ >+// StrAppendFormat() >+// >+// Appends to a `dst` std::string given a format std::string, and zero or more additional >+// arguments, returning `*dst` as a convenience for chaining purposes. Appends >+// nothing in case of error (but possibly alters its capacity). >+// >+// Example: >+// >+// std::string orig("For example PI is approximately "); >+// std::cout << StrAppendFormat(&orig, "%12.6f", 3.14); >+template <typename... Args> >+std::string& StrAppendFormat(std::string* dst, const FormatSpec<Args...>& format, >+ const Args&... args) { >+ return str_format_internal::AppendPack( >+ dst, str_format_internal::UntypedFormatSpecImpl::Extract(format), >+ {str_format_internal::FormatArgImpl(args)...}); >+} >+ >+// StreamFormat() >+// >+// Writes to an output stream given a format std::string and zero or more arguments, >+// generally in a manner that is more efficient than streaming the result of >+// `absl:: StrFormat()`. The returned object must be streamed before the full >+// expression ends. >+// >+// Example: >+// >+// std::cout << StreamFormat("%12.6f", 3.14); >+template <typename... Args> >+ABSL_MUST_USE_RESULT str_format_internal::Streamable StreamFormat( >+ const FormatSpec<Args...>& format, const Args&... args) { >+ return str_format_internal::Streamable( >+ str_format_internal::UntypedFormatSpecImpl::Extract(format), >+ {str_format_internal::FormatArgImpl(args)...}); >+} >+ >+// PrintF() >+// >+// Writes to stdout given a format std::string and zero or more arguments. This >+// function is functionally equivalent to `std::printf()` (and type-safe); >+// prefer `absl::PrintF()` over `std::printf()`. >+// >+// Example: >+// >+// std::string_view s = "Ulaanbaatar"; >+// absl::PrintF("The capital of Mongolia is %s", s); >+// >+// Outputs: "The capital of Mongolia is Ulaanbaatar" >+// >+template <typename... Args> >+int PrintF(const FormatSpec<Args...>& format, const Args&... args) { >+ return str_format_internal::FprintF( >+ stdout, str_format_internal::UntypedFormatSpecImpl::Extract(format), >+ {str_format_internal::FormatArgImpl(args)...}); >+} >+ >+// FPrintF() >+// >+// Writes to a file given a format std::string and zero or more arguments. This >+// function is functionally equivalent to `std::fprintf()` (and type-safe); >+// prefer `absl::FPrintF()` over `std::fprintf()`. >+// >+// Example: >+// >+// std::string_view s = "Ulaanbaatar"; >+// absl::FPrintF("The capital of Mongolia is %s", s); >+// >+// Outputs: "The capital of Mongolia is Ulaanbaatar" >+// >+template <typename... Args> >+int FPrintF(std::FILE* output, const FormatSpec<Args...>& format, >+ const Args&... args) { >+ return str_format_internal::FprintF( >+ output, str_format_internal::UntypedFormatSpecImpl::Extract(format), >+ {str_format_internal::FormatArgImpl(args)...}); >+} >+ >+// SNPrintF() >+// >+// Writes to a sized buffer given a format std::string and zero or more arguments. >+// This function is functionally equivalent to `std::snprintf()` (and >+// type-safe); prefer `absl::SNPrintF()` over `std::snprintf()`. >+// >+// Example: >+// >+// std::string_view s = "Ulaanbaatar"; >+// char output[128]; >+// absl::SNPrintF(output, sizeof(output), >+// "The capital of Mongolia is %s", s); >+// >+// Post-condition: output == "The capital of Mongolia is Ulaanbaatar" >+// >+template <typename... Args> >+int SNPrintF(char* output, std::size_t size, const FormatSpec<Args...>& format, >+ const Args&... args) { >+ return str_format_internal::SnprintF( >+ output, size, str_format_internal::UntypedFormatSpecImpl::Extract(format), >+ {str_format_internal::FormatArgImpl(args)...}); >+} >+ >+// ----------------------------------------------------------------------------- >+// Custom Output Formatting Functions >+// ----------------------------------------------------------------------------- >+ >+// FormatRawSink >+// >+// FormatRawSink is a type erased wrapper around arbitrary sink objects >+// specifically used as an argument to `Format()`. >+// FormatRawSink does not own the passed sink object. The passed object must >+// outlive the FormatRawSink. >+class FormatRawSink { >+ public: >+ // Implicitly convert from any type that provides the hook function as >+ // described above. >+ template <typename T, >+ typename = typename std::enable_if<std::is_constructible< >+ str_format_internal::FormatRawSinkImpl, T*>::value>::type> >+ FormatRawSink(T* raw) // NOLINT >+ : sink_(raw) {} >+ >+ private: >+ friend str_format_internal::FormatRawSinkImpl; >+ str_format_internal::FormatRawSinkImpl sink_; >+}; >+ >+// Format() >+// >+// Writes a formatted std::string to an arbitrary sink object (implementing the >+// `absl::FormatRawSink` interface), using a format std::string and zero or more >+// additional arguments. >+// >+// By default, `string` and `std::ostream` are supported as destination objects. >+// >+// `absl::Format()` is a generic version of `absl::StrFormat(), for custom >+// sinks. The format std::string, like format strings for `StrFormat()`, is checked >+// at compile-time. >+// >+// On failure, this function returns `false` and the state of the sink is >+// unspecified. >+template <typename... Args> >+bool Format(FormatRawSink raw_sink, const FormatSpec<Args...>& format, >+ const Args&... args) { >+ return str_format_internal::FormatUntyped( >+ str_format_internal::FormatRawSinkImpl::Extract(raw_sink), >+ str_format_internal::UntypedFormatSpecImpl::Extract(format), >+ {str_format_internal::FormatArgImpl(args)...}); >+} >+ >+// FormatArg >+// >+// A type-erased handle to a format argument specifically used as an argument to >+// `FormatUntyped()`. You may construct `FormatArg` by passing >+// reference-to-const of any printable type. `FormatArg` is both copyable and >+// assignable. The source data must outlive the `FormatArg` instance. See >+// example below. >+// >+using FormatArg = str_format_internal::FormatArgImpl; >+ >+// FormatUntyped() >+// >+// Writes a formatted std::string to an arbitrary sink object (implementing the >+// `absl::FormatRawSink` interface), using an `UntypedFormatSpec` and zero or >+// more additional arguments. >+// >+// This function acts as the most generic formatting function in the >+// `str_format` library. The caller provides a raw sink, an unchecked format >+// std::string, and (usually) a runtime specified list of arguments; no compile-time >+// checking of formatting is performed within this function. As a result, a >+// caller should check the return value to verify that no error occurred. >+// On failure, this function returns `false` and the state of the sink is >+// unspecified. >+// >+// The arguments are provided in an `absl::Span<const absl::FormatArg>`. >+// Each `absl::FormatArg` object binds to a single argument and keeps a >+// reference to it. The values used to create the `FormatArg` objects must >+// outlive this function call. (See `str_format_arg.h` for information on >+// the `FormatArg` class.)_ >+// >+// Example: >+// >+// std::optional<std::string> FormatDynamic(const std::string& in_format, >+// const vector<std::string>& in_args) { >+// std::string out; >+// std::vector<absl::FormatArg> args; >+// for (const auto& v : in_args) { >+// // It is important that 'v' is a reference to the objects in in_args. >+// // The values we pass to FormatArg must outlive the call to >+// // FormatUntyped. >+// args.emplace_back(v); >+// } >+// absl::UntypedFormatSpec format(in_format); >+// if (!absl::FormatUntyped(&out, format, args)) { >+// return std::nullopt; >+// } >+// return std::move(out); >+// } >+// >+ABSL_MUST_USE_RESULT inline bool FormatUntyped( >+ FormatRawSink raw_sink, const UntypedFormatSpec& format, >+ absl::Span<const FormatArg> args) { >+ return str_format_internal::FormatUntyped( >+ str_format_internal::FormatRawSinkImpl::Extract(raw_sink), >+ str_format_internal::UntypedFormatSpecImpl::Extract(format), args); >+} >+ >+} // namespace absl >+#endif // ABSL_STRINGS_STR_FORMAT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_format_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_format_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..fed75fafb5c65c11b92f8edbca538a4acdd1177c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_format_test.cc >@@ -0,0 +1,603 @@ >+ >+#include <cstdarg> >+#include <cstdint> >+#include <cstdio> >+#include <string> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/strings/str_format.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+namespace { >+using str_format_internal::FormatArgImpl; >+ >+class FormatEntryPointTest : public ::testing::Test { }; >+ >+TEST_F(FormatEntryPointTest, Format) { >+ std::string sink; >+ EXPECT_TRUE(Format(&sink, "A format %d", 123)); >+ EXPECT_EQ("A format 123", sink); >+ sink.clear(); >+ >+ ParsedFormat<'d'> pc("A format %d"); >+ EXPECT_TRUE(Format(&sink, pc, 123)); >+ EXPECT_EQ("A format 123", sink); >+} >+TEST_F(FormatEntryPointTest, UntypedFormat) { >+ constexpr const char* formats[] = { >+ "", >+ "a", >+ "%80d", >+#if !defined(_MSC_VER) && !defined(__ANDROID__) >+ // MSVC and Android don't support positional syntax. >+ "complicated multipart %% %1$d format %1$0999d", >+#endif // _MSC_VER >+ }; >+ for (const char* fmt : formats) { >+ std::string actual; >+ int i = 123; >+ FormatArgImpl arg_123(i); >+ absl::Span<const FormatArgImpl> args(&arg_123, 1); >+ UntypedFormatSpec format(fmt); >+ >+ EXPECT_TRUE(FormatUntyped(&actual, format, args)); >+ char buf[4096]{}; >+ snprintf(buf, sizeof(buf), fmt, 123); >+ EXPECT_EQ( >+ str_format_internal::FormatPack( >+ str_format_internal::UntypedFormatSpecImpl::Extract(format), args), >+ buf); >+ EXPECT_EQ(actual, buf); >+ } >+ // The internal version works with a preparsed format. >+ ParsedFormat<'d'> pc("A format %d"); >+ int i = 345; >+ FormatArg arg(i); >+ std::string out; >+ EXPECT_TRUE(str_format_internal::FormatUntyped( >+ &out, str_format_internal::UntypedFormatSpecImpl(&pc), {&arg, 1})); >+ EXPECT_EQ("A format 345", out); >+} >+ >+TEST_F(FormatEntryPointTest, StringFormat) { >+ EXPECT_EQ("123", StrFormat("%d", 123)); >+ constexpr absl::string_view view("=%d=", 4); >+ EXPECT_EQ("=123=", StrFormat(view, 123)); >+} >+ >+TEST_F(FormatEntryPointTest, AppendFormat) { >+ std::string s; >+ std::string& r = StrAppendFormat(&s, "%d", 123); >+ EXPECT_EQ(&s, &r); // should be same object >+ EXPECT_EQ("123", r); >+} >+ >+TEST_F(FormatEntryPointTest, AppendFormatFail) { >+ std::string s = "orig"; >+ >+ UntypedFormatSpec format(" more %d"); >+ FormatArgImpl arg("not an int"); >+ >+ EXPECT_EQ("orig", >+ str_format_internal::AppendPack( >+ &s, str_format_internal::UntypedFormatSpecImpl::Extract(format), >+ {&arg, 1})); >+} >+ >+ >+TEST_F(FormatEntryPointTest, ManyArgs) { >+ EXPECT_EQ("24", StrFormat("%24$d", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, >+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24)); >+ EXPECT_EQ("60", StrFormat("%60$d", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, >+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, >+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, >+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, >+ 53, 54, 55, 56, 57, 58, 59, 60)); >+} >+ >+TEST_F(FormatEntryPointTest, Preparsed) { >+ ParsedFormat<'d'> pc("%d"); >+ EXPECT_EQ("123", StrFormat(pc, 123)); >+ // rvalue ok? >+ EXPECT_EQ("123", StrFormat(ParsedFormat<'d'>("%d"), 123)); >+ constexpr absl::string_view view("=%d=", 4); >+ EXPECT_EQ("=123=", StrFormat(ParsedFormat<'d'>(view), 123)); >+} >+ >+TEST_F(FormatEntryPointTest, FormatCountCapture) { >+ int n = 0; >+ EXPECT_EQ("", StrFormat("%n", FormatCountCapture(&n))); >+ EXPECT_EQ(0, n); >+ EXPECT_EQ("123", StrFormat("%d%n", 123, FormatCountCapture(&n))); >+ EXPECT_EQ(3, n); >+} >+ >+TEST_F(FormatEntryPointTest, FormatCountCaptureWrongType) { >+ // Should reject int*. >+ int n = 0; >+ UntypedFormatSpec format("%d%n"); >+ int i = 123, *ip = &n; >+ FormatArgImpl args[2] = {FormatArgImpl(i), FormatArgImpl(ip)}; >+ >+ EXPECT_EQ("", str_format_internal::FormatPack( >+ str_format_internal::UntypedFormatSpecImpl::Extract(format), >+ absl::MakeSpan(args))); >+} >+ >+TEST_F(FormatEntryPointTest, FormatCountCaptureMultiple) { >+ int n1 = 0; >+ int n2 = 0; >+ EXPECT_EQ(" 1 2", >+ StrFormat("%5d%n%10d%n", 1, FormatCountCapture(&n1), 2, >+ FormatCountCapture(&n2))); >+ EXPECT_EQ(5, n1); >+ EXPECT_EQ(15, n2); >+} >+ >+TEST_F(FormatEntryPointTest, FormatCountCaptureExample) { >+ int n; >+ std::string s; >+ StrAppendFormat(&s, "%s: %n%s\n", "(1,1)", FormatCountCapture(&n), "(1,2)"); >+ StrAppendFormat(&s, "%*s%s\n", n, "", "(2,2)"); >+ EXPECT_EQ(7, n); >+ EXPECT_EQ( >+ "(1,1): (1,2)\n" >+ " (2,2)\n", >+ s); >+} >+ >+TEST_F(FormatEntryPointTest, Stream) { >+ const std::string formats[] = { >+ "", >+ "a", >+ "%80d", >+#if !defined(_MSC_VER) && !defined(__ANDROID__) >+ // MSVC doesn't support positional syntax. >+ "complicated multipart %% %1$d format %1$080d", >+#endif // _MSC_VER >+ }; >+ std::string buf(4096, '\0'); >+ for (const auto& fmt : formats) { >+ const auto parsed = ParsedFormat<'d'>::NewAllowIgnored(fmt); >+ std::ostringstream oss; >+ oss << StreamFormat(*parsed, 123); >+ int fmt_result = snprintf(&*buf.begin(), buf.size(), fmt.c_str(), 123); >+ ASSERT_TRUE(oss) << fmt; >+ ASSERT_TRUE(fmt_result >= 0 && static_cast<size_t>(fmt_result) < buf.size()) >+ << fmt_result; >+ EXPECT_EQ(buf.c_str(), oss.str()); >+ } >+} >+ >+TEST_F(FormatEntryPointTest, StreamOk) { >+ std::ostringstream oss; >+ oss << StreamFormat("hello %d", 123); >+ EXPECT_EQ("hello 123", oss.str()); >+ EXPECT_TRUE(oss.good()); >+} >+ >+TEST_F(FormatEntryPointTest, StreamFail) { >+ std::ostringstream oss; >+ UntypedFormatSpec format("hello %d"); >+ FormatArgImpl arg("non-numeric"); >+ oss << str_format_internal::Streamable( >+ str_format_internal::UntypedFormatSpecImpl::Extract(format), {&arg, 1}); >+ EXPECT_EQ("hello ", oss.str()); // partial write >+ EXPECT_TRUE(oss.fail()); >+} >+ >+std::string WithSnprintf(const char* fmt, ...) { >+ std::string buf; >+ buf.resize(128); >+ va_list va; >+ va_start(va, fmt); >+ int r = vsnprintf(&*buf.begin(), buf.size(), fmt, va); >+ va_end(va); >+ EXPECT_GE(r, 0); >+ EXPECT_LT(r, buf.size()); >+ buf.resize(r); >+ return buf; >+} >+ >+TEST_F(FormatEntryPointTest, FloatPrecisionArg) { >+ // Test that positional parameters for width and precision >+ // are indexed to precede the value. >+ // Also sanity check the same formats against snprintf. >+ EXPECT_EQ("0.1", StrFormat("%.1f", 0.1)); >+ EXPECT_EQ("0.1", WithSnprintf("%.1f", 0.1)); >+ EXPECT_EQ(" 0.1", StrFormat("%*.1f", 5, 0.1)); >+ EXPECT_EQ(" 0.1", WithSnprintf("%*.1f", 5, 0.1)); >+ EXPECT_EQ("0.1", StrFormat("%.*f", 1, 0.1)); >+ EXPECT_EQ("0.1", WithSnprintf("%.*f", 1, 0.1)); >+ EXPECT_EQ(" 0.1", StrFormat("%*.*f", 5, 1, 0.1)); >+ EXPECT_EQ(" 0.1", WithSnprintf("%*.*f", 5, 1, 0.1)); >+} >+namespace streamed_test { >+struct X {}; >+std::ostream& operator<<(std::ostream& os, const X&) { >+ return os << "X"; >+} >+} // streamed_test >+ >+TEST_F(FormatEntryPointTest, FormatStreamed) { >+ EXPECT_EQ("123", StrFormat("%s", FormatStreamed(123))); >+ EXPECT_EQ(" 123", StrFormat("%5s", FormatStreamed(123))); >+ EXPECT_EQ("123 ", StrFormat("%-5s", FormatStreamed(123))); >+ EXPECT_EQ("X", StrFormat("%s", FormatStreamed(streamed_test::X()))); >+ EXPECT_EQ("123", StrFormat("%s", FormatStreamed(StreamFormat("%d", 123)))); >+} >+ >+// Helper class that creates a temporary file and exposes a FILE* to it. >+// It will close the file on destruction. >+class TempFile { >+ public: >+ TempFile() : file_(std::tmpfile()) {} >+ ~TempFile() { std::fclose(file_); } >+ >+ std::FILE* file() const { return file_; } >+ >+ // Read the file into a std::string. >+ std::string ReadFile() { >+ std::fseek(file_, 0, SEEK_END); >+ int size = std::ftell(file_); >+ std::rewind(file_); >+ std::string str(2 * size, ' '); >+ int read_bytes = std::fread(&str[0], 1, str.size(), file_); >+ EXPECT_EQ(read_bytes, size); >+ str.resize(read_bytes); >+ EXPECT_TRUE(std::feof(file_)); >+ return str; >+ } >+ >+ private: >+ std::FILE* file_; >+}; >+ >+TEST_F(FormatEntryPointTest, FPrintF) { >+ TempFile tmp; >+ int result = >+ FPrintF(tmp.file(), "STRING: %s NUMBER: %010d", std::string("ABC"), -19); >+ EXPECT_EQ(result, 30); >+ EXPECT_EQ(tmp.ReadFile(), "STRING: ABC NUMBER: -000000019"); >+} >+ >+TEST_F(FormatEntryPointTest, FPrintFError) { >+ errno = 0; >+ int result = FPrintF(stdin, "ABC"); >+ EXPECT_LT(result, 0); >+ EXPECT_EQ(errno, EBADF); >+} >+ >+#if __GNUC__ >+TEST_F(FormatEntryPointTest, FprintfTooLarge) { >+ std::FILE* f = std::fopen("/dev/null", "w"); >+ int width = 2000000000; >+ errno = 0; >+ int result = FPrintF(f, "%*d %*d", width, 0, width, 0); >+ EXPECT_LT(result, 0); >+ EXPECT_EQ(errno, EFBIG); >+ std::fclose(f); >+} >+ >+TEST_F(FormatEntryPointTest, PrintF) { >+ int stdout_tmp = dup(STDOUT_FILENO); >+ >+ TempFile tmp; >+ std::fflush(stdout); >+ dup2(fileno(tmp.file()), STDOUT_FILENO); >+ >+ int result = PrintF("STRING: %s NUMBER: %010d", std::string("ABC"), -19); >+ >+ std::fflush(stdout); >+ dup2(stdout_tmp, STDOUT_FILENO); >+ close(stdout_tmp); >+ >+ EXPECT_EQ(result, 30); >+ EXPECT_EQ(tmp.ReadFile(), "STRING: ABC NUMBER: -000000019"); >+} >+#endif // __GNUC__ >+ >+TEST_F(FormatEntryPointTest, SNPrintF) { >+ char buffer[16]; >+ int result = >+ SNPrintF(buffer, sizeof(buffer), "STRING: %s", std::string("ABC")); >+ EXPECT_EQ(result, 11); >+ EXPECT_EQ(std::string(buffer), "STRING: ABC"); >+ >+ result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 123456); >+ EXPECT_EQ(result, 14); >+ EXPECT_EQ(std::string(buffer), "NUMBER: 123456"); >+ >+ result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 1234567); >+ EXPECT_EQ(result, 15); >+ EXPECT_EQ(std::string(buffer), "NUMBER: 1234567"); >+ >+ result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 12345678); >+ EXPECT_EQ(result, 16); >+ EXPECT_EQ(std::string(buffer), "NUMBER: 1234567"); >+ >+ result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 123456789); >+ EXPECT_EQ(result, 17); >+ EXPECT_EQ(std::string(buffer), "NUMBER: 1234567"); >+ >+ result = SNPrintF(nullptr, 0, "Just checking the %s of the output.", "size"); >+ EXPECT_EQ(result, 37); >+} >+ >+TEST(StrFormat, BehavesAsDocumented) { >+ std::string s = absl::StrFormat("%s, %d!", "Hello", 123); >+ EXPECT_EQ("Hello, 123!", s); >+ // The format of a replacement is >+ // '%'[position][flags][width['.'precision]][length_modifier][format] >+ EXPECT_EQ(absl::StrFormat("%1$+3.2Lf", 1.1), "+1.10"); >+ // Text conversion: >+ // "c" - Character. Eg: 'a' -> "A", 20 -> " " >+ EXPECT_EQ(StrFormat("%c", 'a'), "a"); >+ EXPECT_EQ(StrFormat("%c", 0x20), " "); >+ // Formats char and integral types: int, long, uint64_t, etc. >+ EXPECT_EQ(StrFormat("%c", int{'a'}), "a"); >+ EXPECT_EQ(StrFormat("%c", long{'a'}), "a"); // NOLINT >+ EXPECT_EQ(StrFormat("%c", uint64_t{'a'}), "a"); >+ // "s" - std::string Eg: "C" -> "C", std::string("C++") -> "C++" >+ // Formats std::string, char*, string_view, and Cord. >+ EXPECT_EQ(StrFormat("%s", "C"), "C"); >+ EXPECT_EQ(StrFormat("%s", std::string("C++")), "C++"); >+ EXPECT_EQ(StrFormat("%s", string_view("view")), "view"); >+ // Integral Conversion >+ // These format integral types: char, int, long, uint64_t, etc. >+ EXPECT_EQ(StrFormat("%d", char{10}), "10"); >+ EXPECT_EQ(StrFormat("%d", int{10}), "10"); >+ EXPECT_EQ(StrFormat("%d", long{10}), "10"); // NOLINT >+ EXPECT_EQ(StrFormat("%d", uint64_t{10}), "10"); >+ // d,i - signed decimal Eg: -10 -> "-10" >+ EXPECT_EQ(StrFormat("%d", -10), "-10"); >+ EXPECT_EQ(StrFormat("%i", -10), "-10"); >+ // o - octal Eg: 10 -> "12" >+ EXPECT_EQ(StrFormat("%o", 10), "12"); >+ // u - unsigned decimal Eg: 10 -> "10" >+ EXPECT_EQ(StrFormat("%u", 10), "10"); >+ // x/X - lower,upper case hex Eg: 10 -> "a"/"A" >+ EXPECT_EQ(StrFormat("%x", 10), "a"); >+ EXPECT_EQ(StrFormat("%X", 10), "A"); >+ // Floating-point, with upper/lower-case output. >+ // These format floating points types: float, double, long double, etc. >+ EXPECT_EQ(StrFormat("%.1f", float{1}), "1.0"); >+ EXPECT_EQ(StrFormat("%.1f", double{1}), "1.0"); >+ const long double long_double = 1.0; >+ EXPECT_EQ(StrFormat("%.1f", long_double), "1.0"); >+ // These also format integral types: char, int, long, uint64_t, etc.: >+ EXPECT_EQ(StrFormat("%.1f", char{1}), "1.0"); >+ EXPECT_EQ(StrFormat("%.1f", int{1}), "1.0"); >+ EXPECT_EQ(StrFormat("%.1f", long{1}), "1.0"); // NOLINT >+ EXPECT_EQ(StrFormat("%.1f", uint64_t{1}), "1.0"); >+ // f/F - decimal. Eg: 123456789 -> "123456789.000000" >+ EXPECT_EQ(StrFormat("%f", 123456789), "123456789.000000"); >+ EXPECT_EQ(StrFormat("%F", 123456789), "123456789.000000"); >+ // e/E - exponentiated Eg: .01 -> "1.00000e-2"/"1.00000E-2" >+ EXPECT_EQ(StrFormat("%e", .01), "1.000000e-02"); >+ EXPECT_EQ(StrFormat("%E", .01), "1.000000E-02"); >+ // g/G - exponentiate to fit Eg: .01 -> "0.01", 1e10 ->"1e+10"/"1E+10" >+ EXPECT_EQ(StrFormat("%g", .01), "0.01"); >+ EXPECT_EQ(StrFormat("%g", 1e10), "1e+10"); >+ EXPECT_EQ(StrFormat("%G", 1e10), "1E+10"); >+ // a/A - lower,upper case hex Eg: -3.0 -> "-0x1.8p+1"/"-0X1.8P+1" >+ >+// On Android platform <=21, there is a regression in hexfloat formatting. >+#if !defined(__ANDROID_API__) || __ANDROID_API__ > 21 >+ EXPECT_EQ(StrFormat("%.1a", -3.0), "-0x1.8p+1"); // .1 to fix MSVC output >+ EXPECT_EQ(StrFormat("%.1A", -3.0), "-0X1.8P+1"); // .1 to fix MSVC output >+#endif >+ >+ // Other conversion >+ int64_t value = 0x7ffdeb6; >+ auto ptr_value = static_cast<uintptr_t>(value); >+ const int& something = *reinterpret_cast<const int*>(ptr_value); >+ EXPECT_EQ(StrFormat("%p", &something), StrFormat("0x%x", ptr_value)); >+ >+ // Output widths are supported, with optional flags. >+ EXPECT_EQ(StrFormat("%3d", 1), " 1"); >+ EXPECT_EQ(StrFormat("%3d", 123456), "123456"); >+ EXPECT_EQ(StrFormat("%06.2f", 1.234), "001.23"); >+ EXPECT_EQ(StrFormat("%+d", 1), "+1"); >+ EXPECT_EQ(StrFormat("% d", 1), " 1"); >+ EXPECT_EQ(StrFormat("%-4d", -1), "-1 "); >+ EXPECT_EQ(StrFormat("%#o", 10), "012"); >+ EXPECT_EQ(StrFormat("%#x", 15), "0xf"); >+ EXPECT_EQ(StrFormat("%04d", 8), "0008"); >+ // Posix positional substitution. >+ EXPECT_EQ(absl::StrFormat("%2$s, %3$s, %1$s!", "vici", "veni", "vidi"), >+ "veni, vidi, vici!"); >+ // Length modifiers are ignored. >+ EXPECT_EQ(StrFormat("%hhd", int{1}), "1"); >+ EXPECT_EQ(StrFormat("%hd", int{1}), "1"); >+ EXPECT_EQ(StrFormat("%ld", int{1}), "1"); >+ EXPECT_EQ(StrFormat("%lld", int{1}), "1"); >+ EXPECT_EQ(StrFormat("%Ld", int{1}), "1"); >+ EXPECT_EQ(StrFormat("%jd", int{1}), "1"); >+ EXPECT_EQ(StrFormat("%zd", int{1}), "1"); >+ EXPECT_EQ(StrFormat("%td", int{1}), "1"); >+ EXPECT_EQ(StrFormat("%qd", int{1}), "1"); >+} >+ >+using str_format_internal::ExtendedParsedFormat; >+using str_format_internal::ParsedFormatBase; >+ >+struct SummarizeConsumer { >+ std::string* out; >+ explicit SummarizeConsumer(std::string* out) : out(out) {} >+ >+ bool Append(string_view s) { >+ *out += "[" + std::string(s) + "]"; >+ return true; >+ } >+ >+ bool ConvertOne(const str_format_internal::UnboundConversion& conv, >+ string_view s) { >+ *out += "{"; >+ *out += std::string(s); >+ *out += ":"; >+ *out += std::to_string(conv.arg_position) + "$"; >+ if (conv.width.is_from_arg()) { >+ *out += std::to_string(conv.width.get_from_arg()) + "$*"; >+ } >+ if (conv.precision.is_from_arg()) { >+ *out += "." + std::to_string(conv.precision.get_from_arg()) + "$*"; >+ } >+ *out += conv.conv.Char(); >+ *out += "}"; >+ return true; >+ } >+}; >+ >+std::string SummarizeParsedFormat(const ParsedFormatBase& pc) { >+ std::string out; >+ if (!pc.ProcessFormat(SummarizeConsumer(&out))) out += "!"; >+ return out; >+} >+ >+class ParsedFormatTest : public testing::Test {}; >+ >+TEST_F(ParsedFormatTest, SimpleChecked) { >+ EXPECT_EQ("[ABC]{d:1$d}[DEF]", >+ SummarizeParsedFormat(ParsedFormat<'d'>("ABC%dDEF"))); >+ EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", >+ SummarizeParsedFormat(ParsedFormat<'s', 'd', 'f'>("%sFFF%dZZZ%f"))); >+ EXPECT_EQ("{s:1$s}[ ]{.*d:3$.2$*d}", >+ SummarizeParsedFormat(ParsedFormat<'s', '*', 'd'>("%s %.*d"))); >+} >+ >+TEST_F(ParsedFormatTest, SimpleUncheckedCorrect) { >+ auto f = ParsedFormat<'d'>::New("ABC%dDEF"); >+ ASSERT_TRUE(f); >+ EXPECT_EQ("[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f)); >+ >+ std::string format = "%sFFF%dZZZ%f"; >+ auto f2 = ParsedFormat<'s', 'd', 'f'>::New(format); >+ >+ ASSERT_TRUE(f2); >+ EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2)); >+ >+ f2 = ParsedFormat<'s', 'd', 'f'>::New("%s %d %f"); >+ >+ ASSERT_TRUE(f2); >+ EXPECT_EQ("{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2)); >+ >+ auto star = ParsedFormat<'*', 'd'>::New("%*d"); >+ ASSERT_TRUE(star); >+ EXPECT_EQ("{*d:2$1$*d}", SummarizeParsedFormat(*star)); >+ >+ auto dollar = ParsedFormat<'d', 's'>::New("%2$s %1$d"); >+ ASSERT_TRUE(dollar); >+ EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar)); >+ // with reuse >+ dollar = ParsedFormat<'d', 's'>::New("%2$s %1$d %1$d"); >+ ASSERT_TRUE(dollar); >+ EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}[ ]{1$d:1$d}", >+ SummarizeParsedFormat(*dollar)); >+} >+ >+TEST_F(ParsedFormatTest, SimpleUncheckedIgnoredArgs) { >+ EXPECT_FALSE((ParsedFormat<'d', 's'>::New("ABC"))); >+ EXPECT_FALSE((ParsedFormat<'d', 's'>::New("%dABC"))); >+ EXPECT_FALSE((ParsedFormat<'d', 's'>::New("ABC%2$s"))); >+ auto f = ParsedFormat<'d', 's'>::NewAllowIgnored("ABC"); >+ ASSERT_TRUE(f); >+ EXPECT_EQ("[ABC]", SummarizeParsedFormat(*f)); >+ f = ParsedFormat<'d', 's'>::NewAllowIgnored("%dABC"); >+ ASSERT_TRUE(f); >+ EXPECT_EQ("{d:1$d}[ABC]", SummarizeParsedFormat(*f)); >+ f = ParsedFormat<'d', 's'>::NewAllowIgnored("ABC%2$s"); >+ ASSERT_TRUE(f); >+ EXPECT_EQ("[ABC]{2$s:2$s}", SummarizeParsedFormat(*f)); >+} >+ >+TEST_F(ParsedFormatTest, SimpleUncheckedUnsupported) { >+ EXPECT_FALSE(ParsedFormat<'d'>::New("%1$d %1$x")); >+ EXPECT_FALSE(ParsedFormat<'x'>::New("%1$d %1$x")); >+} >+ >+TEST_F(ParsedFormatTest, SimpleUncheckedIncorrect) { >+ EXPECT_FALSE(ParsedFormat<'d'>::New("")); >+ >+ EXPECT_FALSE(ParsedFormat<'d'>::New("ABC%dDEF%d")); >+ >+ std::string format = "%sFFF%dZZZ%f"; >+ EXPECT_FALSE((ParsedFormat<'s', 'd', 'g'>::New(format))); >+} >+ >+using str_format_internal::Conv; >+ >+TEST_F(ParsedFormatTest, UncheckedCorrect) { >+ auto f = ExtendedParsedFormat<Conv::d>::New("ABC%dDEF"); >+ ASSERT_TRUE(f); >+ EXPECT_EQ("[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f)); >+ >+ std::string format = "%sFFF%dZZZ%f"; >+ auto f2 = >+ ExtendedParsedFormat<Conv::string, Conv::d, Conv::floating>::New(format); >+ >+ ASSERT_TRUE(f2); >+ EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2)); >+ >+ f2 = ExtendedParsedFormat<Conv::string, Conv::d, Conv::floating>::New( >+ "%s %d %f"); >+ >+ ASSERT_TRUE(f2); >+ EXPECT_EQ("{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2)); >+ >+ auto star = ExtendedParsedFormat<Conv::star, Conv::d>::New("%*d"); >+ ASSERT_TRUE(star); >+ EXPECT_EQ("{*d:2$1$*d}", SummarizeParsedFormat(*star)); >+ >+ auto dollar = ExtendedParsedFormat<Conv::d, Conv::s>::New("%2$s %1$d"); >+ ASSERT_TRUE(dollar); >+ EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar)); >+ // with reuse >+ dollar = ExtendedParsedFormat<Conv::d, Conv::s>::New("%2$s %1$d %1$d"); >+ ASSERT_TRUE(dollar); >+ EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}[ ]{1$d:1$d}", >+ SummarizeParsedFormat(*dollar)); >+} >+ >+TEST_F(ParsedFormatTest, UncheckedIgnoredArgs) { >+ EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::s>::New("ABC"))); >+ EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::s>::New("%dABC"))); >+ EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::s>::New("ABC%2$s"))); >+ auto f = ExtendedParsedFormat<Conv::d, Conv::s>::NewAllowIgnored("ABC"); >+ ASSERT_TRUE(f); >+ EXPECT_EQ("[ABC]", SummarizeParsedFormat(*f)); >+ f = ExtendedParsedFormat<Conv::d, Conv::s>::NewAllowIgnored("%dABC"); >+ ASSERT_TRUE(f); >+ EXPECT_EQ("{d:1$d}[ABC]", SummarizeParsedFormat(*f)); >+ f = ExtendedParsedFormat<Conv::d, Conv::s>::NewAllowIgnored("ABC%2$s"); >+ ASSERT_TRUE(f); >+ EXPECT_EQ("[ABC]{2$s:2$s}", SummarizeParsedFormat(*f)); >+} >+ >+TEST_F(ParsedFormatTest, UncheckedMultipleTypes) { >+ auto dx = ExtendedParsedFormat<Conv::d | Conv::x>::New("%1$d %1$x"); >+ EXPECT_TRUE(dx); >+ EXPECT_EQ("{1$d:1$d}[ ]{1$x:1$x}", SummarizeParsedFormat(*dx)); >+ >+ dx = ExtendedParsedFormat<Conv::d | Conv::x>::New("%1$d"); >+ EXPECT_TRUE(dx); >+ EXPECT_EQ("{1$d:1$d}", SummarizeParsedFormat(*dx)); >+} >+ >+TEST_F(ParsedFormatTest, UncheckedIncorrect) { >+ EXPECT_FALSE(ExtendedParsedFormat<Conv::d>::New("")); >+ >+ EXPECT_FALSE(ExtendedParsedFormat<Conv::d>::New("ABC%dDEF%d")); >+ >+ std::string format = "%sFFF%dZZZ%f"; >+ EXPECT_FALSE((ExtendedParsedFormat<Conv::s, Conv::d, Conv::g>::New(format))); >+} >+ >+TEST_F(ParsedFormatTest, RegressionMixPositional) { >+ EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::o>::New("%1$d %o"))); >+} >+ >+} // namespace >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_join.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_join.h >new file mode 100644 >index 0000000000000000000000000000000000000000..bd4d0e1d9324cc729214449935b57337a6716fb7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_join.h >@@ -0,0 +1,288 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: str_join.h >+// ----------------------------------------------------------------------------- >+// >+// This header file contains functions for joining a range of elements and >+// returning the result as a std::string. StrJoin operations are specified by passing >+// a range, a separator std::string to use between the elements joined, and an >+// optional Formatter responsible for converting each argument in the range to a >+// std::string. If omitted, a default `AlphaNumFormatter()` is called on the elements >+// to be joined, using the same formatting that `absl::StrCat()` uses. This >+// package defines a number of default formatters, and you can define your own >+// implementations. >+// >+// Ranges are specified by passing a container with `std::begin()` and >+// `std::end()` iterators, container-specific `begin()` and `end()` iterators, a >+// brace-initialized `std::initializer_list`, or a `std::tuple` of heterogeneous >+// objects. The separator std::string is specified as an `absl::string_view`. >+// >+// Because the default formatter uses the `absl::AlphaNum` class, >+// `absl::StrJoin()`, like `absl::StrCat()`, will work out-of-the-box on >+// collections of strings, ints, floats, doubles, etc. >+// >+// Example: >+// >+// std::vector<std::string> v = {"foo", "bar", "baz"}; >+// std::string s = absl::StrJoin(v, "-"); >+// EXPECT_EQ("foo-bar-baz", s); >+// >+// See comments on the `absl::StrJoin()` function for more examples. >+ >+#ifndef ABSL_STRINGS_STR_JOIN_H_ >+#define ABSL_STRINGS_STR_JOIN_H_ >+ >+#include <cstdio> >+#include <cstring> >+#include <initializer_list> >+#include <iterator> >+#include <string> >+#include <tuple> >+#include <utility> >+ >+#include "absl/base/macros.h" >+#include "absl/strings/internal/str_join_internal.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+ >+// ----------------------------------------------------------------------------- >+// Concept: Formatter >+// ----------------------------------------------------------------------------- >+// >+// A Formatter is a function object that is responsible for formatting its >+// argument as a std::string and appending it to a given output std::string. Formatters >+// may be implemented as function objects, lambdas, or normal functions. You may >+// provide your own Formatter to enable `absl::StrJoin()` to work with arbitrary >+// types. >+// >+// The following is an example of a custom Formatter that simply uses >+// `std::to_string()` to format an integer as a std::string. >+// >+// struct MyFormatter { >+// void operator()(std::string* out, int i) const { >+// out->append(std::to_string(i)); >+// } >+// }; >+// >+// You would use the above formatter by passing an instance of it as the final >+// argument to `absl::StrJoin()`: >+// >+// std::vector<int> v = {1, 2, 3, 4}; >+// std::string s = absl::StrJoin(v, "-", MyFormatter()); >+// EXPECT_EQ("1-2-3-4", s); >+// >+// The following standard formatters are provided within this file: >+// >+// - `AlphaNumFormatter()` (the default) >+// - `StreamFormatter()` >+// - `PairFormatter()` >+// - `DereferenceFormatter()` >+ >+// AlphaNumFormatter() >+// >+// Default formatter used if none is specified. Uses `absl::AlphaNum` to convert >+// numeric arguments to strings. >+inline strings_internal::AlphaNumFormatterImpl AlphaNumFormatter() { >+ return strings_internal::AlphaNumFormatterImpl(); >+} >+ >+// StreamFormatter() >+// >+// Formats its argument using the << operator. >+inline strings_internal::StreamFormatterImpl StreamFormatter() { >+ return strings_internal::StreamFormatterImpl(); >+} >+ >+// Function Template: PairFormatter(Formatter, absl::string_view, Formatter) >+// >+// Formats a `std::pair` by putting a given separator between the pair's >+// `.first` and `.second` members. This formatter allows you to specify >+// custom Formatters for both the first and second member of each pair. >+template <typename FirstFormatter, typename SecondFormatter> >+inline strings_internal::PairFormatterImpl<FirstFormatter, SecondFormatter> >+PairFormatter(FirstFormatter f1, absl::string_view sep, SecondFormatter f2) { >+ return strings_internal::PairFormatterImpl<FirstFormatter, SecondFormatter>( >+ std::move(f1), sep, std::move(f2)); >+} >+ >+// Function overload of PairFormatter() for using a default >+// `AlphaNumFormatter()` for each Formatter in the pair. >+inline strings_internal::PairFormatterImpl< >+ strings_internal::AlphaNumFormatterImpl, >+ strings_internal::AlphaNumFormatterImpl> >+PairFormatter(absl::string_view sep) { >+ return PairFormatter(AlphaNumFormatter(), sep, AlphaNumFormatter()); >+} >+ >+// Function Template: DereferenceFormatter(Formatter) >+// >+// Formats its argument by dereferencing it and then applying the given >+// formatter. This formatter is useful for formatting a container of >+// pointer-to-T. This pattern often shows up when joining repeated fields in >+// protocol buffers. >+template <typename Formatter> >+strings_internal::DereferenceFormatterImpl<Formatter> DereferenceFormatter( >+ Formatter&& f) { >+ return strings_internal::DereferenceFormatterImpl<Formatter>( >+ std::forward<Formatter>(f)); >+} >+ >+// Function overload of `DererefenceFormatter()` for using a default >+// `AlphaNumFormatter()`. >+inline strings_internal::DereferenceFormatterImpl< >+ strings_internal::AlphaNumFormatterImpl> >+DereferenceFormatter() { >+ return strings_internal::DereferenceFormatterImpl< >+ strings_internal::AlphaNumFormatterImpl>(AlphaNumFormatter()); >+} >+ >+// ----------------------------------------------------------------------------- >+// StrJoin() >+// ----------------------------------------------------------------------------- >+// >+// Joins a range of elements and returns the result as a std::string. >+// `absl::StrJoin()` takes a range, a separator std::string to use between the >+// elements joined, and an optional Formatter responsible for converting each >+// argument in the range to a std::string. >+// >+// If omitted, the default `AlphaNumFormatter()` is called on the elements to be >+// joined. >+// >+// Example 1: >+// // Joins a collection of strings. This pattern also works with a collection >+// // of `absl::string_view` or even `const char*`. >+// std::vector<std::string> v = {"foo", "bar", "baz"}; >+// std::string s = absl::StrJoin(v, "-"); >+// EXPECT_EQ("foo-bar-baz", s); >+// >+// Example 2: >+// // Joins the values in the given `std::initializer_list<>` specified using >+// // brace initialization. This pattern also works with an initializer_list >+// // of ints or `absl::string_view` -- any `AlphaNum`-compatible type. >+// std::string s = absl::StrJoin({"foo", "bar", "baz"}, "-"); >+// EXPECT_EQ("foo-bar-baz", s); >+// >+// Example 3: >+// // Joins a collection of ints. This pattern also works with floats, >+// // doubles, int64s -- any `StrCat()`-compatible type. >+// std::vector<int> v = {1, 2, 3, -4}; >+// std::string s = absl::StrJoin(v, "-"); >+// EXPECT_EQ("1-2-3--4", s); >+// >+// Example 4: >+// // Joins a collection of pointer-to-int. By default, pointers are >+// // dereferenced and the pointee is formatted using the default format for >+// // that type; such dereferencing occurs for all levels of indirection, so >+// // this pattern works just as well for `std::vector<int**>` as for >+// // `std::vector<int*>`. >+// int x = 1, y = 2, z = 3; >+// std::vector<int*> v = {&x, &y, &z}; >+// std::string s = absl::StrJoin(v, "-"); >+// EXPECT_EQ("1-2-3", s); >+// >+// Example 5: >+// // Dereferencing of `std::unique_ptr<>` is also supported: >+// std::vector<std::unique_ptr<int>> v >+// v.emplace_back(new int(1)); >+// v.emplace_back(new int(2)); >+// v.emplace_back(new int(3)); >+// std::string s = absl::StrJoin(v, "-"); >+// EXPECT_EQ("1-2-3", s); >+// >+// Example 6: >+// // Joins a `std::map`, with each key-value pair separated by an equals >+// // sign. This pattern would also work with, say, a >+// // `std::vector<std::pair<>>`. >+// std::map<std::string, int> m = { >+// std::make_pair("a", 1), >+// std::make_pair("b", 2), >+// std::make_pair("c", 3)}; >+// std::string s = absl::StrJoin(m, ",", absl::PairFormatter("=")); >+// EXPECT_EQ("a=1,b=2,c=3", s); >+// >+// Example 7: >+// // These examples show how `absl::StrJoin()` handles a few common edge >+// // cases: >+// std::vector<std::string> v_empty; >+// EXPECT_EQ("", absl::StrJoin(v_empty, "-")); >+// >+// std::vector<std::string> v_one_item = {"foo"}; >+// EXPECT_EQ("foo", absl::StrJoin(v_one_item, "-")); >+// >+// std::vector<std::string> v_empty_string = {""}; >+// EXPECT_EQ("", absl::StrJoin(v_empty_string, "-")); >+// >+// std::vector<std::string> v_one_item_empty_string = {"a", ""}; >+// EXPECT_EQ("a-", absl::StrJoin(v_one_item_empty_string, "-")); >+// >+// std::vector<std::string> v_two_empty_string = {"", ""}; >+// EXPECT_EQ("-", absl::StrJoin(v_two_empty_string, "-")); >+// >+// Example 8: >+// // Joins a `std::tuple<T...>` of heterogeneous types, converting each to >+// // a std::string using the `absl::AlphaNum` class. >+// std::string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-"); >+// EXPECT_EQ("123-abc-0.456", s); >+ >+template <typename Iterator, typename Formatter> >+std::string StrJoin(Iterator start, Iterator end, absl::string_view sep, >+ Formatter&& fmt) { >+ return strings_internal::JoinAlgorithm(start, end, sep, fmt); >+} >+ >+template <typename Range, typename Formatter> >+std::string StrJoin(const Range& range, absl::string_view separator, >+ Formatter&& fmt) { >+ return strings_internal::JoinRange(range, separator, fmt); >+} >+ >+template <typename T, typename Formatter> >+std::string StrJoin(std::initializer_list<T> il, absl::string_view separator, >+ Formatter&& fmt) { >+ return strings_internal::JoinRange(il, separator, fmt); >+} >+ >+template <typename... T, typename Formatter> >+std::string StrJoin(const std::tuple<T...>& value, absl::string_view separator, >+ Formatter&& fmt) { >+ return strings_internal::JoinAlgorithm(value, separator, fmt); >+} >+ >+template <typename Iterator> >+std::string StrJoin(Iterator start, Iterator end, absl::string_view separator) { >+ return strings_internal::JoinRange(start, end, separator); >+} >+ >+template <typename Range> >+std::string StrJoin(const Range& range, absl::string_view separator) { >+ return strings_internal::JoinRange(range, separator); >+} >+ >+template <typename T> >+std::string StrJoin(std::initializer_list<T> il, absl::string_view separator) { >+ return strings_internal::JoinRange(il, separator); >+} >+ >+template <typename... T> >+std::string StrJoin(const std::tuple<T...>& value, absl::string_view separator) { >+ return strings_internal::JoinAlgorithm(value, separator, AlphaNumFormatter()); >+} >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_STR_JOIN_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_join_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_join_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..7fb0e4973cb468e4d2c83c8d90db0b629181874e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_join_benchmark.cc >@@ -0,0 +1,96 @@ >+// >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/str_join.h" >+ >+#include <string> >+#include <vector> >+#include <utility> >+ >+#include "benchmark/benchmark.h" >+ >+namespace { >+ >+void BM_Join2_Strings(benchmark::State& state) { >+ const int string_len = state.range(0); >+ const int num_strings = state.range(1); >+ const std::string s(string_len, 'x'); >+ const std::vector<std::string> v(num_strings, s); >+ for (auto _ : state) { >+ std::string s = absl::StrJoin(v, "-"); >+ benchmark::DoNotOptimize(s); >+ } >+} >+BENCHMARK(BM_Join2_Strings) >+ ->ArgPair(1 << 0, 1 << 3) >+ ->ArgPair(1 << 10, 1 << 3) >+ ->ArgPair(1 << 13, 1 << 3) >+ ->ArgPair(1 << 0, 1 << 10) >+ ->ArgPair(1 << 10, 1 << 10) >+ ->ArgPair(1 << 13, 1 << 10) >+ ->ArgPair(1 << 0, 1 << 13) >+ ->ArgPair(1 << 10, 1 << 13) >+ ->ArgPair(1 << 13, 1 << 13); >+ >+void BM_Join2_Ints(benchmark::State& state) { >+ const int num_ints = state.range(0); >+ const std::vector<int> v(num_ints, 42); >+ for (auto _ : state) { >+ std::string s = absl::StrJoin(v, "-"); >+ benchmark::DoNotOptimize(s); >+ } >+} >+BENCHMARK(BM_Join2_Ints)->Range(0, 1 << 13); >+ >+void BM_Join2_KeysAndValues(benchmark::State& state) { >+ const int string_len = state.range(0); >+ const int num_pairs = state.range(1); >+ const std::string s(string_len, 'x'); >+ const std::vector<std::pair<std::string, int>> v(num_pairs, std::make_pair(s, 42)); >+ for (auto _ : state) { >+ std::string s = absl::StrJoin(v, ",", absl::PairFormatter("=")); >+ benchmark::DoNotOptimize(s); >+ } >+} >+BENCHMARK(BM_Join2_KeysAndValues) >+ ->ArgPair(1 << 0, 1 << 3) >+ ->ArgPair(1 << 10, 1 << 3) >+ ->ArgPair(1 << 13, 1 << 3) >+ ->ArgPair(1 << 0, 1 << 10) >+ ->ArgPair(1 << 10, 1 << 10) >+ ->ArgPair(1 << 13, 1 << 10) >+ ->ArgPair(1 << 0, 1 << 13) >+ ->ArgPair(1 << 10, 1 << 13) >+ ->ArgPair(1 << 13, 1 << 13); >+ >+void BM_JoinStreamable(benchmark::State& state) { >+ const int string_len = state.range(0); >+ const int num_strings = state.range(1); >+ const std::vector<std::string> v(num_strings, std::string(string_len, 'x')); >+ for (auto _ : state) { >+ std::string s = absl::StrJoin(v, "", absl::StreamFormatter()); >+ benchmark::DoNotOptimize(s); >+ } >+} >+BENCHMARK(BM_JoinStreamable) >+ ->ArgPair(0, 0) >+ ->ArgPair(16, 1) >+ ->ArgPair(256, 1) >+ ->ArgPair(16, 16) >+ ->ArgPair(256, 16) >+ ->ArgPair(16, 256) >+ ->ArgPair(256, 256); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_join_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_join_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..c941f9c80d49982977f18e91c0c70790927ab85f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_join_test.cc >@@ -0,0 +1,472 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Unit tests for all join.h functions >+ >+#include "absl/strings/str_join.h" >+ >+#include <cstddef> >+#include <cstdint> >+#include <cstdio> >+#include <functional> >+#include <initializer_list> >+#include <map> >+#include <memory> >+#include <ostream> >+#include <tuple> >+#include <type_traits> >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/base/macros.h" >+#include "absl/memory/memory.h" >+#include "absl/strings/str_cat.h" >+#include "absl/strings/str_split.h" >+ >+namespace { >+ >+TEST(StrJoin, APIExamples) { >+ { >+ // Collection of strings >+ std::vector<std::string> v = {"foo", "bar", "baz"}; >+ EXPECT_EQ("foo-bar-baz", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // Collection of absl::string_view >+ std::vector<absl::string_view> v = {"foo", "bar", "baz"}; >+ EXPECT_EQ("foo-bar-baz", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // Collection of const char* >+ std::vector<const char*> v = {"foo", "bar", "baz"}; >+ EXPECT_EQ("foo-bar-baz", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // Collection of non-const char* >+ std::string a = "foo", b = "bar", c = "baz"; >+ std::vector<char*> v = {&a[0], &b[0], &c[0]}; >+ EXPECT_EQ("foo-bar-baz", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // Collection of ints >+ std::vector<int> v = {1, 2, 3, -4}; >+ EXPECT_EQ("1-2-3--4", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // Literals passed as a std::initializer_list >+ std::string s = absl::StrJoin({"a", "b", "c"}, "-"); >+ EXPECT_EQ("a-b-c", s); >+ } >+ { >+ // Join a std::tuple<T...>. >+ std::string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-"); >+ EXPECT_EQ("123-abc-0.456", s); >+ } >+ >+ { >+ // Collection of unique_ptrs >+ std::vector<std::unique_ptr<int>> v; >+ v.emplace_back(new int(1)); >+ v.emplace_back(new int(2)); >+ v.emplace_back(new int(3)); >+ EXPECT_EQ("1-2-3", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // Array of ints >+ const int a[] = {1, 2, 3, -4}; >+ EXPECT_EQ("1-2-3--4", absl::StrJoin(a, a + ABSL_ARRAYSIZE(a), "-")); >+ } >+ >+ { >+ // Collection of pointers >+ int x = 1, y = 2, z = 3; >+ std::vector<int*> v = {&x, &y, &z}; >+ EXPECT_EQ("1-2-3", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // Collection of pointers to pointers >+ int x = 1, y = 2, z = 3; >+ int *px = &x, *py = &y, *pz = &z; >+ std::vector<int**> v = {&px, &py, &pz}; >+ EXPECT_EQ("1-2-3", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // Collection of pointers to std::string >+ std::string a("a"), b("b"); >+ std::vector<std::string*> v = {&a, &b}; >+ EXPECT_EQ("a-b", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // A std::map, which is a collection of std::pair<>s. >+ std::map<std::string, int> m = { {"a", 1}, {"b", 2}, {"c", 3} }; >+ EXPECT_EQ("a=1,b=2,c=3", absl::StrJoin(m, ",", absl::PairFormatter("="))); >+ } >+ >+ { >+ // Shows absl::StrSplit and absl::StrJoin working together. This example is >+ // equivalent to s/=/-/g. >+ const std::string s = "a=b=c=d"; >+ EXPECT_EQ("a-b-c-d", absl::StrJoin(absl::StrSplit(s, "="), "-")); >+ } >+ >+ // >+ // A few examples of edge cases >+ // >+ >+ { >+ // Empty range yields an empty std::string. >+ std::vector<std::string> v; >+ EXPECT_EQ("", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // A range of 1 element gives a std::string with that element but no separator. >+ std::vector<std::string> v = {"foo"}; >+ EXPECT_EQ("foo", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // A range with a single empty std::string element >+ std::vector<std::string> v = {""}; >+ EXPECT_EQ("", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // A range with 2 elements, one of which is an empty std::string >+ std::vector<std::string> v = {"a", ""}; >+ EXPECT_EQ("a-", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // A range with 2 empty elements. >+ std::vector<std::string> v = {"", ""}; >+ EXPECT_EQ("-", absl::StrJoin(v, "-")); >+ } >+ >+ { >+ // A std::vector of bool. >+ std::vector<bool> v = {true, false, true}; >+ EXPECT_EQ("1-0-1", absl::StrJoin(v, "-")); >+ } >+} >+ >+TEST(StrJoin, CustomFormatter) { >+ std::vector<std::string> v{"One", "Two", "Three"}; >+ { >+ std::string joined = absl::StrJoin(v, "", [](std::string* out, const std::string& in) { >+ absl::StrAppend(out, "(", in, ")"); >+ }); >+ EXPECT_EQ("(One)(Two)(Three)", joined); >+ } >+ { >+ class ImmovableFormatter { >+ public: >+ void operator()(std::string* out, const std::string& in) { >+ absl::StrAppend(out, "(", in, ")"); >+ } >+ ImmovableFormatter() {} >+ ImmovableFormatter(const ImmovableFormatter&) = delete; >+ }; >+ EXPECT_EQ("(One)(Two)(Three)", absl::StrJoin(v, "", ImmovableFormatter())); >+ } >+ { >+ class OverloadedFormatter { >+ public: >+ void operator()(std::string* out, const std::string& in) { >+ absl::StrAppend(out, "(", in, ")"); >+ } >+ void operator()(std::string* out, const std::string& in) const { >+ absl::StrAppend(out, "[", in, "]"); >+ } >+ }; >+ EXPECT_EQ("(One)(Two)(Three)", absl::StrJoin(v, "", OverloadedFormatter())); >+ const OverloadedFormatter fmt = {}; >+ EXPECT_EQ("[One][Two][Three]", absl::StrJoin(v, "", fmt)); >+ } >+} >+ >+// >+// Tests the Formatters >+// >+ >+TEST(AlphaNumFormatter, FormatterAPI) { >+ // Not an exhaustive test. See strings/strcat_test.h for the exhaustive test >+ // of what AlphaNum can convert. >+ auto f = absl::AlphaNumFormatter(); >+ std::string s; >+ f(&s, "Testing: "); >+ f(&s, static_cast<int>(1)); >+ f(&s, static_cast<int16_t>(2)); >+ f(&s, static_cast<int64_t>(3)); >+ f(&s, static_cast<float>(4)); >+ f(&s, static_cast<double>(5)); >+ f(&s, static_cast<unsigned>(6)); >+ f(&s, static_cast<size_t>(7)); >+ f(&s, absl::string_view(" OK")); >+ EXPECT_EQ("Testing: 1234567 OK", s); >+} >+ >+// Make sure people who are mistakenly using std::vector<bool> even though >+// they're not memory-constrained can use absl::AlphaNumFormatter(). >+TEST(AlphaNumFormatter, VectorOfBool) { >+ auto f = absl::AlphaNumFormatter(); >+ std::string s; >+ std::vector<bool> v = {true, false, true}; >+ f(&s, *v.cbegin()); >+ f(&s, *v.begin()); >+ f(&s, v[1]); >+ EXPECT_EQ("110", s); >+} >+ >+TEST(AlphaNumFormatter, AlphaNum) { >+ auto f = absl::AlphaNumFormatter(); >+ std::string s; >+ f(&s, absl::AlphaNum("hello")); >+ EXPECT_EQ("hello", s); >+} >+ >+struct StreamableType { >+ std::string contents; >+}; >+inline std::ostream& operator<<(std::ostream& os, const StreamableType& t) { >+ os << "Streamable:" << t.contents; >+ return os; >+} >+ >+TEST(StreamFormatter, FormatterAPI) { >+ auto f = absl::StreamFormatter(); >+ std::string s; >+ f(&s, "Testing: "); >+ f(&s, static_cast<int>(1)); >+ f(&s, static_cast<int16_t>(2)); >+ f(&s, static_cast<int64_t>(3)); >+ f(&s, static_cast<float>(4)); >+ f(&s, static_cast<double>(5)); >+ f(&s, static_cast<unsigned>(6)); >+ f(&s, static_cast<size_t>(7)); >+ f(&s, absl::string_view(" OK ")); >+ StreamableType streamable = {"object"}; >+ f(&s, streamable); >+ EXPECT_EQ("Testing: 1234567 OK Streamable:object", s); >+} >+ >+// A dummy formatter that wraps each element in parens. Used in some tests >+// below. >+struct TestingParenFormatter { >+ template <typename T> >+ void operator()(std::string* s, const T& t) { >+ absl::StrAppend(s, "(", t, ")"); >+ } >+}; >+ >+TEST(PairFormatter, FormatterAPI) { >+ { >+ // Tests default PairFormatter(sep) that uses AlphaNumFormatter for the >+ // 'first' and 'second' members. >+ const auto f = absl::PairFormatter("="); >+ std::string s; >+ f(&s, std::make_pair("a", "b")); >+ f(&s, std::make_pair(1, 2)); >+ EXPECT_EQ("a=b1=2", s); >+ } >+ >+ { >+ // Tests using a custom formatter for the 'first' and 'second' members. >+ auto f = absl::PairFormatter(TestingParenFormatter(), "=", >+ TestingParenFormatter()); >+ std::string s; >+ f(&s, std::make_pair("a", "b")); >+ f(&s, std::make_pair(1, 2)); >+ EXPECT_EQ("(a)=(b)(1)=(2)", s); >+ } >+} >+ >+TEST(DereferenceFormatter, FormatterAPI) { >+ { >+ // Tests wrapping the default AlphaNumFormatter. >+ const absl::strings_internal::DereferenceFormatterImpl< >+ absl::strings_internal::AlphaNumFormatterImpl> >+ f; >+ int x = 1, y = 2, z = 3; >+ std::string s; >+ f(&s, &x); >+ f(&s, &y); >+ f(&s, &z); >+ EXPECT_EQ("123", s); >+ } >+ >+ { >+ // Tests wrapping std::string's default formatter. >+ absl::strings_internal::DereferenceFormatterImpl< >+ absl::strings_internal::DefaultFormatter<std::string>::Type> >+ f; >+ >+ std::string x = "x"; >+ std::string y = "y"; >+ std::string z = "z"; >+ std::string s; >+ f(&s, &x); >+ f(&s, &y); >+ f(&s, &z); >+ EXPECT_EQ(s, "xyz"); >+ } >+ >+ { >+ // Tests wrapping a custom formatter. >+ auto f = absl::DereferenceFormatter(TestingParenFormatter()); >+ int x = 1, y = 2, z = 3; >+ std::string s; >+ f(&s, &x); >+ f(&s, &y); >+ f(&s, &z); >+ EXPECT_EQ("(1)(2)(3)", s); >+ } >+ >+ { >+ absl::strings_internal::DereferenceFormatterImpl< >+ absl::strings_internal::AlphaNumFormatterImpl> >+ f; >+ auto x = std::unique_ptr<int>(new int(1)); >+ auto y = std::unique_ptr<int>(new int(2)); >+ auto z = std::unique_ptr<int>(new int(3)); >+ std::string s; >+ f(&s, x); >+ f(&s, y); >+ f(&s, z); >+ EXPECT_EQ("123", s); >+ } >+} >+ >+// >+// Tests the interfaces for the 4 public Join function overloads. The semantics >+// of the algorithm is covered in the above APIExamples test. >+// >+TEST(StrJoin, PublicAPIOverloads) { >+ std::vector<std::string> v = {"a", "b", "c"}; >+ >+ // Iterators + formatter >+ EXPECT_EQ("a-b-c", >+ absl::StrJoin(v.begin(), v.end(), "-", absl::AlphaNumFormatter())); >+ // Range + formatter >+ EXPECT_EQ("a-b-c", absl::StrJoin(v, "-", absl::AlphaNumFormatter())); >+ // Iterators, no formatter >+ EXPECT_EQ("a-b-c", absl::StrJoin(v.begin(), v.end(), "-")); >+ // Range, no formatter >+ EXPECT_EQ("a-b-c", absl::StrJoin(v, "-")); >+} >+ >+TEST(StrJoin, Array) { >+ const absl::string_view a[] = {"a", "b", "c"}; >+ EXPECT_EQ("a-b-c", absl::StrJoin(a, "-")); >+} >+ >+TEST(StrJoin, InitializerList) { >+ { EXPECT_EQ("a-b-c", absl::StrJoin({"a", "b", "c"}, "-")); } >+ >+ { >+ auto a = {"a", "b", "c"}; >+ EXPECT_EQ("a-b-c", absl::StrJoin(a, "-")); >+ } >+ >+ { >+ std::initializer_list<const char*> a = {"a", "b", "c"}; >+ EXPECT_EQ("a-b-c", absl::StrJoin(a, "-")); >+ } >+ >+ { >+ std::initializer_list<std::string> a = {"a", "b", "c"}; >+ EXPECT_EQ("a-b-c", absl::StrJoin(a, "-")); >+ } >+ >+ { >+ std::initializer_list<absl::string_view> a = {"a", "b", "c"}; >+ EXPECT_EQ("a-b-c", absl::StrJoin(a, "-")); >+ } >+ >+ { >+ // Tests initializer_list with a non-default formatter >+ auto a = {"a", "b", "c"}; >+ TestingParenFormatter f; >+ EXPECT_EQ("(a)-(b)-(c)", absl::StrJoin(a, "-", f)); >+ } >+ >+ { >+ // initializer_list of ints >+ EXPECT_EQ("1-2-3", absl::StrJoin({1, 2, 3}, "-")); >+ } >+ >+ { >+ // Tests initializer_list of ints with a non-default formatter >+ auto a = {1, 2, 3}; >+ TestingParenFormatter f; >+ EXPECT_EQ("(1)-(2)-(3)", absl::StrJoin(a, "-", f)); >+ } >+} >+ >+TEST(StrJoin, Tuple) { >+ EXPECT_EQ("", absl::StrJoin(std::make_tuple(), "-")); >+ EXPECT_EQ("hello", absl::StrJoin(std::make_tuple("hello"), "-")); >+ >+ int x(10); >+ std::string y("hello"); >+ double z(3.14); >+ EXPECT_EQ("10-hello-3.14", absl::StrJoin(std::make_tuple(x, y, z), "-")); >+ >+ // Faster! Faster!! >+ EXPECT_EQ("10-hello-3.14", >+ absl::StrJoin(std::make_tuple(x, std::cref(y), z), "-")); >+ >+ struct TestFormatter { >+ char buffer[128]; >+ void operator()(std::string* out, int v) { >+ snprintf(buffer, sizeof(buffer), "%#.8x", v); >+ out->append(buffer); >+ } >+ void operator()(std::string* out, double v) { >+ snprintf(buffer, sizeof(buffer), "%#.0f", v); >+ out->append(buffer); >+ } >+ void operator()(std::string* out, const std::string& v) { >+ snprintf(buffer, sizeof(buffer), "%.4s", v.c_str()); >+ out->append(buffer); >+ } >+ }; >+ EXPECT_EQ("0x0000000a-hell-3.", >+ absl::StrJoin(std::make_tuple(x, y, z), "-", TestFormatter())); >+ EXPECT_EQ( >+ "0x0000000a-hell-3.", >+ absl::StrJoin(std::make_tuple(x, std::cref(y), z), "-", TestFormatter())); >+ EXPECT_EQ("0x0000000a-hell-3.", >+ absl::StrJoin(std::make_tuple(&x, &y, &z), "-", >+ absl::DereferenceFormatter(TestFormatter()))); >+ EXPECT_EQ("0x0000000a-hell-3.", >+ absl::StrJoin(std::make_tuple(absl::make_unique<int>(x), >+ absl::make_unique<std::string>(y), >+ absl::make_unique<double>(z)), >+ "-", absl::DereferenceFormatter(TestFormatter()))); >+ EXPECT_EQ("0x0000000a-hell-3.", >+ absl::StrJoin(std::make_tuple(absl::make_unique<int>(x), &y, &z), >+ "-", absl::DereferenceFormatter(TestFormatter()))); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..69efa3571388b65441a5c15eac478f32be6b381b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace.cc >@@ -0,0 +1,79 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/str_replace.h" >+ >+#include "absl/strings/str_cat.h" >+ >+namespace absl { >+namespace strings_internal { >+ >+using FixedMapping = >+ std::initializer_list<std::pair<absl::string_view, absl::string_view>>; >+ >+// Applies the ViableSubstitutions in subs_ptr to the absl::string_view s, and >+// stores the result in *result_ptr. Returns the number of substitutions that >+// occurred. >+int ApplySubstitutions( >+ absl::string_view s, >+ std::vector<strings_internal::ViableSubstitution>* subs_ptr, >+ std::string* result_ptr) { >+ auto& subs = *subs_ptr; >+ int substitutions = 0; >+ size_t pos = 0; >+ while (!subs.empty()) { >+ auto& sub = subs.back(); >+ if (sub.offset >= pos) { >+ if (pos <= s.size()) { >+ StrAppend(result_ptr, s.substr(pos, sub.offset - pos), sub.replacement); >+ } >+ pos = sub.offset + sub.old.size(); >+ substitutions += 1; >+ } >+ sub.offset = s.find(sub.old, pos); >+ if (sub.offset == s.npos) { >+ subs.pop_back(); >+ } else { >+ // Insertion sort to ensure the last ViableSubstitution continues to be >+ // before all the others. >+ size_t index = subs.size(); >+ while (--index && subs[index - 1].OccursBefore(subs[index])) { >+ std::swap(subs[index], subs[index - 1]); >+ } >+ } >+ } >+ result_ptr->append(s.data() + pos, s.size() - pos); >+ return substitutions; >+} >+ >+} // namespace strings_internal >+ >+// We can implement this in terms of the generic StrReplaceAll, but >+// we must specify the template overload because C++ cannot deduce the type >+// of an initializer_list parameter to a function, and also if we don't specify >+// the type, we just call ourselves. >+// >+// Note that we implement them here, rather than in the header, so that they >+// aren't inlined. >+ >+std::string StrReplaceAll(absl::string_view s, >+ strings_internal::FixedMapping replacements) { >+ return StrReplaceAll<strings_internal::FixedMapping>(s, replacements); >+} >+ >+int StrReplaceAll(strings_internal::FixedMapping replacements, std::string* target) { >+ return StrReplaceAll<strings_internal::FixedMapping>(replacements, target); >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f4d9bb9545d689762180a1a430e64b5065bcf27c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace.h >@@ -0,0 +1,213 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: str_replace.h >+// ----------------------------------------------------------------------------- >+// >+// This file defines `absl::StrReplaceAll()`, a general-purpose std::string >+// replacement function designed for large, arbitrary text substitutions, >+// especially on strings which you are receiving from some other system for >+// further processing (e.g. processing regular expressions, escaping HTML >+// entities, etc. `StrReplaceAll` is designed to be efficient even when only >+// one substitution is being performed, or when substitution is rare. >+// >+// If the std::string being modified is known at compile-time, and the substitutions >+// vary, `absl::Substitute()` may be a better choice. >+// >+// Example: >+// >+// std::string html_escaped = absl::StrReplaceAll(user_input, { >+// {"&", "&"}, >+// {"<", "<"}, >+// {">", ">"}, >+// {"\"", """}, >+// {"'", "'"}}); >+#ifndef ABSL_STRINGS_STR_REPLACE_H_ >+#define ABSL_STRINGS_STR_REPLACE_H_ >+ >+#include <string> >+#include <utility> >+#include <vector> >+ >+#include "absl/base/attributes.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+ >+// StrReplaceAll() >+// >+// Replaces character sequences within a given std::string with replacements provided >+// within an initializer list of key/value pairs. Candidate replacements are >+// considered in order as they occur within the std::string, with earlier matches >+// taking precedence, and longer matches taking precedence for candidates >+// starting at the same position in the std::string. Once a substitution is made, the >+// replaced text is not considered for any further substitutions. >+// >+// Example: >+// >+// std::string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!", >+// {{"$count", absl::StrCat(5)}, >+// {"$who", "Bob"}, >+// {"#Noun", "Apples"}}); >+// EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s); >+ABSL_MUST_USE_RESULT std::string StrReplaceAll( >+ absl::string_view s, >+ std::initializer_list<std::pair<absl::string_view, absl::string_view>> >+ replacements); >+ >+// Overload of `StrReplaceAll()` to accept a container of key/value replacement >+// pairs (typically either an associative map or a `std::vector` of `std::pair` >+// elements). A vector of pairs is generally more efficient. >+// >+// Examples: >+// >+// std::map<const absl::string_view, const absl::string_view> replacements; >+// replacements["$who"] = "Bob"; >+// replacements["$count"] = "5"; >+// replacements["#Noun"] = "Apples"; >+// std::string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!", >+// replacements); >+// EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s); >+// >+// // A std::vector of std::pair elements can be more efficient. >+// std::vector<std::pair<const absl::string_view, std::string>> replacements; >+// replacements.push_back({"&", "&"}); >+// replacements.push_back({"<", "<"}); >+// replacements.push_back({">", ">"}); >+// std::string s = absl::StrReplaceAll("if (ptr < &foo)", >+// replacements); >+// EXPECT_EQ("if (ptr < &foo)", s); >+template <typename StrToStrMapping> >+std::string StrReplaceAll(absl::string_view s, const StrToStrMapping& replacements); >+ >+// Overload of `StrReplaceAll()` to replace character sequences within a given >+// output std::string *in place* with replacements provided within an initializer >+// list of key/value pairs, returning the number of substitutions that occurred. >+// >+// Example: >+// >+// std::string s = std::string("$who bought $count #Noun. Thanks $who!"); >+// int count; >+// count = absl::StrReplaceAll({{"$count", absl::StrCat(5)}, >+// {"$who", "Bob"}, >+// {"#Noun", "Apples"}}, &s); >+// EXPECT_EQ(count, 4); >+// EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s); >+int StrReplaceAll( >+ std::initializer_list<std::pair<absl::string_view, absl::string_view>> >+ replacements, >+ std::string* target); >+ >+// Overload of `StrReplaceAll()` to replace patterns within a given output >+// std::string *in place* with replacements provided within a container of key/value >+// pairs. >+// >+// Example: >+// >+// std::string s = std::string("if (ptr < &foo)"); >+// int count = absl::StrReplaceAll({{"&", "&"}, >+// {"<", "<"}, >+// {">", ">"}}, &s); >+// EXPECT_EQ(count, 2); >+// EXPECT_EQ("if (ptr < &foo)", s); >+template <typename StrToStrMapping> >+int StrReplaceAll(const StrToStrMapping& replacements, std::string* target); >+ >+// Implementation details only, past this point. >+namespace strings_internal { >+ >+struct ViableSubstitution { >+ absl::string_view old; >+ absl::string_view replacement; >+ size_t offset; >+ >+ ViableSubstitution(absl::string_view old_str, >+ absl::string_view replacement_str, size_t offset_val) >+ : old(old_str), replacement(replacement_str), offset(offset_val) {} >+ >+ // One substitution occurs "before" another (takes priority) if either >+ // it has the lowest offset, or it has the same offset but a larger size. >+ bool OccursBefore(const ViableSubstitution& y) const { >+ if (offset != y.offset) return offset < y.offset; >+ return old.size() > y.old.size(); >+ } >+}; >+ >+// Build a vector of ViableSubstitutions based on the given list of >+// replacements. subs can be implemented as a priority_queue. However, it turns >+// out that most callers have small enough a list of substitutions that the >+// overhead of such a queue isn't worth it. >+template <typename StrToStrMapping> >+std::vector<ViableSubstitution> FindSubstitutions( >+ absl::string_view s, const StrToStrMapping& replacements) { >+ std::vector<ViableSubstitution> subs; >+ subs.reserve(replacements.size()); >+ >+ for (const auto& rep : replacements) { >+ using std::get; >+ absl::string_view old(get<0>(rep)); >+ >+ size_t pos = s.find(old); >+ if (pos == s.npos) continue; >+ >+ // Ignore attempts to replace "". This condition is almost never true, >+ // but above condition is frequently true. That's why we test for this >+ // now and not before. >+ if (old.empty()) continue; >+ >+ subs.emplace_back(old, get<1>(rep), pos); >+ >+ // Insertion sort to ensure the last ViableSubstitution comes before >+ // all the others. >+ size_t index = subs.size(); >+ while (--index && subs[index - 1].OccursBefore(subs[index])) { >+ std::swap(subs[index], subs[index - 1]); >+ } >+ } >+ return subs; >+} >+ >+int ApplySubstitutions(absl::string_view s, >+ std::vector<ViableSubstitution>* subs_ptr, >+ std::string* result_ptr); >+ >+} // namespace strings_internal >+ >+template <typename StrToStrMapping> >+std::string StrReplaceAll(absl::string_view s, const StrToStrMapping& replacements) { >+ auto subs = strings_internal::FindSubstitutions(s, replacements); >+ std::string result; >+ result.reserve(s.size()); >+ strings_internal::ApplySubstitutions(s, &subs, &result); >+ return result; >+} >+ >+template <typename StrToStrMapping> >+int StrReplaceAll(const StrToStrMapping& replacements, std::string* target) { >+ auto subs = strings_internal::FindSubstitutions(*target, replacements); >+ if (subs.empty()) return 0; >+ >+ std::string result; >+ result.reserve(target->size()); >+ int substitutions = >+ strings_internal::ApplySubstitutions(*target, &subs, &result); >+ target->swap(result); >+ return substitutions; >+} >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_STR_REPLACE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e608de8d19e41ba73c3d54ffa37643c72be802db >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace_benchmark.cc >@@ -0,0 +1,122 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/str_replace.h" >+ >+#include <cstring> >+#include <string> >+ >+#include "benchmark/benchmark.h" >+#include "absl/base/internal/raw_logging.h" >+ >+namespace { >+ >+std::string* big_string; >+std::string* after_replacing_the; >+std::string* after_replacing_many; >+ >+struct Replacement { >+ const char* needle; >+ const char* replacement; >+} replacements[] = { >+ {"the", "box"}, // >+ {"brown", "quick"}, // >+ {"jumped", "liquored"}, // >+ {"dozen", "brown"}, // >+ {"lazy", "pack"}, // >+ {"liquor", "shakes"}, // >+}; >+ >+// Here, we set up a std::string for use in global-replace benchmarks. >+// We started with a million blanks, and then deterministically insert >+// 10,000 copies each of two pangrams. The result is a std::string that is >+// 40% blank space and 60% these words. 'the' occurs 18,247 times and >+// all the substitutions together occur 49,004 times. >+// >+// We then create "after_replacing_the" to be a std::string that is a result of >+// replacing "the" with "box" in big_string. >+// >+// And then we create "after_replacing_many" to be a std::string that is result >+// of preferring several substitutions. >+void SetUpStrings() { >+ if (big_string == nullptr) { >+ size_t r = 0; >+ big_string = new std::string(1000 * 1000, ' '); >+ for (std::string phrase : {"the quick brown fox jumped over the lazy dogs", >+ "pack my box with the five dozen liquor jugs"}) { >+ for (int i = 0; i < 10 * 1000; ++i) { >+ r = r * 237 + 41; // not very random. >+ memcpy(&(*big_string)[r % (big_string->size() - phrase.size())], >+ phrase.data(), phrase.size()); >+ } >+ } >+ // big_string->resize(50); >+ // OK, we've set up the std::string, now let's set up expectations - first by >+ // just replacing "the" with "box" >+ after_replacing_the = new std::string(*big_string); >+ for (size_t pos = 0; >+ (pos = after_replacing_the->find("the", pos)) != std::string::npos;) { >+ memcpy(&(*after_replacing_the)[pos], "box", 3); >+ } >+ // And then with all the replacements. >+ after_replacing_many = new std::string(*big_string); >+ for (size_t pos = 0;;) { >+ size_t next_pos = static_cast<size_t>(-1); >+ const char* needle_string = nullptr; >+ const char* replacement_string = nullptr; >+ for (const auto& r : replacements) { >+ auto needlepos = after_replacing_many->find(r.needle, pos); >+ if (needlepos != std::string::npos && needlepos < next_pos) { >+ next_pos = needlepos; >+ needle_string = r.needle; >+ replacement_string = r.replacement; >+ } >+ } >+ if (next_pos > after_replacing_many->size()) break; >+ after_replacing_many->replace(next_pos, strlen(needle_string), >+ replacement_string); >+ next_pos += strlen(replacement_string); >+ pos = next_pos; >+ } >+ } >+} >+ >+void BM_StrReplaceAllOneReplacement(benchmark::State& state) { >+ SetUpStrings(); >+ std::string src = *big_string; >+ for (auto _ : state) { >+ std::string dest = absl::StrReplaceAll(src, {{"the", "box"}}); >+ ABSL_RAW_CHECK(dest == *after_replacing_the, >+ "not benchmarking intended behavior"); >+ } >+} >+BENCHMARK(BM_StrReplaceAllOneReplacement); >+ >+void BM_StrReplaceAll(benchmark::State& state) { >+ SetUpStrings(); >+ std::string src = *big_string; >+ for (auto _ : state) { >+ std::string dest = absl::StrReplaceAll(src, {{"the", "box"}, >+ {"brown", "quick"}, >+ {"jumped", "liquored"}, >+ {"dozen", "brown"}, >+ {"lazy", "pack"}, >+ {"liquor", "shakes"}}); >+ ABSL_RAW_CHECK(dest == *after_replacing_many, >+ "not benchmarking intended behavior"); >+ } >+} >+BENCHMARK(BM_StrReplaceAll); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..5d003a224a4fa888504573150f0641add4014064 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_replace_test.cc >@@ -0,0 +1,341 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/str_replace.h" >+ >+#include <list> >+#include <map> >+#include <tuple> >+ >+#include "gtest/gtest.h" >+#include "absl/strings/str_cat.h" >+#include "absl/strings/str_split.h" >+ >+TEST(StrReplaceAll, OneReplacement) { >+ std::string s; >+ >+ // Empty std::string. >+ s = absl::StrReplaceAll(s, {{"", ""}}); >+ EXPECT_EQ(s, ""); >+ s = absl::StrReplaceAll(s, {{"x", ""}}); >+ EXPECT_EQ(s, ""); >+ s = absl::StrReplaceAll(s, {{"", "y"}}); >+ EXPECT_EQ(s, ""); >+ s = absl::StrReplaceAll(s, {{"x", "y"}}); >+ EXPECT_EQ(s, ""); >+ >+ // Empty substring. >+ s = absl::StrReplaceAll("abc", {{"", ""}}); >+ EXPECT_EQ(s, "abc"); >+ s = absl::StrReplaceAll("abc", {{"", "y"}}); >+ EXPECT_EQ(s, "abc"); >+ s = absl::StrReplaceAll("abc", {{"x", ""}}); >+ EXPECT_EQ(s, "abc"); >+ >+ // Substring not found. >+ s = absl::StrReplaceAll("abc", {{"xyz", "123"}}); >+ EXPECT_EQ(s, "abc"); >+ >+ // Replace entire std::string. >+ s = absl::StrReplaceAll("abc", {{"abc", "xyz"}}); >+ EXPECT_EQ(s, "xyz"); >+ >+ // Replace once at the start. >+ s = absl::StrReplaceAll("abc", {{"a", "x"}}); >+ EXPECT_EQ(s, "xbc"); >+ >+ // Replace once in the middle. >+ s = absl::StrReplaceAll("abc", {{"b", "x"}}); >+ EXPECT_EQ(s, "axc"); >+ >+ // Replace once at the end. >+ s = absl::StrReplaceAll("abc", {{"c", "x"}}); >+ EXPECT_EQ(s, "abx"); >+ >+ // Replace multiple times with varying lengths of original/replacement. >+ s = absl::StrReplaceAll("ababa", {{"a", "xxx"}}); >+ EXPECT_EQ(s, "xxxbxxxbxxx"); >+ >+ s = absl::StrReplaceAll("ababa", {{"b", "xxx"}}); >+ EXPECT_EQ(s, "axxxaxxxa"); >+ >+ s = absl::StrReplaceAll("aaabaaabaaa", {{"aaa", "x"}}); >+ EXPECT_EQ(s, "xbxbx"); >+ >+ s = absl::StrReplaceAll("abbbabbba", {{"bbb", "x"}}); >+ EXPECT_EQ(s, "axaxa"); >+ >+ // Overlapping matches are replaced greedily. >+ s = absl::StrReplaceAll("aaa", {{"aa", "x"}}); >+ EXPECT_EQ(s, "xa"); >+ >+ // The replacements are not recursive. >+ s = absl::StrReplaceAll("aaa", {{"aa", "a"}}); >+ EXPECT_EQ(s, "aa"); >+} >+ >+TEST(StrReplaceAll, ManyReplacements) { >+ std::string s; >+ >+ // Empty std::string. >+ s = absl::StrReplaceAll("", {{"", ""}, {"x", ""}, {"", "y"}, {"x", "y"}}); >+ EXPECT_EQ(s, ""); >+ >+ // Empty substring. >+ s = absl::StrReplaceAll("abc", {{"", ""}, {"", "y"}, {"x", ""}}); >+ EXPECT_EQ(s, "abc"); >+ >+ // Replace entire std::string, one char at a time >+ s = absl::StrReplaceAll("abc", {{"a", "x"}, {"b", "y"}, {"c", "z"}}); >+ EXPECT_EQ(s, "xyz"); >+ s = absl::StrReplaceAll("zxy", {{"z", "x"}, {"x", "y"}, {"y", "z"}}); >+ EXPECT_EQ(s, "xyz"); >+ >+ // Replace once at the start (longer matches take precedence) >+ s = absl::StrReplaceAll("abc", {{"a", "x"}, {"ab", "xy"}, {"abc", "xyz"}}); >+ EXPECT_EQ(s, "xyz"); >+ >+ // Replace once in the middle. >+ s = absl::StrReplaceAll( >+ "Abc!", {{"a", "x"}, {"ab", "xy"}, {"b", "y"}, {"bc", "yz"}, {"c", "z"}}); >+ EXPECT_EQ(s, "Ayz!"); >+ >+ // Replace once at the end. >+ s = absl::StrReplaceAll( >+ "Abc!", >+ {{"a", "x"}, {"ab", "xy"}, {"b", "y"}, {"bc!", "yz?"}, {"c!", "z;"}}); >+ EXPECT_EQ(s, "Ayz?"); >+ >+ // Replace multiple times with varying lengths of original/replacement. >+ s = absl::StrReplaceAll("ababa", {{"a", "xxx"}, {"b", "XXXX"}}); >+ EXPECT_EQ(s, "xxxXXXXxxxXXXXxxx"); >+ >+ // Overlapping matches are replaced greedily. >+ s = absl::StrReplaceAll("aaa", {{"aa", "x"}, {"a", "X"}}); >+ EXPECT_EQ(s, "xX"); >+ s = absl::StrReplaceAll("aaa", {{"a", "X"}, {"aa", "x"}}); >+ EXPECT_EQ(s, "xX"); >+ >+ // Two well-known sentences >+ s = absl::StrReplaceAll("the quick brown fox jumped over the lazy dogs", >+ { >+ {"brown", "box"}, >+ {"dogs", "jugs"}, >+ {"fox", "with"}, >+ {"jumped", "five"}, >+ {"over", "dozen"}, >+ {"quick", "my"}, >+ {"the", "pack"}, >+ {"the lazy", "liquor"}, >+ }); >+ EXPECT_EQ(s, "pack my box with five dozen liquor jugs"); >+} >+ >+TEST(StrReplaceAll, ManyReplacementsInMap) { >+ std::map<const char *, const char *> replacements; >+ replacements["$who"] = "Bob"; >+ replacements["$count"] = "5"; >+ replacements["#Noun"] = "Apples"; >+ std::string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!", >+ replacements); >+ EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s); >+} >+ >+TEST(StrReplaceAll, ReplacementsInPlace) { >+ std::string s = std::string("$who bought $count #Noun. Thanks $who!"); >+ int count; >+ count = absl::StrReplaceAll({{"$count", absl::StrCat(5)}, >+ {"$who", "Bob"}, >+ {"#Noun", "Apples"}}, &s); >+ EXPECT_EQ(count, 4); >+ EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s); >+} >+ >+TEST(StrReplaceAll, ReplacementsInPlaceInMap) { >+ std::string s = std::string("$who bought $count #Noun. Thanks $who!"); >+ std::map<absl::string_view, absl::string_view> replacements; >+ replacements["$who"] = "Bob"; >+ replacements["$count"] = "5"; >+ replacements["#Noun"] = "Apples"; >+ int count; >+ count = absl::StrReplaceAll(replacements, &s); >+ EXPECT_EQ(count, 4); >+ EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s); >+} >+ >+struct Cont { >+ Cont() {} >+ explicit Cont(absl::string_view src) : data(src) {} >+ >+ absl::string_view data; >+}; >+ >+template <int index> >+absl::string_view get(const Cont& c) { >+ auto splitter = absl::StrSplit(c.data, ':'); >+ auto it = splitter.begin(); >+ for (int i = 0; i < index; ++i) ++it; >+ >+ return *it; >+} >+ >+TEST(StrReplaceAll, VariableNumber) { >+ std::string s; >+ { >+ std::vector<std::pair<std::string, std::string>> replacements; >+ >+ s = "abc"; >+ EXPECT_EQ(0, absl::StrReplaceAll(replacements, &s)); >+ EXPECT_EQ("abc", s); >+ >+ s = "abc"; >+ replacements.push_back({"a", "A"}); >+ EXPECT_EQ(1, absl::StrReplaceAll(replacements, &s)); >+ EXPECT_EQ("Abc", s); >+ >+ s = "abc"; >+ replacements.push_back({"b", "B"}); >+ EXPECT_EQ(2, absl::StrReplaceAll(replacements, &s)); >+ EXPECT_EQ("ABc", s); >+ >+ s = "abc"; >+ replacements.push_back({"d", "D"}); >+ EXPECT_EQ(2, absl::StrReplaceAll(replacements, &s)); >+ EXPECT_EQ("ABc", s); >+ >+ EXPECT_EQ("ABcABc", absl::StrReplaceAll("abcabc", replacements)); >+ } >+ >+ { >+ std::map<const char*, const char*> replacements; >+ replacements["aa"] = "x"; >+ replacements["a"] = "X"; >+ s = "aaa"; >+ EXPECT_EQ(2, absl::StrReplaceAll(replacements, &s)); >+ EXPECT_EQ("xX", s); >+ >+ EXPECT_EQ("xxX", absl::StrReplaceAll("aaaaa", replacements)); >+ } >+ >+ { >+ std::list<std::pair<absl::string_view, absl::string_view>> replacements = { >+ {"a", "x"}, {"b", "y"}, {"c", "z"}}; >+ >+ std::string s = absl::StrReplaceAll("abc", replacements); >+ EXPECT_EQ(s, "xyz"); >+ } >+ >+ { >+ using X = std::tuple<absl::string_view, std::string, int>; >+ std::vector<X> replacements(3); >+ replacements[0] = X{"a", "x", 1}; >+ replacements[1] = X{"b", "y", 0}; >+ replacements[2] = X{"c", "z", -1}; >+ >+ std::string s = absl::StrReplaceAll("abc", replacements); >+ EXPECT_EQ(s, "xyz"); >+ } >+ >+ { >+ std::vector<Cont> replacements(3); >+ replacements[0] = Cont{"a:x"}; >+ replacements[1] = Cont{"b:y"}; >+ replacements[2] = Cont{"c:z"}; >+ >+ std::string s = absl::StrReplaceAll("abc", replacements); >+ EXPECT_EQ(s, "xyz"); >+ } >+} >+ >+// Same as above, but using the in-place variant of absl::StrReplaceAll, >+// that returns the # of replacements performed. >+TEST(StrReplaceAll, Inplace) { >+ std::string s; >+ int reps; >+ >+ // Empty std::string. >+ s = ""; >+ reps = absl::StrReplaceAll({{"", ""}, {"x", ""}, {"", "y"}, {"x", "y"}}, &s); >+ EXPECT_EQ(reps, 0); >+ EXPECT_EQ(s, ""); >+ >+ // Empty substring. >+ s = "abc"; >+ reps = absl::StrReplaceAll({{"", ""}, {"", "y"}, {"x", ""}}, &s); >+ EXPECT_EQ(reps, 0); >+ EXPECT_EQ(s, "abc"); >+ >+ // Replace entire std::string, one char at a time >+ s = "abc"; >+ reps = absl::StrReplaceAll({{"a", "x"}, {"b", "y"}, {"c", "z"}}, &s); >+ EXPECT_EQ(reps, 3); >+ EXPECT_EQ(s, "xyz"); >+ s = "zxy"; >+ reps = absl::StrReplaceAll({{"z", "x"}, {"x", "y"}, {"y", "z"}}, &s); >+ EXPECT_EQ(reps, 3); >+ EXPECT_EQ(s, "xyz"); >+ >+ // Replace once at the start (longer matches take precedence) >+ s = "abc"; >+ reps = absl::StrReplaceAll({{"a", "x"}, {"ab", "xy"}, {"abc", "xyz"}}, &s); >+ EXPECT_EQ(reps, 1); >+ EXPECT_EQ(s, "xyz"); >+ >+ // Replace once in the middle. >+ s = "Abc!"; >+ reps = absl::StrReplaceAll( >+ {{"a", "x"}, {"ab", "xy"}, {"b", "y"}, {"bc", "yz"}, {"c", "z"}}, &s); >+ EXPECT_EQ(reps, 1); >+ EXPECT_EQ(s, "Ayz!"); >+ >+ // Replace once at the end. >+ s = "Abc!"; >+ reps = absl::StrReplaceAll( >+ {{"a", "x"}, {"ab", "xy"}, {"b", "y"}, {"bc!", "yz?"}, {"c!", "z;"}}, &s); >+ EXPECT_EQ(reps, 1); >+ EXPECT_EQ(s, "Ayz?"); >+ >+ // Replace multiple times with varying lengths of original/replacement. >+ s = "ababa"; >+ reps = absl::StrReplaceAll({{"a", "xxx"}, {"b", "XXXX"}}, &s); >+ EXPECT_EQ(reps, 5); >+ EXPECT_EQ(s, "xxxXXXXxxxXXXXxxx"); >+ >+ // Overlapping matches are replaced greedily. >+ s = "aaa"; >+ reps = absl::StrReplaceAll({{"aa", "x"}, {"a", "X"}}, &s); >+ EXPECT_EQ(reps, 2); >+ EXPECT_EQ(s, "xX"); >+ s = "aaa"; >+ reps = absl::StrReplaceAll({{"a", "X"}, {"aa", "x"}}, &s); >+ EXPECT_EQ(reps, 2); >+ EXPECT_EQ(s, "xX"); >+ >+ // Two well-known sentences >+ s = "the quick brown fox jumped over the lazy dogs"; >+ reps = absl::StrReplaceAll( >+ { >+ {"brown", "box"}, >+ {"dogs", "jugs"}, >+ {"fox", "with"}, >+ {"jumped", "five"}, >+ {"over", "dozen"}, >+ {"quick", "my"}, >+ {"the", "pack"}, >+ {"the lazy", "liquor"}, >+ }, >+ &s); >+ EXPECT_EQ(reps, 8); >+ EXPECT_EQ(s, "pack my box with five dozen liquor jugs"); >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..0207213c26baf913d9981497943d7867a1cdeeea >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split.cc >@@ -0,0 +1,136 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/str_split.h" >+ >+#include <algorithm> >+#include <cassert> >+#include <cstdint> >+#include <cstdlib> >+#include <cstring> >+#include <iterator> >+#include <limits> >+#include <memory> >+ >+#include "absl/base/internal/raw_logging.h" >+#include "absl/strings/ascii.h" >+ >+namespace absl { >+ >+namespace { >+ >+// This GenericFind() template function encapsulates the finding algorithm >+// shared between the ByString and ByAnyChar delimiters. The FindPolicy >+// template parameter allows each delimiter to customize the actual find >+// function to use and the length of the found delimiter. For example, the >+// Literal delimiter will ultimately use absl::string_view::find(), and the >+// AnyOf delimiter will use absl::string_view::find_first_of(). >+template <typename FindPolicy> >+absl::string_view GenericFind(absl::string_view text, >+ absl::string_view delimiter, size_t pos, >+ FindPolicy find_policy) { >+ if (delimiter.empty() && text.length() > 0) { >+ // Special case for empty std::string delimiters: always return a zero-length >+ // absl::string_view referring to the item at position 1 past pos. >+ return absl::string_view(text.begin() + pos + 1, 0); >+ } >+ size_t found_pos = absl::string_view::npos; >+ absl::string_view found(text.end(), 0); // By default, not found >+ found_pos = find_policy.Find(text, delimiter, pos); >+ if (found_pos != absl::string_view::npos) { >+ found = absl::string_view(text.data() + found_pos, >+ find_policy.Length(delimiter)); >+ } >+ return found; >+} >+ >+// Finds using absl::string_view::find(), therefore the length of the found >+// delimiter is delimiter.length(). >+struct LiteralPolicy { >+ size_t Find(absl::string_view text, absl::string_view delimiter, size_t pos) { >+ return text.find(delimiter, pos); >+ } >+ size_t Length(absl::string_view delimiter) { return delimiter.length(); } >+}; >+ >+// Finds using absl::string_view::find_first_of(), therefore the length of the >+// found delimiter is 1. >+struct AnyOfPolicy { >+ size_t Find(absl::string_view text, absl::string_view delimiter, size_t pos) { >+ return text.find_first_of(delimiter, pos); >+ } >+ size_t Length(absl::string_view /* delimiter */) { return 1; } >+}; >+ >+} // namespace >+ >+// >+// ByString >+// >+ >+ByString::ByString(absl::string_view sp) : delimiter_(sp) {} >+ >+absl::string_view ByString::Find(absl::string_view text, size_t pos) const { >+ if (delimiter_.length() == 1) { >+ // Much faster to call find on a single character than on an >+ // absl::string_view. >+ size_t found_pos = text.find(delimiter_[0], pos); >+ if (found_pos == absl::string_view::npos) >+ return absl::string_view(text.end(), 0); >+ return text.substr(found_pos, 1); >+ } >+ return GenericFind(text, delimiter_, pos, LiteralPolicy()); >+} >+ >+// >+// ByChar >+// >+ >+absl::string_view ByChar::Find(absl::string_view text, size_t pos) const { >+ size_t found_pos = text.find(c_, pos); >+ if (found_pos == absl::string_view::npos) >+ return absl::string_view(text.end(), 0); >+ return text.substr(found_pos, 1); >+} >+ >+// >+// ByAnyChar >+// >+ >+ByAnyChar::ByAnyChar(absl::string_view sp) : delimiters_(sp) {} >+ >+absl::string_view ByAnyChar::Find(absl::string_view text, size_t pos) const { >+ return GenericFind(text, delimiters_, pos, AnyOfPolicy()); >+} >+ >+// >+// ByLength >+// >+ByLength::ByLength(ptrdiff_t length) : length_(length) { >+ ABSL_RAW_CHECK(length > 0, ""); >+} >+ >+absl::string_view ByLength::Find(absl::string_view text, >+ size_t pos) const { >+ pos = std::min(pos, text.size()); // truncate `pos` >+ absl::string_view substr = text.substr(pos); >+ // If the std::string is shorter than the chunk size we say we >+ // "can't find the delimiter" so this will be the last chunk. >+ if (substr.length() <= static_cast<size_t>(length_)) >+ return absl::string_view(text.end(), 0); >+ >+ return absl::string_view(substr.begin() + length_, 0); >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9a7be2b0534425872c25e986aebc21db7e7fb756 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split.h >@@ -0,0 +1,511 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: str_split.h >+// ----------------------------------------------------------------------------- >+// >+// This file contains functions for splitting strings. It defines the main >+// `StrSplit()` function, several delimiters for determining the boundaries on >+// which to split the std::string, and predicates for filtering delimited results. >+// `StrSplit()` adapts the returned collection to the type specified by the >+// caller. >+// >+// Example: >+// >+// // Splits the given std::string on commas. Returns the results in a >+// // vector of strings. >+// std::vector<std::string> v = absl::StrSplit("a,b,c", ','); >+// // Can also use "," >+// // v[0] == "a", v[1] == "b", v[2] == "c" >+// >+// See StrSplit() below for more information. >+#ifndef ABSL_STRINGS_STR_SPLIT_H_ >+#define ABSL_STRINGS_STR_SPLIT_H_ >+ >+#include <algorithm> >+#include <cstddef> >+#include <map> >+#include <set> >+#include <string> >+#include <utility> >+#include <vector> >+ >+#include "absl/base/internal/raw_logging.h" >+#include "absl/strings/internal/str_split_internal.h" >+#include "absl/strings/string_view.h" >+#include "absl/strings/strip.h" >+ >+namespace absl { >+ >+//------------------------------------------------------------------------------ >+// Delimiters >+//------------------------------------------------------------------------------ >+// >+// `StrSplit()` uses delimiters to define the boundaries between elements in the >+// provided input. Several `Delimiter` types are defined below. If a std::string >+// (`const char*`, `std::string`, or `absl::string_view`) is passed in place of >+// an explicit `Delimiter` object, `StrSplit()` treats it the same way as if it >+// were passed a `ByString` delimiter. >+// >+// A `Delimiter` is an object with a `Find()` function that knows how to find >+// the first occurrence of itself in a given `absl::string_view`. >+// >+// The following `Delimiter` types are available for use within `StrSplit()`: >+// >+// - `ByString` (default for std::string arguments) >+// - `ByChar` (default for a char argument) >+// - `ByAnyChar` >+// - `ByLength` >+// - `MaxSplits` >+// >+// >+// A Delimiter's Find() member function will be passed the input text that is to >+// be split and the position to begin searching for the next delimiter in the >+// input text. The returned absl::string_view should refer to the next >+// occurrence (after pos) of the represented delimiter; this returned >+// absl::string_view represents the next location where the input std::string should >+// be broken. The returned absl::string_view may be zero-length if the Delimiter >+// does not represent a part of the std::string (e.g., a fixed-length delimiter). If >+// no delimiter is found in the given text, a zero-length absl::string_view >+// referring to text.end() should be returned (e.g., >+// absl::string_view(text.end(), 0)). It is important that the returned >+// absl::string_view always be within the bounds of input text given as an >+// argument--it must not refer to a std::string that is physically located outside of >+// the given std::string. >+// >+// The following example is a simple Delimiter object that is created with a >+// single char and will look for that char in the text passed to the Find() >+// function: >+// >+// struct SimpleDelimiter { >+// const char c_; >+// explicit SimpleDelimiter(char c) : c_(c) {} >+// absl::string_view Find(absl::string_view text, size_t pos) { >+// auto found = text.find(c_, pos); >+// if (found == absl::string_view::npos) >+// return absl::string_view(text.end(), 0); >+// >+// return absl::string_view(text, found, 1); >+// } >+// }; >+ >+// ByString >+// >+// A sub-std::string delimiter. If `StrSplit()` is passed a std::string in place of a >+// `Delimiter` object, the std::string will be implicitly converted into a >+// `ByString` delimiter. >+// >+// Example: >+// >+// // Because a std::string literal is converted to an `absl::ByString`, >+// // the following two splits are equivalent. >+// >+// std::vector<std::string> v1 = absl::StrSplit("a, b, c", ", "); >+// >+// using absl::ByString; >+// std::vector<std::string> v2 = absl::StrSplit("a, b, c", >+// ByString(", ")); >+// // v[0] == "a", v[1] == "b", v[2] == "c" >+class ByString { >+ public: >+ explicit ByString(absl::string_view sp); >+ absl::string_view Find(absl::string_view text, size_t pos) const; >+ >+ private: >+ const std::string delimiter_; >+}; >+ >+// ByChar >+// >+// A single character delimiter. `ByChar` is functionally equivalent to a >+// 1-char std::string within a `ByString` delimiter, but slightly more >+// efficient. >+// >+// Example: >+// >+// // Because a char literal is converted to a absl::ByChar, >+// // the following two splits are equivalent. >+// std::vector<std::string> v1 = absl::StrSplit("a,b,c", ','); >+// using absl::ByChar; >+// std::vector<std::string> v2 = absl::StrSplit("a,b,c", ByChar(',')); >+// // v[0] == "a", v[1] == "b", v[2] == "c" >+// >+// `ByChar` is also the default delimiter if a single character is given >+// as the delimiter to `StrSplit()`. For example, the following calls are >+// equivalent: >+// >+// std::vector<std::string> v = absl::StrSplit("a-b", '-'); >+// >+// using absl::ByChar; >+// std::vector<std::string> v = absl::StrSplit("a-b", ByChar('-')); >+// >+class ByChar { >+ public: >+ explicit ByChar(char c) : c_(c) {} >+ absl::string_view Find(absl::string_view text, size_t pos) const; >+ >+ private: >+ char c_; >+}; >+ >+// ByAnyChar >+// >+// A delimiter that will match any of the given byte-sized characters within >+// its provided std::string. >+// >+// Note: this delimiter works with single-byte std::string data, but does not work >+// with variable-width encodings, such as UTF-8. >+// >+// Example: >+// >+// using absl::ByAnyChar; >+// std::vector<std::string> v = absl::StrSplit("a,b=c", ByAnyChar(",=")); >+// // v[0] == "a", v[1] == "b", v[2] == "c" >+// >+// If `ByAnyChar` is given the empty std::string, it behaves exactly like >+// `ByString` and matches each individual character in the input std::string. >+// >+class ByAnyChar { >+ public: >+ explicit ByAnyChar(absl::string_view sp); >+ absl::string_view Find(absl::string_view text, size_t pos) const; >+ >+ private: >+ const std::string delimiters_; >+}; >+ >+// ByLength >+// >+// A delimiter for splitting into equal-length strings. The length argument to >+// the constructor must be greater than 0. >+// >+// Note: this delimiter works with single-byte std::string data, but does not work >+// with variable-width encodings, such as UTF-8. >+// >+// Example: >+// >+// using absl::ByLength; >+// std::vector<std::string> v = absl::StrSplit("123456789", ByLength(3)); >+ >+// // v[0] == "123", v[1] == "456", v[2] == "789" >+// >+// Note that the std::string does not have to be a multiple of the fixed split >+// length. In such a case, the last substring will be shorter. >+// >+// using absl::ByLength; >+// std::vector<std::string> v = absl::StrSplit("12345", ByLength(2)); >+// >+// // v[0] == "12", v[1] == "34", v[2] == "5" >+class ByLength { >+ public: >+ explicit ByLength(ptrdiff_t length); >+ absl::string_view Find(absl::string_view text, size_t pos) const; >+ >+ private: >+ const ptrdiff_t length_; >+}; >+ >+namespace strings_internal { >+ >+// A traits-like metafunction for selecting the default Delimiter object type >+// for a particular Delimiter type. The base case simply exposes type Delimiter >+// itself as the delimiter's Type. However, there are specializations for >+// std::string-like objects that map them to the ByString delimiter object. >+// This allows functions like absl::StrSplit() and absl::MaxSplits() to accept >+// std::string-like objects (e.g., ',') as delimiter arguments but they will be >+// treated as if a ByString delimiter was given. >+template <typename Delimiter> >+struct SelectDelimiter { >+ using type = Delimiter; >+}; >+ >+template <> >+struct SelectDelimiter<char> { >+ using type = ByChar; >+}; >+template <> >+struct SelectDelimiter<char*> { >+ using type = ByString; >+}; >+template <> >+struct SelectDelimiter<const char*> { >+ using type = ByString; >+}; >+template <> >+struct SelectDelimiter<absl::string_view> { >+ using type = ByString; >+}; >+template <> >+struct SelectDelimiter<std::string> { >+ using type = ByString; >+}; >+ >+// Wraps another delimiter and sets a max number of matches for that delimiter. >+template <typename Delimiter> >+class MaxSplitsImpl { >+ public: >+ MaxSplitsImpl(Delimiter delimiter, int limit) >+ : delimiter_(delimiter), limit_(limit), count_(0) {} >+ absl::string_view Find(absl::string_view text, size_t pos) { >+ if (count_++ == limit_) { >+ return absl::string_view(text.end(), 0); // No more matches. >+ } >+ return delimiter_.Find(text, pos); >+ } >+ >+ private: >+ Delimiter delimiter_; >+ const int limit_; >+ int count_; >+}; >+ >+} // namespace strings_internal >+ >+// MaxSplits() >+// >+// A delimiter that limits the number of matches which can occur to the passed >+// `limit`. The last element in the returned collection will contain all >+// remaining unsplit pieces, which may contain instances of the delimiter. >+// The collection will contain at most `limit` + 1 elements. >+// Example: >+// >+// using absl::MaxSplits; >+// std::vector<std::string> v = absl::StrSplit("a,b,c", MaxSplits(',', 1)); >+// >+// // v[0] == "a", v[1] == "b,c" >+template <typename Delimiter> >+inline strings_internal::MaxSplitsImpl< >+ typename strings_internal::SelectDelimiter<Delimiter>::type> >+MaxSplits(Delimiter delimiter, int limit) { >+ typedef >+ typename strings_internal::SelectDelimiter<Delimiter>::type DelimiterType; >+ return strings_internal::MaxSplitsImpl<DelimiterType>( >+ DelimiterType(delimiter), limit); >+} >+ >+//------------------------------------------------------------------------------ >+// Predicates >+//------------------------------------------------------------------------------ >+// >+// Predicates filter the results of a `StrSplit()` by determining whether or not >+// a resultant element is included in the result set. A predicate may be passed >+// as an optional third argument to the `StrSplit()` function. >+// >+// Predicates are unary functions (or functors) that take a single >+// `absl::string_view` argument and return a bool indicating whether the >+// argument should be included (`true`) or excluded (`false`). >+// >+// Predicates are useful when filtering out empty substrings. By default, empty >+// substrings may be returned by `StrSplit()`, which is similar to the way split >+// functions work in other programming languages. >+ >+// AllowEmpty() >+// >+// Always returns `true`, indicating that all strings--including empty >+// strings--should be included in the split output. This predicate is not >+// strictly needed because this is the default behavior of `StrSplit()`; >+// however, it might be useful at some call sites to make the intent explicit. >+// >+// Example: >+// >+// std::vector<std::string> v = absl::StrSplit(" a , ,,b,", ',', AllowEmpty()); >+// >+// // v[0] == " a ", v[1] == " ", v[2] == "", v[3] = "b", v[4] == "" >+struct AllowEmpty { >+ bool operator()(absl::string_view) const { return true; } >+}; >+ >+// SkipEmpty() >+// >+// Returns `false` if the given `absl::string_view` is empty, indicating that >+// `StrSplit()` should omit the empty std::string. >+// >+// Example: >+// >+// std::vector<std::string> v = absl::StrSplit(",a,,b,", ',', SkipEmpty()); >+// >+// // v[0] == "a", v[1] == "b" >+// >+// Note: `SkipEmpty()` does not consider a std::string containing only whitespace >+// to be empty. To skip such whitespace as well, use the `SkipWhitespace()` >+// predicate. >+struct SkipEmpty { >+ bool operator()(absl::string_view sp) const { return !sp.empty(); } >+}; >+ >+// SkipWhitespace() >+// >+// Returns `false` if the given `absl::string_view` is empty *or* contains only >+// whitespace, indicating that `StrSplit()` should omit the std::string. >+// >+// Example: >+// >+// std::vector<std::string> v = absl::StrSplit(" a , ,,b,", >+// ',', SkipWhitespace()); >+// // v[0] == " a ", v[1] == "b" >+// >+// // SkipEmpty() would return whitespace elements >+// std::vector<std::string> v = absl::StrSplit(" a , ,,b,", ',', SkipEmpty()); >+// // v[0] == " a ", v[1] == " ", v[2] == "b" >+struct SkipWhitespace { >+ bool operator()(absl::string_view sp) const { >+ sp = absl::StripAsciiWhitespace(sp); >+ return !sp.empty(); >+ } >+}; >+ >+//------------------------------------------------------------------------------ >+// StrSplit() >+//------------------------------------------------------------------------------ >+ >+// StrSplit() >+// >+// Splits a given std::string based on the provided `Delimiter` object, returning the >+// elements within the type specified by the caller. Optionally, you may pass a >+// `Predicate` to `StrSplit()` indicating whether to include or exclude the >+// resulting element within the final result set. (See the overviews for >+// Delimiters and Predicates above.) >+// >+// Example: >+// >+// std::vector<std::string> v = absl::StrSplit("a,b,c,d", ','); >+// // v[0] == "a", v[1] == "b", v[2] == "c", v[3] == "d" >+// >+// You can also provide an explicit `Delimiter` object: >+// >+// Example: >+// >+// using absl::ByAnyChar; >+// std::vector<std::string> v = absl::StrSplit("a,b=c", ByAnyChar(",=")); >+// // v[0] == "a", v[1] == "b", v[2] == "c" >+// >+// See above for more information on delimiters. >+// >+// By default, empty strings are included in the result set. You can optionally >+// include a third `Predicate` argument to apply a test for whether the >+// resultant element should be included in the result set: >+// >+// Example: >+// >+// std::vector<std::string> v = absl::StrSplit(" a , ,,b,", >+// ',', SkipWhitespace()); >+// // v[0] == " a ", v[1] == "b" >+// >+// See above for more information on predicates. >+// >+//------------------------------------------------------------------------------ >+// StrSplit() Return Types >+//------------------------------------------------------------------------------ >+// >+// The `StrSplit()` function adapts the returned collection to the collection >+// specified by the caller (e.g. `std::vector` above). The returned collections >+// may contain `string`, `absl::string_view` (in which case the original std::string >+// being split must ensure that it outlives the collection), or any object that >+// can be explicitly created from an `absl::string_view`. This behavior works >+// for: >+// >+// 1) All standard STL containers including `std::vector`, `std::list`, >+// `std::deque`, `std::set`,`std::multiset`, 'std::map`, and `std::multimap` >+// 2) `std::pair` (which is not actually a container). See below. >+// >+// Example: >+// >+// // The results are returned as `absl::string_view` objects. Note that we >+// // have to ensure that the input std::string outlives any results. >+// std::vector<absl::string_view> v = absl::StrSplit("a,b,c", ','); >+// >+// // Stores results in a std::set<std::string>, which also performs >+// // de-duplication and orders the elements in ascending order. >+// std::set<std::string> a = absl::StrSplit("b,a,c,a,b", ','); >+// // v[0] == "a", v[1] == "b", v[2] = "c" >+// >+// // `StrSplit()` can be used within a range-based for loop, in which case >+// // each element will be of type `absl::string_view`. >+// std::vector<std::string> v; >+// for (const auto sv : absl::StrSplit("a,b,c", ',')) { >+// if (sv != "b") v.emplace_back(sv); >+// } >+// // v[0] == "a", v[1] == "c" >+// >+// // Stores results in a map. The map implementation assumes that the input >+// // is provided as a series of key/value pairs. For example, the 0th element >+// // resulting from the split will be stored as a key to the 1st element. If >+// // an odd number of elements are resolved, the last element is paired with >+// // a default-constructed value (e.g., empty std::string). >+// std::map<std::string, std::string> m = absl::StrSplit("a,b,c", ','); >+// // m["a"] == "b", m["c"] == "" // last component value equals "" >+// >+// Splitting to `std::pair` is an interesting case because it can hold only two >+// elements and is not a collection type. When splitting to a `std::pair` the >+// first two split strings become the `std::pair` `.first` and `.second` >+// members, respectively. The remaining split substrings are discarded. If there >+// are less than two split substrings, the empty std::string is used for the >+// corresponding >+// `std::pair` member. >+// >+// Example: >+// >+// // Stores first two split strings as the members in a std::pair. >+// std::pair<std::string, std::string> p = absl::StrSplit("a,b,c", ','); >+// // p.first == "a", p.second == "b" // "c" is omitted. >+// >+// The `StrSplit()` function can be used multiple times to perform more >+// complicated splitting logic, such as intelligently parsing key-value pairs. >+// >+// Example: >+// >+// // The input std::string "a=b=c,d=e,f=,g" becomes >+// // { "a" => "b=c", "d" => "e", "f" => "", "g" => "" } >+// std::map<std::string, std::string> m; >+// for (absl::string_view sp : absl::StrSplit("a=b=c,d=e,f=,g", ',')) { >+// m.insert(absl::StrSplit(sp, absl::MaxSplits('=', 1))); >+// } >+// EXPECT_EQ("b=c", m.find("a")->second); >+// EXPECT_EQ("e", m.find("d")->second); >+// EXPECT_EQ("", m.find("f")->second); >+// EXPECT_EQ("", m.find("g")->second); >+// >+// WARNING: Due to a legacy bug that is maintained for backward compatibility, >+// splitting the following empty string_views produces different results: >+// >+// absl::StrSplit(absl::string_view(""), '-'); // {""} >+// absl::StrSplit(absl::string_view(), '-'); // {}, but should be {""} >+// >+// Try not to depend on this distinction because the bug may one day be fixed. >+template <typename Delimiter> >+strings_internal::Splitter< >+ typename strings_internal::SelectDelimiter<Delimiter>::type, AllowEmpty> >+StrSplit(strings_internal::ConvertibleToStringView text, Delimiter d) { >+ using DelimiterType = >+ typename strings_internal::SelectDelimiter<Delimiter>::type; >+ return strings_internal::Splitter<DelimiterType, AllowEmpty>( >+ std::move(text), DelimiterType(d), AllowEmpty()); >+} >+ >+template <typename Delimiter, typename Predicate> >+strings_internal::Splitter< >+ typename strings_internal::SelectDelimiter<Delimiter>::type, Predicate> >+StrSplit(strings_internal::ConvertibleToStringView text, Delimiter d, >+ Predicate p) { >+ using DelimiterType = >+ typename strings_internal::SelectDelimiter<Delimiter>::type; >+ return strings_internal::Splitter<DelimiterType, Predicate>( >+ std::move(text), DelimiterType(d), std::move(p)); >+} >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_STR_SPLIT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..326ff744ebd946e7781063ce93d731c2e15c4b5c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split_benchmark.cc >@@ -0,0 +1,156 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/str_split.h" >+ >+#include <iterator> >+#include <string> >+#include <unordered_map> >+#include <unordered_set> >+#include <vector> >+ >+#include "benchmark/benchmark.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/strings/string_view.h" >+ >+namespace { >+ >+std::string MakeTestString(int desired_length) { >+ static const int kAverageValueLen = 25; >+ std::string test(desired_length * kAverageValueLen, 'x'); >+ for (int i = 1; i < test.size(); i += kAverageValueLen) { >+ test[i] = ';'; >+ } >+ return test; >+} >+ >+void BM_Split2StringPiece(benchmark::State& state) { >+ std::string test = MakeTestString(state.range(0)); >+ for (auto _ : state) { >+ std::vector<absl::string_view> result = absl::StrSplit(test, ';'); >+ benchmark::DoNotOptimize(result); >+ } >+} >+BENCHMARK_RANGE(BM_Split2StringPiece, 0, 1 << 20); >+ >+void BM_Split2StringPieceLifted(benchmark::State& state) { >+ std::string test = MakeTestString(state.range(0)); >+ std::vector<absl::string_view> result; >+ for (auto _ : state) { >+ result = absl::StrSplit(test, ';'); >+ } >+ benchmark::DoNotOptimize(result); >+} >+BENCHMARK_RANGE(BM_Split2StringPieceLifted, 0, 1 << 20); >+ >+void BM_Split2String(benchmark::State& state) { >+ std::string test = MakeTestString(state.range(0)); >+ for (auto _ : state) { >+ std::vector<std::string> result = absl::StrSplit(test, ';'); >+ benchmark::DoNotOptimize(result); >+ } >+} >+BENCHMARK_RANGE(BM_Split2String, 0, 1 << 20); >+ >+// This benchmark is for comparing Split2 to Split1 (SplitStringUsing). In >+// particular, this benchmark uses SkipEmpty() to match SplitStringUsing's >+// behavior. >+void BM_Split2SplitStringUsing(benchmark::State& state) { >+ std::string test = MakeTestString(state.range(0)); >+ for (auto _ : state) { >+ std::vector<std::string> result = absl::StrSplit(test, ';', absl::SkipEmpty()); >+ benchmark::DoNotOptimize(result); >+ } >+} >+BENCHMARK_RANGE(BM_Split2SplitStringUsing, 0, 1 << 20); >+ >+void BM_SplitStringToUnorderedSet(benchmark::State& state) { >+ const int len = state.range(0); >+ std::string test(len, 'x'); >+ for (int i = 1; i < len; i += 2) { >+ test[i] = ';'; >+ } >+ for (auto _ : state) { >+ std::unordered_set<std::string> result = >+ absl::StrSplit(test, ':', absl::SkipEmpty()); >+ benchmark::DoNotOptimize(result); >+ } >+} >+BENCHMARK_RANGE(BM_SplitStringToUnorderedSet, 0, 1 << 20); >+ >+void BM_SplitStringToUnorderedMap(benchmark::State& state) { >+ const int len = state.range(0); >+ std::string test(len, 'x'); >+ for (int i = 1; i < len; i += 2) { >+ test[i] = ';'; >+ } >+ for (auto _ : state) { >+ std::unordered_map<std::string, std::string> result = >+ absl::StrSplit(test, ':', absl::SkipEmpty()); >+ benchmark::DoNotOptimize(result); >+ } >+} >+BENCHMARK_RANGE(BM_SplitStringToUnorderedMap, 0, 1 << 20); >+ >+void BM_SplitStringAllowEmpty(benchmark::State& state) { >+ const int len = state.range(0); >+ std::string test(len, 'x'); >+ for (int i = 1; i < len; i += 2) { >+ test[i] = ';'; >+ } >+ for (auto _ : state) { >+ std::vector<std::string> result = absl::StrSplit(test, ';'); >+ benchmark::DoNotOptimize(result); >+ } >+} >+BENCHMARK_RANGE(BM_SplitStringAllowEmpty, 0, 1 << 20); >+ >+struct OneCharLiteral { >+ char operator()() const { return 'X'; } >+}; >+ >+struct OneCharStringLiteral { >+ const char* operator()() const { return "X"; } >+}; >+ >+template <typename DelimiterFactory> >+void BM_SplitStringWithOneChar(benchmark::State& state) { >+ const auto delimiter = DelimiterFactory()(); >+ std::vector<absl::string_view> pieces; >+ size_t v = 0; >+ for (auto _ : state) { >+ pieces = absl::StrSplit("The quick brown fox jumps over the lazy dog", >+ delimiter); >+ v += pieces.size(); >+ } >+ ABSL_RAW_CHECK(v == state.iterations(), ""); >+} >+BENCHMARK_TEMPLATE(BM_SplitStringWithOneChar, OneCharLiteral); >+BENCHMARK_TEMPLATE(BM_SplitStringWithOneChar, OneCharStringLiteral); >+ >+template <typename DelimiterFactory> >+void BM_SplitStringWithOneCharNoVector(benchmark::State& state) { >+ const auto delimiter = DelimiterFactory()(); >+ size_t v = 0; >+ for (auto _ : state) { >+ auto splitter = absl::StrSplit( >+ "The quick brown fox jumps over the lazy dog", delimiter); >+ v += std::distance(splitter.begin(), splitter.end()); >+ } >+ ABSL_RAW_CHECK(v == state.iterations(), ""); >+} >+BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharLiteral); >+BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharStringLiteral); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..29a68047c99aef31bc7d3673a32b7228542c79a3 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/str_split_test.cc >@@ -0,0 +1,935 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/str_split.h" >+ >+#include <deque> >+#include <initializer_list> >+#include <list> >+#include <map> >+#include <memory> >+#include <string> >+#include <type_traits> >+#include <unordered_map> >+#include <unordered_set> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/dynamic_annotations.h" // for AbslRunningOnValgrind >+#include "absl/base/macros.h" >+#include "absl/strings/numbers.h" >+ >+namespace { >+ >+using ::testing::ElementsAre; >+using ::testing::Pair; >+using ::testing::UnorderedElementsAre; >+ >+TEST(Split, TraitsTest) { >+ static_assert(!absl::strings_internal::SplitterIsConvertibleTo<int>::value, >+ ""); >+ static_assert(!absl::strings_internal::SplitterIsConvertibleTo<std::string>::value, >+ ""); >+ static_assert(absl::strings_internal::SplitterIsConvertibleTo< >+ std::vector<std::string>>::value, >+ ""); >+ static_assert( >+ !absl::strings_internal::SplitterIsConvertibleTo<std::vector<int>>::value, >+ ""); >+ static_assert(absl::strings_internal::SplitterIsConvertibleTo< >+ std::vector<absl::string_view>>::value, >+ ""); >+ static_assert(absl::strings_internal::SplitterIsConvertibleTo< >+ std::map<std::string, std::string>>::value, >+ ""); >+ static_assert(absl::strings_internal::SplitterIsConvertibleTo< >+ std::map<absl::string_view, absl::string_view>>::value, >+ ""); >+ static_assert(!absl::strings_internal::SplitterIsConvertibleTo< >+ std::map<int, std::string>>::value, >+ ""); >+ static_assert(!absl::strings_internal::SplitterIsConvertibleTo< >+ std::map<std::string, int>>::value, >+ ""); >+} >+ >+// This tests the overall split API, which is made up of the absl::StrSplit() >+// function and the Delimiter objects in the absl:: namespace. >+// This TEST macro is outside of any namespace to require full specification of >+// namespaces just like callers will need to use. >+TEST(Split, APIExamples) { >+ { >+ // Passes std::string delimiter. Assumes the default of Literal. >+ std::vector<std::string> v = absl::StrSplit("a,b,c", ','); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ >+ // Equivalent to... >+ using absl::ByString; >+ v = absl::StrSplit("a,b,c", ByString(",")); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ >+ // Equivalent to... >+ EXPECT_THAT(absl::StrSplit("a,b,c", ByString(",")), >+ ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Same as above, but using a single character as the delimiter. >+ std::vector<std::string> v = absl::StrSplit("a,b,c", ','); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ >+ // Equivalent to... >+ using absl::ByChar; >+ v = absl::StrSplit("a,b,c", ByChar(',')); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Same as above, but using std::string >+ std::vector<std::string> v = absl::StrSplit("a,b,c", ','); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ >+ // Equivalent to... >+ using absl::ByChar; >+ v = absl::StrSplit("a,b,c", ByChar(',')); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Uses the Literal std::string "=>" as the delimiter. >+ const std::vector<std::string> v = absl::StrSplit("a=>b=>c", "=>"); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // The substrings are returned as string_views, eliminating copying. >+ std::vector<absl::string_view> v = absl::StrSplit("a,b,c", ','); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Leading and trailing empty substrings. >+ std::vector<std::string> v = absl::StrSplit(",a,b,c,", ','); >+ EXPECT_THAT(v, ElementsAre("", "a", "b", "c", "")); >+ } >+ >+ { >+ // Splits on a delimiter that is not found. >+ std::vector<std::string> v = absl::StrSplit("abc", ','); >+ EXPECT_THAT(v, ElementsAre("abc")); >+ } >+ >+ { >+ // Splits the input std::string into individual characters by using an empty >+ // std::string as the delimiter. >+ std::vector<std::string> v = absl::StrSplit("abc", ""); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Splits std::string data with embedded NUL characters, using NUL as the >+ // delimiter. A simple delimiter of "\0" doesn't work because strlen() will >+ // say that's the empty std::string when constructing the absl::string_view >+ // delimiter. Instead, a non-empty std::string containing NUL can be used as the >+ // delimiter. >+ std::string embedded_nulls("a\0b\0c", 5); >+ std::string null_delim("\0", 1); >+ std::vector<std::string> v = absl::StrSplit(embedded_nulls, null_delim); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Stores first two split strings as the members in a std::pair. >+ std::pair<std::string, std::string> p = absl::StrSplit("a,b,c", ','); >+ EXPECT_EQ("a", p.first); >+ EXPECT_EQ("b", p.second); >+ // "c" is omitted because std::pair can hold only two elements. >+ } >+ >+ { >+ // Results stored in std::set<std::string> >+ std::set<std::string> v = absl::StrSplit("a,b,c,a,b,c,a,b,c", ','); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Uses a non-const char* delimiter. >+ char a[] = ","; >+ char* d = a + 0; >+ std::vector<std::string> v = absl::StrSplit("a,b,c", d); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Results split using either of , or ; >+ using absl::ByAnyChar; >+ std::vector<std::string> v = absl::StrSplit("a,b;c", ByAnyChar(",;")); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Uses the SkipWhitespace predicate. >+ using absl::SkipWhitespace; >+ std::vector<std::string> v = absl::StrSplit(" a , ,,b,", ',', SkipWhitespace()); >+ EXPECT_THAT(v, ElementsAre(" a ", "b")); >+ } >+ >+ { >+ // Uses the ByLength delimiter. >+ using absl::ByLength; >+ std::vector<std::string> v = absl::StrSplit("abcdefg", ByLength(3)); >+ EXPECT_THAT(v, ElementsAre("abc", "def", "g")); >+ } >+ >+ { >+ // Different forms of initialization / conversion. >+ std::vector<std::string> v1 = absl::StrSplit("a,b,c", ','); >+ EXPECT_THAT(v1, ElementsAre("a", "b", "c")); >+ std::vector<std::string> v2(absl::StrSplit("a,b,c", ',')); >+ EXPECT_THAT(v2, ElementsAre("a", "b", "c")); >+ auto v3 = std::vector<std::string>(absl::StrSplit("a,b,c", ',')); >+ EXPECT_THAT(v3, ElementsAre("a", "b", "c")); >+ v3 = absl::StrSplit("a,b,c", ','); >+ EXPECT_THAT(v3, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Results stored in a std::map. >+ std::map<std::string, std::string> m = absl::StrSplit("a,1,b,2,a,3", ','); >+ EXPECT_EQ(2, m.size()); >+ EXPECT_EQ("3", m["a"]); >+ EXPECT_EQ("2", m["b"]); >+ } >+ >+ { >+ // Results stored in a std::multimap. >+ std::multimap<std::string, std::string> m = absl::StrSplit("a,1,b,2,a,3", ','); >+ EXPECT_EQ(3, m.size()); >+ auto it = m.find("a"); >+ EXPECT_EQ("1", it->second); >+ ++it; >+ EXPECT_EQ("3", it->second); >+ it = m.find("b"); >+ EXPECT_EQ("2", it->second); >+ } >+ >+ { >+ // Demonstrates use in a range-based for loop in C++11. >+ std::string s = "x,x,x,x,x,x,x"; >+ for (absl::string_view sp : absl::StrSplit(s, ',')) { >+ EXPECT_EQ("x", sp); >+ } >+ } >+ >+ { >+ // Demonstrates use with a Predicate in a range-based for loop. >+ using absl::SkipWhitespace; >+ std::string s = " ,x,,x,,x,x,x,,"; >+ for (absl::string_view sp : absl::StrSplit(s, ',', SkipWhitespace())) { >+ EXPECT_EQ("x", sp); >+ } >+ } >+ >+ { >+ // Demonstrates a "smart" split to std::map using two separate calls to >+ // absl::StrSplit. One call to split the records, and another call to split >+ // the keys and values. This also uses the Limit delimiter so that the >+ // std::string "a=b=c" will split to "a" -> "b=c". >+ std::map<std::string, std::string> m; >+ for (absl::string_view sp : absl::StrSplit("a=b=c,d=e,f=,g", ',')) { >+ m.insert(absl::StrSplit(sp, absl::MaxSplits('=', 1))); >+ } >+ EXPECT_EQ("b=c", m.find("a")->second); >+ EXPECT_EQ("e", m.find("d")->second); >+ EXPECT_EQ("", m.find("f")->second); >+ EXPECT_EQ("", m.find("g")->second); >+ } >+} >+ >+// >+// Tests for SplitIterator >+// >+ >+TEST(SplitIterator, Basics) { >+ auto splitter = absl::StrSplit("a,b", ','); >+ auto it = splitter.begin(); >+ auto end = splitter.end(); >+ >+ EXPECT_NE(it, end); >+ EXPECT_EQ("a", *it); // tests dereference >+ ++it; // tests preincrement >+ EXPECT_NE(it, end); >+ EXPECT_EQ("b", std::string(it->data(), it->size())); // tests dereference as ptr >+ it++; // tests postincrement >+ EXPECT_EQ(it, end); >+} >+ >+// Simple Predicate to skip a particular std::string. >+class Skip { >+ public: >+ explicit Skip(const std::string& s) : s_(s) {} >+ bool operator()(absl::string_view sp) { return sp != s_; } >+ >+ private: >+ std::string s_; >+}; >+ >+TEST(SplitIterator, Predicate) { >+ auto splitter = absl::StrSplit("a,b,c", ',', Skip("b")); >+ auto it = splitter.begin(); >+ auto end = splitter.end(); >+ >+ EXPECT_NE(it, end); >+ EXPECT_EQ("a", *it); // tests dereference >+ ++it; // tests preincrement -- "b" should be skipped here. >+ EXPECT_NE(it, end); >+ EXPECT_EQ("c", std::string(it->data(), it->size())); // tests dereference as ptr >+ it++; // tests postincrement >+ EXPECT_EQ(it, end); >+} >+ >+TEST(SplitIterator, EdgeCases) { >+ // Expected input and output, assuming a delimiter of ',' >+ struct { >+ std::string in; >+ std::vector<std::string> expect; >+ } specs[] = { >+ {"", {""}}, >+ {"foo", {"foo"}}, >+ {",", {"", ""}}, >+ {",foo", {"", "foo"}}, >+ {"foo,", {"foo", ""}}, >+ {",foo,", {"", "foo", ""}}, >+ {"foo,bar", {"foo", "bar"}}, >+ }; >+ >+ for (const auto& spec : specs) { >+ SCOPED_TRACE(spec.in); >+ auto splitter = absl::StrSplit(spec.in, ','); >+ auto it = splitter.begin(); >+ auto end = splitter.end(); >+ for (const auto& expected : spec.expect) { >+ EXPECT_NE(it, end); >+ EXPECT_EQ(expected, *it++); >+ } >+ EXPECT_EQ(it, end); >+ } >+} >+ >+TEST(Splitter, Const) { >+ const auto splitter = absl::StrSplit("a,b,c", ','); >+ EXPECT_THAT(splitter, ElementsAre("a", "b", "c")); >+} >+ >+TEST(Split, EmptyAndNull) { >+ // Attention: Splitting a null absl::string_view is different than splitting >+ // an empty absl::string_view even though both string_views are considered >+ // equal. This behavior is likely surprising and undesirable. However, to >+ // maintain backward compatibility, there is a small "hack" in >+ // str_split_internal.h that preserves this behavior. If that behavior is ever >+ // changed/fixed, this test will need to be updated. >+ EXPECT_THAT(absl::StrSplit(absl::string_view(""), '-'), ElementsAre("")); >+ EXPECT_THAT(absl::StrSplit(absl::string_view(), '-'), ElementsAre()); >+} >+ >+TEST(SplitIterator, EqualityAsEndCondition) { >+ auto splitter = absl::StrSplit("a,b,c", ','); >+ auto it = splitter.begin(); >+ auto it2 = it; >+ >+ // Increments it2 twice to point to "c" in the input text. >+ ++it2; >+ ++it2; >+ EXPECT_EQ("c", *it2); >+ >+ // This test uses a non-end SplitIterator as the terminating condition in a >+ // for loop. This relies on SplitIterator equality for non-end SplitIterators >+ // working correctly. At this point it2 points to "c", and we use that as the >+ // "end" condition in this test. >+ std::vector<absl::string_view> v; >+ for (; it != it2; ++it) { >+ v.push_back(*it); >+ } >+ EXPECT_THAT(v, ElementsAre("a", "b")); >+} >+ >+// >+// Tests for Splitter >+// >+ >+TEST(Splitter, RangeIterators) { >+ auto splitter = absl::StrSplit("a,b,c", ','); >+ std::vector<absl::string_view> output; >+ for (const absl::string_view p : splitter) { >+ output.push_back(p); >+ } >+ EXPECT_THAT(output, ElementsAre("a", "b", "c")); >+} >+ >+// Some template functions for use in testing conversion operators >+template <typename ContainerType, typename Splitter> >+void TestConversionOperator(const Splitter& splitter) { >+ ContainerType output = splitter; >+ EXPECT_THAT(output, UnorderedElementsAre("a", "b", "c", "d")); >+} >+ >+template <typename MapType, typename Splitter> >+void TestMapConversionOperator(const Splitter& splitter) { >+ MapType m = splitter; >+ EXPECT_THAT(m, UnorderedElementsAre(Pair("a", "b"), Pair("c", "d"))); >+} >+ >+template <typename FirstType, typename SecondType, typename Splitter> >+void TestPairConversionOperator(const Splitter& splitter) { >+ std::pair<FirstType, SecondType> p = splitter; >+ EXPECT_EQ(p, (std::pair<FirstType, SecondType>("a", "b"))); >+} >+ >+TEST(Splitter, ConversionOperator) { >+ auto splitter = absl::StrSplit("a,b,c,d", ','); >+ >+ TestConversionOperator<std::vector<absl::string_view>>(splitter); >+ TestConversionOperator<std::vector<std::string>>(splitter); >+ TestConversionOperator<std::list<absl::string_view>>(splitter); >+ TestConversionOperator<std::list<std::string>>(splitter); >+ TestConversionOperator<std::deque<absl::string_view>>(splitter); >+ TestConversionOperator<std::deque<std::string>>(splitter); >+ TestConversionOperator<std::set<absl::string_view>>(splitter); >+ TestConversionOperator<std::set<std::string>>(splitter); >+ TestConversionOperator<std::multiset<absl::string_view>>(splitter); >+ TestConversionOperator<std::multiset<std::string>>(splitter); >+ TestConversionOperator<std::unordered_set<std::string>>(splitter); >+ >+ // Tests conversion to map-like objects. >+ >+ TestMapConversionOperator<std::map<absl::string_view, absl::string_view>>( >+ splitter); >+ TestMapConversionOperator<std::map<absl::string_view, std::string>>(splitter); >+ TestMapConversionOperator<std::map<std::string, absl::string_view>>(splitter); >+ TestMapConversionOperator<std::map<std::string, std::string>>(splitter); >+ TestMapConversionOperator< >+ std::multimap<absl::string_view, absl::string_view>>(splitter); >+ TestMapConversionOperator<std::multimap<absl::string_view, std::string>>(splitter); >+ TestMapConversionOperator<std::multimap<std::string, absl::string_view>>(splitter); >+ TestMapConversionOperator<std::multimap<std::string, std::string>>(splitter); >+ TestMapConversionOperator<std::unordered_map<std::string, std::string>>(splitter); >+ >+ // Tests conversion to std::pair >+ >+ TestPairConversionOperator<absl::string_view, absl::string_view>(splitter); >+ TestPairConversionOperator<absl::string_view, std::string>(splitter); >+ TestPairConversionOperator<std::string, absl::string_view>(splitter); >+ TestPairConversionOperator<std::string, std::string>(splitter); >+} >+ >+// A few additional tests for conversion to std::pair. This conversion is >+// different from others because a std::pair always has exactly two elements: >+// .first and .second. The split has to work even when the split has >+// less-than, equal-to, and more-than 2 strings. >+TEST(Splitter, ToPair) { >+ { >+ // Empty std::string >+ std::pair<std::string, std::string> p = absl::StrSplit("", ','); >+ EXPECT_EQ("", p.first); >+ EXPECT_EQ("", p.second); >+ } >+ >+ { >+ // Only first >+ std::pair<std::string, std::string> p = absl::StrSplit("a", ','); >+ EXPECT_EQ("a", p.first); >+ EXPECT_EQ("", p.second); >+ } >+ >+ { >+ // Only second >+ std::pair<std::string, std::string> p = absl::StrSplit(",b", ','); >+ EXPECT_EQ("", p.first); >+ EXPECT_EQ("b", p.second); >+ } >+ >+ { >+ // First and second. >+ std::pair<std::string, std::string> p = absl::StrSplit("a,b", ','); >+ EXPECT_EQ("a", p.first); >+ EXPECT_EQ("b", p.second); >+ } >+ >+ { >+ // First and second and then more stuff that will be ignored. >+ std::pair<std::string, std::string> p = absl::StrSplit("a,b,c", ','); >+ EXPECT_EQ("a", p.first); >+ EXPECT_EQ("b", p.second); >+ // "c" is omitted. >+ } >+} >+ >+TEST(Splitter, Predicates) { >+ static const char kTestChars[] = ",a, ,b,"; >+ using absl::AllowEmpty; >+ using absl::SkipEmpty; >+ using absl::SkipWhitespace; >+ >+ { >+ // No predicate. Does not skip empties. >+ auto splitter = absl::StrSplit(kTestChars, ','); >+ std::vector<std::string> v = splitter; >+ EXPECT_THAT(v, ElementsAre("", "a", " ", "b", "")); >+ } >+ >+ { >+ // Allows empty strings. Same behavior as no predicate at all. >+ auto splitter = absl::StrSplit(kTestChars, ',', AllowEmpty()); >+ std::vector<std::string> v_allowempty = splitter; >+ EXPECT_THAT(v_allowempty, ElementsAre("", "a", " ", "b", "")); >+ >+ // Ensures AllowEmpty equals the behavior with no predicate. >+ auto splitter_nopredicate = absl::StrSplit(kTestChars, ','); >+ std::vector<std::string> v_nopredicate = splitter_nopredicate; >+ EXPECT_EQ(v_allowempty, v_nopredicate); >+ } >+ >+ { >+ // Skips empty strings. >+ auto splitter = absl::StrSplit(kTestChars, ',', SkipEmpty()); >+ std::vector<std::string> v = splitter; >+ EXPECT_THAT(v, ElementsAre("a", " ", "b")); >+ } >+ >+ { >+ // Skips empty and all-whitespace strings. >+ auto splitter = absl::StrSplit(kTestChars, ',', SkipWhitespace()); >+ std::vector<std::string> v = splitter; >+ EXPECT_THAT(v, ElementsAre("a", "b")); >+ } >+} >+ >+// >+// Tests for StrSplit() >+// >+ >+TEST(Split, Basics) { >+ { >+ // Doesn't really do anything useful because the return value is ignored, >+ // but it should work. >+ absl::StrSplit("a,b,c", ','); >+ } >+ >+ { >+ std::vector<absl::string_view> v = absl::StrSplit("a,b,c", ','); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ std::vector<std::string> v = absl::StrSplit("a,b,c", ','); >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ } >+ >+ { >+ // Ensures that assignment works. This requires a little extra work with >+ // C++11 because of overloads with initializer_list. >+ std::vector<std::string> v; >+ v = absl::StrSplit("a,b,c", ','); >+ >+ EXPECT_THAT(v, ElementsAre("a", "b", "c")); >+ std::map<std::string, std::string> m; >+ m = absl::StrSplit("a,b,c", ','); >+ EXPECT_EQ(2, m.size()); >+ std::unordered_map<std::string, std::string> hm; >+ hm = absl::StrSplit("a,b,c", ','); >+ EXPECT_EQ(2, hm.size()); >+ } >+} >+ >+absl::string_view ReturnStringView() { return "Hello World"; } >+const char* ReturnConstCharP() { return "Hello World"; } >+char* ReturnCharP() { return const_cast<char*>("Hello World"); } >+ >+TEST(Split, AcceptsCertainTemporaries) { >+ std::vector<std::string> v; >+ v = absl::StrSplit(ReturnStringView(), ' '); >+ EXPECT_THAT(v, ElementsAre("Hello", "World")); >+ v = absl::StrSplit(ReturnConstCharP(), ' '); >+ EXPECT_THAT(v, ElementsAre("Hello", "World")); >+ v = absl::StrSplit(ReturnCharP(), ' '); >+ EXPECT_THAT(v, ElementsAre("Hello", "World")); >+} >+ >+TEST(Split, Temporary) { >+ // Use a std::string longer than the small-std::string-optimization length, so that when >+ // the temporary is destroyed, if the splitter keeps a reference to the >+ // std::string's contents, it'll reference freed memory instead of just dead >+ // on-stack memory. >+ const char input[] = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u"; >+ EXPECT_LT(sizeof(std::string), ABSL_ARRAYSIZE(input)) >+ << "Input should be larger than fits on the stack."; >+ >+ // This happens more often in C++11 as part of a range-based for loop. >+ auto splitter = absl::StrSplit(std::string(input), ','); >+ std::string expected = "a"; >+ for (absl::string_view letter : splitter) { >+ EXPECT_EQ(expected, letter); >+ ++expected[0]; >+ } >+ EXPECT_EQ("v", expected); >+ >+ // This happens more often in C++11 as part of a range-based for loop. >+ auto std_splitter = absl::StrSplit(std::string(input), ','); >+ expected = "a"; >+ for (absl::string_view letter : std_splitter) { >+ EXPECT_EQ(expected, letter); >+ ++expected[0]; >+ } >+ EXPECT_EQ("v", expected); >+} >+ >+template <typename T> >+static std::unique_ptr<T> CopyToHeap(const T& value) { >+ return std::unique_ptr<T>(new T(value)); >+} >+ >+TEST(Split, LvalueCaptureIsCopyable) { >+ std::string input = "a,b"; >+ auto heap_splitter = CopyToHeap(absl::StrSplit(input, ',')); >+ auto stack_splitter = *heap_splitter; >+ heap_splitter.reset(); >+ std::vector<std::string> result = stack_splitter; >+ EXPECT_THAT(result, testing::ElementsAre("a", "b")); >+} >+ >+TEST(Split, TemporaryCaptureIsCopyable) { >+ auto heap_splitter = CopyToHeap(absl::StrSplit(std::string("a,b"), ',')); >+ auto stack_splitter = *heap_splitter; >+ heap_splitter.reset(); >+ std::vector<std::string> result = stack_splitter; >+ EXPECT_THAT(result, testing::ElementsAre("a", "b")); >+} >+ >+TEST(Split, SplitterIsCopyableAndMoveable) { >+ auto a = absl::StrSplit("foo", '-'); >+ >+ // Ensures that the following expressions compile. >+ auto b = a; // Copy construct >+ auto c = std::move(a); // Move construct >+ b = c; // Copy assign >+ c = std::move(b); // Move assign >+ >+ EXPECT_THAT(c, ElementsAre("foo")); >+} >+ >+TEST(Split, StringDelimiter) { >+ { >+ std::vector<absl::string_view> v = absl::StrSplit("a,b", ','); >+ EXPECT_THAT(v, ElementsAre("a", "b")); >+ } >+ >+ { >+ std::vector<absl::string_view> v = absl::StrSplit("a,b", std::string(",")); >+ EXPECT_THAT(v, ElementsAre("a", "b")); >+ } >+ >+ { >+ std::vector<absl::string_view> v = >+ absl::StrSplit("a,b", absl::string_view(",")); >+ EXPECT_THAT(v, ElementsAre("a", "b")); >+ } >+} >+ >+TEST(Split, UTF8) { >+ // Tests splitting utf8 strings and utf8 delimiters. >+ std::string utf8_string = u8"\u03BA\u1F79\u03C3\u03BC\u03B5"; >+ { >+ // A utf8 input std::string with an ascii delimiter. >+ std::string to_split = "a," + utf8_string; >+ std::vector<absl::string_view> v = absl::StrSplit(to_split, ','); >+ EXPECT_THAT(v, ElementsAre("a", utf8_string)); >+ } >+ >+ { >+ // A utf8 input std::string and a utf8 delimiter. >+ std::string to_split = "a," + utf8_string + ",b"; >+ std::string unicode_delimiter = "," + utf8_string + ","; >+ std::vector<absl::string_view> v = >+ absl::StrSplit(to_split, unicode_delimiter); >+ EXPECT_THAT(v, ElementsAre("a", "b")); >+ } >+ >+ { >+ // A utf8 input std::string and ByAnyChar with ascii chars. >+ std::vector<absl::string_view> v = >+ absl::StrSplit(u8"Foo h\u00E4llo th\u4E1Ere", absl::ByAnyChar(" \t")); >+ EXPECT_THAT(v, ElementsAre("Foo", u8"h\u00E4llo", u8"th\u4E1Ere")); >+ } >+} >+ >+TEST(Split, EmptyStringDelimiter) { >+ { >+ std::vector<std::string> v = absl::StrSplit("", ""); >+ EXPECT_THAT(v, ElementsAre("")); >+ } >+ >+ { >+ std::vector<std::string> v = absl::StrSplit("a", ""); >+ EXPECT_THAT(v, ElementsAre("a")); >+ } >+ >+ { >+ std::vector<std::string> v = absl::StrSplit("ab", ""); >+ EXPECT_THAT(v, ElementsAre("a", "b")); >+ } >+ >+ { >+ std::vector<std::string> v = absl::StrSplit("a b", ""); >+ EXPECT_THAT(v, ElementsAre("a", " ", "b")); >+ } >+} >+ >+TEST(Split, SubstrDelimiter) { >+ std::vector<absl::string_view> results; >+ absl::string_view delim("//"); >+ >+ results = absl::StrSplit("", delim); >+ EXPECT_THAT(results, ElementsAre("")); >+ >+ results = absl::StrSplit("//", delim); >+ EXPECT_THAT(results, ElementsAre("", "")); >+ >+ results = absl::StrSplit("ab", delim); >+ EXPECT_THAT(results, ElementsAre("ab")); >+ >+ results = absl::StrSplit("ab//", delim); >+ EXPECT_THAT(results, ElementsAre("ab", "")); >+ >+ results = absl::StrSplit("ab/", delim); >+ EXPECT_THAT(results, ElementsAre("ab/")); >+ >+ results = absl::StrSplit("a/b", delim); >+ EXPECT_THAT(results, ElementsAre("a/b")); >+ >+ results = absl::StrSplit("a//b", delim); >+ EXPECT_THAT(results, ElementsAre("a", "b")); >+ >+ results = absl::StrSplit("a///b", delim); >+ EXPECT_THAT(results, ElementsAre("a", "/b")); >+ >+ results = absl::StrSplit("a////b", delim); >+ EXPECT_THAT(results, ElementsAre("a", "", "b")); >+} >+ >+TEST(Split, EmptyResults) { >+ std::vector<absl::string_view> results; >+ >+ results = absl::StrSplit("", '#'); >+ EXPECT_THAT(results, ElementsAre("")); >+ >+ results = absl::StrSplit("#", '#'); >+ EXPECT_THAT(results, ElementsAre("", "")); >+ >+ results = absl::StrSplit("#cd", '#'); >+ EXPECT_THAT(results, ElementsAre("", "cd")); >+ >+ results = absl::StrSplit("ab#cd#", '#'); >+ EXPECT_THAT(results, ElementsAre("ab", "cd", "")); >+ >+ results = absl::StrSplit("ab##cd", '#'); >+ EXPECT_THAT(results, ElementsAre("ab", "", "cd")); >+ >+ results = absl::StrSplit("ab##", '#'); >+ EXPECT_THAT(results, ElementsAre("ab", "", "")); >+ >+ results = absl::StrSplit("ab#ab#", '#'); >+ EXPECT_THAT(results, ElementsAre("ab", "ab", "")); >+ >+ results = absl::StrSplit("aaaa", 'a'); >+ EXPECT_THAT(results, ElementsAre("", "", "", "", "")); >+ >+ results = absl::StrSplit("", '#', absl::SkipEmpty()); >+ EXPECT_THAT(results, ElementsAre()); >+} >+ >+template <typename Delimiter> >+static bool IsFoundAtStartingPos(absl::string_view text, Delimiter d, >+ size_t starting_pos, int expected_pos) { >+ absl::string_view found = d.Find(text, starting_pos); >+ return found.data() != text.end() && >+ expected_pos == found.data() - text.data(); >+} >+ >+// Helper function for testing Delimiter objects. Returns true if the given >+// Delimiter is found in the given std::string at the given position. This function >+// tests two cases: >+// 1. The actual text given, staring at position 0 >+// 2. The text given with leading padding that should be ignored >+template <typename Delimiter> >+static bool IsFoundAt(absl::string_view text, Delimiter d, int expected_pos) { >+ const std::string leading_text = ",x,y,z,"; >+ return IsFoundAtStartingPos(text, d, 0, expected_pos) && >+ IsFoundAtStartingPos(leading_text + std::string(text), d, >+ leading_text.length(), >+ expected_pos + leading_text.length()); >+} >+ >+// >+// Tests for Literal >+// >+ >+// Tests using any delimiter that represents a single comma. >+template <typename Delimiter> >+void TestComma(Delimiter d) { >+ EXPECT_TRUE(IsFoundAt(",", d, 0)); >+ EXPECT_TRUE(IsFoundAt("a,", d, 1)); >+ EXPECT_TRUE(IsFoundAt(",b", d, 0)); >+ EXPECT_TRUE(IsFoundAt("a,b", d, 1)); >+ EXPECT_TRUE(IsFoundAt("a,b,", d, 1)); >+ EXPECT_TRUE(IsFoundAt("a,b,c", d, 1)); >+ EXPECT_FALSE(IsFoundAt("", d, -1)); >+ EXPECT_FALSE(IsFoundAt(" ", d, -1)); >+ EXPECT_FALSE(IsFoundAt("a", d, -1)); >+ EXPECT_FALSE(IsFoundAt("a b c", d, -1)); >+ EXPECT_FALSE(IsFoundAt("a;b;c", d, -1)); >+ EXPECT_FALSE(IsFoundAt(";", d, -1)); >+} >+ >+TEST(Delimiter, Literal) { >+ using absl::ByString; >+ TestComma(ByString(",")); >+ >+ // Works as named variable. >+ ByString comma_string(","); >+ TestComma(comma_string); >+ >+ // The first occurrence of empty std::string ("") in a std::string is at position 0. >+ // There is a test below that demonstrates this for absl::string_view::find(). >+ // If the ByString delimiter returned position 0 for this, there would >+ // be an infinite loop in the SplitIterator code. To avoid this, empty std::string >+ // is a special case in that it always returns the item at position 1. >+ absl::string_view abc("abc"); >+ EXPECT_EQ(0, abc.find("")); // "" is found at position 0 >+ ByString empty(""); >+ EXPECT_FALSE(IsFoundAt("", empty, 0)); >+ EXPECT_FALSE(IsFoundAt("a", empty, 0)); >+ EXPECT_TRUE(IsFoundAt("ab", empty, 1)); >+ EXPECT_TRUE(IsFoundAt("abc", empty, 1)); >+} >+ >+TEST(Split, ByChar) { >+ using absl::ByChar; >+ TestComma(ByChar(',')); >+ >+ // Works as named variable. >+ ByChar comma_char(','); >+ TestComma(comma_char); >+} >+ >+// >+// Tests for ByAnyChar >+// >+ >+TEST(Delimiter, ByAnyChar) { >+ using absl::ByAnyChar; >+ ByAnyChar one_delim(","); >+ // Found >+ EXPECT_TRUE(IsFoundAt(",", one_delim, 0)); >+ EXPECT_TRUE(IsFoundAt("a,", one_delim, 1)); >+ EXPECT_TRUE(IsFoundAt("a,b", one_delim, 1)); >+ EXPECT_TRUE(IsFoundAt(",b", one_delim, 0)); >+ // Not found >+ EXPECT_FALSE(IsFoundAt("", one_delim, -1)); >+ EXPECT_FALSE(IsFoundAt(" ", one_delim, -1)); >+ EXPECT_FALSE(IsFoundAt("a", one_delim, -1)); >+ EXPECT_FALSE(IsFoundAt("a;b;c", one_delim, -1)); >+ EXPECT_FALSE(IsFoundAt(";", one_delim, -1)); >+ >+ ByAnyChar two_delims(",;"); >+ // Found >+ EXPECT_TRUE(IsFoundAt(",", two_delims, 0)); >+ EXPECT_TRUE(IsFoundAt(";", two_delims, 0)); >+ EXPECT_TRUE(IsFoundAt(",;", two_delims, 0)); >+ EXPECT_TRUE(IsFoundAt(";,", two_delims, 0)); >+ EXPECT_TRUE(IsFoundAt(",;b", two_delims, 0)); >+ EXPECT_TRUE(IsFoundAt(";,b", two_delims, 0)); >+ EXPECT_TRUE(IsFoundAt("a;,", two_delims, 1)); >+ EXPECT_TRUE(IsFoundAt("a,;", two_delims, 1)); >+ EXPECT_TRUE(IsFoundAt("a;,b", two_delims, 1)); >+ EXPECT_TRUE(IsFoundAt("a,;b", two_delims, 1)); >+ // Not found >+ EXPECT_FALSE(IsFoundAt("", two_delims, -1)); >+ EXPECT_FALSE(IsFoundAt(" ", two_delims, -1)); >+ EXPECT_FALSE(IsFoundAt("a", two_delims, -1)); >+ EXPECT_FALSE(IsFoundAt("a=b=c", two_delims, -1)); >+ EXPECT_FALSE(IsFoundAt("=", two_delims, -1)); >+ >+ // ByAnyChar behaves just like ByString when given a delimiter of empty >+ // std::string. That is, it always returns a zero-length absl::string_view >+ // referring to the item at position 1, not position 0. >+ ByAnyChar empty(""); >+ EXPECT_FALSE(IsFoundAt("", empty, 0)); >+ EXPECT_FALSE(IsFoundAt("a", empty, 0)); >+ EXPECT_TRUE(IsFoundAt("ab", empty, 1)); >+ EXPECT_TRUE(IsFoundAt("abc", empty, 1)); >+} >+ >+// >+// Tests for ByLength >+// >+ >+TEST(Delimiter, ByLength) { >+ using absl::ByLength; >+ >+ ByLength four_char_delim(4); >+ >+ // Found >+ EXPECT_TRUE(IsFoundAt("abcde", four_char_delim, 4)); >+ EXPECT_TRUE(IsFoundAt("abcdefghijklmnopqrstuvwxyz", four_char_delim, 4)); >+ EXPECT_TRUE(IsFoundAt("a b,c\nd", four_char_delim, 4)); >+ // Not found >+ EXPECT_FALSE(IsFoundAt("", four_char_delim, 0)); >+ EXPECT_FALSE(IsFoundAt("a", four_char_delim, 0)); >+ EXPECT_FALSE(IsFoundAt("ab", four_char_delim, 0)); >+ EXPECT_FALSE(IsFoundAt("abc", four_char_delim, 0)); >+ EXPECT_FALSE(IsFoundAt("abcd", four_char_delim, 0)); >+} >+ >+TEST(Split, WorksWithLargeStrings) { >+ if (sizeof(size_t) > 4) { >+ std::string s((uint32_t{1} << 31) + 1, 'x'); // 2G + 1 byte >+ s.back() = '-'; >+ std::vector<absl::string_view> v = absl::StrSplit(s, '-'); >+ EXPECT_EQ(2, v.size()); >+ // The first element will contain 2G of 'x's. >+ // testing::StartsWith is too slow with a 2G std::string. >+ EXPECT_EQ('x', v[0][0]); >+ EXPECT_EQ('x', v[0][1]); >+ EXPECT_EQ('x', v[0][3]); >+ EXPECT_EQ("", v[1]); >+ } >+} >+ >+TEST(SplitInternalTest, TypeTraits) { >+ EXPECT_FALSE(absl::strings_internal::HasMappedType<int>::value); >+ EXPECT_TRUE( >+ (absl::strings_internal::HasMappedType<std::map<int, int>>::value)); >+ EXPECT_FALSE(absl::strings_internal::HasValueType<int>::value); >+ EXPECT_TRUE( >+ (absl::strings_internal::HasValueType<std::map<int, int>>::value)); >+ EXPECT_FALSE(absl::strings_internal::HasConstIterator<int>::value); >+ EXPECT_TRUE( >+ (absl::strings_internal::HasConstIterator<std::map<int, int>>::value)); >+ EXPECT_FALSE(absl::strings_internal::IsInitializerList<int>::value); >+ EXPECT_TRUE((absl::strings_internal::IsInitializerList< >+ std::initializer_list<int>>::value)); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..4ceeb6bff580c8c55642db7e01e8d7f2021d97bf >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view.cc >@@ -0,0 +1,245 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/string_view.h" >+ >+#ifndef ABSL_HAVE_STD_STRING_VIEW >+ >+#include <algorithm> >+#include <climits> >+#include <cstring> >+#include <ostream> >+ >+#include "absl/strings/internal/memutil.h" >+ >+namespace absl { >+ >+namespace { >+void WritePadding(std::ostream& o, size_t pad) { >+ char fill_buf[32]; >+ memset(fill_buf, o.fill(), sizeof(fill_buf)); >+ while (pad) { >+ size_t n = std::min(pad, sizeof(fill_buf)); >+ o.write(fill_buf, n); >+ pad -= n; >+ } >+} >+ >+class LookupTable { >+ public: >+ // For each character in wanted, sets the index corresponding >+ // to the ASCII code of that character. This is used by >+ // the find_.*_of methods below to tell whether or not a character is in >+ // the lookup table in constant time. >+ explicit LookupTable(string_view wanted) { >+ for (char c : wanted) { >+ table_[Index(c)] = true; >+ } >+ } >+ bool operator[](char c) const { return table_[Index(c)]; } >+ >+ private: >+ static unsigned char Index(char c) { return static_cast<unsigned char>(c); } >+ bool table_[UCHAR_MAX + 1] = {}; >+}; >+ >+} // namespace >+ >+std::ostream& operator<<(std::ostream& o, string_view piece) { >+ std::ostream::sentry sentry(o); >+ if (sentry) { >+ size_t lpad = 0; >+ size_t rpad = 0; >+ if (static_cast<size_t>(o.width()) > piece.size()) { >+ size_t pad = o.width() - piece.size(); >+ if ((o.flags() & o.adjustfield) == o.left) { >+ rpad = pad; >+ } else { >+ lpad = pad; >+ } >+ } >+ if (lpad) WritePadding(o, lpad); >+ o.write(piece.data(), piece.size()); >+ if (rpad) WritePadding(o, rpad); >+ o.width(0); >+ } >+ return o; >+} >+ >+string_view::size_type string_view::copy(char* buf, size_type n, >+ size_type pos) const { >+ size_type ulen = length_; >+ assert(pos <= ulen); >+ size_type rlen = std::min(ulen - pos, n); >+ if (rlen > 0) { >+ const char* start = ptr_ + pos; >+ std::copy(start, start + rlen, buf); >+ } >+ return rlen; >+} >+ >+string_view::size_type string_view::find(string_view s, size_type pos) const >+ noexcept { >+ if (empty() || pos > length_) { >+ if (empty() && pos == 0 && s.empty()) return 0; >+ return npos; >+ } >+ const char* result = >+ strings_internal::memmatch(ptr_ + pos, length_ - pos, s.ptr_, s.length_); >+ return result ? result - ptr_ : npos; >+} >+ >+string_view::size_type string_view::find(char c, size_type pos) const noexcept { >+ if (empty() || pos >= length_) { >+ return npos; >+ } >+ const char* result = >+ static_cast<const char*>(memchr(ptr_ + pos, c, length_ - pos)); >+ return result != nullptr ? result - ptr_ : npos; >+} >+ >+string_view::size_type string_view::rfind(string_view s, size_type pos) const >+ noexcept { >+ if (length_ < s.length_) return npos; >+ if (s.empty()) return std::min(length_, pos); >+ const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_; >+ const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_); >+ return result != last ? result - ptr_ : npos; >+} >+ >+// Search range is [0..pos] inclusive. If pos == npos, search everything. >+string_view::size_type string_view::rfind(char c, size_type pos) const >+ noexcept { >+ // Note: memrchr() is not available on Windows. >+ if (empty()) return npos; >+ for (size_type i = std::min(pos, length_ - 1);; --i) { >+ if (ptr_[i] == c) { >+ return i; >+ } >+ if (i == 0) break; >+ } >+ return npos; >+} >+ >+string_view::size_type string_view::find_first_of(string_view s, >+ size_type pos) const >+ noexcept { >+ if (empty() || s.empty()) { >+ return npos; >+ } >+ // Avoid the cost of LookupTable() for a single-character search. >+ if (s.length_ == 1) return find_first_of(s.ptr_[0], pos); >+ LookupTable tbl(s); >+ for (size_type i = pos; i < length_; ++i) { >+ if (tbl[ptr_[i]]) { >+ return i; >+ } >+ } >+ return npos; >+} >+ >+string_view::size_type string_view::find_first_not_of(string_view s, >+ size_type pos) const >+ noexcept { >+ if (empty()) return npos; >+ // Avoid the cost of LookupTable() for a single-character search. >+ if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos); >+ LookupTable tbl(s); >+ for (size_type i = pos; i < length_; ++i) { >+ if (!tbl[ptr_[i]]) { >+ return i; >+ } >+ } >+ return npos; >+} >+ >+string_view::size_type string_view::find_first_not_of(char c, >+ size_type pos) const >+ noexcept { >+ if (empty()) return npos; >+ for (; pos < length_; ++pos) { >+ if (ptr_[pos] != c) { >+ return pos; >+ } >+ } >+ return npos; >+} >+ >+string_view::size_type string_view::find_last_of(string_view s, >+ size_type pos) const noexcept { >+ if (empty() || s.empty()) return npos; >+ // Avoid the cost of LookupTable() for a single-character search. >+ if (s.length_ == 1) return find_last_of(s.ptr_[0], pos); >+ LookupTable tbl(s); >+ for (size_type i = std::min(pos, length_ - 1);; --i) { >+ if (tbl[ptr_[i]]) { >+ return i; >+ } >+ if (i == 0) break; >+ } >+ return npos; >+} >+ >+string_view::size_type string_view::find_last_not_of(string_view s, >+ size_type pos) const >+ noexcept { >+ if (empty()) return npos; >+ size_type i = std::min(pos, length_ - 1); >+ if (s.empty()) return i; >+ // Avoid the cost of LookupTable() for a single-character search. >+ if (s.length_ == 1) return find_last_not_of(s.ptr_[0], pos); >+ LookupTable tbl(s); >+ for (;; --i) { >+ if (!tbl[ptr_[i]]) { >+ return i; >+ } >+ if (i == 0) break; >+ } >+ return npos; >+} >+ >+string_view::size_type string_view::find_last_not_of(char c, >+ size_type pos) const >+ noexcept { >+ if (empty()) return npos; >+ size_type i = std::min(pos, length_ - 1); >+ for (;; --i) { >+ if (ptr_[i] != c) { >+ return i; >+ } >+ if (i == 0) break; >+ } >+ return npos; >+} >+ >+// MSVC has non-standard behavior that implicitly creates definitions for static >+// const members. These implicit definitions conflict with explicit out-of-class >+// member definitions that are required by the C++ standard, resulting in >+// LNK1169 "multiply defined" errors at link time. __declspec(selectany) asks >+// MSVC to choose only one definition for the symbol it decorates. See details >+// at http://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx >+#ifdef _MSC_VER >+#define ABSL_STRING_VIEW_SELECTANY __declspec(selectany) >+#else >+#define ABSL_STRING_VIEW_SELECTANY >+#endif >+ >+ABSL_STRING_VIEW_SELECTANY >+constexpr string_view::size_type string_view::npos; >+ABSL_STRING_VIEW_SELECTANY >+constexpr string_view::size_type string_view::kMaxSize; >+ >+} // namespace absl >+ >+#endif // ABSL_HAVE_STD_STRING_VIEW >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view.h >new file mode 100644 >index 0000000000000000000000000000000000000000..a7f9199240a217c6a03fa206683f05ca2a9e7003 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view.h >@@ -0,0 +1,570 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: string_view.h >+// ----------------------------------------------------------------------------- >+// >+// This file contains the definition of the `absl::string_view` class. A >+// `string_view` points to a contiguous span of characters, often part or all of >+// another `std::string`, double-quoted std::string literal, character array, or even >+// another `string_view`. >+// >+// This `absl::string_view` abstraction is designed to be a drop-in >+// replacement for the C++17 `std::string_view` abstraction. >+#ifndef ABSL_STRINGS_STRING_VIEW_H_ >+#define ABSL_STRINGS_STRING_VIEW_H_ >+ >+#include <algorithm> >+#include "absl/base/config.h" >+ >+#ifdef ABSL_HAVE_STD_STRING_VIEW >+ >+#include <string_view> >+ >+namespace absl { >+using std::string_view; >+} // namespace absl >+ >+#else // ABSL_HAVE_STD_STRING_VIEW >+ >+#include <cassert> >+#include <cstddef> >+#include <cstring> >+#include <iosfwd> >+#include <iterator> >+#include <limits> >+#include <string> >+ >+#include "absl/base/internal/throw_delegate.h" >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+ >+namespace absl { >+ >+// absl::string_view >+// >+// A `string_view` provides a lightweight view into the std::string data provided by >+// a `std::string`, double-quoted std::string literal, character array, or even >+// another `string_view`. A `string_view` does *not* own the std::string to which it >+// points, and that data cannot be modified through the view. >+// >+// You can use `string_view` as a function or method parameter anywhere a >+// parameter can receive a double-quoted std::string literal, `const char*`, >+// `std::string`, or another `absl::string_view` argument with no need to copy >+// the std::string data. Systematic use of `string_view` within function arguments >+// reduces data copies and `strlen()` calls. >+// >+// Because of its small size, prefer passing `string_view` by value: >+// >+// void MyFunction(absl::string_view arg); >+// >+// If circumstances require, you may also pass one by const reference: >+// >+// void MyFunction(const absl::string_view& arg); // not preferred >+// >+// Passing by value generates slightly smaller code for many architectures. >+// >+// In either case, the source data of the `string_view` must outlive the >+// `string_view` itself. >+// >+// A `string_view` is also suitable for local variables if you know that the >+// lifetime of the underlying object is longer than the lifetime of your >+// `string_view` variable. However, beware of binding a `string_view` to a >+// temporary value: >+// >+// // BAD use of string_view: lifetime problem >+// absl::string_view sv = obj.ReturnAString(); >+// >+// // GOOD use of string_view: str outlives sv >+// std::string str = obj.ReturnAString(); >+// absl::string_view sv = str; >+// >+// Due to lifetime issues, a `string_view` is sometimes a poor choice for a >+// return value and usually a poor choice for a data member. If you do use a >+// `string_view` this way, it is your responsibility to ensure that the object >+// pointed to by the `string_view` outlives the `string_view`. >+// >+// A `string_view` may represent a whole std::string or just part of a std::string. For >+// example, when splitting a std::string, `std::vector<absl::string_view>` is a >+// natural data type for the output. >+// >+// >+// When constructed from a source which is nul-terminated, the `string_view` >+// itself will not include the nul-terminator unless a specific size (including >+// the nul) is passed to the constructor. As a result, common idioms that work >+// on nul-terminated strings do not work on `string_view` objects. If you write >+// code that scans a `string_view`, you must check its length rather than test >+// for nul, for example. Note, however, that nuls may still be embedded within >+// a `string_view` explicitly. >+// >+// You may create a null `string_view` in two ways: >+// >+// absl::string_view sv(); >+// absl::string_view sv(nullptr, 0); >+// >+// For the above, `sv.data() == nullptr`, `sv.length() == 0`, and >+// `sv.empty() == true`. Also, if you create a `string_view` with a non-null >+// pointer then `sv.data() != nullptr`. Thus, you can use `string_view()` to >+// signal an undefined value that is different from other `string_view` values >+// in a similar fashion to how `const char* p1 = nullptr;` is different from >+// `const char* p2 = "";`. However, in practice, it is not recommended to rely >+// on this behavior. >+// >+// Be careful not to confuse a null `string_view` with an empty one. A null >+// `string_view` is an empty `string_view`, but some empty `string_view`s are >+// not null. Prefer checking for emptiness over checking for null. >+// >+// There are many ways to create an empty string_view: >+// >+// const char* nullcp = nullptr; >+// // string_view.size() will return 0 in all cases. >+// absl::string_view(); >+// absl::string_view(nullcp, 0); >+// absl::string_view(""); >+// absl::string_view("", 0); >+// absl::string_view("abcdef", 0); >+// absl::string_view("abcdef" + 6, 0); >+// >+// All empty `string_view` objects whether null or not, are equal: >+// >+// absl::string_view() == absl::string_view("", 0) >+// absl::string_view(nullptr, 0) == absl:: string_view("abcdef"+6, 0) >+class string_view { >+ public: >+ using traits_type = std::char_traits<char>; >+ using value_type = char; >+ using pointer = char*; >+ using const_pointer = const char*; >+ using reference = char&; >+ using const_reference = const char&; >+ using const_iterator = const char*; >+ using iterator = const_iterator; >+ using const_reverse_iterator = std::reverse_iterator<const_iterator>; >+ using reverse_iterator = const_reverse_iterator; >+ using size_type = size_t; >+ using difference_type = std::ptrdiff_t; >+ >+ static constexpr size_type npos = static_cast<size_type>(-1); >+ >+ // Null `string_view` constructor >+ constexpr string_view() noexcept : ptr_(nullptr), length_(0) {} >+ >+ // Implicit constructors >+ >+ template <typename Allocator> >+ string_view( // NOLINT(runtime/explicit) >+ const std::basic_string<char, std::char_traits<char>, Allocator>& >+ str) noexcept >+ : ptr_(str.data()), length_(CheckLengthInternal(str.size())) {} >+ >+ // Implicit constructor of a `string_view` from nul-terminated `str`. When >+ // accepting possibly null strings, use `absl::NullSafeStringView(str)` >+ // instead (see below). >+ constexpr string_view(const char* str) // NOLINT(runtime/explicit) >+ : ptr_(str), length_(CheckLengthInternal(StrLenInternal(str))) {} >+ >+ // Implicit constructor of a `string_view` from a `const char*` and length. >+ constexpr string_view(const char* data, size_type len) >+ : ptr_(data), length_(CheckLengthInternal(len)) {} >+ >+ // NOTE: Harmlessly omitted to work around gdb bug. >+ // constexpr string_view(const string_view&) noexcept = default; >+ // string_view& operator=(const string_view&) noexcept = default; >+ >+ // Iterators >+ >+ // string_view::begin() >+ // >+ // Returns an iterator pointing to the first character at the beginning of the >+ // `string_view`, or `end()` if the `string_view` is empty. >+ constexpr const_iterator begin() const noexcept { return ptr_; } >+ >+ // string_view::end() >+ // >+ // Returns an iterator pointing just beyond the last character at the end of >+ // the `string_view`. This iterator acts as a placeholder; attempting to >+ // access it results in undefined behavior. >+ constexpr const_iterator end() const noexcept { return ptr_ + length_; } >+ >+ // string_view::cbegin() >+ // >+ // Returns a const iterator pointing to the first character at the beginning >+ // of the `string_view`, or `end()` if the `string_view` is empty. >+ constexpr const_iterator cbegin() const noexcept { return begin(); } >+ >+ // string_view::cend() >+ // >+ // Returns a const iterator pointing just beyond the last character at the end >+ // of the `string_view`. This pointer acts as a placeholder; attempting to >+ // access its element results in undefined behavior. >+ constexpr const_iterator cend() const noexcept { return end(); } >+ >+ // string_view::rbegin() >+ // >+ // Returns a reverse iterator pointing to the last character at the end of the >+ // `string_view`, or `rend()` if the `string_view` is empty. >+ const_reverse_iterator rbegin() const noexcept { >+ return const_reverse_iterator(end()); >+ } >+ >+ // string_view::rend() >+ // >+ // Returns a reverse iterator pointing just before the first character at the >+ // beginning of the `string_view`. This pointer acts as a placeholder; >+ // attempting to access its element results in undefined behavior. >+ const_reverse_iterator rend() const noexcept { >+ return const_reverse_iterator(begin()); >+ } >+ >+ // string_view::crbegin() >+ // >+ // Returns a const reverse iterator pointing to the last character at the end >+ // of the `string_view`, or `crend()` if the `string_view` is empty. >+ const_reverse_iterator crbegin() const noexcept { return rbegin(); } >+ >+ // string_view::crend() >+ // >+ // Returns a const reverse iterator pointing just before the first character >+ // at the beginning of the `string_view`. This pointer acts as a placeholder; >+ // attempting to access its element results in undefined behavior. >+ const_reverse_iterator crend() const noexcept { return rend(); } >+ >+ // Capacity Utilities >+ >+ // string_view::size() >+ // >+ // Returns the number of characters in the `string_view`. >+ constexpr size_type size() const noexcept { >+ return length_; >+ } >+ >+ // string_view::length() >+ // >+ // Returns the number of characters in the `string_view`. Alias for `size()`. >+ constexpr size_type length() const noexcept { return size(); } >+ >+ // string_view::max_size() >+ // >+ // Returns the maximum number of characters the `string_view` can hold. >+ constexpr size_type max_size() const noexcept { return kMaxSize; } >+ >+ // string_view::empty() >+ // >+ // Checks if the `string_view` is empty (refers to no characters). >+ constexpr bool empty() const noexcept { return length_ == 0; } >+ >+ // std::string:view::operator[] >+ // >+ // Returns the ith element of an `string_view` using the array operator. >+ // Note that this operator does not perform any bounds checking. >+ constexpr const_reference operator[](size_type i) const { return ptr_[i]; } >+ >+ // string_view::front() >+ // >+ // Returns the first element of a `string_view`. >+ constexpr const_reference front() const { return ptr_[0]; } >+ >+ // string_view::back() >+ // >+ // Returns the last element of a `string_view`. >+ constexpr const_reference back() const { return ptr_[size() - 1]; } >+ >+ // string_view::data() >+ // >+ // Returns a pointer to the underlying character array (which is of course >+ // stored elsewhere). Note that `string_view::data()` may contain embedded nul >+ // characters, but the returned buffer may or may not be nul-terminated; >+ // therefore, do not pass `data()` to a routine that expects a nul-terminated >+ // std::string. >+ constexpr const_pointer data() const noexcept { return ptr_; } >+ >+ // Modifiers >+ >+ // string_view::remove_prefix() >+ // >+ // Removes the first `n` characters from the `string_view`. Note that the >+ // underlying std::string is not changed, only the view. >+ void remove_prefix(size_type n) { >+ assert(n <= length_); >+ ptr_ += n; >+ length_ -= n; >+ } >+ >+ // string_view::remove_suffix() >+ // >+ // Removes the last `n` characters from the `string_view`. Note that the >+ // underlying std::string is not changed, only the view. >+ void remove_suffix(size_type n) { >+ assert(n <= length_); >+ length_ -= n; >+ } >+ >+ // string_view::swap() >+ // >+ // Swaps this `string_view` with another `string_view`. >+ void swap(string_view& s) noexcept { >+ auto t = *this; >+ *this = s; >+ s = t; >+ } >+ >+ // Explicit conversion operators >+ >+ // Converts to `std::basic_string`. >+ template <typename A> >+ explicit operator std::basic_string<char, traits_type, A>() const { >+ if (!data()) return {}; >+ return std::basic_string<char, traits_type, A>(data(), size()); >+ } >+ >+ // string_view::copy() >+ // >+ // Copies the contents of the `string_view` at offset `pos` and length `n` >+ // into `buf`. >+ size_type copy(char* buf, size_type n, size_type pos = 0) const; >+ >+ // string_view::substr() >+ // >+ // Returns a "substring" of the `string_view` (at offset `pos` and length >+ // `n`) as another string_view. This function throws `std::out_of_bounds` if >+ // `pos > size'. >+ string_view substr(size_type pos, size_type n = npos) const { >+ if (ABSL_PREDICT_FALSE(pos > length_)) >+ base_internal::ThrowStdOutOfRange("absl::string_view::substr"); >+ n = std::min(n, length_ - pos); >+ return string_view(ptr_ + pos, n); >+ } >+ >+ // string_view::compare() >+ // >+ // Performs a lexicographical comparison between the `string_view` and >+ // another `absl::string_view), returning -1 if `this` is less than, 0 if >+ // `this` is equal to, and 1 if `this` is greater than the passed std::string >+ // view. Note that in the case of data equality, a further comparison is made >+ // on the respective sizes of the two `string_view`s to determine which is >+ // smaller, equal, or greater. >+ int compare(string_view x) const noexcept { >+ auto min_length = std::min(length_, x.length_); >+ if (min_length > 0) { >+ int r = memcmp(ptr_, x.ptr_, min_length); >+ if (r < 0) return -1; >+ if (r > 0) return 1; >+ } >+ if (length_ < x.length_) return -1; >+ if (length_ > x.length_) return 1; >+ return 0; >+ } >+ >+ // Overload of `string_view::compare()` for comparing a substring of the >+ // 'string_view` and another `absl::string_view`. >+ int compare(size_type pos1, size_type count1, string_view v) const { >+ return substr(pos1, count1).compare(v); >+ } >+ >+ // Overload of `string_view::compare()` for comparing a substring of the >+ // `string_view` and a substring of another `absl::string_view`. >+ int compare(size_type pos1, size_type count1, string_view v, size_type pos2, >+ size_type count2) const { >+ return substr(pos1, count1).compare(v.substr(pos2, count2)); >+ } >+ >+ // Overload of `string_view::compare()` for comparing a `string_view` and a >+ // a different C-style std::string `s`. >+ int compare(const char* s) const { return compare(string_view(s)); } >+ >+ // Overload of `string_view::compare()` for comparing a substring of the >+ // `string_view` and a different std::string C-style std::string `s`. >+ int compare(size_type pos1, size_type count1, const char* s) const { >+ return substr(pos1, count1).compare(string_view(s)); >+ } >+ >+ // Overload of `string_view::compare()` for comparing a substring of the >+ // `string_view` and a substring of a different C-style std::string `s`. >+ int compare(size_type pos1, size_type count1, const char* s, >+ size_type count2) const { >+ return substr(pos1, count1).compare(string_view(s, count2)); >+ } >+ >+ // Find Utilities >+ >+ // string_view::find() >+ // >+ // Finds the first occurrence of the substring `s` within the `string_view`, >+ // returning the position of the first character's match, or `npos` if no >+ // match was found. >+ size_type find(string_view s, size_type pos = 0) const noexcept; >+ >+ // Overload of `string_view::find()` for finding the given character `c` >+ // within the `string_view`. >+ size_type find(char c, size_type pos = 0) const noexcept; >+ >+ // string_view::rfind() >+ // >+ // Finds the last occurrence of a substring `s` within the `string_view`, >+ // returning the position of the first character's match, or `npos` if no >+ // match was found. >+ size_type rfind(string_view s, size_type pos = npos) const >+ noexcept; >+ >+ // Overload of `string_view::rfind()` for finding the last given character `c` >+ // within the `string_view`. >+ size_type rfind(char c, size_type pos = npos) const noexcept; >+ >+ // string_view::find_first_of() >+ // >+ // Finds the first occurrence of any of the characters in `s` within the >+ // `string_view`, returning the start position of the match, or `npos` if no >+ // match was found. >+ size_type find_first_of(string_view s, size_type pos = 0) const >+ noexcept; >+ >+ // Overload of `string_view::find_first_of()` for finding a character `c` >+ // within the `string_view`. >+ size_type find_first_of(char c, size_type pos = 0) const >+ noexcept { >+ return find(c, pos); >+ } >+ >+ // string_view::find_last_of() >+ // >+ // Finds the last occurrence of any of the characters in `s` within the >+ // `string_view`, returning the start position of the match, or `npos` if no >+ // match was found. >+ size_type find_last_of(string_view s, size_type pos = npos) const >+ noexcept; >+ >+ // Overload of `string_view::find_last_of()` for finding a character `c` >+ // within the `string_view`. >+ size_type find_last_of(char c, size_type pos = npos) const >+ noexcept { >+ return rfind(c, pos); >+ } >+ >+ // string_view::find_first_not_of() >+ // >+ // Finds the first occurrence of any of the characters not in `s` within the >+ // `string_view`, returning the start position of the first non-match, or >+ // `npos` if no non-match was found. >+ size_type find_first_not_of(string_view s, size_type pos = 0) const noexcept; >+ >+ // Overload of `string_view::find_first_not_of()` for finding a character >+ // that is not `c` within the `string_view`. >+ size_type find_first_not_of(char c, size_type pos = 0) const noexcept; >+ >+ // string_view::find_last_not_of() >+ // >+ // Finds the last occurrence of any of the characters not in `s` within the >+ // `string_view`, returning the start position of the last non-match, or >+ // `npos` if no non-match was found. >+ size_type find_last_not_of(string_view s, >+ size_type pos = npos) const noexcept; >+ >+ // Overload of `string_view::find_last_not_of()` for finding a character >+ // that is not `c` within the `string_view`. >+ size_type find_last_not_of(char c, size_type pos = npos) const >+ noexcept; >+ >+ private: >+ static constexpr size_type kMaxSize = >+ std::numeric_limits<difference_type>::max(); >+ >+ // check whether __builtin_strlen is provided by the compiler. >+ // GCC doesn't have __has_builtin() >+ // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970), >+ // but has __builtin_strlen according to >+ // https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Other-Builtins.html. >+#if ABSL_HAVE_BUILTIN(__builtin_strlen) || \ >+ (defined(__GNUC__) && !defined(__clang__)) >+ static constexpr size_type StrLenInternal(const char* str) { >+ return str ? __builtin_strlen(str) : 0; >+ } >+#else >+ static constexpr size_type StrLenInternal(const char* str) { >+ return str ? strlen(str) : 0; >+ } >+#endif >+ >+ static constexpr size_type CheckLengthInternal(size_type len) { >+ return ABSL_ASSERT(len <= kMaxSize), len; >+ } >+ >+ const char* ptr_; >+ size_type length_; >+}; >+ >+// This large function is defined inline so that in a fairly common case where >+// one of the arguments is a literal, the compiler can elide a lot of the >+// following comparisons. >+inline bool operator==(string_view x, string_view y) noexcept { >+ auto len = x.size(); >+ if (len != y.size()) { >+ return false; >+ } >+ return x.data() == y.data() || len <= 0 || >+ memcmp(x.data(), y.data(), len) == 0; >+} >+ >+inline bool operator!=(string_view x, string_view y) noexcept { >+ return !(x == y); >+} >+ >+inline bool operator<(string_view x, string_view y) noexcept { >+ auto min_size = std::min(x.size(), y.size()); >+ const int r = min_size == 0 ? 0 : memcmp(x.data(), y.data(), min_size); >+ return (r < 0) || (r == 0 && x.size() < y.size()); >+} >+ >+inline bool operator>(string_view x, string_view y) noexcept { return y < x; } >+ >+inline bool operator<=(string_view x, string_view y) noexcept { >+ return !(y < x); >+} >+ >+inline bool operator>=(string_view x, string_view y) noexcept { >+ return !(x < y); >+} >+ >+// IO Insertion Operator >+std::ostream& operator<<(std::ostream& o, string_view piece); >+ >+} // namespace absl >+ >+#endif // ABSL_HAVE_STD_STRING_VIEW >+ >+namespace absl { >+ >+// ClippedSubstr() >+// >+// Like `s.substr(pos, n)`, but clips `pos` to an upper bound of `s.size()`. >+// Provided because std::string_view::substr throws if `pos > size()` >+inline string_view ClippedSubstr(string_view s, size_t pos, >+ size_t n = string_view::npos) { >+ pos = std::min(pos, static_cast<size_t>(s.size())); >+ return s.substr(pos, n); >+} >+ >+// NullSafeStringView() >+// >+// Creates an `absl::string_view` from a pointer `p` even if it's null-valued. >+// This function should be used where an `absl::string_view` can be created from >+// a possibly-null pointer. >+inline string_view NullSafeStringView(const char* p) { >+ return p ? string_view(p) : string_view(); >+} >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_STRING_VIEW_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..fb46db18b3c3902b0d7d68ecb53b06a57ad55d3f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view_benchmark.cc >@@ -0,0 +1,329 @@ >+// Copyright 2018 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/string_view.h" >+ >+#include <algorithm> >+#include <cstdint> >+#include <map> >+#include <random> >+#include <string> >+#include <unordered_set> >+#include <vector> >+ >+#include "benchmark/benchmark.h" >+#include "absl/base/attributes.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/macros.h" >+#include "absl/strings/str_cat.h" >+ >+namespace { >+ >+// Provide a forcibly out-of-line wrapper for operator== that can be used in >+// benchmarks to measure the impact of inlining. >+ABSL_ATTRIBUTE_NOINLINE >+bool NonInlinedEq(absl::string_view a, absl::string_view b) { return a == b; } >+ >+// We use functions that cannot be inlined to perform the comparison loops so >+// that inlining of the operator== can't optimize away *everything*. >+ABSL_ATTRIBUTE_NOINLINE >+void DoEqualityComparisons(benchmark::State& state, absl::string_view a, >+ absl::string_view b) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(a == b); >+ } >+} >+ >+void BM_EqualIdentical(benchmark::State& state) { >+ std::string x(state.range(0), 'a'); >+ DoEqualityComparisons(state, x, x); >+} >+BENCHMARK(BM_EqualIdentical)->DenseRange(0, 3)->Range(4, 1 << 10); >+ >+void BM_EqualSame(benchmark::State& state) { >+ std::string x(state.range(0), 'a'); >+ std::string y = x; >+ DoEqualityComparisons(state, x, y); >+} >+BENCHMARK(BM_EqualSame) >+ ->DenseRange(0, 10) >+ ->Arg(20) >+ ->Arg(40) >+ ->Arg(70) >+ ->Arg(110) >+ ->Range(160, 4096); >+ >+void BM_EqualDifferent(benchmark::State& state) { >+ const int len = state.range(0); >+ std::string x(len, 'a'); >+ std::string y = x; >+ if (len > 0) { >+ y[len - 1] = 'b'; >+ } >+ DoEqualityComparisons(state, x, y); >+} >+BENCHMARK(BM_EqualDifferent)->DenseRange(0, 3)->Range(4, 1 << 10); >+ >+// This benchmark is intended to check that important simplifications can be >+// made with absl::string_view comparisons against constant strings. The idea is >+// that if constant strings cause redundant components of the comparison, the >+// compiler should detect and eliminate them. Here we use 8 different strings, >+// each with the same size. Provided our comparison makes the implementation >+// inline-able by the compiler, it should fold all of these away into a single >+// size check once per loop iteration. >+ABSL_ATTRIBUTE_NOINLINE >+void DoConstantSizeInlinedEqualityComparisons(benchmark::State& state, >+ absl::string_view a) { >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(a == "aaa"); >+ benchmark::DoNotOptimize(a == "bbb"); >+ benchmark::DoNotOptimize(a == "ccc"); >+ benchmark::DoNotOptimize(a == "ddd"); >+ benchmark::DoNotOptimize(a == "eee"); >+ benchmark::DoNotOptimize(a == "fff"); >+ benchmark::DoNotOptimize(a == "ggg"); >+ benchmark::DoNotOptimize(a == "hhh"); >+ } >+} >+void BM_EqualConstantSizeInlined(benchmark::State& state) { >+ std::string x(state.range(0), 'a'); >+ DoConstantSizeInlinedEqualityComparisons(state, x); >+} >+// We only need to check for size of 3, and <> 3 as this benchmark only has to >+// do with size differences. >+BENCHMARK(BM_EqualConstantSizeInlined)->DenseRange(2, 4); >+ >+// This benchmark exists purely to give context to the above timings: this is >+// what they would look like if the compiler is completely unable to simplify >+// between two comparisons when they are comparing against constant strings. >+ABSL_ATTRIBUTE_NOINLINE >+void DoConstantSizeNonInlinedEqualityComparisons(benchmark::State& state, >+ absl::string_view a) { >+ for (auto _ : state) { >+ // Force these out-of-line to compare with the above function. >+ benchmark::DoNotOptimize(NonInlinedEq(a, "aaa")); >+ benchmark::DoNotOptimize(NonInlinedEq(a, "bbb")); >+ benchmark::DoNotOptimize(NonInlinedEq(a, "ccc")); >+ benchmark::DoNotOptimize(NonInlinedEq(a, "ddd")); >+ benchmark::DoNotOptimize(NonInlinedEq(a, "eee")); >+ benchmark::DoNotOptimize(NonInlinedEq(a, "fff")); >+ benchmark::DoNotOptimize(NonInlinedEq(a, "ggg")); >+ benchmark::DoNotOptimize(NonInlinedEq(a, "hhh")); >+ } >+} >+ >+void BM_EqualConstantSizeNonInlined(benchmark::State& state) { >+ std::string x(state.range(0), 'a'); >+ DoConstantSizeNonInlinedEqualityComparisons(state, x); >+} >+// We only need to check for size of 3, and <> 3 as this benchmark only has to >+// do with size differences. >+BENCHMARK(BM_EqualConstantSizeNonInlined)->DenseRange(2, 4); >+ >+void BM_CompareSame(benchmark::State& state) { >+ const int len = state.range(0); >+ std::string x; >+ for (int i = 0; i < len; i++) { >+ x += 'a'; >+ } >+ std::string y = x; >+ absl::string_view a = x; >+ absl::string_view b = y; >+ >+ for (auto _ : state) { >+ benchmark::DoNotOptimize(a.compare(b)); >+ } >+} >+BENCHMARK(BM_CompareSame)->DenseRange(0, 3)->Range(4, 1 << 10); >+ >+void BM_find_string_view_len_one(benchmark::State& state) { >+ std::string haystack(state.range(0), '0'); >+ absl::string_view s(haystack); >+ for (auto _ : state) { >+ s.find("x"); // not present; length 1 >+ } >+} >+BENCHMARK(BM_find_string_view_len_one)->Range(1, 1 << 20); >+ >+void BM_find_string_view_len_two(benchmark::State& state) { >+ std::string haystack(state.range(0), '0'); >+ absl::string_view s(haystack); >+ for (auto _ : state) { >+ s.find("xx"); // not present; length 2 >+ } >+} >+BENCHMARK(BM_find_string_view_len_two)->Range(1, 1 << 20); >+ >+void BM_find_one_char(benchmark::State& state) { >+ std::string haystack(state.range(0), '0'); >+ absl::string_view s(haystack); >+ for (auto _ : state) { >+ s.find('x'); // not present >+ } >+} >+BENCHMARK(BM_find_one_char)->Range(1, 1 << 20); >+ >+void BM_rfind_one_char(benchmark::State& state) { >+ std::string haystack(state.range(0), '0'); >+ absl::string_view s(haystack); >+ for (auto _ : state) { >+ s.rfind('x'); // not present >+ } >+} >+BENCHMARK(BM_rfind_one_char)->Range(1, 1 << 20); >+ >+void BM_worst_case_find_first_of(benchmark::State& state, int haystack_len) { >+ const int needle_len = state.range(0); >+ std::string needle; >+ for (int i = 0; i < needle_len; ++i) { >+ needle += 'a' + i; >+ } >+ std::string haystack(haystack_len, '0'); // 1000 zeros. >+ >+ absl::string_view s(haystack); >+ for (auto _ : state) { >+ s.find_first_of(needle); >+ } >+} >+ >+void BM_find_first_of_short(benchmark::State& state) { >+ BM_worst_case_find_first_of(state, 10); >+} >+ >+void BM_find_first_of_medium(benchmark::State& state) { >+ BM_worst_case_find_first_of(state, 100); >+} >+ >+void BM_find_first_of_long(benchmark::State& state) { >+ BM_worst_case_find_first_of(state, 1000); >+} >+ >+BENCHMARK(BM_find_first_of_short)->DenseRange(0, 4)->Arg(8)->Arg(16)->Arg(32); >+BENCHMARK(BM_find_first_of_medium)->DenseRange(0, 4)->Arg(8)->Arg(16)->Arg(32); >+BENCHMARK(BM_find_first_of_long)->DenseRange(0, 4)->Arg(8)->Arg(16)->Arg(32); >+ >+struct EasyMap : public std::map<absl::string_view, uint64_t> { >+ explicit EasyMap(size_t) {} >+}; >+ >+// This templated benchmark helper function is intended to stress operator== or >+// operator< in a realistic test. It surely isn't entirely realistic, but it's >+// a start. The test creates a map of type Map, a template arg, and populates >+// it with table_size key/value pairs. Each key has WordsPerKey words. After >+// creating the map, a number of lookups are done in random order. Some keys >+// are used much more frequently than others in this phase of the test. >+template <typename Map, int WordsPerKey> >+void StringViewMapBenchmark(benchmark::State& state) { >+ const int table_size = state.range(0); >+ const double kFractionOfKeysThatAreHot = 0.2; >+ const int kNumLookupsOfHotKeys = 20; >+ const int kNumLookupsOfColdKeys = 1; >+ const char* words[] = {"the", "quick", "brown", "fox", "jumped", >+ "over", "the", "lazy", "dog", "and", >+ "found", "a", "large", "mushroom", "and", >+ "a", "couple", "crickets", "eating", "pie"}; >+ // Create some keys that consist of words in random order. >+ std::random_device r; >+ std::seed_seq seed({r(), r(), r(), r(), r(), r(), r(), r()}); >+ std::mt19937 rng(seed); >+ std::vector<std::string> keys(table_size); >+ std::vector<int> all_indices; >+ const int kBlockSize = 1 << 12; >+ std::unordered_set<std::string> t(kBlockSize); >+ std::uniform_int_distribution<int> uniform(0, ABSL_ARRAYSIZE(words) - 1); >+ for (int i = 0; i < table_size; i++) { >+ all_indices.push_back(i); >+ do { >+ keys[i].clear(); >+ for (int j = 0; j < WordsPerKey; j++) { >+ absl::StrAppend(&keys[i], j > 0 ? " " : "", words[uniform(rng)]); >+ } >+ } while (!t.insert(keys[i]).second); >+ } >+ >+ // Create a list of strings to lookup: a permutation of the array of >+ // keys we just created, with repeats. "Hot" keys get repeated more. >+ std::shuffle(all_indices.begin(), all_indices.end(), rng); >+ const int num_hot = table_size * kFractionOfKeysThatAreHot; >+ const int num_cold = table_size - num_hot; >+ std::vector<int> hot_indices(all_indices.begin(), >+ all_indices.begin() + num_hot); >+ std::vector<int> indices; >+ for (int i = 0; i < kNumLookupsOfColdKeys; i++) { >+ indices.insert(indices.end(), all_indices.begin(), all_indices.end()); >+ } >+ for (int i = 0; i < kNumLookupsOfHotKeys - kNumLookupsOfColdKeys; i++) { >+ indices.insert(indices.end(), hot_indices.begin(), hot_indices.end()); >+ } >+ std::shuffle(indices.begin(), indices.end(), rng); >+ ABSL_RAW_CHECK( >+ num_cold * kNumLookupsOfColdKeys + num_hot * kNumLookupsOfHotKeys == >+ indices.size(), >+ ""); >+ // After constructing the array we probe it with absl::string_views built from >+ // test_strings. This means operator== won't see equal pointers, so >+ // it'll have to check for equal lengths and equal characters. >+ std::vector<std::string> test_strings(indices.size()); >+ for (int i = 0; i < indices.size(); i++) { >+ test_strings[i] = keys[indices[i]]; >+ } >+ >+ // Run the benchmark. It includes map construction but is mostly >+ // map lookups. >+ for (auto _ : state) { >+ Map h(table_size); >+ for (int i = 0; i < table_size; i++) { >+ h[keys[i]] = i * 2; >+ } >+ ABSL_RAW_CHECK(h.size() == table_size, ""); >+ uint64_t sum = 0; >+ for (int i = 0; i < indices.size(); i++) { >+ sum += h[test_strings[i]]; >+ } >+ benchmark::DoNotOptimize(sum); >+ } >+} >+ >+void BM_StdMap_4(benchmark::State& state) { >+ StringViewMapBenchmark<EasyMap, 4>(state); >+} >+BENCHMARK(BM_StdMap_4)->Range(1 << 10, 1 << 16); >+ >+void BM_StdMap_8(benchmark::State& state) { >+ StringViewMapBenchmark<EasyMap, 8>(state); >+} >+BENCHMARK(BM_StdMap_8)->Range(1 << 10, 1 << 16); >+ >+void BM_CopyToStringNative(benchmark::State& state) { >+ std::string src(state.range(0), 'x'); >+ absl::string_view sv(src); >+ std::string dst; >+ for (auto _ : state) { >+ dst.assign(sv.begin(), sv.end()); >+ } >+} >+BENCHMARK(BM_CopyToStringNative)->Range(1 << 3, 1 << 12); >+ >+void BM_AppendToStringNative(benchmark::State& state) { >+ std::string src(state.range(0), 'x'); >+ absl::string_view sv(src); >+ std::string dst; >+ for (auto _ : state) { >+ dst.clear(); >+ dst.insert(dst.end(), sv.begin(), sv.end()); >+ } >+} >+BENCHMARK(BM_AppendToStringNative)->Range(1 << 3, 1 << 12); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..b19d07c7fd61d821223bfc0bf97b2a2a6234d38c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/string_view_test.cc >@@ -0,0 +1,1146 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/string_view.h" >+ >+#include <stdlib.h> >+#include <iomanip> >+#include <iterator> >+#include <limits> >+#include <map> >+#include <sstream> >+#include <stdexcept> >+#include <string> >+#include <type_traits> >+#include <utility> >+ >+#include "gtest/gtest.h" >+#include "absl/base/config.h" >+#include "absl/base/dynamic_annotations.h" >+ >+#ifdef __ANDROID__ >+// Android assert messages only go to system log, so death tests cannot inspect >+// the message for matching. >+#define ABSL_EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ >+ EXPECT_DEATH_IF_SUPPORTED(statement, ".*") >+#else >+#define ABSL_EXPECT_DEATH_IF_SUPPORTED EXPECT_DEATH_IF_SUPPORTED >+#endif >+ >+namespace { >+ >+// A minimal allocator that uses malloc(). >+template <typename T> >+struct Mallocator { >+ typedef T value_type; >+ typedef size_t size_type; >+ typedef ptrdiff_t difference_type; >+ typedef T* pointer; >+ typedef const T* const_pointer; >+ typedef T& reference; >+ typedef const T& const_reference; >+ >+ size_type max_size() const { >+ return size_t(std::numeric_limits<size_type>::max()) / sizeof(value_type); >+ } >+ template <typename U> >+ struct rebind { >+ typedef Mallocator<U> other; >+ }; >+ Mallocator() = default; >+ template <class U> >+ Mallocator(const Mallocator<U>&) {} // NOLINT(runtime/explicit) >+ >+ T* allocate(size_t n) { return static_cast<T*>(std::malloc(n * sizeof(T))); } >+ void deallocate(T* p, size_t) { std::free(p); } >+}; >+template <typename T, typename U> >+bool operator==(const Mallocator<T>&, const Mallocator<U>&) { >+ return true; >+} >+template <typename T, typename U> >+bool operator!=(const Mallocator<T>&, const Mallocator<U>&) { >+ return false; >+} >+ >+TEST(StringViewTest, Ctor) { >+ { >+ // Null. >+ absl::string_view s10; >+ EXPECT_TRUE(s10.data() == nullptr); >+ EXPECT_EQ(0, s10.length()); >+ } >+ >+ { >+ // const char* without length. >+ const char* hello = "hello"; >+ absl::string_view s20(hello); >+ EXPECT_TRUE(s20.data() == hello); >+ EXPECT_EQ(5, s20.length()); >+ >+ // const char* with length. >+ absl::string_view s21(hello, 4); >+ EXPECT_TRUE(s21.data() == hello); >+ EXPECT_EQ(4, s21.length()); >+ >+ // Not recommended, but valid C++ >+ absl::string_view s22(hello, 6); >+ EXPECT_TRUE(s22.data() == hello); >+ EXPECT_EQ(6, s22.length()); >+ } >+ >+ { >+ // std::string. >+ std::string hola = "hola"; >+ absl::string_view s30(hola); >+ EXPECT_TRUE(s30.data() == hola.data()); >+ EXPECT_EQ(4, s30.length()); >+ >+ // std::string with embedded '\0'. >+ hola.push_back('\0'); >+ hola.append("h2"); >+ hola.push_back('\0'); >+ absl::string_view s31(hola); >+ EXPECT_TRUE(s31.data() == hola.data()); >+ EXPECT_EQ(8, s31.length()); >+ } >+ >+ { >+ using mstring = >+ std::basic_string<char, std::char_traits<char>, Mallocator<char>>; >+ mstring str1("BUNGIE-JUMPING!"); >+ const mstring str2("SLEEPING!"); >+ >+ absl::string_view s1(str1); >+ s1.remove_prefix(strlen("BUNGIE-JUM")); >+ >+ absl::string_view s2(str2); >+ s2.remove_prefix(strlen("SLEE")); >+ >+ EXPECT_EQ(s1, s2); >+ EXPECT_EQ(s1, "PING!"); >+ } >+ >+ // TODO(mec): absl::string_view(const absl::string_view&); >+} >+ >+TEST(StringViewTest, Swap) { >+ absl::string_view a("a"); >+ absl::string_view b("bbb"); >+ EXPECT_TRUE(noexcept(a.swap(b))); >+ a.swap(b); >+ EXPECT_EQ(a, "bbb"); >+ EXPECT_EQ(b, "a"); >+ a.swap(b); >+ EXPECT_EQ(a, "a"); >+ EXPECT_EQ(b, "bbb"); >+} >+ >+TEST(StringViewTest, STLComparator) { >+ std::string s1("foo"); >+ std::string s2("bar"); >+ std::string s3("baz"); >+ >+ absl::string_view p1(s1); >+ absl::string_view p2(s2); >+ absl::string_view p3(s3); >+ >+ typedef std::map<absl::string_view, int> TestMap; >+ TestMap map; >+ >+ map.insert(std::make_pair(p1, 0)); >+ map.insert(std::make_pair(p2, 1)); >+ map.insert(std::make_pair(p3, 2)); >+ EXPECT_EQ(map.size(), 3); >+ >+ TestMap::const_iterator iter = map.begin(); >+ EXPECT_EQ(iter->second, 1); >+ ++iter; >+ EXPECT_EQ(iter->second, 2); >+ ++iter; >+ EXPECT_EQ(iter->second, 0); >+ ++iter; >+ EXPECT_TRUE(iter == map.end()); >+ >+ TestMap::iterator new_iter = map.find("zot"); >+ EXPECT_TRUE(new_iter == map.end()); >+ >+ new_iter = map.find("bar"); >+ EXPECT_TRUE(new_iter != map.end()); >+ >+ map.erase(new_iter); >+ EXPECT_EQ(map.size(), 2); >+ >+ iter = map.begin(); >+ EXPECT_EQ(iter->second, 2); >+ ++iter; >+ EXPECT_EQ(iter->second, 0); >+ ++iter; >+ EXPECT_TRUE(iter == map.end()); >+} >+ >+#define COMPARE(result, op, x, y) \ >+ EXPECT_EQ(result, absl::string_view((x)) op absl::string_view((y))); \ >+ EXPECT_EQ(result, absl::string_view((x)).compare(absl::string_view((y))) op 0) >+ >+TEST(StringViewTest, ComparisonOperators) { >+ COMPARE(true, ==, "", ""); >+ COMPARE(true, ==, "", absl::string_view()); >+ COMPARE(true, ==, absl::string_view(), ""); >+ COMPARE(true, ==, "a", "a"); >+ COMPARE(true, ==, "aa", "aa"); >+ COMPARE(false, ==, "a", ""); >+ COMPARE(false, ==, "", "a"); >+ COMPARE(false, ==, "a", "b"); >+ COMPARE(false, ==, "a", "aa"); >+ COMPARE(false, ==, "aa", "a"); >+ >+ COMPARE(false, !=, "", ""); >+ COMPARE(false, !=, "a", "a"); >+ COMPARE(false, !=, "aa", "aa"); >+ COMPARE(true, !=, "a", ""); >+ COMPARE(true, !=, "", "a"); >+ COMPARE(true, !=, "a", "b"); >+ COMPARE(true, !=, "a", "aa"); >+ COMPARE(true, !=, "aa", "a"); >+ >+ COMPARE(true, <, "a", "b"); >+ COMPARE(true, <, "a", "aa"); >+ COMPARE(true, <, "aa", "b"); >+ COMPARE(true, <, "aa", "bb"); >+ COMPARE(false, <, "a", "a"); >+ COMPARE(false, <, "b", "a"); >+ COMPARE(false, <, "aa", "a"); >+ COMPARE(false, <, "b", "aa"); >+ COMPARE(false, <, "bb", "aa"); >+ >+ COMPARE(true, <=, "a", "a"); >+ COMPARE(true, <=, "a", "b"); >+ COMPARE(true, <=, "a", "aa"); >+ COMPARE(true, <=, "aa", "b"); >+ COMPARE(true, <=, "aa", "bb"); >+ COMPARE(false, <=, "b", "a"); >+ COMPARE(false, <=, "aa", "a"); >+ COMPARE(false, <=, "b", "aa"); >+ COMPARE(false, <=, "bb", "aa"); >+ >+ COMPARE(false, >=, "a", "b"); >+ COMPARE(false, >=, "a", "aa"); >+ COMPARE(false, >=, "aa", "b"); >+ COMPARE(false, >=, "aa", "bb"); >+ COMPARE(true, >=, "a", "a"); >+ COMPARE(true, >=, "b", "a"); >+ COMPARE(true, >=, "aa", "a"); >+ COMPARE(true, >=, "b", "aa"); >+ COMPARE(true, >=, "bb", "aa"); >+ >+ COMPARE(false, >, "a", "a"); >+ COMPARE(false, >, "a", "b"); >+ COMPARE(false, >, "a", "aa"); >+ COMPARE(false, >, "aa", "b"); >+ COMPARE(false, >, "aa", "bb"); >+ COMPARE(true, >, "b", "a"); >+ COMPARE(true, >, "aa", "a"); >+ COMPARE(true, >, "b", "aa"); >+ COMPARE(true, >, "bb", "aa"); >+} >+ >+TEST(StringViewTest, ComparisonOperatorsByCharacterPosition) { >+ std::string x; >+ for (int i = 0; i < 256; i++) { >+ x += 'a'; >+ std::string y = x; >+ COMPARE(true, ==, x, y); >+ for (int j = 0; j < i; j++) { >+ std::string z = x; >+ z[j] = 'b'; // Differs in position 'j' >+ COMPARE(false, ==, x, z); >+ COMPARE(true, <, x, z); >+ COMPARE(true, >, z, x); >+ if (j + 1 < i) { >+ z[j + 1] = 'A'; // Differs in position 'j+1' as well >+ COMPARE(false, ==, x, z); >+ COMPARE(true, <, x, z); >+ COMPARE(true, >, z, x); >+ z[j + 1] = 'z'; // Differs in position 'j+1' as well >+ COMPARE(false, ==, x, z); >+ COMPARE(true, <, x, z); >+ COMPARE(true, >, z, x); >+ } >+ } >+ } >+} >+#undef COMPARE >+ >+// Sadly, our users often confuse std::string::npos with absl::string_view::npos; >+// So much so that we test here that they are the same. They need to >+// both be unsigned, and both be the maximum-valued integer of their type. >+ >+template <typename T> >+struct is_type { >+ template <typename U> >+ static bool same(U) { >+ return false; >+ } >+ static bool same(T) { return true; } >+}; >+ >+TEST(StringViewTest, NposMatchesStdStringView) { >+ EXPECT_EQ(absl::string_view::npos, std::string::npos); >+ >+ EXPECT_TRUE(is_type<size_t>::same(absl::string_view::npos)); >+ EXPECT_FALSE(is_type<size_t>::same("")); >+ >+ // Make sure absl::string_view::npos continues to be a header constant. >+ char test[absl::string_view::npos & 1] = {0}; >+ EXPECT_EQ(0, test[0]); >+} >+ >+TEST(StringViewTest, STL1) { >+ const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); >+ const absl::string_view b("abc"); >+ const absl::string_view c("xyz"); >+ const absl::string_view d("foobar"); >+ const absl::string_view e; >+ std::string temp("123"); >+ temp += '\0'; >+ temp += "456"; >+ const absl::string_view f(temp); >+ >+ EXPECT_EQ(a[6], 'g'); >+ EXPECT_EQ(b[0], 'a'); >+ EXPECT_EQ(c[2], 'z'); >+ EXPECT_EQ(f[3], '\0'); >+ EXPECT_EQ(f[5], '5'); >+ >+ EXPECT_EQ(*d.data(), 'f'); >+ EXPECT_EQ(d.data()[5], 'r'); >+ EXPECT_TRUE(e.data() == nullptr); >+ >+ EXPECT_EQ(*a.begin(), 'a'); >+ EXPECT_EQ(*(b.begin() + 2), 'c'); >+ EXPECT_EQ(*(c.end() - 1), 'z'); >+ >+ EXPECT_EQ(*a.rbegin(), 'z'); >+ EXPECT_EQ(*(b.rbegin() + 2), 'a'); >+ EXPECT_EQ(*(c.rend() - 1), 'x'); >+ EXPECT_TRUE(a.rbegin() + 26 == a.rend()); >+ >+ EXPECT_EQ(a.size(), 26); >+ EXPECT_EQ(b.size(), 3); >+ EXPECT_EQ(c.size(), 3); >+ EXPECT_EQ(d.size(), 6); >+ EXPECT_EQ(e.size(), 0); >+ EXPECT_EQ(f.size(), 7); >+ >+ EXPECT_TRUE(!d.empty()); >+ EXPECT_TRUE(d.begin() != d.end()); >+ EXPECT_TRUE(d.begin() + 6 == d.end()); >+ >+ EXPECT_TRUE(e.empty()); >+ EXPECT_TRUE(e.begin() == e.end()); >+ >+ char buf[4] = { '%', '%', '%', '%' }; >+ EXPECT_EQ(a.copy(buf, 4), 4); >+ EXPECT_EQ(buf[0], a[0]); >+ EXPECT_EQ(buf[1], a[1]); >+ EXPECT_EQ(buf[2], a[2]); >+ EXPECT_EQ(buf[3], a[3]); >+ EXPECT_EQ(a.copy(buf, 3, 7), 3); >+ EXPECT_EQ(buf[0], a[7]); >+ EXPECT_EQ(buf[1], a[8]); >+ EXPECT_EQ(buf[2], a[9]); >+ EXPECT_EQ(buf[3], a[3]); >+ EXPECT_EQ(c.copy(buf, 99), 3); >+ EXPECT_EQ(buf[0], c[0]); >+ EXPECT_EQ(buf[1], c[1]); >+ EXPECT_EQ(buf[2], c[2]); >+ EXPECT_EQ(buf[3], a[3]); >+} >+ >+// Separated from STL1() because some compilers produce an overly >+// large stack frame for the combined function. >+TEST(StringViewTest, STL2) { >+ const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); >+ const absl::string_view b("abc"); >+ const absl::string_view c("xyz"); >+ absl::string_view d("foobar"); >+ const absl::string_view e; >+ const absl::string_view f( >+ "123" >+ "\0" >+ "456", >+ 7); >+ >+ d = absl::string_view(); >+ EXPECT_EQ(d.size(), 0); >+ EXPECT_TRUE(d.empty()); >+ EXPECT_TRUE(d.data() == nullptr); >+ EXPECT_TRUE(d.begin() == d.end()); >+ >+ EXPECT_EQ(a.find(b), 0); >+ EXPECT_EQ(a.find(b, 1), absl::string_view::npos); >+ EXPECT_EQ(a.find(c), 23); >+ EXPECT_EQ(a.find(c, 9), 23); >+ EXPECT_EQ(a.find(c, absl::string_view::npos), absl::string_view::npos); >+ EXPECT_EQ(b.find(c), absl::string_view::npos); >+ EXPECT_EQ(b.find(c, absl::string_view::npos), absl::string_view::npos); >+ EXPECT_EQ(a.find(d), 0); >+ EXPECT_EQ(a.find(e), 0); >+ EXPECT_EQ(a.find(d, 12), 12); >+ EXPECT_EQ(a.find(e, 17), 17); >+ absl::string_view g("xx not found bb"); >+ EXPECT_EQ(a.find(g), absl::string_view::npos); >+ // empty std::string nonsense >+ EXPECT_EQ(d.find(b), absl::string_view::npos); >+ EXPECT_EQ(e.find(b), absl::string_view::npos); >+ EXPECT_EQ(d.find(b, 4), absl::string_view::npos); >+ EXPECT_EQ(e.find(b, 7), absl::string_view::npos); >+ >+ size_t empty_search_pos = std::string().find(std::string()); >+ EXPECT_EQ(d.find(d), empty_search_pos); >+ EXPECT_EQ(d.find(e), empty_search_pos); >+ EXPECT_EQ(e.find(d), empty_search_pos); >+ EXPECT_EQ(e.find(e), empty_search_pos); >+ EXPECT_EQ(d.find(d, 4), std::string().find(std::string(), 4)); >+ EXPECT_EQ(d.find(e, 4), std::string().find(std::string(), 4)); >+ EXPECT_EQ(e.find(d, 4), std::string().find(std::string(), 4)); >+ EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4)); >+ >+ EXPECT_EQ(a.find('a'), 0); >+ EXPECT_EQ(a.find('c'), 2); >+ EXPECT_EQ(a.find('z'), 25); >+ EXPECT_EQ(a.find('$'), absl::string_view::npos); >+ EXPECT_EQ(a.find('\0'), absl::string_view::npos); >+ EXPECT_EQ(f.find('\0'), 3); >+ EXPECT_EQ(f.find('3'), 2); >+ EXPECT_EQ(f.find('5'), 5); >+ EXPECT_EQ(g.find('o'), 4); >+ EXPECT_EQ(g.find('o', 4), 4); >+ EXPECT_EQ(g.find('o', 5), 8); >+ EXPECT_EQ(a.find('b', 5), absl::string_view::npos); >+ // empty std::string nonsense >+ EXPECT_EQ(d.find('\0'), absl::string_view::npos); >+ EXPECT_EQ(e.find('\0'), absl::string_view::npos); >+ EXPECT_EQ(d.find('\0', 4), absl::string_view::npos); >+ EXPECT_EQ(e.find('\0', 7), absl::string_view::npos); >+ EXPECT_EQ(d.find('x'), absl::string_view::npos); >+ EXPECT_EQ(e.find('x'), absl::string_view::npos); >+ EXPECT_EQ(d.find('x', 4), absl::string_view::npos); >+ EXPECT_EQ(e.find('x', 7), absl::string_view::npos); >+ >+ EXPECT_EQ(a.rfind(b), 0); >+ EXPECT_EQ(a.rfind(b, 1), 0); >+ EXPECT_EQ(a.rfind(c), 23); >+ EXPECT_EQ(a.rfind(c, 22), absl::string_view::npos); >+ EXPECT_EQ(a.rfind(c, 1), absl::string_view::npos); >+ EXPECT_EQ(a.rfind(c, 0), absl::string_view::npos); >+ EXPECT_EQ(b.rfind(c), absl::string_view::npos); >+ EXPECT_EQ(b.rfind(c, 0), absl::string_view::npos); >+ EXPECT_EQ(a.rfind(d), std::string(a).rfind(std::string())); >+ EXPECT_EQ(a.rfind(e), std::string(a).rfind(std::string())); >+ EXPECT_EQ(a.rfind(d, 12), 12); >+ EXPECT_EQ(a.rfind(e, 17), 17); >+ EXPECT_EQ(a.rfind(g), absl::string_view::npos); >+ EXPECT_EQ(d.rfind(b), absl::string_view::npos); >+ EXPECT_EQ(e.rfind(b), absl::string_view::npos); >+ EXPECT_EQ(d.rfind(b, 4), absl::string_view::npos); >+ EXPECT_EQ(e.rfind(b, 7), absl::string_view::npos); >+ // empty std::string nonsense >+ EXPECT_EQ(d.rfind(d, 4), std::string().rfind(std::string())); >+ EXPECT_EQ(e.rfind(d, 7), std::string().rfind(std::string())); >+ EXPECT_EQ(d.rfind(e, 4), std::string().rfind(std::string())); >+ EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string())); >+ EXPECT_EQ(d.rfind(d), std::string().rfind(std::string())); >+ EXPECT_EQ(e.rfind(d), std::string().rfind(std::string())); >+ EXPECT_EQ(d.rfind(e), std::string().rfind(std::string())); >+ EXPECT_EQ(e.rfind(e), std::string().rfind(std::string())); >+ >+ EXPECT_EQ(g.rfind('o'), 8); >+ EXPECT_EQ(g.rfind('q'), absl::string_view::npos); >+ EXPECT_EQ(g.rfind('o', 8), 8); >+ EXPECT_EQ(g.rfind('o', 7), 4); >+ EXPECT_EQ(g.rfind('o', 3), absl::string_view::npos); >+ EXPECT_EQ(f.rfind('\0'), 3); >+ EXPECT_EQ(f.rfind('\0', 12), 3); >+ EXPECT_EQ(f.rfind('3'), 2); >+ EXPECT_EQ(f.rfind('5'), 5); >+ // empty std::string nonsense >+ EXPECT_EQ(d.rfind('o'), absl::string_view::npos); >+ EXPECT_EQ(e.rfind('o'), absl::string_view::npos); >+ EXPECT_EQ(d.rfind('o', 4), absl::string_view::npos); >+ EXPECT_EQ(e.rfind('o', 7), absl::string_view::npos); >+} >+ >+// Continued from STL2 >+TEST(StringViewTest, STL2FindFirst) { >+ const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); >+ const absl::string_view b("abc"); >+ const absl::string_view c("xyz"); >+ absl::string_view d("foobar"); >+ const absl::string_view e; >+ const absl::string_view f( >+ "123" >+ "\0" >+ "456", >+ 7); >+ absl::string_view g("xx not found bb"); >+ >+ d = absl::string_view(); >+ EXPECT_EQ(a.find_first_of(b), 0); >+ EXPECT_EQ(a.find_first_of(b, 0), 0); >+ EXPECT_EQ(a.find_first_of(b, 1), 1); >+ EXPECT_EQ(a.find_first_of(b, 2), 2); >+ EXPECT_EQ(a.find_first_of(b, 3), absl::string_view::npos); >+ EXPECT_EQ(a.find_first_of(c), 23); >+ EXPECT_EQ(a.find_first_of(c, 23), 23); >+ EXPECT_EQ(a.find_first_of(c, 24), 24); >+ EXPECT_EQ(a.find_first_of(c, 25), 25); >+ EXPECT_EQ(a.find_first_of(c, 26), absl::string_view::npos); >+ EXPECT_EQ(g.find_first_of(b), 13); >+ EXPECT_EQ(g.find_first_of(c), 0); >+ EXPECT_EQ(a.find_first_of(f), absl::string_view::npos); >+ EXPECT_EQ(f.find_first_of(a), absl::string_view::npos); >+ // empty std::string nonsense >+ EXPECT_EQ(a.find_first_of(d), absl::string_view::npos); >+ EXPECT_EQ(a.find_first_of(e), absl::string_view::npos); >+ EXPECT_EQ(d.find_first_of(b), absl::string_view::npos); >+ EXPECT_EQ(e.find_first_of(b), absl::string_view::npos); >+ EXPECT_EQ(d.find_first_of(d), absl::string_view::npos); >+ EXPECT_EQ(e.find_first_of(d), absl::string_view::npos); >+ EXPECT_EQ(d.find_first_of(e), absl::string_view::npos); >+ EXPECT_EQ(e.find_first_of(e), absl::string_view::npos); >+ >+ EXPECT_EQ(a.find_first_not_of(b), 3); >+ EXPECT_EQ(a.find_first_not_of(c), 0); >+ EXPECT_EQ(b.find_first_not_of(a), absl::string_view::npos); >+ EXPECT_EQ(c.find_first_not_of(a), absl::string_view::npos); >+ EXPECT_EQ(f.find_first_not_of(a), 0); >+ EXPECT_EQ(a.find_first_not_of(f), 0); >+ EXPECT_EQ(a.find_first_not_of(d), 0); >+ EXPECT_EQ(a.find_first_not_of(e), 0); >+ // empty std::string nonsense >+ EXPECT_EQ(a.find_first_not_of(d), 0); >+ EXPECT_EQ(a.find_first_not_of(e), 0); >+ EXPECT_EQ(a.find_first_not_of(d, 1), 1); >+ EXPECT_EQ(a.find_first_not_of(e, 1), 1); >+ EXPECT_EQ(a.find_first_not_of(d, a.size() - 1), a.size() - 1); >+ EXPECT_EQ(a.find_first_not_of(e, a.size() - 1), a.size() - 1); >+ EXPECT_EQ(a.find_first_not_of(d, a.size()), absl::string_view::npos); >+ EXPECT_EQ(a.find_first_not_of(e, a.size()), absl::string_view::npos); >+ EXPECT_EQ(a.find_first_not_of(d, absl::string_view::npos), >+ absl::string_view::npos); >+ EXPECT_EQ(a.find_first_not_of(e, absl::string_view::npos), >+ absl::string_view::npos); >+ EXPECT_EQ(d.find_first_not_of(a), absl::string_view::npos); >+ EXPECT_EQ(e.find_first_not_of(a), absl::string_view::npos); >+ EXPECT_EQ(d.find_first_not_of(d), absl::string_view::npos); >+ EXPECT_EQ(e.find_first_not_of(d), absl::string_view::npos); >+ EXPECT_EQ(d.find_first_not_of(e), absl::string_view::npos); >+ EXPECT_EQ(e.find_first_not_of(e), absl::string_view::npos); >+ >+ absl::string_view h("===="); >+ EXPECT_EQ(h.find_first_not_of('='), absl::string_view::npos); >+ EXPECT_EQ(h.find_first_not_of('=', 3), absl::string_view::npos); >+ EXPECT_EQ(h.find_first_not_of('\0'), 0); >+ EXPECT_EQ(g.find_first_not_of('x'), 2); >+ EXPECT_EQ(f.find_first_not_of('\0'), 0); >+ EXPECT_EQ(f.find_first_not_of('\0', 3), 4); >+ EXPECT_EQ(f.find_first_not_of('\0', 2), 2); >+ // empty std::string nonsense >+ EXPECT_EQ(d.find_first_not_of('x'), absl::string_view::npos); >+ EXPECT_EQ(e.find_first_not_of('x'), absl::string_view::npos); >+ EXPECT_EQ(d.find_first_not_of('\0'), absl::string_view::npos); >+ EXPECT_EQ(e.find_first_not_of('\0'), absl::string_view::npos); >+} >+ >+// Continued from STL2 >+TEST(StringViewTest, STL2FindLast) { >+ const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); >+ const absl::string_view b("abc"); >+ const absl::string_view c("xyz"); >+ absl::string_view d("foobar"); >+ const absl::string_view e; >+ const absl::string_view f( >+ "123" >+ "\0" >+ "456", >+ 7); >+ absl::string_view g("xx not found bb"); >+ absl::string_view h("===="); >+ absl::string_view i("56"); >+ >+ d = absl::string_view(); >+ EXPECT_EQ(h.find_last_of(a), absl::string_view::npos); >+ EXPECT_EQ(g.find_last_of(a), g.size()-1); >+ EXPECT_EQ(a.find_last_of(b), 2); >+ EXPECT_EQ(a.find_last_of(c), a.size()-1); >+ EXPECT_EQ(f.find_last_of(i), 6); >+ EXPECT_EQ(a.find_last_of('a'), 0); >+ EXPECT_EQ(a.find_last_of('b'), 1); >+ EXPECT_EQ(a.find_last_of('z'), 25); >+ EXPECT_EQ(a.find_last_of('a', 5), 0); >+ EXPECT_EQ(a.find_last_of('b', 5), 1); >+ EXPECT_EQ(a.find_last_of('b', 0), absl::string_view::npos); >+ EXPECT_EQ(a.find_last_of('z', 25), 25); >+ EXPECT_EQ(a.find_last_of('z', 24), absl::string_view::npos); >+ EXPECT_EQ(f.find_last_of(i, 5), 5); >+ EXPECT_EQ(f.find_last_of(i, 6), 6); >+ EXPECT_EQ(f.find_last_of(a, 4), absl::string_view::npos); >+ // empty std::string nonsense >+ EXPECT_EQ(f.find_last_of(d), absl::string_view::npos); >+ EXPECT_EQ(f.find_last_of(e), absl::string_view::npos); >+ EXPECT_EQ(f.find_last_of(d, 4), absl::string_view::npos); >+ EXPECT_EQ(f.find_last_of(e, 4), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_of(d), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_of(e), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_of(d), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_of(e), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_of(f), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_of(f), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_of(d, 4), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_of(e, 4), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_of(d, 4), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_of(e, 4), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_of(f, 4), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_of(f, 4), absl::string_view::npos); >+ >+ EXPECT_EQ(a.find_last_not_of(b), a.size()-1); >+ EXPECT_EQ(a.find_last_not_of(c), 22); >+ EXPECT_EQ(b.find_last_not_of(a), absl::string_view::npos); >+ EXPECT_EQ(b.find_last_not_of(b), absl::string_view::npos); >+ EXPECT_EQ(f.find_last_not_of(i), 4); >+ EXPECT_EQ(a.find_last_not_of(c, 24), 22); >+ EXPECT_EQ(a.find_last_not_of(b, 3), 3); >+ EXPECT_EQ(a.find_last_not_of(b, 2), absl::string_view::npos); >+ // empty std::string nonsense >+ EXPECT_EQ(f.find_last_not_of(d), f.size()-1); >+ EXPECT_EQ(f.find_last_not_of(e), f.size()-1); >+ EXPECT_EQ(f.find_last_not_of(d, 4), 4); >+ EXPECT_EQ(f.find_last_not_of(e, 4), 4); >+ EXPECT_EQ(d.find_last_not_of(d), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_not_of(e), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_not_of(d), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_not_of(e), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_not_of(f), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_not_of(f), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_not_of(d, 4), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_not_of(e, 4), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_not_of(d, 4), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_not_of(e, 4), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_not_of(f, 4), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_not_of(f, 4), absl::string_view::npos); >+ >+ EXPECT_EQ(h.find_last_not_of('x'), h.size() - 1); >+ EXPECT_EQ(h.find_last_not_of('='), absl::string_view::npos); >+ EXPECT_EQ(b.find_last_not_of('c'), 1); >+ EXPECT_EQ(h.find_last_not_of('x', 2), 2); >+ EXPECT_EQ(h.find_last_not_of('=', 2), absl::string_view::npos); >+ EXPECT_EQ(b.find_last_not_of('b', 1), 0); >+ // empty std::string nonsense >+ EXPECT_EQ(d.find_last_not_of('x'), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_not_of('x'), absl::string_view::npos); >+ EXPECT_EQ(d.find_last_not_of('\0'), absl::string_view::npos); >+ EXPECT_EQ(e.find_last_not_of('\0'), absl::string_view::npos); >+} >+ >+// Continued from STL2 >+TEST(StringViewTest, STL2Substr) { >+ const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); >+ const absl::string_view b("abc"); >+ const absl::string_view c("xyz"); >+ absl::string_view d("foobar"); >+ const absl::string_view e; >+ >+ d = absl::string_view(); >+ EXPECT_EQ(a.substr(0, 3), b); >+ EXPECT_EQ(a.substr(23), c); >+ EXPECT_EQ(a.substr(23, 3), c); >+ EXPECT_EQ(a.substr(23, 99), c); >+ EXPECT_EQ(a.substr(0), a); >+ EXPECT_EQ(a.substr(3, 2), "de"); >+ // empty std::string nonsense >+ EXPECT_EQ(d.substr(0, 99), e); >+ // use of npos >+ EXPECT_EQ(a.substr(0, absl::string_view::npos), a); >+ EXPECT_EQ(a.substr(23, absl::string_view::npos), c); >+ // throw exception >+#ifdef ABSL_HAVE_EXCEPTIONS >+ EXPECT_THROW(a.substr(99, 2), std::out_of_range); >+#else >+ EXPECT_DEATH(a.substr(99, 2), "absl::string_view::substr"); >+#endif >+} >+ >+TEST(StringViewTest, TruncSubstr) { >+ const absl::string_view hi("hi"); >+ EXPECT_EQ("", absl::ClippedSubstr(hi, 0, 0)); >+ EXPECT_EQ("h", absl::ClippedSubstr(hi, 0, 1)); >+ EXPECT_EQ("hi", absl::ClippedSubstr(hi, 0)); >+ EXPECT_EQ("i", absl::ClippedSubstr(hi, 1)); >+ EXPECT_EQ("", absl::ClippedSubstr(hi, 2)); >+ EXPECT_EQ("", absl::ClippedSubstr(hi, 3)); // truncation >+ EXPECT_EQ("", absl::ClippedSubstr(hi, 3, 2)); // truncation >+} >+ >+TEST(StringViewTest, UTF8) { >+ std::string utf8 = "\u00E1"; >+ std::string utf8_twice = utf8 + " " + utf8; >+ int utf8_len = strlen(utf8.data()); >+ EXPECT_EQ(utf8_len, absl::string_view(utf8_twice).find_first_of(" ")); >+ EXPECT_EQ(utf8_len, absl::string_view(utf8_twice).find_first_of(" \t")); >+} >+ >+TEST(StringViewTest, FindConformance) { >+ struct { >+ std::string haystack; >+ std::string needle; >+ } specs[] = { >+ {"", ""}, >+ {"", "a"}, >+ {"a", ""}, >+ {"a", "a"}, >+ {"a", "b"}, >+ {"aa", ""}, >+ {"aa", "a"}, >+ {"aa", "b"}, >+ {"ab", "a"}, >+ {"ab", "b"}, >+ {"abcd", ""}, >+ {"abcd", "a"}, >+ {"abcd", "d"}, >+ {"abcd", "ab"}, >+ {"abcd", "bc"}, >+ {"abcd", "cd"}, >+ {"abcd", "abcd"}, >+ }; >+ for (const auto& s : specs) { >+ SCOPED_TRACE(s.haystack); >+ SCOPED_TRACE(s.needle); >+ std::string st = s.haystack; >+ absl::string_view sp = s.haystack; >+ for (size_t i = 0; i <= sp.size(); ++i) { >+ size_t pos = (i == sp.size()) ? absl::string_view::npos : i; >+ SCOPED_TRACE(pos); >+ EXPECT_EQ(sp.find(s.needle, pos), >+ st.find(s.needle, pos)); >+ EXPECT_EQ(sp.rfind(s.needle, pos), >+ st.rfind(s.needle, pos)); >+ EXPECT_EQ(sp.find_first_of(s.needle, pos), >+ st.find_first_of(s.needle, pos)); >+ EXPECT_EQ(sp.find_first_not_of(s.needle, pos), >+ st.find_first_not_of(s.needle, pos)); >+ EXPECT_EQ(sp.find_last_of(s.needle, pos), >+ st.find_last_of(s.needle, pos)); >+ EXPECT_EQ(sp.find_last_not_of(s.needle, pos), >+ st.find_last_not_of(s.needle, pos)); >+ } >+ } >+} >+ >+TEST(StringViewTest, Remove) { >+ absl::string_view a("foobar"); >+ std::string s1("123"); >+ s1 += '\0'; >+ s1 += "456"; >+ absl::string_view b(s1); >+ absl::string_view e; >+ std::string s2; >+ >+ // remove_prefix >+ absl::string_view c(a); >+ c.remove_prefix(3); >+ EXPECT_EQ(c, "bar"); >+ c = a; >+ c.remove_prefix(0); >+ EXPECT_EQ(c, a); >+ c.remove_prefix(c.size()); >+ EXPECT_EQ(c, e); >+ >+ // remove_suffix >+ c = a; >+ c.remove_suffix(3); >+ EXPECT_EQ(c, "foo"); >+ c = a; >+ c.remove_suffix(0); >+ EXPECT_EQ(c, a); >+ c.remove_suffix(c.size()); >+ EXPECT_EQ(c, e); >+} >+ >+TEST(StringViewTest, Set) { >+ absl::string_view a("foobar"); >+ absl::string_view empty; >+ absl::string_view b; >+ >+ // set >+ b = absl::string_view("foobar", 6); >+ EXPECT_EQ(b, a); >+ b = absl::string_view("foobar", 0); >+ EXPECT_EQ(b, empty); >+ b = absl::string_view("foobar", 7); >+ EXPECT_NE(b, a); >+ >+ b = absl::string_view("foobar"); >+ EXPECT_EQ(b, a); >+} >+ >+TEST(StringViewTest, FrontBack) { >+ static const char arr[] = "abcd"; >+ const absl::string_view csp(arr, 4); >+ EXPECT_EQ(&arr[0], &csp.front()); >+ EXPECT_EQ(&arr[3], &csp.back()); >+} >+ >+TEST(StringViewTest, FrontBackSingleChar) { >+ static const char c = 'a'; >+ const absl::string_view csp(&c, 1); >+ EXPECT_EQ(&c, &csp.front()); >+ EXPECT_EQ(&c, &csp.back()); >+} >+ >+// `std::string_view::string_view(const char*)` calls >+// `std::char_traits<char>::length(const char*)` to get the std::string length. In >+// libc++, it doesn't allow `nullptr` in the constexpr context, with the error >+// "read of dereferenced null pointer is not allowed in a constant expression". >+// At run time, the behavior of `std::char_traits::length()` on `nullptr` is >+// undefined by the standard and usually results in crash with libc++. This >+// conforms to the standard, but `absl::string_view` implements a different >+// behavior for historical reasons. We work around tests that construct >+// `string_view` from `nullptr` when using libc++. >+#if !defined(ABSL_HAVE_STD_STRING_VIEW) || !defined(_LIBCPP_VERSION) >+#define ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 1 >+#endif // !defined(ABSL_HAVE_STD_STRING_VIEW) || !defined(_LIBCPP_VERSION) >+ >+TEST(StringViewTest, NULLInput) { >+ absl::string_view s; >+ EXPECT_EQ(s.data(), nullptr); >+ EXPECT_EQ(s.size(), 0); >+ >+#ifdef ABSL_HAVE_STRING_VIEW_FROM_NULLPTR >+ s = absl::string_view(nullptr); >+ EXPECT_EQ(s.data(), nullptr); >+ EXPECT_EQ(s.size(), 0); >+ >+ // .ToString() on a absl::string_view with nullptr should produce the empty >+ // std::string. >+ EXPECT_EQ("", std::string(s)); >+#endif // ABSL_HAVE_STRING_VIEW_FROM_NULLPTR >+} >+ >+TEST(StringViewTest, Comparisons2) { >+ // The `compare` member has 6 overloads (v: string_view, s: const char*): >+ // (1) compare(v) >+ // (2) compare(pos1, count1, v) >+ // (3) compare(pos1, count1, v, pos2, count2) >+ // (4) compare(s) >+ // (5) compare(pos1, count1, s) >+ // (6) compare(pos1, count1, s, count2) >+ >+ absl::string_view abc("abcdefghijklmnopqrstuvwxyz"); >+ >+ // check comparison operations on strings longer than 4 bytes. >+ EXPECT_EQ(abc, absl::string_view("abcdefghijklmnopqrstuvwxyz")); >+ EXPECT_EQ(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxyz")), 0); >+ >+ EXPECT_LT(abc, absl::string_view("abcdefghijklmnopqrstuvwxzz")); >+ EXPECT_LT(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxzz")), 0); >+ >+ EXPECT_GT(abc, absl::string_view("abcdefghijklmnopqrstuvwxyy")); >+ EXPECT_GT(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxyy")), 0); >+ >+ // The "substr" variants of `compare`. >+ absl::string_view digits("0123456789"); >+ auto npos = absl::string_view::npos; >+ >+ // Taking string_view >+ EXPECT_EQ(digits.compare(3, npos, absl::string_view("3456789")), 0); // 2 >+ EXPECT_EQ(digits.compare(3, 4, absl::string_view("3456")), 0); // 2 >+ EXPECT_EQ(digits.compare(10, 0, absl::string_view()), 0); // 2 >+ EXPECT_EQ(digits.compare(3, 4, absl::string_view("0123456789"), 3, 4), >+ 0); // 3 >+ EXPECT_LT(digits.compare(3, 4, absl::string_view("0123456789"), 3, 5), >+ 0); // 3 >+ EXPECT_LT(digits.compare(0, npos, absl::string_view("0123456789"), 3, 5), >+ 0); // 3 >+ // Taking const char* >+ EXPECT_EQ(digits.compare(3, 4, "3456"), 0); // 5 >+ EXPECT_EQ(digits.compare(3, npos, "3456789"), 0); // 5 >+ EXPECT_EQ(digits.compare(10, 0, ""), 0); // 5 >+ EXPECT_EQ(digits.compare(3, 4, "0123456789", 3, 4), 0); // 6 >+ EXPECT_LT(digits.compare(3, 4, "0123456789", 3, 5), 0); // 6 >+ EXPECT_LT(digits.compare(0, npos, "0123456789", 3, 5), 0); // 6 >+} >+ >+struct MyCharAlloc : std::allocator<char> {}; >+ >+TEST(StringViewTest, ExplicitConversionOperator) { >+ absl::string_view sp = "hi"; >+ EXPECT_EQ(sp, std::string(sp)); >+} >+ >+TEST(StringViewTest, NullSafeStringView) { >+ { >+ absl::string_view s = absl::NullSafeStringView(nullptr); >+ EXPECT_EQ(nullptr, s.data()); >+ EXPECT_EQ(0, s.size()); >+ EXPECT_EQ(absl::string_view(), s); >+ } >+ { >+ static const char kHi[] = "hi"; >+ absl::string_view s = absl::NullSafeStringView(kHi); >+ EXPECT_EQ(kHi, s.data()); >+ EXPECT_EQ(strlen(kHi), s.size()); >+ EXPECT_EQ(absl::string_view("hi"), s); >+ } >+} >+ >+TEST(StringViewTest, ConstexprCompiles) { >+ constexpr absl::string_view sp; >+#ifdef ABSL_HAVE_STRING_VIEW_FROM_NULLPTR >+ constexpr absl::string_view cstr(nullptr); >+#endif >+ constexpr absl::string_view cstr_len("cstr", 4); >+ >+#if defined(ABSL_HAVE_STD_STRING_VIEW) >+ // In libstdc++ (as of 7.2), `std::string_view::string_view(const char*)` >+ // calls `std::char_traits<char>::length(const char*)` to get the std::string >+ // length, but it is not marked constexpr yet. See GCC bug: >+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78156 >+ // Also, there is a LWG issue that adds constexpr to length() which was just >+ // resolved 2017-06-02. See >+ // http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2232 >+ // TODO(zhangxy): Update the condition when libstdc++ adopts the constexpr >+ // length(). >+#if !defined(__GLIBCXX__) >+#define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 >+#endif // !__GLIBCXX__ >+ >+#else // ABSL_HAVE_STD_STRING_VIEW >+ >+// This duplicates the check for __builtin_strlen in the header. >+#if ABSL_HAVE_BUILTIN(__builtin_strlen) || \ >+ (defined(__GNUC__) && !defined(__clang__)) >+#define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 >+#elif defined(__GNUC__) // GCC or clang >+#error GCC/clang should have constexpr string_view. >+#endif >+ >+#endif // ABSL_HAVE_STD_STRING_VIEW >+ >+#ifdef ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR >+ constexpr absl::string_view cstr_strlen("foo"); >+ EXPECT_EQ(cstr_strlen.length(), 3); >+ constexpr absl::string_view cstr_strlen2 = "bar"; >+ EXPECT_EQ(cstr_strlen2, "bar"); >+#endif >+ >+#if !defined(__clang__) || 3 < __clang_major__ || \ >+ (3 == __clang_major__ && 4 < __clang_minor__) >+ // older clang versions (< 3.5) complain that: >+ // "cannot perform pointer arithmetic on null pointer" >+ constexpr absl::string_view::iterator const_begin_empty = sp.begin(); >+ constexpr absl::string_view::iterator const_end_empty = sp.end(); >+ EXPECT_EQ(const_begin_empty, const_end_empty); >+ >+#ifdef ABSL_HAVE_STRING_VIEW_FROM_NULLPTR >+ constexpr absl::string_view::iterator const_begin_nullptr = cstr.begin(); >+ constexpr absl::string_view::iterator const_end_nullptr = cstr.end(); >+ EXPECT_EQ(const_begin_nullptr, const_end_nullptr); >+#endif // ABSL_HAVE_STRING_VIEW_FROM_NULLPTR >+#endif // !defined(__clang__) || ... >+ >+ constexpr absl::string_view::iterator const_begin = cstr_len.begin(); >+ constexpr absl::string_view::iterator const_end = cstr_len.end(); >+ constexpr absl::string_view::size_type const_size = cstr_len.size(); >+ constexpr absl::string_view::size_type const_length = cstr_len.length(); >+ EXPECT_EQ(const_begin + const_size, const_end); >+ EXPECT_EQ(const_begin + const_length, const_end); >+ >+ constexpr bool isempty = sp.empty(); >+ EXPECT_TRUE(isempty); >+ >+ constexpr const char c = cstr_len[2]; >+ EXPECT_EQ(c, 't'); >+ >+ constexpr const char cfront = cstr_len.front(); >+ constexpr const char cback = cstr_len.back(); >+ EXPECT_EQ(cfront, 'c'); >+ EXPECT_EQ(cback, 'r'); >+ >+ constexpr const char* np = sp.data(); >+ constexpr const char* cstr_ptr = cstr_len.data(); >+ EXPECT_EQ(np, nullptr); >+ EXPECT_NE(cstr_ptr, nullptr); >+ >+ constexpr size_t sp_npos = sp.npos; >+ EXPECT_EQ(sp_npos, -1); >+} >+ >+TEST(StringViewTest, Noexcept) { >+ EXPECT_TRUE((std::is_nothrow_constructible<absl::string_view, >+ const std::string&>::value)); >+ EXPECT_TRUE( >+ (std::is_nothrow_constructible<absl::string_view, const std::string&>::value)); >+ EXPECT_TRUE(std::is_nothrow_constructible<absl::string_view>::value); >+ constexpr absl::string_view sp; >+ EXPECT_TRUE(noexcept(sp.begin())); >+ EXPECT_TRUE(noexcept(sp.end())); >+ EXPECT_TRUE(noexcept(sp.cbegin())); >+ EXPECT_TRUE(noexcept(sp.cend())); >+ EXPECT_TRUE(noexcept(sp.rbegin())); >+ EXPECT_TRUE(noexcept(sp.rend())); >+ EXPECT_TRUE(noexcept(sp.crbegin())); >+ EXPECT_TRUE(noexcept(sp.crend())); >+ EXPECT_TRUE(noexcept(sp.size())); >+ EXPECT_TRUE(noexcept(sp.length())); >+ EXPECT_TRUE(noexcept(sp.empty())); >+ EXPECT_TRUE(noexcept(sp.data())); >+ EXPECT_TRUE(noexcept(sp.compare(sp))); >+ EXPECT_TRUE(noexcept(sp.find(sp))); >+ EXPECT_TRUE(noexcept(sp.find('f'))); >+ EXPECT_TRUE(noexcept(sp.rfind(sp))); >+ EXPECT_TRUE(noexcept(sp.rfind('f'))); >+ EXPECT_TRUE(noexcept(sp.find_first_of(sp))); >+ EXPECT_TRUE(noexcept(sp.find_first_of('f'))); >+ EXPECT_TRUE(noexcept(sp.find_last_of(sp))); >+ EXPECT_TRUE(noexcept(sp.find_last_of('f'))); >+ EXPECT_TRUE(noexcept(sp.find_first_not_of(sp))); >+ EXPECT_TRUE(noexcept(sp.find_first_not_of('f'))); >+ EXPECT_TRUE(noexcept(sp.find_last_not_of(sp))); >+ EXPECT_TRUE(noexcept(sp.find_last_not_of('f'))); >+} >+ >+TEST(ComparisonOpsTest, StringCompareNotAmbiguous) { >+ EXPECT_EQ("hello", std::string("hello")); >+ EXPECT_LT("hello", std::string("world")); >+} >+ >+TEST(ComparisonOpsTest, HeterogenousStringViewEquals) { >+ EXPECT_EQ(absl::string_view("hello"), std::string("hello")); >+ EXPECT_EQ("hello", absl::string_view("hello")); >+} >+ >+TEST(FindOneCharTest, EdgeCases) { >+ absl::string_view a("xxyyyxx"); >+ >+ // Set a = "xyyyx". >+ a.remove_prefix(1); >+ a.remove_suffix(1); >+ >+ EXPECT_EQ(0, a.find('x')); >+ EXPECT_EQ(0, a.find('x', 0)); >+ EXPECT_EQ(4, a.find('x', 1)); >+ EXPECT_EQ(4, a.find('x', 4)); >+ EXPECT_EQ(absl::string_view::npos, a.find('x', 5)); >+ >+ EXPECT_EQ(4, a.rfind('x')); >+ EXPECT_EQ(4, a.rfind('x', 5)); >+ EXPECT_EQ(4, a.rfind('x', 4)); >+ EXPECT_EQ(0, a.rfind('x', 3)); >+ EXPECT_EQ(0, a.rfind('x', 0)); >+ >+ // Set a = "yyy". >+ a.remove_prefix(1); >+ a.remove_suffix(1); >+ >+ EXPECT_EQ(absl::string_view::npos, a.find('x')); >+ EXPECT_EQ(absl::string_view::npos, a.rfind('x')); >+} >+ >+#ifndef THREAD_SANITIZER // Allocates too much memory for tsan. >+TEST(HugeStringView, TwoPointTwoGB) { >+ if (sizeof(size_t) <= 4 || AbslRunningOnValgrind()) >+ return; >+ // Try a huge std::string piece. >+ const size_t size = size_t{2200} * 1000 * 1000; >+ std::string s(size, 'a'); >+ absl::string_view sp(s); >+ EXPECT_EQ(size, sp.length()); >+ sp.remove_prefix(1); >+ EXPECT_EQ(size - 1, sp.length()); >+ sp.remove_suffix(2); >+ EXPECT_EQ(size - 1 - 2, sp.length()); >+} >+#endif // THREAD_SANITIZER >+ >+#if !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW) >+TEST(NonNegativeLenTest, NonNegativeLen) { >+ ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1), >+ "len <= kMaxSize"); >+} >+ >+TEST(LenExceedsMaxSizeTest, LenExceedsMaxSize) { >+ auto max_size = absl::string_view().max_size(); >+ >+ // This should construct ok (although the view itself is obviously invalid). >+ absl::string_view ok_view("", max_size); >+ >+ // Adding one to the max should trigger an assertion. >+ ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("", max_size + 1), >+ "len <= kMaxSize"); >+} >+#endif // !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW) >+ >+class StringViewStreamTest : public ::testing::Test { >+ public: >+ // Set negative 'width' for right justification. >+ template <typename T> >+ std::string Pad(const T& s, int width, char fill = 0) { >+ std::ostringstream oss; >+ if (fill != 0) { >+ oss << std::setfill(fill); >+ } >+ if (width < 0) { >+ width = -width; >+ oss << std::right; >+ } >+ oss << std::setw(width) << s; >+ return oss.str(); >+ } >+}; >+ >+TEST_F(StringViewStreamTest, Padding) { >+ std::string s("hello"); >+ absl::string_view sp(s); >+ for (int w = -64; w < 64; ++w) { >+ SCOPED_TRACE(w); >+ EXPECT_EQ(Pad(s, w), Pad(sp, w)); >+ } >+ for (int w = -64; w < 64; ++w) { >+ SCOPED_TRACE(w); >+ EXPECT_EQ(Pad(s, w, '#'), Pad(sp, w, '#')); >+ } >+} >+ >+TEST_F(StringViewStreamTest, ResetsWidth) { >+ // Width should reset after one formatted write. >+ // If we weren't resetting width after formatting the string_view, >+ // we'd have width=5 carrying over to the printing of the "]", >+ // creating "[###hi####]". >+ std::string s = "hi"; >+ absl::string_view sp = s; >+ { >+ std::ostringstream oss; >+ oss << "[" << std::setfill('#') << std::setw(5) << s << "]"; >+ ASSERT_EQ("[###hi]", oss.str()); >+ } >+ { >+ std::ostringstream oss; >+ oss << "[" << std::setfill('#') << std::setw(5) << sp << "]"; >+ EXPECT_EQ("[###hi]", oss.str()); >+ } >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/strip.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/strip.h >new file mode 100644 >index 0000000000000000000000000000000000000000..2f8d21f7deb9fca02938ca7a9240a0e17756f211 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/strip.h >@@ -0,0 +1,89 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: strip.h >+// ----------------------------------------------------------------------------- >+// >+// This file contains various functions for stripping substrings from a std::string. >+#ifndef ABSL_STRINGS_STRIP_H_ >+#define ABSL_STRINGS_STRIP_H_ >+ >+#include <cstddef> >+#include <string> >+ >+#include "absl/base/macros.h" >+#include "absl/strings/ascii.h" >+#include "absl/strings/match.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+ >+// ConsumePrefix() >+// >+// Strips the `expected` prefix from the start of the given std::string, returning >+// `true` if the strip operation succeeded or false otherwise. >+// >+// Example: >+// >+// absl::string_view input("abc"); >+// EXPECT_TRUE(absl::ConsumePrefix(&input, "a")); >+// EXPECT_EQ(input, "bc"); >+inline bool ConsumePrefix(absl::string_view* str, absl::string_view expected) { >+ if (!absl::StartsWith(*str, expected)) return false; >+ str->remove_prefix(expected.size()); >+ return true; >+} >+// ConsumeSuffix() >+// >+// Strips the `expected` suffix from the end of the given std::string, returning >+// `true` if the strip operation succeeded or false otherwise. >+// >+// Example: >+// >+// absl::string_view input("abcdef"); >+// EXPECT_TRUE(absl::ConsumeSuffix(&input, "def")); >+// EXPECT_EQ(input, "abc"); >+inline bool ConsumeSuffix(absl::string_view* str, absl::string_view expected) { >+ if (!absl::EndsWith(*str, expected)) return false; >+ str->remove_suffix(expected.size()); >+ return true; >+} >+ >+// StripPrefix() >+// >+// Returns a view into the input std::string 'str' with the given 'prefix' removed, >+// but leaving the original std::string intact. If the prefix does not match at the >+// start of the std::string, returns the original std::string instead. >+ABSL_MUST_USE_RESULT inline absl::string_view StripPrefix( >+ absl::string_view str, absl::string_view prefix) { >+ if (absl::StartsWith(str, prefix)) str.remove_prefix(prefix.size()); >+ return str; >+} >+ >+// StripSuffix() >+// >+// Returns a view into the input std::string 'str' with the given 'suffix' removed, >+// but leaving the original std::string intact. If the suffix does not match at the >+// end of the std::string, returns the original std::string instead. >+ABSL_MUST_USE_RESULT inline absl::string_view StripSuffix( >+ absl::string_view str, absl::string_view suffix) { >+ if (absl::EndsWith(str, suffix)) str.remove_suffix(suffix.size()); >+ return str; >+} >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_STRIP_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/strip_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/strip_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..205c160c1929263796a59323ac59509e8ab6589e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/strip_test.cc >@@ -0,0 +1,201 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// This file contains functions that remove a defined part from the std::string, >+// i.e., strip the std::string. >+ >+#include "absl/strings/strip.h" >+ >+#include <cassert> >+#include <cstdio> >+#include <cstring> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/strings/string_view.h" >+ >+namespace { >+ >+using testing::ElementsAre; >+using testing::IsEmpty; >+ >+TEST(Strip, ConsumePrefixOneChar) { >+ absl::string_view input("abc"); >+ EXPECT_TRUE(absl::ConsumePrefix(&input, "a")); >+ EXPECT_EQ(input, "bc"); >+ >+ EXPECT_FALSE(absl::ConsumePrefix(&input, "x")); >+ EXPECT_EQ(input, "bc"); >+ >+ EXPECT_TRUE(absl::ConsumePrefix(&input, "b")); >+ EXPECT_EQ(input, "c"); >+ >+ EXPECT_TRUE(absl::ConsumePrefix(&input, "c")); >+ EXPECT_EQ(input, ""); >+ >+ EXPECT_FALSE(absl::ConsumePrefix(&input, "a")); >+ EXPECT_EQ(input, ""); >+} >+ >+TEST(Strip, ConsumePrefix) { >+ absl::string_view input("abcdef"); >+ EXPECT_FALSE(absl::ConsumePrefix(&input, "abcdefg")); >+ EXPECT_EQ(input, "abcdef"); >+ >+ EXPECT_FALSE(absl::ConsumePrefix(&input, "abce")); >+ EXPECT_EQ(input, "abcdef"); >+ >+ EXPECT_TRUE(absl::ConsumePrefix(&input, "")); >+ EXPECT_EQ(input, "abcdef"); >+ >+ EXPECT_FALSE(absl::ConsumePrefix(&input, "abcdeg")); >+ EXPECT_EQ(input, "abcdef"); >+ >+ EXPECT_TRUE(absl::ConsumePrefix(&input, "abcdef")); >+ EXPECT_EQ(input, ""); >+ >+ input = "abcdef"; >+ EXPECT_TRUE(absl::ConsumePrefix(&input, "abcde")); >+ EXPECT_EQ(input, "f"); >+} >+ >+TEST(Strip, ConsumeSuffix) { >+ absl::string_view input("abcdef"); >+ EXPECT_FALSE(absl::ConsumeSuffix(&input, "abcdefg")); >+ EXPECT_EQ(input, "abcdef"); >+ >+ EXPECT_TRUE(absl::ConsumeSuffix(&input, "")); >+ EXPECT_EQ(input, "abcdef"); >+ >+ EXPECT_TRUE(absl::ConsumeSuffix(&input, "def")); >+ EXPECT_EQ(input, "abc"); >+ >+ input = "abcdef"; >+ EXPECT_FALSE(absl::ConsumeSuffix(&input, "abcdeg")); >+ EXPECT_EQ(input, "abcdef"); >+ >+ EXPECT_TRUE(absl::ConsumeSuffix(&input, "f")); >+ EXPECT_EQ(input, "abcde"); >+ >+ EXPECT_TRUE(absl::ConsumeSuffix(&input, "abcde")); >+ EXPECT_EQ(input, ""); >+} >+ >+TEST(Strip, StripPrefix) { >+ const absl::string_view null_str; >+ >+ EXPECT_EQ(absl::StripPrefix("foobar", "foo"), "bar"); >+ EXPECT_EQ(absl::StripPrefix("foobar", ""), "foobar"); >+ EXPECT_EQ(absl::StripPrefix("foobar", null_str), "foobar"); >+ EXPECT_EQ(absl::StripPrefix("foobar", "foobar"), ""); >+ EXPECT_EQ(absl::StripPrefix("foobar", "bar"), "foobar"); >+ EXPECT_EQ(absl::StripPrefix("foobar", "foobarr"), "foobar"); >+ EXPECT_EQ(absl::StripPrefix("", ""), ""); >+} >+ >+TEST(Strip, StripSuffix) { >+ const absl::string_view null_str; >+ >+ EXPECT_EQ(absl::StripSuffix("foobar", "bar"), "foo"); >+ EXPECT_EQ(absl::StripSuffix("foobar", ""), "foobar"); >+ EXPECT_EQ(absl::StripSuffix("foobar", null_str), "foobar"); >+ EXPECT_EQ(absl::StripSuffix("foobar", "foobar"), ""); >+ EXPECT_EQ(absl::StripSuffix("foobar", "foo"), "foobar"); >+ EXPECT_EQ(absl::StripSuffix("foobar", "ffoobar"), "foobar"); >+ EXPECT_EQ(absl::StripSuffix("", ""), ""); >+} >+ >+TEST(Strip, RemoveExtraAsciiWhitespace) { >+ const char* inputs[] = { >+ "No extra space", >+ " Leading whitespace", >+ "Trailing whitespace ", >+ " Leading and trailing ", >+ " Whitespace \t in\v middle ", >+ "'Eeeeep! \n Newlines!\n", >+ "nospaces", >+ }; >+ const char* outputs[] = { >+ "No extra space", >+ "Leading whitespace", >+ "Trailing whitespace", >+ "Leading and trailing", >+ "Whitespace in middle", >+ "'Eeeeep! Newlines!", >+ "nospaces", >+ }; >+ int NUM_TESTS = 7; >+ >+ for (int i = 0; i < NUM_TESTS; i++) { >+ std::string s(inputs[i]); >+ absl::RemoveExtraAsciiWhitespace(&s); >+ EXPECT_STREQ(outputs[i], s.c_str()); >+ } >+ >+ // Test that absl::RemoveExtraAsciiWhitespace returns immediately for empty >+ // strings (It was adding the \0 character to the C++ std::string, which broke >+ // tests involving empty()) >+ std::string zero_string = ""; >+ assert(zero_string.empty()); >+ absl::RemoveExtraAsciiWhitespace(&zero_string); >+ EXPECT_EQ(zero_string.size(), 0); >+ EXPECT_TRUE(zero_string.empty()); >+} >+ >+TEST(Strip, StripTrailingAsciiWhitespace) { >+ std::string test = "foo "; >+ absl::StripTrailingAsciiWhitespace(&test); >+ EXPECT_EQ(test, "foo"); >+ >+ test = " "; >+ absl::StripTrailingAsciiWhitespace(&test); >+ EXPECT_EQ(test, ""); >+ >+ test = ""; >+ absl::StripTrailingAsciiWhitespace(&test); >+ EXPECT_EQ(test, ""); >+ >+ test = " abc\t"; >+ absl::StripTrailingAsciiWhitespace(&test); >+ EXPECT_EQ(test, " abc"); >+} >+ >+TEST(String, StripLeadingAsciiWhitespace) { >+ absl::string_view orig = "\t \n\f\r\n\vfoo"; >+ EXPECT_EQ("foo", absl::StripLeadingAsciiWhitespace(orig)); >+ orig = "\t \n\f\r\v\n\t \n\f\r\v\n"; >+ EXPECT_EQ(absl::string_view(), absl::StripLeadingAsciiWhitespace(orig)); >+} >+ >+TEST(Strip, StripAsciiWhitespace) { >+ std::string test2 = "\t \f\r\n\vfoo \t\f\r\v\n"; >+ absl::StripAsciiWhitespace(&test2); >+ EXPECT_EQ(test2, "foo"); >+ std::string test3 = "bar"; >+ absl::StripAsciiWhitespace(&test3); >+ EXPECT_EQ(test3, "bar"); >+ std::string test4 = "\t \f\r\n\vfoo"; >+ absl::StripAsciiWhitespace(&test4); >+ EXPECT_EQ(test4, "foo"); >+ std::string test5 = "foo \t\f\r\v\n"; >+ absl::StripAsciiWhitespace(&test5); >+ EXPECT_EQ(test5, "foo"); >+ absl::string_view test6("\t \f\r\n\vfoo \t\f\r\v\n"); >+ test6 = absl::StripAsciiWhitespace(test6); >+ EXPECT_EQ(test6, "foo"); >+ test6 = absl::StripAsciiWhitespace(test6); >+ EXPECT_EQ(test6, "foo"); // already stripped >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/substitute.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/substitute.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..3b200594509516139419d8f21cfd4ad210014f79 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/substitute.cc >@@ -0,0 +1,170 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/substitute.h" >+ >+#include <algorithm> >+ >+#include "absl/base/internal/raw_logging.h" >+#include "absl/strings/ascii.h" >+#include "absl/strings/escaping.h" >+#include "absl/strings/internal/resize_uninitialized.h" >+#include "absl/strings/string_view.h" >+ >+namespace absl { >+namespace substitute_internal { >+ >+void SubstituteAndAppendArray(std::string* output, absl::string_view format, >+ const absl::string_view* args_array, >+ size_t num_args) { >+ // Determine total size needed. >+ size_t size = 0; >+ for (size_t i = 0; i < format.size(); i++) { >+ if (format[i] == '$') { >+ if (i + 1 >= format.size()) { >+#ifndef NDEBUG >+ ABSL_RAW_LOG(FATAL, >+ "Invalid strings::Substitute() format std::string: \"%s\".", >+ absl::CEscape(format).c_str()); >+#endif >+ return; >+ } else if (absl::ascii_isdigit(format[i + 1])) { >+ int index = format[i + 1] - '0'; >+ if (static_cast<size_t>(index) >= num_args) { >+#ifndef NDEBUG >+ ABSL_RAW_LOG( >+ FATAL, >+ "Invalid strings::Substitute() format std::string: asked for \"$" >+ "%d\", but only %d args were given. Full format std::string was: " >+ "\"%s\".", >+ index, static_cast<int>(num_args), absl::CEscape(format).c_str()); >+#endif >+ return; >+ } >+ size += args_array[index].size(); >+ ++i; // Skip next char. >+ } else if (format[i + 1] == '$') { >+ ++size; >+ ++i; // Skip next char. >+ } else { >+#ifndef NDEBUG >+ ABSL_RAW_LOG(FATAL, >+ "Invalid strings::Substitute() format std::string: \"%s\".", >+ absl::CEscape(format).c_str()); >+#endif >+ return; >+ } >+ } else { >+ ++size; >+ } >+ } >+ >+ if (size == 0) return; >+ >+ // Build the std::string. >+ size_t original_size = output->size(); >+ strings_internal::STLStringResizeUninitialized(output, original_size + size); >+ char* target = &(*output)[original_size]; >+ for (size_t i = 0; i < format.size(); i++) { >+ if (format[i] == '$') { >+ if (absl::ascii_isdigit(format[i + 1])) { >+ const absl::string_view src = args_array[format[i + 1] - '0']; >+ target = std::copy(src.begin(), src.end(), target); >+ ++i; // Skip next char. >+ } else if (format[i + 1] == '$') { >+ *target++ = '$'; >+ ++i; // Skip next char. >+ } >+ } else { >+ *target++ = format[i]; >+ } >+ } >+ >+ assert(target == output->data() + output->size()); >+} >+ >+static const char kHexDigits[] = "0123456789abcdef"; >+Arg::Arg(const void* value) { >+ static_assert(sizeof(scratch_) >= sizeof(value) * 2 + 2, >+ "fix sizeof(scratch_)"); >+ if (value == nullptr) { >+ piece_ = "NULL"; >+ } else { >+ char* ptr = scratch_ + sizeof(scratch_); >+ uintptr_t num = reinterpret_cast<uintptr_t>(value); >+ do { >+ *--ptr = kHexDigits[num & 0xf]; >+ num >>= 4; >+ } while (num != 0); >+ *--ptr = 'x'; >+ *--ptr = '0'; >+ piece_ = absl::string_view(ptr, scratch_ + sizeof(scratch_) - ptr); >+ } >+} >+ >+// TODO(jorg): Don't duplicate so much code between here and str_cat.cc >+Arg::Arg(Hex hex) { >+ char* const end = &scratch_[numbers_internal::kFastToBufferSize]; >+ char* writer = end; >+ uint64_t value = hex.value; >+ do { >+ *--writer = kHexDigits[value & 0xF]; >+ value >>= 4; >+ } while (value != 0); >+ >+ char* beg; >+ if (end - writer < hex.width) { >+ beg = end - hex.width; >+ std::fill_n(beg, writer - beg, hex.fill); >+ } else { >+ beg = writer; >+ } >+ >+ piece_ = absl::string_view(beg, end - beg); >+} >+ >+// TODO(jorg): Don't duplicate so much code between here and str_cat.cc >+Arg::Arg(Dec dec) { >+ assert(dec.width <= numbers_internal::kFastToBufferSize); >+ char* const end = &scratch_[numbers_internal::kFastToBufferSize]; >+ char* const minfill = end - dec.width; >+ char* writer = end; >+ uint64_t value = dec.value; >+ bool neg = dec.neg; >+ while (value > 9) { >+ *--writer = '0' + (value % 10); >+ value /= 10; >+ } >+ *--writer = '0' + value; >+ if (neg) *--writer = '-'; >+ >+ ptrdiff_t fillers = writer - minfill; >+ if (fillers > 0) { >+ // Tricky: if the fill character is ' ', then it's <fill><+/-><digits> >+ // But...: if the fill character is '0', then it's <+/-><fill><digits> >+ bool add_sign_again = false; >+ if (neg && dec.fill == '0') { // If filling with '0', >+ ++writer; // ignore the sign we just added >+ add_sign_again = true; // and re-add the sign later. >+ } >+ writer -= fillers; >+ std::fill_n(writer, fillers, dec.fill); >+ if (add_sign_again) *--writer = '-'; >+ } >+ >+ piece_ = absl::string_view(writer, end - writer); >+} >+ >+} // namespace substitute_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/substitute.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/substitute.h >new file mode 100644 >index 0000000000000000000000000000000000000000..c4b25ba70952c19d64ebc849b7e3c09cafbc52cf >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/substitute.h >@@ -0,0 +1,671 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: substitute.h >+// ----------------------------------------------------------------------------- >+// >+// This package contains functions for efficiently performing std::string >+// substitutions using a format std::string with positional notation: >+// `Substitute()` and `SubstituteAndAppend()`. >+// >+// Unlike printf-style format specifiers, `Substitute()` functions do not need >+// to specify the type of the substitution arguments. Supported arguments >+// following the format std::string, such as strings, string_views, ints, >+// floats, and bools, are automatically converted to strings during the >+// substitution process. (See below for a full list of supported types.) >+// >+// `Substitute()` does not allow you to specify *how* to format a value, beyond >+// the default conversion to std::string. For example, you cannot format an integer >+// in hex. >+// >+// The format std::string uses positional identifiers indicated by a dollar sign ($) >+// and single digit positional ids to indicate which substitution arguments to >+// use at that location within the format std::string. >+// >+// Example 1: >+// std::string s = Substitute("$1 purchased $0 $2. Thanks $1!", >+// 5, "Bob", "Apples"); >+// EXPECT_EQ("Bob purchased 5 Apples. Thanks Bob!", s); >+// >+// Example 2: >+// std::string s = "Hi. "; >+// SubstituteAndAppend(&s, "My name is $0 and I am $1 years old.", "Bob", 5); >+// EXPECT_EQ("Hi. My name is Bob and I am 5 years old.", s); >+// >+// >+// Supported types: >+// * absl::string_view, std::string, const char* (null is equivalent to "") >+// * int32_t, int64_t, uint32_t, uint64 >+// * float, double >+// * bool (Printed as "true" or "false") >+// * pointer types other than char* (Printed as "0x<lower case hex std::string>", >+// except that null is printed as "NULL") >+// >+// If an invalid format std::string is provided, Substitute returns an empty std::string >+// and SubstituteAndAppend does not change the provided output std::string. >+// A format std::string is invalid if it: >+// * ends in an unescaped $ character, >+// e.g. "Hello $", or >+// * calls for a position argument which is not provided, >+// e.g. Substitute("Hello $2", "world"), or >+// * specifies a non-digit, non-$ character after an unescaped $ character, >+// e.g. "Hello $f". >+// In debug mode, i.e. #ifndef NDEBUG, such errors terminate the program. >+ >+#ifndef ABSL_STRINGS_SUBSTITUTE_H_ >+#define ABSL_STRINGS_SUBSTITUTE_H_ >+ >+#include <cstring> >+#include <string> >+ >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+#include "absl/strings/ascii.h" >+#include "absl/strings/escaping.h" >+#include "absl/strings/numbers.h" >+#include "absl/strings/str_cat.h" >+#include "absl/strings/str_split.h" >+#include "absl/strings/string_view.h" >+#include "absl/strings/strip.h" >+ >+namespace absl { >+namespace substitute_internal { >+ >+// Arg >+// >+// This class provides an argument type for `absl::Substitute()` and >+// `absl::SubstituteAndAppend()`. `Arg` handles implicit conversion of various >+// types to a std::string. (`Arg` is very similar to the `AlphaNum` class in >+// `StrCat()`.) >+// >+// This class has implicit constructors. >+class Arg { >+ public: >+ // Overloads for std::string-y things >+ // >+ // Explicitly overload `const char*` so the compiler doesn't cast to `bool`. >+ Arg(const char* value) // NOLINT(runtime/explicit) >+ : piece_(absl::NullSafeStringView(value)) {} >+ template <typename Allocator> >+ Arg( // NOLINT >+ const std::basic_string<char, std::char_traits<char>, Allocator>& >+ value) noexcept >+ : piece_(value) {} >+ Arg(absl::string_view value) // NOLINT(runtime/explicit) >+ : piece_(value) {} >+ >+ // Overloads for primitives >+ // >+ // No overloads are available for signed and unsigned char because if people >+ // are explicitly declaring their chars as signed or unsigned then they are >+ // probably using them as 8-bit integers and would probably prefer an integer >+ // representation. However, we can't really know, so we make the caller decide >+ // what to do. >+ Arg(char value) // NOLINT(runtime/explicit) >+ : piece_(scratch_, 1) { scratch_[0] = value; } >+ Arg(short value) // NOLINT(*) >+ : piece_(scratch_, >+ numbers_internal::FastIntToBuffer(value, scratch_) - scratch_) {} >+ Arg(unsigned short value) // NOLINT(*) >+ : piece_(scratch_, >+ numbers_internal::FastIntToBuffer(value, scratch_) - scratch_) {} >+ Arg(int value) // NOLINT(runtime/explicit) >+ : piece_(scratch_, >+ numbers_internal::FastIntToBuffer(value, scratch_) - scratch_) {} >+ Arg(unsigned int value) // NOLINT(runtime/explicit) >+ : piece_(scratch_, >+ numbers_internal::FastIntToBuffer(value, scratch_) - scratch_) {} >+ Arg(long value) // NOLINT(*) >+ : piece_(scratch_, >+ numbers_internal::FastIntToBuffer(value, scratch_) - scratch_) {} >+ Arg(unsigned long value) // NOLINT(*) >+ : piece_(scratch_, >+ numbers_internal::FastIntToBuffer(value, scratch_) - scratch_) {} >+ Arg(long long value) // NOLINT(*) >+ : piece_(scratch_, >+ numbers_internal::FastIntToBuffer(value, scratch_) - scratch_) {} >+ Arg(unsigned long long value) // NOLINT(*) >+ : piece_(scratch_, >+ numbers_internal::FastIntToBuffer(value, scratch_) - scratch_) {} >+ Arg(float value) // NOLINT(runtime/explicit) >+ : piece_(scratch_, numbers_internal::SixDigitsToBuffer(value, scratch_)) { >+ } >+ Arg(double value) // NOLINT(runtime/explicit) >+ : piece_(scratch_, numbers_internal::SixDigitsToBuffer(value, scratch_)) { >+ } >+ Arg(bool value) // NOLINT(runtime/explicit) >+ : piece_(value ? "true" : "false") {} >+ >+ Arg(Hex hex); // NOLINT(runtime/explicit) >+ Arg(Dec dec); // NOLINT(runtime/explicit) >+ >+ // `void*` values, with the exception of `char*`, are printed as >+ // "0x<hex value>". However, in the case of `nullptr`, "NULL" is printed. >+ Arg(const void* value); // NOLINT(runtime/explicit) >+ >+ Arg(const Arg&) = delete; >+ Arg& operator=(const Arg&) = delete; >+ >+ absl::string_view piece() const { return piece_; } >+ >+ private: >+ absl::string_view piece_; >+ char scratch_[numbers_internal::kFastToBufferSize]; >+}; >+ >+// Internal helper function. Don't call this from outside this implementation. >+// This interface may change without notice. >+void SubstituteAndAppendArray(std::string* output, absl::string_view format, >+ const absl::string_view* args_array, >+ size_t num_args); >+ >+#if defined(ABSL_BAD_CALL_IF) >+constexpr int CalculateOneBit(const char* format) { >+ return (*format < '0' || *format > '9') ? 0 : (1 << (*format - '0')); >+} >+ >+constexpr const char* SkipNumber(const char* format) { >+ return !*format ? format : (format + 1); >+} >+ >+constexpr int PlaceholderBitmask(const char* format) { >+ return !*format ? 0 : *format != '$' >+ ? PlaceholderBitmask(format + 1) >+ : (CalculateOneBit(format + 1) | >+ PlaceholderBitmask(SkipNumber(format + 1))); >+} >+#endif // ABSL_BAD_CALL_IF >+ >+} // namespace substitute_internal >+ >+// >+// PUBLIC API >+// >+ >+// SubstituteAndAppend() >+// >+// Substitutes variables into a given format std::string and appends to a given >+// output std::string. See file comments above for usage. >+// >+// The declarations of `SubstituteAndAppend()` below consist of overloads >+// for passing 0 to 10 arguments, respectively. >+// >+// NOTE: A zero-argument `SubstituteAndAppend()` may be used within variadic >+// templates to allow a variable number of arguments. >+// >+// Example: >+// template <typename... Args> >+// void VarMsg(std::string* boilerplate, absl::string_view format, >+// const Args&... args) { >+// absl::SubstituteAndAppend(boilerplate, format, args...); >+// } >+// >+inline void SubstituteAndAppend(std::string* output, absl::string_view format) { >+ substitute_internal::SubstituteAndAppendArray(output, format, nullptr, 0); >+} >+ >+inline void SubstituteAndAppend(std::string* output, absl::string_view format, >+ const substitute_internal::Arg& a0) { >+ const absl::string_view args[] = {a0.piece()}; >+ substitute_internal::SubstituteAndAppendArray(output, format, args, >+ ABSL_ARRAYSIZE(args)); >+} >+ >+inline void SubstituteAndAppend(std::string* output, absl::string_view format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1) { >+ const absl::string_view args[] = {a0.piece(), a1.piece()}; >+ substitute_internal::SubstituteAndAppendArray(output, format, args, >+ ABSL_ARRAYSIZE(args)); >+} >+ >+inline void SubstituteAndAppend(std::string* output, absl::string_view format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2) { >+ const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece()}; >+ substitute_internal::SubstituteAndAppendArray(output, format, args, >+ ABSL_ARRAYSIZE(args)); >+} >+ >+inline void SubstituteAndAppend(std::string* output, absl::string_view format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3) { >+ const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(), >+ a3.piece()}; >+ substitute_internal::SubstituteAndAppendArray(output, format, args, >+ ABSL_ARRAYSIZE(args)); >+} >+ >+inline void SubstituteAndAppend(std::string* output, absl::string_view format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4) { >+ const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(), >+ a3.piece(), a4.piece()}; >+ substitute_internal::SubstituteAndAppendArray(output, format, args, >+ ABSL_ARRAYSIZE(args)); >+} >+ >+inline void SubstituteAndAppend(std::string* output, absl::string_view format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5) { >+ const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(), >+ a3.piece(), a4.piece(), a5.piece()}; >+ substitute_internal::SubstituteAndAppendArray(output, format, args, >+ ABSL_ARRAYSIZE(args)); >+} >+ >+inline void SubstituteAndAppend(std::string* output, absl::string_view format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, >+ const substitute_internal::Arg& a6) { >+ const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(), >+ a3.piece(), a4.piece(), a5.piece(), >+ a6.piece()}; >+ substitute_internal::SubstituteAndAppendArray(output, format, args, >+ ABSL_ARRAYSIZE(args)); >+} >+ >+inline void SubstituteAndAppend( >+ std::string* output, absl::string_view format, >+ const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4, const substitute_internal::Arg& a5, >+ const substitute_internal::Arg& a6, const substitute_internal::Arg& a7) { >+ const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(), >+ a3.piece(), a4.piece(), a5.piece(), >+ a6.piece(), a7.piece()}; >+ substitute_internal::SubstituteAndAppendArray(output, format, args, >+ ABSL_ARRAYSIZE(args)); >+} >+ >+inline void SubstituteAndAppend( >+ std::string* output, absl::string_view format, >+ const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4, const substitute_internal::Arg& a5, >+ const substitute_internal::Arg& a6, const substitute_internal::Arg& a7, >+ const substitute_internal::Arg& a8) { >+ const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(), >+ a3.piece(), a4.piece(), a5.piece(), >+ a6.piece(), a7.piece(), a8.piece()}; >+ substitute_internal::SubstituteAndAppendArray(output, format, args, >+ ABSL_ARRAYSIZE(args)); >+} >+ >+inline void SubstituteAndAppend( >+ std::string* output, absl::string_view format, >+ const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4, const substitute_internal::Arg& a5, >+ const substitute_internal::Arg& a6, const substitute_internal::Arg& a7, >+ const substitute_internal::Arg& a8, const substitute_internal::Arg& a9) { >+ const absl::string_view args[] = { >+ a0.piece(), a1.piece(), a2.piece(), a3.piece(), a4.piece(), >+ a5.piece(), a6.piece(), a7.piece(), a8.piece(), a9.piece()}; >+ substitute_internal::SubstituteAndAppendArray(output, format, args, >+ ABSL_ARRAYSIZE(args)); >+} >+ >+#if defined(ABSL_BAD_CALL_IF) >+// This body of functions catches cases where the number of placeholders >+// doesn't match the number of data arguments. >+void SubstituteAndAppend(std::string* output, const char* format) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 0, >+ "There were no substitution arguments " >+ "but this format std::string has a $[0-9] in it"); >+ >+void SubstituteAndAppend(std::string* output, const char* format, >+ const substitute_internal::Arg& a0) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1, >+ "There was 1 substitution argument given, but " >+ "this format std::string is either missing its $0, or " >+ "contains one of $1-$9"); >+ >+void SubstituteAndAppend(std::string* output, const char* format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 3, >+ "There were 2 substitution arguments given, but " >+ "this format std::string is either missing its $0/$1, or " >+ "contains one of $2-$9"); >+ >+void SubstituteAndAppend(std::string* output, const char* format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 7, >+ "There were 3 substitution arguments given, but " >+ "this format std::string is either missing its $0/$1/$2, or " >+ "contains one of $3-$9"); >+ >+void SubstituteAndAppend(std::string* output, const char* format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 15, >+ "There were 4 substitution arguments given, but " >+ "this format std::string is either missing its $0-$3, or " >+ "contains one of $4-$9"); >+ >+void SubstituteAndAppend(std::string* output, const char* format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 31, >+ "There were 5 substitution arguments given, but " >+ "this format std::string is either missing its $0-$4, or " >+ "contains one of $5-$9"); >+ >+void SubstituteAndAppend(std::string* output, const char* format, >+ const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 63, >+ "There were 6 substitution arguments given, but " >+ "this format std::string is either missing its $0-$5, or " >+ "contains one of $6-$9"); >+ >+void SubstituteAndAppend( >+ std::string* output, const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 127, >+ "There were 7 substitution arguments given, but " >+ "this format std::string is either missing its $0-$6, or " >+ "contains one of $7-$9"); >+ >+void SubstituteAndAppend( >+ std::string* output, const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, >+ const substitute_internal::Arg& a7) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 255, >+ "There were 8 substitution arguments given, but " >+ "this format std::string is either missing its $0-$7, or " >+ "contains one of $8-$9"); >+ >+void SubstituteAndAppend( >+ std::string* output, const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, >+ const substitute_internal::Arg& a7, const substitute_internal::Arg& a8) >+ ABSL_BAD_CALL_IF( >+ substitute_internal::PlaceholderBitmask(format) != 511, >+ "There were 9 substitution arguments given, but " >+ "this format std::string is either missing its $0-$8, or contains a $9"); >+ >+void SubstituteAndAppend( >+ std::string* output, const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, >+ const substitute_internal::Arg& a7, const substitute_internal::Arg& a8, >+ const substitute_internal::Arg& a9) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1023, >+ "There were 10 substitution arguments given, but this " >+ "format std::string doesn't contain all of $0 through $9"); >+#endif // ABSL_BAD_CALL_IF >+ >+// Substitute() >+// >+// Substitutes variables into a given format std::string. See file comments above >+// for usage. >+// >+// The declarations of `Substitute()` below consist of overloads for passing 0 >+// to 10 arguments, respectively. >+// >+// NOTE: A zero-argument `Substitute()` may be used within variadic templates to >+// allow a variable number of arguments. >+// >+// Example: >+// template <typename... Args> >+// void VarMsg(absl::string_view format, const Args&... args) { >+// std::string s = absl::Substitute(format, args...); >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute(absl::string_view format) { >+ std::string result; >+ SubstituteAndAppend(&result, format); >+ return result; >+} >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute( >+ absl::string_view format, const substitute_internal::Arg& a0) { >+ std::string result; >+ SubstituteAndAppend(&result, format, a0); >+ return result; >+} >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute( >+ absl::string_view format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1) { >+ std::string result; >+ SubstituteAndAppend(&result, format, a0, a1); >+ return result; >+} >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute( >+ absl::string_view format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2) { >+ std::string result; >+ SubstituteAndAppend(&result, format, a0, a1, a2); >+ return result; >+} >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute( >+ absl::string_view format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3) { >+ std::string result; >+ SubstituteAndAppend(&result, format, a0, a1, a2, a3); >+ return result; >+} >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute( >+ absl::string_view format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4) { >+ std::string result; >+ SubstituteAndAppend(&result, format, a0, a1, a2, a3, a4); >+ return result; >+} >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute( >+ absl::string_view format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5) { >+ std::string result; >+ SubstituteAndAppend(&result, format, a0, a1, a2, a3, a4, a5); >+ return result; >+} >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute( >+ absl::string_view format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6) { >+ std::string result; >+ SubstituteAndAppend(&result, format, a0, a1, a2, a3, a4, a5, a6); >+ return result; >+} >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute( >+ absl::string_view format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, >+ const substitute_internal::Arg& a7) { >+ std::string result; >+ SubstituteAndAppend(&result, format, a0, a1, a2, a3, a4, a5, a6, a7); >+ return result; >+} >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute( >+ absl::string_view format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, >+ const substitute_internal::Arg& a7, const substitute_internal::Arg& a8) { >+ std::string result; >+ SubstituteAndAppend(&result, format, a0, a1, a2, a3, a4, a5, a6, a7, a8); >+ return result; >+} >+ >+ABSL_MUST_USE_RESULT inline std::string Substitute( >+ absl::string_view format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, >+ const substitute_internal::Arg& a7, const substitute_internal::Arg& a8, >+ const substitute_internal::Arg& a9) { >+ std::string result; >+ SubstituteAndAppend(&result, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); >+ return result; >+} >+ >+#if defined(ABSL_BAD_CALL_IF) >+// This body of functions catches cases where the number of placeholders >+// doesn't match the number of data arguments. >+std::string Substitute(const char* format) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 0, >+ "There were no substitution arguments " >+ "but this format std::string has a $[0-9] in it"); >+ >+std::string Substitute(const char* format, const substitute_internal::Arg& a0) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1, >+ "There was 1 substitution argument given, but " >+ "this format std::string is either missing its $0, or " >+ "contains one of $1-$9"); >+ >+std::string Substitute(const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 3, >+ "There were 2 substitution arguments given, but " >+ "this format std::string is either missing its $0/$1, or " >+ "contains one of $2-$9"); >+ >+std::string Substitute(const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 7, >+ "There were 3 substitution arguments given, but " >+ "this format std::string is either missing its $0/$1/$2, or " >+ "contains one of $3-$9"); >+ >+std::string Substitute(const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 15, >+ "There were 4 substitution arguments given, but " >+ "this format std::string is either missing its $0-$3, or " >+ "contains one of $4-$9"); >+ >+std::string Substitute(const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 31, >+ "There were 5 substitution arguments given, but " >+ "this format std::string is either missing its $0-$4, or " >+ "contains one of $5-$9"); >+ >+std::string Substitute(const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 63, >+ "There were 6 substitution arguments given, but " >+ "this format std::string is either missing its $0-$5, or " >+ "contains one of $6-$9"); >+ >+std::string Substitute(const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, >+ const substitute_internal::Arg& a6) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 127, >+ "There were 7 substitution arguments given, but " >+ "this format std::string is either missing its $0-$6, or " >+ "contains one of $7-$9"); >+ >+std::string Substitute(const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, >+ const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, >+ const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, >+ const substitute_internal::Arg& a6, >+ const substitute_internal::Arg& a7) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 255, >+ "There were 8 substitution arguments given, but " >+ "this format std::string is either missing its $0-$7, or " >+ "contains one of $8-$9"); >+ >+std::string Substitute( >+ const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, >+ const substitute_internal::Arg& a7, const substitute_internal::Arg& a8) >+ ABSL_BAD_CALL_IF( >+ substitute_internal::PlaceholderBitmask(format) != 511, >+ "There were 9 substitution arguments given, but " >+ "this format std::string is either missing its $0-$8, or contains a $9"); >+ >+std::string Substitute( >+ const char* format, const substitute_internal::Arg& a0, >+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, >+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, >+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, >+ const substitute_internal::Arg& a7, const substitute_internal::Arg& a8, >+ const substitute_internal::Arg& a9) >+ ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1023, >+ "There were 10 substitution arguments given, but this " >+ "format std::string doesn't contain all of $0 through $9"); >+#endif // ABSL_BAD_CALL_IF >+ >+} // namespace absl >+ >+#endif // ABSL_STRINGS_SUBSTITUTE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/substitute_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/substitute_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..144df01ec184f5d09f3be89b86e0bfeed5e14ade >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/substitute_test.cc >@@ -0,0 +1,192 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/strings/substitute.h" >+ >+#include <cstdint> >+ >+#include "gtest/gtest.h" >+#include "absl/strings/str_cat.h" >+ >+namespace { >+ >+TEST(SubstituteTest, Substitute) { >+ // Basic. >+ EXPECT_EQ("Hello, world!", absl::Substitute("$0, $1!", "Hello", "world")); >+ >+ // Non-char* types. >+ EXPECT_EQ("123 0.2 0.1 foo true false x", >+ absl::Substitute("$0 $1 $2 $3 $4 $5 $6", 123, 0.2, 0.1f, >+ std::string("foo"), true, false, 'x')); >+ >+ // All int types. >+ EXPECT_EQ( >+ "-32767 65535 " >+ "-1234567890 3234567890 " >+ "-1234567890 3234567890 " >+ "-1234567890123456789 9234567890123456789", >+ absl::Substitute( >+ "$0 $1 $2 $3 $4 $5 $6 $7", >+ static_cast<short>(-32767), // NOLINT(runtime/int) >+ static_cast<unsigned short>(65535), // NOLINT(runtime/int) >+ -1234567890, 3234567890U, -1234567890L, 3234567890UL, >+ -int64_t{1234567890123456789}, uint64_t{9234567890123456789u})); >+ >+ // Hex format >+ EXPECT_EQ("0 1 f ffff0ffff 0123456789abcdef", >+ absl::Substitute("$0$1$2$3$4 $5", // >+ absl::Hex(0), absl::Hex(1, absl::kSpacePad2), >+ absl::Hex(0xf, absl::kSpacePad2), >+ absl::Hex(int16_t{-1}, absl::kSpacePad5), >+ absl::Hex(int16_t{-1}, absl::kZeroPad5), >+ absl::Hex(0x123456789abcdef, absl::kZeroPad16))); >+ >+ // Dec format >+ EXPECT_EQ("0 115 -1-0001 81985529216486895", >+ absl::Substitute("$0$1$2$3$4 $5", // >+ absl::Dec(0), absl::Dec(1, absl::kSpacePad2), >+ absl::Dec(0xf, absl::kSpacePad2), >+ absl::Dec(int16_t{-1}, absl::kSpacePad5), >+ absl::Dec(int16_t{-1}, absl::kZeroPad5), >+ absl::Dec(0x123456789abcdef, absl::kZeroPad16))); >+ >+ // Pointer. >+ const int* int_p = reinterpret_cast<const int*>(0x12345); >+ std::string str = absl::Substitute("$0", int_p); >+ EXPECT_EQ(absl::StrCat("0x", absl::Hex(int_p)), str); >+ >+ // Volatile Pointer. >+ // Like C++ streamed I/O, such pointers implicitly become bool >+ volatile int vol = 237; >+ volatile int *volatile volptr = &vol; >+ str = absl::Substitute("$0", volptr); >+ EXPECT_EQ("true", str); >+ >+ // null is special. StrCat prints 0x0. Substitute prints NULL. >+ const uint64_t* null_p = nullptr; >+ str = absl::Substitute("$0", null_p); >+ EXPECT_EQ("NULL", str); >+ >+ // char* is also special. >+ const char* char_p = "print me"; >+ str = absl::Substitute("$0", char_p); >+ EXPECT_EQ("print me", str); >+ >+ char char_buf[16]; >+ strncpy(char_buf, "print me too", sizeof(char_buf)); >+ str = absl::Substitute("$0", char_buf); >+ EXPECT_EQ("print me too", str); >+ >+ // null char* is "doubly" special. Represented as the empty std::string. >+ char_p = nullptr; >+ str = absl::Substitute("$0", char_p); >+ EXPECT_EQ("", str); >+ >+ // Out-of-order. >+ EXPECT_EQ("b, a, c, b", absl::Substitute("$1, $0, $2, $1", "a", "b", "c")); >+ >+ // Literal $ >+ EXPECT_EQ("$", absl::Substitute("$$")); >+ >+ EXPECT_EQ("$1", absl::Substitute("$$1")); >+ >+ // Test all overloads. >+ EXPECT_EQ("a", absl::Substitute("$0", "a")); >+ EXPECT_EQ("a b", absl::Substitute("$0 $1", "a", "b")); >+ EXPECT_EQ("a b c", absl::Substitute("$0 $1 $2", "a", "b", "c")); >+ EXPECT_EQ("a b c d", absl::Substitute("$0 $1 $2 $3", "a", "b", "c", "d")); >+ EXPECT_EQ("a b c d e", >+ absl::Substitute("$0 $1 $2 $3 $4", "a", "b", "c", "d", "e")); >+ EXPECT_EQ("a b c d e f", absl::Substitute("$0 $1 $2 $3 $4 $5", "a", "b", "c", >+ "d", "e", "f")); >+ EXPECT_EQ("a b c d e f g", absl::Substitute("$0 $1 $2 $3 $4 $5 $6", "a", "b", >+ "c", "d", "e", "f", "g")); >+ EXPECT_EQ("a b c d e f g h", >+ absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7", "a", "b", "c", "d", "e", >+ "f", "g", "h")); >+ EXPECT_EQ("a b c d e f g h i", >+ absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8", "a", "b", "c", "d", >+ "e", "f", "g", "h", "i")); >+ EXPECT_EQ("a b c d e f g h i j", >+ absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9", "a", "b", "c", >+ "d", "e", "f", "g", "h", "i", "j")); >+ EXPECT_EQ("a b c d e f g h i j b0", >+ absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $10", "a", "b", "c", >+ "d", "e", "f", "g", "h", "i", "j")); >+ >+ const char* null_cstring = nullptr; >+ EXPECT_EQ("Text: ''", absl::Substitute("Text: '$0'", null_cstring)); >+} >+ >+TEST(SubstituteTest, SubstituteAndAppend) { >+ std::string str = "Hello"; >+ absl::SubstituteAndAppend(&str, ", $0!", "world"); >+ EXPECT_EQ("Hello, world!", str); >+ >+ // Test all overloads. >+ str.clear(); >+ absl::SubstituteAndAppend(&str, "$0", "a"); >+ EXPECT_EQ("a", str); >+ str.clear(); >+ absl::SubstituteAndAppend(&str, "$0 $1", "a", "b"); >+ EXPECT_EQ("a b", str); >+ str.clear(); >+ absl::SubstituteAndAppend(&str, "$0 $1 $2", "a", "b", "c"); >+ EXPECT_EQ("a b c", str); >+ str.clear(); >+ absl::SubstituteAndAppend(&str, "$0 $1 $2 $3", "a", "b", "c", "d"); >+ EXPECT_EQ("a b c d", str); >+ str.clear(); >+ absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4", "a", "b", "c", "d", "e"); >+ EXPECT_EQ("a b c d e", str); >+ str.clear(); >+ absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5", "a", "b", "c", "d", "e", >+ "f"); >+ EXPECT_EQ("a b c d e f", str); >+ str.clear(); >+ absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6", "a", "b", "c", "d", >+ "e", "f", "g"); >+ EXPECT_EQ("a b c d e f g", str); >+ str.clear(); >+ absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6 $7", "a", "b", "c", "d", >+ "e", "f", "g", "h"); >+ EXPECT_EQ("a b c d e f g h", str); >+ str.clear(); >+ absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6 $7 $8", "a", "b", "c", >+ "d", "e", "f", "g", "h", "i"); >+ EXPECT_EQ("a b c d e f g h i", str); >+ str.clear(); >+ absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6 $7 $8 $9", "a", "b", >+ "c", "d", "e", "f", "g", "h", "i", "j"); >+ EXPECT_EQ("a b c d e f g h i j", str); >+} >+ >+#ifdef GTEST_HAS_DEATH_TEST >+ >+TEST(SubstituteDeathTest, SubstituteDeath) { >+ EXPECT_DEBUG_DEATH( >+ static_cast<void>(absl::Substitute(absl::string_view("-$2"), "a", "b")), >+ "Invalid strings::Substitute\\(\\) format std::string: asked for \"\\$2\", " >+ "but only 2 args were given."); >+ EXPECT_DEBUG_DEATH( >+ static_cast<void>(absl::Substitute("-$z-")), >+ "Invalid strings::Substitute\\(\\) format std::string: \"-\\$z-\""); >+ EXPECT_DEBUG_DEATH( >+ static_cast<void>(absl::Substitute("-$")), >+ "Invalid strings::Substitute\\(\\) format std::string: \"-\\$\""); >+} >+ >+#endif // GTEST_HAS_DEATH_TEST >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/testdata/getline-1.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/testdata/getline-1.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..19b909733ae379047f40da2e28199614c3621a53 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/testdata/getline-1.txt >@@ -0,0 +1,3 @@ >+alpha >+ >+beta gamma >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/testdata/getline-2.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/testdata/getline-2.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d6842d8ee362391bd9f9290f22dd8e868011570b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/strings/testdata/getline-2.txt >@@ -0,0 +1 @@ >+one.two.three >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..8d302e01223b45bd92a21670a11f5592f9b15c64 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/BUILD.bazel >@@ -0,0 +1,234 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+) >+ >+package(default_visibility = ["//visibility:public"]) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+# Internal data structure for efficiently detecting mutex dependency cycles >+cc_library( >+ name = "graphcycles_internal", >+ srcs = [ >+ "internal/graphcycles.cc", >+ ], >+ hdrs = [ >+ "internal/graphcycles.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ visibility = [ >+ "//absl:__subpackages__", >+ ], >+ deps = [ >+ "//absl/base", >+ "//absl/base:base_internal", >+ "//absl/base:core_headers", >+ "//absl/base:malloc_internal", >+ ], >+) >+ >+cc_library( >+ name = "synchronization", >+ srcs = [ >+ "barrier.cc", >+ "blocking_counter.cc", >+ "internal/create_thread_identity.cc", >+ "internal/per_thread_sem.cc", >+ "internal/waiter.cc", >+ "notification.cc", >+ ] + select({ >+ "//conditions:default": ["mutex.cc"], >+ }), >+ hdrs = [ >+ "barrier.h", >+ "blocking_counter.h", >+ "internal/create_thread_identity.h", >+ "internal/kernel_timeout.h", >+ "internal/mutex_nonprod.inc", >+ "internal/per_thread_sem.h", >+ "internal/waiter.h", >+ "mutex.h", >+ "notification.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":graphcycles_internal", >+ "//absl/base", >+ "//absl/base:base_internal", >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ "//absl/base:dynamic_annotations", >+ "//absl/base:malloc_internal", >+ "//absl/debugging:stacktrace", >+ "//absl/debugging:symbolize", >+ "//absl/time", >+ ], >+) >+ >+cc_test( >+ name = "barrier_test", >+ size = "small", >+ srcs = ["barrier_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":synchronization", >+ "//absl/time", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "blocking_counter_test", >+ size = "small", >+ srcs = ["blocking_counter_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":synchronization", >+ "//absl/time", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "graphcycles_test", >+ size = "medium", >+ srcs = ["internal/graphcycles_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":graphcycles_internal", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "graphcycles_benchmark", >+ srcs = ["internal/graphcycles_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = [ >+ "benchmark", >+ ], >+ deps = [ >+ ":graphcycles_internal", >+ "//absl/base", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_library( >+ name = "thread_pool", >+ testonly = 1, >+ hdrs = ["internal/thread_pool.h"], >+ deps = [ >+ ":synchronization", >+ "//absl/base:core_headers", >+ ], >+) >+ >+cc_test( >+ name = "mutex_test", >+ size = "large", >+ srcs = ["mutex_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":synchronization", >+ ":thread_pool", >+ "//absl/base", >+ "//absl/base:core_headers", >+ "//absl/memory", >+ "//absl/time", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "mutex_benchmark", >+ srcs = ["mutex_benchmark.cc"], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ visibility = ["//visibility:private"], >+ deps = [ >+ ":synchronization", >+ ":thread_pool", >+ "//absl/base", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "notification_test", >+ size = "small", >+ srcs = ["notification_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":synchronization", >+ "//absl/time", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_library( >+ name = "per_thread_sem_test_common", >+ testonly = 1, >+ srcs = ["internal/per_thread_sem_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":synchronization", >+ "//absl/base", >+ "//absl/strings", >+ "//absl/time", >+ "@com_google_googletest//:gtest", >+ ], >+ alwayslink = 1, >+) >+ >+cc_test( >+ name = "per_thread_sem_test", >+ size = "medium", >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":per_thread_sem_test_common", >+ ":synchronization", >+ "//absl/base", >+ "//absl/strings", >+ "//absl/time", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "lifetime_test", >+ srcs = [ >+ "lifetime_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ linkopts = select({ >+ "//absl:windows": [], >+ "//conditions:default": ["-pthread"], >+ }), >+ tags = ["no_test_ios_x86_64"], >+ deps = [ >+ ":synchronization", >+ "//absl/base", >+ "//absl/base:core_headers", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..3664aa13274f4040f9369b95f40deef2b590db8f >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/BUILD.gn >@@ -0,0 +1,116 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("graphcycles_internal") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/graphcycles.cc", >+ ] >+ public = [ >+ "internal/graphcycles.h", >+ ] >+ deps = [ >+ "../base", >+ "../base:base_internal", >+ "../base:core_headers", >+ "../base:malloc_internal", >+ ] >+ visibility = [] >+ visibility += [ "../*" ] >+} >+ >+source_set("synchronization") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "barrier.cc", >+ "blocking_counter.cc", >+ "internal/create_thread_identity.cc", >+ "internal/per_thread_sem.cc", >+ "internal/waiter.cc", >+ "notification.cc", >+ "mutex.cc" >+ ] >+ public = [ >+ "barrier.h", >+ "blocking_counter.h", >+ "internal/create_thread_identity.h", >+ "internal/kernel_timeout.h", >+ "internal/mutex_nonprod.inc", >+ "internal/per_thread_sem.h", >+ "internal/waiter.h", >+ "mutex.h", >+ "notification.h", >+ ] >+ deps = [ >+ ":graphcycles_internal", >+ "../base", >+ "../base:base_internal", >+ "../base:config", >+ "../base:core_headers", >+ "../base:dynamic_annotations", >+ "../base:malloc_internal", >+ "../debugging:stacktrace", >+ "../debugging:symbolize", >+ "../time", >+ ] >+} >+ >+source_set("thread_pool") { >+ testonly = true >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "internal/thread_pool.h", >+ ] >+ deps = [ >+ ":synchronization", >+ "../base:core_headers", >+ ] >+} >+ >+source_set("per_thread_sem_test_common") { >+ testonly = true >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_test_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/per_thread_sem_test.cc", >+ ] >+ deps = [ >+ ":synchronization", >+ "../base", >+ "../strings", >+ "../time", >+ "//testing/gtest", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..de0d7b7d45007c07a33663c96498e6f390107f09 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt >@@ -0,0 +1,155 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+list(APPEND SYNCHRONIZATION_PUBLIC_HEADERS >+ "barrier.h" >+ "blocking_counter.h" >+ "mutex.h" >+ "notification.h" >+) >+ >+ >+list(APPEND SYNCHRONIZATION_INTERNAL_HEADERS >+ "internal/create_thread_identity.h" >+ "internal/graphcycles.h" >+ "internal/kernel_timeout.h" >+ "internal/per_thread_sem.h" >+ "internal/thread_pool.h" >+ "internal/waiter.h" >+) >+ >+ >+ >+# synchronization library >+list(APPEND SYNCHRONIZATION_SRC >+ "barrier.cc" >+ "blocking_counter.cc" >+ "internal/create_thread_identity.cc" >+ "internal/per_thread_sem.cc" >+ "internal/waiter.cc" >+ "internal/graphcycles.cc" >+ "notification.cc" >+ "mutex.cc" >+) >+ >+set(SYNCHRONIZATION_PUBLIC_LIBRARIES absl::base absl::stacktrace absl::symbolize absl::time) >+ >+absl_library( >+ TARGET >+ absl_synchronization >+ SOURCES >+ ${SYNCHRONIZATION_SRC} >+ PUBLIC_LIBRARIES >+ ${SYNCHRONIZATION_PUBLIC_LIBRARIES} >+ EXPORT_NAME >+ synchronization >+) >+ >+ >+# >+## TESTS >+# >+ >+ >+# test barrier_test >+set(BARRIER_TEST_SRC "barrier_test.cc") >+set(BARRIER_TEST_PUBLIC_LIBRARIES absl::synchronization) >+ >+absl_test( >+ TARGET >+ barrier_test >+ SOURCES >+ ${BARRIER_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${BARRIER_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test blocking_counter_test >+set(BLOCKING_COUNTER_TEST_SRC "blocking_counter_test.cc") >+set(BLOCKING_COUNTER_TEST_PUBLIC_LIBRARIES absl::synchronization) >+ >+absl_test( >+ TARGET >+ blocking_counter_test >+ SOURCES >+ ${BLOCKING_COUNTER_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${BLOCKING_COUNTER_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test graphcycles_test >+set(GRAPHCYCLES_TEST_SRC "internal/graphcycles_test.cc") >+set(GRAPHCYCLES_TEST_PUBLIC_LIBRARIES absl::synchronization) >+ >+absl_test( >+ TARGET >+ graphcycles_test >+ SOURCES >+ ${GRAPHCYCLES_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${GRAPHCYCLES_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test mutex_test >+set(MUTEX_TEST_SRC "mutex_test.cc") >+set(MUTEX_TEST_PUBLIC_LIBRARIES absl::synchronization) >+ >+absl_test( >+ TARGET >+ mutex_test >+ SOURCES >+ ${MUTEX_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${MUTEX_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test notification_test >+set(NOTIFICATION_TEST_SRC "notification_test.cc") >+set(NOTIFICATION_TEST_PUBLIC_LIBRARIES absl::synchronization) >+ >+absl_test( >+ TARGET >+ notification_test >+ SOURCES >+ ${NOTIFICATION_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${NOTIFICATION_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test per_thread_sem_test_common >+set(PER_THREAD_SEM_TEST_COMMON_SRC "internal/per_thread_sem_test.cc") >+set(PER_THREAD_SEM_TEST_COMMON_PUBLIC_LIBRARIES absl::synchronization absl::strings) >+ >+absl_test( >+ TARGET >+ per_thread_sem_test_common >+ SOURCES >+ ${PER_THREAD_SEM_TEST_COMMON_SRC} >+ PUBLIC_LIBRARIES >+ ${PER_THREAD_SEM_TEST_COMMON_PUBLIC_LIBRARIES} >+) >+ >+ >+ >+ >+ >+ >+ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/barrier.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/barrier.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..a1b3ad5c21740b4eccd9aeaae152f688eec96be7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/barrier.cc >@@ -0,0 +1,50 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/barrier.h" >+ >+#include "absl/base/internal/raw_logging.h" >+#include "absl/synchronization/mutex.h" >+ >+namespace absl { >+ >+// Return whether int *arg is zero. >+static bool IsZero(void *arg) { >+ return 0 == *reinterpret_cast<int *>(arg); >+} >+ >+bool Barrier::Block() { >+ MutexLock l(&this->lock_); >+ >+ this->num_to_block_--; >+ if (this->num_to_block_ < 0) { >+ ABSL_RAW_LOG( >+ FATAL, >+ "Block() called too many times. num_to_block_=%d out of total=%d", >+ this->num_to_block_, this->num_to_exit_); >+ } >+ >+ this->lock_.Await(Condition(IsZero, &this->num_to_block_)); >+ >+ // Determine which thread can safely delete this Barrier object >+ this->num_to_exit_--; >+ ABSL_RAW_CHECK(this->num_to_exit_ >= 0, "barrier underflow"); >+ >+ // If num_to_exit_ == 0 then all other threads in the barrier have >+ // exited the Wait() and have released the Mutex so this thread is >+ // free to delete the barrier. >+ return this->num_to_exit_ == 0; >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/barrier.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/barrier.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f834feec11dcbbbc23288167382d41a4ac7a8faf >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/barrier.h >@@ -0,0 +1,77 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// barrier.h >+// ----------------------------------------------------------------------------- >+ >+#ifndef ABSL_SYNCHRONIZATION_BARRIER_H_ >+#define ABSL_SYNCHRONIZATION_BARRIER_H_ >+ >+#include "absl/base/thread_annotations.h" >+#include "absl/synchronization/mutex.h" >+ >+namespace absl { >+ >+// Barrier >+// >+// This class creates a barrier which blocks threads until a prespecified >+// threshold of threads (`num_threads`) utilizes the barrier. A thread utilizes >+// the `Barrier` by calling `Block()` on the barrier, which will block that >+// thread; no call to `Block()` will return until `num_threads` threads have >+// called it. >+// >+// Exactly one call to `Block()` will return `true`, which is then responsible >+// for destroying the barrier; because stack allocation will cause the barrier >+// to be deleted when it is out of scope, barriers should not be stack >+// allocated. >+// >+// Example: >+// >+// // Main thread creates a `Barrier`: >+// barrier = new Barrier(num_threads); >+// >+// // Each participating thread could then call: >+// if (barrier->Block()) delete barrier; // Exactly one call to `Block()` >+// // returns `true`; that call >+// // deletes the barrier. >+class Barrier { >+ public: >+ // `num_threads` is the number of threads that will participate in the barrier >+ explicit Barrier(int num_threads) >+ : num_to_block_(num_threads), num_to_exit_(num_threads) {} >+ >+ Barrier(const Barrier&) = delete; >+ Barrier& operator=(const Barrier&) = delete; >+ >+ // Barrier::Block() >+ // >+ // Blocks the current thread, and returns only when the `num_threads` >+ // threshold of threads utilizing this barrier has been reached. `Block()` >+ // returns `true` for precisely one caller, which may then destroy the >+ // barrier. >+ // >+ // Memory ordering: For any threads X and Y, any action taken by X >+ // before X calls `Block()` will be visible to Y after Y returns from >+ // `Block()`. >+ bool Block(); >+ >+ private: >+ Mutex lock_; >+ int num_to_block_ GUARDED_BY(lock_); >+ int num_to_exit_ GUARDED_BY(lock_); >+}; >+ >+} // namespace absl >+#endif // ABSL_SYNCHRONIZATION_BARRIER_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/barrier_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/barrier_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..d6cababdf73315f2616e813c4f18f91c67bc360b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/barrier_test.cc >@@ -0,0 +1,75 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/barrier.h" >+ >+#include <thread> // NOLINT(build/c++11) >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/synchronization/mutex.h" >+#include "absl/time/clock.h" >+ >+ >+TEST(Barrier, SanityTest) { >+ constexpr int kNumThreads = 10; >+ absl::Barrier* barrier = new absl::Barrier(kNumThreads); >+ >+ absl::Mutex mutex; >+ int counter = 0; // Guarded by mutex. >+ >+ auto thread_func = [&] { >+ if (barrier->Block()) { >+ // This thread is the last thread to reach the barrier so it is >+ // responsible for deleting it. >+ delete barrier; >+ } >+ >+ // Increment the counter. >+ absl::MutexLock lock(&mutex); >+ ++counter; >+ }; >+ >+ // Start (kNumThreads - 1) threads running thread_func. >+ std::vector<std::thread> threads; >+ for (int i = 0; i < kNumThreads - 1; ++i) { >+ threads.push_back(std::thread(thread_func)); >+ } >+ >+ // Give (kNumThreads - 1) threads a chance to reach the barrier. >+ // This test assumes at least one thread will have run after the >+ // sleep has elapsed. Sleeping in a test is usually bad form, but we >+ // need to make sure that we are testing the barrier instead of some >+ // other synchronization method. >+ absl::SleepFor(absl::Seconds(1)); >+ >+ // The counter should still be zero since no thread should have >+ // been able to pass the barrier yet. >+ { >+ absl::MutexLock lock(&mutex); >+ EXPECT_EQ(counter, 0); >+ } >+ >+ // Start 1 more thread. This should make all threads pass the barrier. >+ threads.push_back(std::thread(thread_func)); >+ >+ // All threads should now be able to proceed and finish. >+ for (auto& thread : threads) { >+ thread.join(); >+ } >+ >+ // All threads should now have incremented the counter. >+ absl::MutexLock lock(&mutex); >+ EXPECT_EQ(counter, kNumThreads); >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..7e68e960bc3ad407e2b92fe0419791f56b768d97 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc >@@ -0,0 +1,55 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/blocking_counter.h" >+ >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+ >+// Return whether int *arg is zero. >+static bool IsZero(void *arg) { >+ return 0 == *reinterpret_cast<int *>(arg); >+} >+ >+bool BlockingCounter::DecrementCount() { >+ MutexLock l(&lock_); >+ count_--; >+ if (count_ < 0) { >+ ABSL_RAW_LOG( >+ FATAL, >+ "BlockingCounter::DecrementCount() called too many times. count=%d", >+ count_); >+ } >+ return count_ == 0; >+} >+ >+void BlockingCounter::Wait() { >+ MutexLock l(&this->lock_); >+ ABSL_RAW_CHECK(count_ >= 0, "BlockingCounter underflow"); >+ >+ // only one thread may call Wait(). To support more than one thread, >+ // implement a counter num_to_exit, like in the Barrier class. >+ ABSL_RAW_CHECK(num_waiting_ == 0, "multiple threads called Wait()"); >+ num_waiting_++; >+ >+ this->lock_.Await(Condition(IsZero, &this->count_)); >+ >+ // At this point, We know that all threads executing DecrementCount have >+ // released the lock, and so will not touch this object again. >+ // Therefore, the thread calling this method is free to delete the object >+ // after we return from this method. >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/blocking_counter.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/blocking_counter.h >new file mode 100644 >index 0000000000000000000000000000000000000000..557ed028fe5223c9cc25a02ece5a6c5f563d9cab >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/blocking_counter.h >@@ -0,0 +1,97 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// blocking_counter.h >+// ----------------------------------------------------------------------------- >+ >+#ifndef ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_ >+#define ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_ >+ >+#include "absl/base/thread_annotations.h" >+#include "absl/synchronization/mutex.h" >+ >+namespace absl { >+ >+// BlockingCounter >+// >+// This class allows a thread to block for a pre-specified number of actions. >+// `BlockingCounter` maintains a single non-negative abstract integer "count" >+// with an initial value `initial_count`. A thread can then call `Wait()` on >+// this blocking counter to block until the specified number of events occur; >+// worker threads then call 'DecrementCount()` on the counter upon completion of >+// their work. Once the counter's internal "count" reaches zero, the blocked >+// thread unblocks. >+// >+// A `BlockingCounter` requires the following: >+// - its `initial_count` is non-negative. >+// - the number of calls to `DecrementCount()` on it is at most >+// `initial_count`. >+// - `Wait()` is called at most once on it. >+// >+// Given the above requirements, a `BlockingCounter` provides the following >+// guarantees: >+// - Once its internal "count" reaches zero, no legal action on the object >+// can further change the value of "count". >+// - When `Wait()` returns, it is legal to destroy the `BlockingCounter`. >+// - When `Wait()` returns, the number of calls to `DecrementCount()` on >+// this blocking counter exactly equals `initial_count`. >+// >+// Example: >+// BlockingCounter bcount(N); // there are N items of work >+// ... Allow worker threads to start. >+// ... On completing each work item, workers do: >+// ... bcount.DecrementCount(); // an item of work has been completed >+// >+// bcount.Wait(); // wait for all work to be complete >+// >+class BlockingCounter { >+ public: >+ explicit BlockingCounter(int initial_count) >+ : count_(initial_count), num_waiting_(0) {} >+ >+ BlockingCounter(const BlockingCounter&) = delete; >+ BlockingCounter& operator=(const BlockingCounter&) = delete; >+ >+ // BlockingCounter::DecrementCount() >+ // >+ // Decrements the counter's "count" by one, and return "count == 0". This >+ // function requires that "count != 0" when it is called. >+ // >+ // Memory ordering: For any threads X and Y, any action taken by X >+ // before it calls `DecrementCount()` is visible to thread Y after >+ // Y's call to `DecrementCount()`, provided Y's call returns `true`. >+ bool DecrementCount(); >+ >+ // BlockingCounter::Wait() >+ // >+ // Blocks until the counter reaches zero. This function may be called at most >+ // once. On return, `DecrementCount()` will have been called "initial_count" >+ // times and the blocking counter may be destroyed. >+ // >+ // Memory ordering: For any threads X and Y, any action taken by X >+ // before X calls `DecrementCount()` is visible to Y after Y returns >+ // from `Wait()`. >+ void Wait(); >+ >+ private: >+ Mutex lock_; >+ int count_ GUARDED_BY(lock_); >+ int num_waiting_ GUARDED_BY(lock_); >+}; >+ >+} // namespace absl >+ >+#endif // ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/blocking_counter_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/blocking_counter_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e8223f841a5f07c9334d12835e5c1d6968464215 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/blocking_counter_test.cc >@@ -0,0 +1,66 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/blocking_counter.h" >+ >+#include <thread> // NOLINT(build/c++11) >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/time/clock.h" >+#include "absl/time/time.h" >+ >+namespace absl { >+namespace { >+ >+void PauseAndDecreaseCounter(BlockingCounter* counter, int* done) { >+ absl::SleepFor(absl::Seconds(1)); >+ *done = 1; >+ counter->DecrementCount(); >+} >+ >+TEST(BlockingCounterTest, BasicFunctionality) { >+ // This test verifies that BlockingCounter functions correctly. Starts a >+ // number of threads that just sleep for a second and decrement a counter. >+ >+ // Initialize the counter. >+ const int num_workers = 10; >+ BlockingCounter counter(num_workers); >+ >+ std::vector<std::thread> workers; >+ std::vector<int> done(num_workers, 0); >+ >+ // Start a number of parallel tasks that will just wait for a seconds and >+ // then decrement the count. >+ workers.reserve(num_workers); >+ for (int k = 0; k < num_workers; k++) { >+ workers.emplace_back( >+ [&counter, &done, k] { PauseAndDecreaseCounter(&counter, &done[k]); }); >+ } >+ >+ // Wait for the threads to have all finished. >+ counter.Wait(); >+ >+ // Check that all the workers have completed. >+ for (int k = 0; k < num_workers; k++) { >+ EXPECT_EQ(1, done[k]); >+ } >+ >+ for (std::thread& w : workers) { >+ w.join(); >+ } >+} >+ >+} // namespace >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e7a65cd884a1d26cb97479a085bbf883095c5ee8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc >@@ -0,0 +1,112 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <stdint.h> >+#include <new> >+ >+// This file is a no-op if the required LowLevelAlloc support is missing. >+#include "absl/base/internal/low_level_alloc.h" >+#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING >+ >+#include <string.h> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/internal/spinlock.h" >+#include "absl/base/internal/thread_identity.h" >+#include "absl/synchronization/internal/per_thread_sem.h" >+ >+namespace absl { >+namespace synchronization_internal { >+ >+// ThreadIdentity storage is persistent, we maintain a free-list of previously >+// released ThreadIdentity objects. >+static base_internal::SpinLock freelist_lock(base_internal::kLinkerInitialized); >+static base_internal::ThreadIdentity* thread_identity_freelist; >+ >+// A per-thread destructor for reclaiming associated ThreadIdentity objects. >+// Since we must preserve their storage we cache them for re-use. >+static void ReclaimThreadIdentity(void* v) { >+ base_internal::ThreadIdentity* identity = >+ static_cast<base_internal::ThreadIdentity*>(v); >+ >+ // all_locks might have been allocated by the Mutex implementation. >+ // We free it here when we are notified that our thread is dying. >+ if (identity->per_thread_synch.all_locks != nullptr) { >+ base_internal::LowLevelAlloc::Free(identity->per_thread_synch.all_locks); >+ } >+ >+ // We must explicitly clear the current thread's identity: >+ // (a) Subsequent (unrelated) per-thread destructors may require an identity. >+ // We must guarantee a new identity is used in this case (this instructor >+ // will be reinvoked up to PTHREAD_DESTRUCTOR_ITERATIONS in this case). >+ // (b) ThreadIdentity implementations may depend on memory that is not >+ // reinitialized before reuse. We must allow explicit clearing of the >+ // association state in this case. >+ base_internal::ClearCurrentThreadIdentity(); >+ { >+ base_internal::SpinLockHolder l(&freelist_lock); >+ identity->next = thread_identity_freelist; >+ thread_identity_freelist = identity; >+ } >+} >+ >+// Return value rounded up to next multiple of align. >+// Align must be a power of two. >+static intptr_t RoundUp(intptr_t addr, intptr_t align) { >+ return (addr + align - 1) & ~(align - 1); >+} >+ >+static base_internal::ThreadIdentity* NewThreadIdentity() { >+ base_internal::ThreadIdentity* identity = nullptr; >+ >+ { >+ // Re-use a previously released object if possible. >+ base_internal::SpinLockHolder l(&freelist_lock); >+ if (thread_identity_freelist) { >+ identity = thread_identity_freelist; // Take list-head. >+ thread_identity_freelist = thread_identity_freelist->next; >+ } >+ } >+ >+ if (identity == nullptr) { >+ // Allocate enough space to align ThreadIdentity to a multiple of >+ // PerThreadSynch::kAlignment. This space is never released (it is >+ // added to a freelist by ReclaimThreadIdentity instead). >+ void* allocation = base_internal::LowLevelAlloc::Alloc( >+ sizeof(*identity) + base_internal::PerThreadSynch::kAlignment - 1); >+ // Round up the address to the required alignment. >+ identity = reinterpret_cast<base_internal::ThreadIdentity*>( >+ RoundUp(reinterpret_cast<intptr_t>(allocation), >+ base_internal::PerThreadSynch::kAlignment)); >+ } >+ memset(identity, 0, sizeof(*identity)); >+ >+ return identity; >+} >+ >+// Allocates and attaches ThreadIdentity object for the calling thread. Returns >+// the new identity. >+// REQUIRES: CurrentThreadIdentity(false) == nullptr >+base_internal::ThreadIdentity* CreateThreadIdentity() { >+ base_internal::ThreadIdentity* identity = NewThreadIdentity(); >+ PerThreadSem::Init(identity); >+ // Associate the value with the current thread, and attach our destructor. >+ base_internal::SetCurrentThreadIdentity(identity, ReclaimThreadIdentity); >+ return identity; >+} >+ >+} // namespace synchronization_internal >+} // namespace absl >+ >+#endif // ABSL_LOW_LEVEL_ALLOC_MISSING >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.h >new file mode 100644 >index 0000000000000000000000000000000000000000..1bb87dee630724980e87c3563c1e03b83dacdf59 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.h >@@ -0,0 +1,53 @@ >+/* >+ * Copyright 2017 The Abseil Authors. >+ * >+ * Licensed under the Apache License, Version 2.0 (the "License"); >+ * you may not use this file except in compliance with the License. >+ * You may obtain a copy of the License at >+ * >+ * http://www.apache.org/licenses/LICENSE-2.0 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+ >+// Interface for getting the current ThreadIdentity, creating one if necessary. >+// See thread_identity.h. >+// >+// This file is separate from thread_identity.h because creating a new >+// ThreadIdentity requires slightly higher level libraries (per_thread_sem >+// and low_level_alloc) than accessing an existing one. This separation allows >+// us to have a smaller //absl/base:base. >+ >+#ifndef ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_ >+#define ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_ >+ >+#include "absl/base/internal/thread_identity.h" >+#include "absl/base/port.h" >+ >+namespace absl { >+namespace synchronization_internal { >+ >+// Allocates and attaches a ThreadIdentity object for the calling thread. >+// For private use only. >+base_internal::ThreadIdentity* CreateThreadIdentity(); >+ >+// Returns the ThreadIdentity object representing the calling thread; guaranteed >+// to be unique for its lifetime. The returned object will remain valid for the >+// program's lifetime; although it may be re-assigned to a subsequent thread. >+// If one does not exist for the calling thread, allocate it now. >+inline base_internal::ThreadIdentity* GetOrCreateCurrentThreadIdentity() { >+ base_internal::ThreadIdentity* identity = >+ base_internal::CurrentThreadIdentityIfPresent(); >+ if (ABSL_PREDICT_FALSE(identity == nullptr)) { >+ return CreateThreadIdentity(); >+ } >+ return identity; >+} >+ >+} // namespace synchronization_internal >+} // namespace absl >+#endif // ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..ab1f3f84e74c1d7edef6379e02684b00b53a7e34 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc >@@ -0,0 +1,699 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// GraphCycles provides incremental cycle detection on a dynamic >+// graph using the following algorithm: >+// >+// A dynamic topological sort algorithm for directed acyclic graphs >+// David J. Pearce, Paul H. J. Kelly >+// Journal of Experimental Algorithmics (JEA) JEA Homepage archive >+// Volume 11, 2006, Article No. 1.7 >+// >+// Brief summary of the algorithm: >+// >+// (1) Maintain a rank for each node that is consistent >+// with the topological sort of the graph. I.e., path from x to y >+// implies rank[x] < rank[y]. >+// (2) When a new edge (x->y) is inserted, do nothing if rank[x] < rank[y]. >+// (3) Otherwise: adjust ranks in the neighborhood of x and y. >+ >+#include "absl/base/attributes.h" >+// This file is a no-op if the required LowLevelAlloc support is missing. >+#include "absl/base/internal/low_level_alloc.h" >+#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING >+ >+#include "absl/synchronization/internal/graphcycles.h" >+ >+#include <algorithm> >+#include <array> >+#include "absl/base/internal/hide_ptr.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/spinlock.h" >+ >+// Do not use STL. This module does not use standard memory allocation. >+ >+namespace absl { >+namespace synchronization_internal { >+ >+namespace { >+ >+// Avoid LowLevelAlloc's default arena since it calls malloc hooks in >+// which people are doing things like acquiring Mutexes. >+static absl::base_internal::SpinLock arena_mu( >+ absl::base_internal::kLinkerInitialized); >+static base_internal::LowLevelAlloc::Arena* arena; >+ >+static void InitArenaIfNecessary() { >+ arena_mu.Lock(); >+ if (arena == nullptr) { >+ arena = base_internal::LowLevelAlloc::NewArena(0); >+ } >+ arena_mu.Unlock(); >+} >+ >+// Number of inlined elements in Vec. Hash table implementation >+// relies on this being a power of two. >+static const uint32_t kInline = 8; >+ >+// A simple LowLevelAlloc based resizable vector with inlined storage >+// for a few elements. T must be a plain type since constructor >+// and destructor are not run on elements of type T managed by Vec. >+template <typename T> >+class Vec { >+ public: >+ Vec() { Init(); } >+ ~Vec() { Discard(); } >+ >+ void clear() { >+ Discard(); >+ Init(); >+ } >+ >+ bool empty() const { return size_ == 0; } >+ uint32_t size() const { return size_; } >+ T* begin() { return ptr_; } >+ T* end() { return ptr_ + size_; } >+ const T& operator[](uint32_t i) const { return ptr_[i]; } >+ T& operator[](uint32_t i) { return ptr_[i]; } >+ const T& back() const { return ptr_[size_-1]; } >+ void pop_back() { size_--; } >+ >+ void push_back(const T& v) { >+ if (size_ == capacity_) Grow(size_ + 1); >+ ptr_[size_] = v; >+ size_++; >+ } >+ >+ void resize(uint32_t n) { >+ if (n > capacity_) Grow(n); >+ size_ = n; >+ } >+ >+ void fill(const T& val) { >+ for (uint32_t i = 0; i < size(); i++) { >+ ptr_[i] = val; >+ } >+ } >+ >+ // Guarantees src is empty at end. >+ // Provided for the hash table resizing code below. >+ void MoveFrom(Vec<T>* src) { >+ if (src->ptr_ == src->space_) { >+ // Need to actually copy >+ resize(src->size_); >+ std::copy(src->ptr_, src->ptr_ + src->size_, ptr_); >+ src->size_ = 0; >+ } else { >+ Discard(); >+ ptr_ = src->ptr_; >+ size_ = src->size_; >+ capacity_ = src->capacity_; >+ src->Init(); >+ } >+ } >+ >+ private: >+ T* ptr_; >+ T space_[kInline]; >+ uint32_t size_; >+ uint32_t capacity_; >+ >+ void Init() { >+ ptr_ = space_; >+ size_ = 0; >+ capacity_ = kInline; >+ } >+ >+ void Discard() { >+ if (ptr_ != space_) base_internal::LowLevelAlloc::Free(ptr_); >+ } >+ >+ void Grow(uint32_t n) { >+ while (capacity_ < n) { >+ capacity_ *= 2; >+ } >+ size_t request = static_cast<size_t>(capacity_) * sizeof(T); >+ T* copy = static_cast<T*>( >+ base_internal::LowLevelAlloc::AllocWithArena(request, arena)); >+ std::copy(ptr_, ptr_ + size_, copy); >+ Discard(); >+ ptr_ = copy; >+ } >+ >+ Vec(const Vec&) = delete; >+ Vec& operator=(const Vec&) = delete; >+}; >+ >+// A hash set of non-negative int32_t that uses Vec for its underlying storage. >+class NodeSet { >+ public: >+ NodeSet() { Init(); } >+ >+ void clear() { Init(); } >+ bool contains(int32_t v) const { return table_[FindIndex(v)] == v; } >+ >+ bool insert(int32_t v) { >+ uint32_t i = FindIndex(v); >+ if (table_[i] == v) { >+ return false; >+ } >+ if (table_[i] == kEmpty) { >+ // Only inserting over an empty cell increases the number of occupied >+ // slots. >+ occupied_++; >+ } >+ table_[i] = v; >+ // Double when 75% full. >+ if (occupied_ >= table_.size() - table_.size()/4) Grow(); >+ return true; >+ } >+ >+ void erase(uint32_t v) { >+ uint32_t i = FindIndex(v); >+ if (static_cast<uint32_t>(table_[i]) == v) { >+ table_[i] = kDel; >+ } >+ } >+ >+ // Iteration: is done via HASH_FOR_EACH >+ // Example: >+ // HASH_FOR_EACH(elem, node->out) { ... } >+#define HASH_FOR_EACH(elem, eset) \ >+ for (int32_t elem, _cursor = 0; (eset).Next(&_cursor, &elem); ) >+ bool Next(int32_t* cursor, int32_t* elem) { >+ while (static_cast<uint32_t>(*cursor) < table_.size()) { >+ int32_t v = table_[*cursor]; >+ (*cursor)++; >+ if (v >= 0) { >+ *elem = v; >+ return true; >+ } >+ } >+ return false; >+ } >+ >+ private: >+ static const int32_t kEmpty; >+ static const int32_t kDel; >+ Vec<int32_t> table_; >+ uint32_t occupied_; // Count of non-empty slots (includes deleted slots) >+ >+ static uint32_t Hash(uint32_t a) { return a * 41; } >+ >+ // Return index for storing v. May return an empty index or deleted index >+ int FindIndex(int32_t v) const { >+ // Search starting at hash index. >+ const uint32_t mask = table_.size() - 1; >+ uint32_t i = Hash(v) & mask; >+ int deleted_index = -1; // If >= 0, index of first deleted element we see >+ while (true) { >+ int32_t e = table_[i]; >+ if (v == e) { >+ return i; >+ } else if (e == kEmpty) { >+ // Return any previously encountered deleted slot. >+ return (deleted_index >= 0) ? deleted_index : i; >+ } else if (e == kDel && deleted_index < 0) { >+ // Keep searching since v might be present later. >+ deleted_index = i; >+ } >+ i = (i + 1) & mask; // Linear probing; quadratic is slightly slower. >+ } >+ } >+ >+ void Init() { >+ table_.clear(); >+ table_.resize(kInline); >+ table_.fill(kEmpty); >+ occupied_ = 0; >+ } >+ >+ void Grow() { >+ Vec<int32_t> copy; >+ copy.MoveFrom(&table_); >+ occupied_ = 0; >+ table_.resize(copy.size() * 2); >+ table_.fill(kEmpty); >+ >+ for (const auto& e : copy) { >+ if (e >= 0) insert(e); >+ } >+ } >+ >+ NodeSet(const NodeSet&) = delete; >+ NodeSet& operator=(const NodeSet&) = delete; >+}; >+ >+const int32_t NodeSet::kEmpty = -1; >+const int32_t NodeSet::kDel = -2; >+ >+// We encode a node index and a node version in GraphId. The version >+// number is incremented when the GraphId is freed which automatically >+// invalidates all copies of the GraphId. >+ >+inline GraphId MakeId(int32_t index, uint32_t version) { >+ GraphId g; >+ g.handle = >+ (static_cast<uint64_t>(version) << 32) | static_cast<uint32_t>(index); >+ return g; >+} >+ >+inline int32_t NodeIndex(GraphId id) { >+ return static_cast<uint32_t>(id.handle & 0xfffffffful); >+} >+ >+inline uint32_t NodeVersion(GraphId id) { >+ return static_cast<uint32_t>(id.handle >> 32); >+} >+ >+struct Node { >+ int32_t rank; // rank number assigned by Pearce-Kelly algorithm >+ uint32_t version; // Current version number >+ int32_t next_hash; // Next entry in hash table >+ bool visited; // Temporary marker used by depth-first-search >+ uintptr_t masked_ptr; // User-supplied pointer >+ NodeSet in; // List of immediate predecessor nodes in graph >+ NodeSet out; // List of immediate successor nodes in graph >+ int priority; // Priority of recorded stack trace. >+ int nstack; // Depth of recorded stack trace. >+ void* stack[40]; // stack[0,nstack-1] holds stack trace for node. >+}; >+ >+// Hash table for pointer to node index lookups. >+class PointerMap { >+ public: >+ explicit PointerMap(const Vec<Node*>* nodes) : nodes_(nodes) { >+ table_.fill(-1); >+ } >+ >+ int32_t Find(void* ptr) { >+ auto masked = base_internal::HidePtr(ptr); >+ for (int32_t i = table_[Hash(ptr)]; i != -1;) { >+ Node* n = (*nodes_)[i]; >+ if (n->masked_ptr == masked) return i; >+ i = n->next_hash; >+ } >+ return -1; >+ } >+ >+ void Add(void* ptr, int32_t i) { >+ int32_t* head = &table_[Hash(ptr)]; >+ (*nodes_)[i]->next_hash = *head; >+ *head = i; >+ } >+ >+ int32_t Remove(void* ptr) { >+ // Advance through linked list while keeping track of the >+ // predecessor slot that points to the current entry. >+ auto masked = base_internal::HidePtr(ptr); >+ for (int32_t* slot = &table_[Hash(ptr)]; *slot != -1; ) { >+ int32_t index = *slot; >+ Node* n = (*nodes_)[index]; >+ if (n->masked_ptr == masked) { >+ *slot = n->next_hash; // Remove n from linked list >+ n->next_hash = -1; >+ return index; >+ } >+ slot = &n->next_hash; >+ } >+ return -1; >+ } >+ >+ private: >+ // Number of buckets in hash table for pointer lookups. >+ static constexpr uint32_t kHashTableSize = 8171; // should be prime >+ >+ const Vec<Node*>* nodes_; >+ std::array<int32_t, kHashTableSize> table_; >+ >+ static uint32_t Hash(void* ptr) { >+ return reinterpret_cast<uintptr_t>(ptr) % kHashTableSize; >+ } >+}; >+ >+} // namespace >+ >+struct GraphCycles::Rep { >+ Vec<Node*> nodes_; >+ Vec<int32_t> free_nodes_; // Indices for unused entries in nodes_ >+ PointerMap ptrmap_; >+ >+ // Temporary state. >+ Vec<int32_t> deltaf_; // Results of forward DFS >+ Vec<int32_t> deltab_; // Results of backward DFS >+ Vec<int32_t> list_; // All nodes to reprocess >+ Vec<int32_t> merged_; // Rank values to assign to list_ entries >+ Vec<int32_t> stack_; // Emulates recursion stack for depth-first searches >+ >+ Rep() : ptrmap_(&nodes_) {} >+}; >+ >+static Node* FindNode(GraphCycles::Rep* rep, GraphId id) { >+ Node* n = rep->nodes_[NodeIndex(id)]; >+ return (n->version == NodeVersion(id)) ? n : nullptr; >+} >+ >+GraphCycles::GraphCycles() { >+ InitArenaIfNecessary(); >+ rep_ = new (base_internal::LowLevelAlloc::AllocWithArena(sizeof(Rep), arena)) >+ Rep; >+} >+ >+GraphCycles::~GraphCycles() { >+ for (auto* node : rep_->nodes_) { >+ node->Node::~Node(); >+ base_internal::LowLevelAlloc::Free(node); >+ } >+ rep_->Rep::~Rep(); >+ base_internal::LowLevelAlloc::Free(rep_); >+} >+ >+bool GraphCycles::CheckInvariants() const { >+ Rep* r = rep_; >+ NodeSet ranks; // Set of ranks seen so far. >+ for (uint32_t x = 0; x < r->nodes_.size(); x++) { >+ Node* nx = r->nodes_[x]; >+ void* ptr = base_internal::UnhidePtr<void>(nx->masked_ptr); >+ if (ptr != nullptr && static_cast<uint32_t>(r->ptrmap_.Find(ptr)) != x) { >+ ABSL_RAW_LOG(FATAL, "Did not find live node in hash table %u %p", x, ptr); >+ } >+ if (nx->visited) { >+ ABSL_RAW_LOG(FATAL, "Did not clear visited marker on node %u", x); >+ } >+ if (!ranks.insert(nx->rank)) { >+ ABSL_RAW_LOG(FATAL, "Duplicate occurrence of rank %d", nx->rank); >+ } >+ HASH_FOR_EACH(y, nx->out) { >+ Node* ny = r->nodes_[y]; >+ if (nx->rank >= ny->rank) { >+ ABSL_RAW_LOG(FATAL, "Edge %u->%d has bad rank assignment %d->%d", x, y, >+ nx->rank, ny->rank); >+ } >+ } >+ } >+ return true; >+} >+ >+GraphId GraphCycles::GetId(void* ptr) { >+ int32_t i = rep_->ptrmap_.Find(ptr); >+ if (i != -1) { >+ return MakeId(i, rep_->nodes_[i]->version); >+ } else if (rep_->free_nodes_.empty()) { >+ Node* n = >+ new (base_internal::LowLevelAlloc::AllocWithArena(sizeof(Node), arena)) >+ Node; >+ n->version = 1; // Avoid 0 since it is used by InvalidGraphId() >+ n->visited = false; >+ n->rank = rep_->nodes_.size(); >+ n->masked_ptr = base_internal::HidePtr(ptr); >+ n->nstack = 0; >+ n->priority = 0; >+ rep_->nodes_.push_back(n); >+ rep_->ptrmap_.Add(ptr, n->rank); >+ return MakeId(n->rank, n->version); >+ } else { >+ // Preserve preceding rank since the set of ranks in use must be >+ // a permutation of [0,rep_->nodes_.size()-1]. >+ int32_t r = rep_->free_nodes_.back(); >+ rep_->free_nodes_.pop_back(); >+ Node* n = rep_->nodes_[r]; >+ n->masked_ptr = base_internal::HidePtr(ptr); >+ n->nstack = 0; >+ n->priority = 0; >+ rep_->ptrmap_.Add(ptr, r); >+ return MakeId(r, n->version); >+ } >+} >+ >+void GraphCycles::RemoveNode(void* ptr) { >+ int32_t i = rep_->ptrmap_.Remove(ptr); >+ if (i == -1) { >+ return; >+ } >+ Node* x = rep_->nodes_[i]; >+ HASH_FOR_EACH(y, x->out) { >+ rep_->nodes_[y]->in.erase(i); >+ } >+ HASH_FOR_EACH(y, x->in) { >+ rep_->nodes_[y]->out.erase(i); >+ } >+ x->in.clear(); >+ x->out.clear(); >+ x->masked_ptr = base_internal::HidePtr<void>(nullptr); >+ if (x->version == std::numeric_limits<uint32_t>::max()) { >+ // Cannot use x any more >+ } else { >+ x->version++; // Invalidates all copies of node. >+ rep_->free_nodes_.push_back(i); >+ } >+} >+ >+void* GraphCycles::Ptr(GraphId id) { >+ Node* n = FindNode(rep_, id); >+ return n == nullptr ? nullptr >+ : base_internal::UnhidePtr<void>(n->masked_ptr); >+} >+ >+bool GraphCycles::HasNode(GraphId node) { >+ return FindNode(rep_, node) != nullptr; >+} >+ >+bool GraphCycles::HasEdge(GraphId x, GraphId y) const { >+ Node* xn = FindNode(rep_, x); >+ return xn && FindNode(rep_, y) && xn->out.contains(NodeIndex(y)); >+} >+ >+void GraphCycles::RemoveEdge(GraphId x, GraphId y) { >+ Node* xn = FindNode(rep_, x); >+ Node* yn = FindNode(rep_, y); >+ if (xn && yn) { >+ xn->out.erase(NodeIndex(y)); >+ yn->in.erase(NodeIndex(x)); >+ // No need to update the rank assignment since a previous valid >+ // rank assignment remains valid after an edge deletion. >+ } >+} >+ >+static bool ForwardDFS(GraphCycles::Rep* r, int32_t n, int32_t upper_bound); >+static void BackwardDFS(GraphCycles::Rep* r, int32_t n, int32_t lower_bound); >+static void Reorder(GraphCycles::Rep* r); >+static void Sort(const Vec<Node*>&, Vec<int32_t>* delta); >+static void MoveToList( >+ GraphCycles::Rep* r, Vec<int32_t>* src, Vec<int32_t>* dst); >+ >+bool GraphCycles::InsertEdge(GraphId idx, GraphId idy) { >+ Rep* r = rep_; >+ const int32_t x = NodeIndex(idx); >+ const int32_t y = NodeIndex(idy); >+ Node* nx = FindNode(r, idx); >+ Node* ny = FindNode(r, idy); >+ if (nx == nullptr || ny == nullptr) return true; // Expired ids >+ >+ if (nx == ny) return false; // Self edge >+ if (!nx->out.insert(y)) { >+ // Edge already exists. >+ return true; >+ } >+ >+ ny->in.insert(x); >+ >+ if (nx->rank <= ny->rank) { >+ // New edge is consistent with existing rank assignment. >+ return true; >+ } >+ >+ // Current rank assignments are incompatible with the new edge. Recompute. >+ // We only need to consider nodes that fall in the range [ny->rank,nx->rank]. >+ if (!ForwardDFS(r, y, nx->rank)) { >+ // Found a cycle. Undo the insertion and tell caller. >+ nx->out.erase(y); >+ ny->in.erase(x); >+ // Since we do not call Reorder() on this path, clear any visited >+ // markers left by ForwardDFS. >+ for (const auto& d : r->deltaf_) { >+ r->nodes_[d]->visited = false; >+ } >+ return false; >+ } >+ BackwardDFS(r, x, ny->rank); >+ Reorder(r); >+ return true; >+} >+ >+static bool ForwardDFS(GraphCycles::Rep* r, int32_t n, int32_t upper_bound) { >+ // Avoid recursion since stack space might be limited. >+ // We instead keep a stack of nodes to visit. >+ r->deltaf_.clear(); >+ r->stack_.clear(); >+ r->stack_.push_back(n); >+ while (!r->stack_.empty()) { >+ n = r->stack_.back(); >+ r->stack_.pop_back(); >+ Node* nn = r->nodes_[n]; >+ if (nn->visited) continue; >+ >+ nn->visited = true; >+ r->deltaf_.push_back(n); >+ >+ HASH_FOR_EACH(w, nn->out) { >+ Node* nw = r->nodes_[w]; >+ if (nw->rank == upper_bound) { >+ return false; // Cycle >+ } >+ if (!nw->visited && nw->rank < upper_bound) { >+ r->stack_.push_back(w); >+ } >+ } >+ } >+ return true; >+} >+ >+static void BackwardDFS(GraphCycles::Rep* r, int32_t n, int32_t lower_bound) { >+ r->deltab_.clear(); >+ r->stack_.clear(); >+ r->stack_.push_back(n); >+ while (!r->stack_.empty()) { >+ n = r->stack_.back(); >+ r->stack_.pop_back(); >+ Node* nn = r->nodes_[n]; >+ if (nn->visited) continue; >+ >+ nn->visited = true; >+ r->deltab_.push_back(n); >+ >+ HASH_FOR_EACH(w, nn->in) { >+ Node* nw = r->nodes_[w]; >+ if (!nw->visited && lower_bound < nw->rank) { >+ r->stack_.push_back(w); >+ } >+ } >+ } >+} >+ >+static void Reorder(GraphCycles::Rep* r) { >+ Sort(r->nodes_, &r->deltab_); >+ Sort(r->nodes_, &r->deltaf_); >+ >+ // Adds contents of delta lists to list_ (backwards deltas first). >+ r->list_.clear(); >+ MoveToList(r, &r->deltab_, &r->list_); >+ MoveToList(r, &r->deltaf_, &r->list_); >+ >+ // Produce sorted list of all ranks that will be reassigned. >+ r->merged_.resize(r->deltab_.size() + r->deltaf_.size()); >+ std::merge(r->deltab_.begin(), r->deltab_.end(), >+ r->deltaf_.begin(), r->deltaf_.end(), >+ r->merged_.begin()); >+ >+ // Assign the ranks in order to the collected list. >+ for (uint32_t i = 0; i < r->list_.size(); i++) { >+ r->nodes_[r->list_[i]]->rank = r->merged_[i]; >+ } >+} >+ >+static void Sort(const Vec<Node*>& nodes, Vec<int32_t>* delta) { >+ struct ByRank { >+ const Vec<Node*>* nodes; >+ bool operator()(int32_t a, int32_t b) const { >+ return (*nodes)[a]->rank < (*nodes)[b]->rank; >+ } >+ }; >+ ByRank cmp; >+ cmp.nodes = &nodes; >+ std::sort(delta->begin(), delta->end(), cmp); >+} >+ >+static void MoveToList( >+ GraphCycles::Rep* r, Vec<int32_t>* src, Vec<int32_t>* dst) { >+ for (auto& v : *src) { >+ int32_t w = v; >+ v = r->nodes_[w]->rank; // Replace v entry with its rank >+ r->nodes_[w]->visited = false; // Prepare for future DFS calls >+ dst->push_back(w); >+ } >+} >+ >+int GraphCycles::FindPath(GraphId idx, GraphId idy, int max_path_len, >+ GraphId path[]) const { >+ Rep* r = rep_; >+ if (FindNode(r, idx) == nullptr || FindNode(r, idy) == nullptr) return 0; >+ const int32_t x = NodeIndex(idx); >+ const int32_t y = NodeIndex(idy); >+ >+ // Forward depth first search starting at x until we hit y. >+ // As we descend into a node, we push it onto the path. >+ // As we leave a node, we remove it from the path. >+ int path_len = 0; >+ >+ NodeSet seen; >+ r->stack_.clear(); >+ r->stack_.push_back(x); >+ while (!r->stack_.empty()) { >+ int32_t n = r->stack_.back(); >+ r->stack_.pop_back(); >+ if (n < 0) { >+ // Marker to indicate that we are leaving a node >+ path_len--; >+ continue; >+ } >+ >+ if (path_len < max_path_len) { >+ path[path_len] = MakeId(n, rep_->nodes_[n]->version); >+ } >+ path_len++; >+ r->stack_.push_back(-1); // Will remove tentative path entry >+ >+ if (n == y) { >+ return path_len; >+ } >+ >+ HASH_FOR_EACH(w, r->nodes_[n]->out) { >+ if (seen.insert(w)) { >+ r->stack_.push_back(w); >+ } >+ } >+ } >+ >+ return 0; >+} >+ >+bool GraphCycles::IsReachable(GraphId x, GraphId y) const { >+ return FindPath(x, y, 0, nullptr) > 0; >+} >+ >+void GraphCycles::UpdateStackTrace(GraphId id, int priority, >+ int (*get_stack_trace)(void** stack, int)) { >+ Node* n = FindNode(rep_, id); >+ if (n == nullptr || n->priority >= priority) { >+ return; >+ } >+ n->nstack = (*get_stack_trace)(n->stack, ABSL_ARRAYSIZE(n->stack)); >+ n->priority = priority; >+} >+ >+int GraphCycles::GetStackTrace(GraphId id, void*** ptr) { >+ Node* n = FindNode(rep_, id); >+ if (n == nullptr) { >+ *ptr = nullptr; >+ return 0; >+ } else { >+ *ptr = n->stack; >+ return n->nstack; >+ } >+} >+ >+} // namespace synchronization_internal >+} // namespace absl >+ >+#endif // ABSL_LOW_LEVEL_ALLOC_MISSING >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h >new file mode 100644 >index 0000000000000000000000000000000000000000..2e6686a4c0628bc7e99f285c98bed1579a8ad06b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h >@@ -0,0 +1,137 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_SYNCHRONIZATION_INTERNAL_GRAPHCYCLES_H_ >+#define ABSL_SYNCHRONIZATION_INTERNAL_GRAPHCYCLES_H_ >+ >+// GraphCycles detects the introduction of a cycle into a directed >+// graph that is being built up incrementally. >+// >+// Nodes are identified by small integers. It is not possible to >+// record multiple edges with the same (source, destination) pair; >+// requests to add an edge where one already exists are silently >+// ignored. >+// >+// It is also not possible to introduce a cycle; an attempt to insert >+// an edge that would introduce a cycle fails and returns false. >+// >+// GraphCycles uses no internal locking; calls into it should be >+// serialized externally. >+ >+// Performance considerations: >+// Works well on sparse graphs, poorly on dense graphs. >+// Extra information is maintained incrementally to detect cycles quickly. >+// InsertEdge() is very fast when the edge already exists, and reasonably fast >+// otherwise. >+// FindPath() is linear in the size of the graph. >+// The current implemenation uses O(|V|+|E|) space. >+ >+#include <cstdint> >+ >+namespace absl { >+namespace synchronization_internal { >+ >+// Opaque identifier for a graph node. >+struct GraphId { >+ uint64_t handle; >+ >+ bool operator==(const GraphId& x) const { return handle == x.handle; } >+ bool operator!=(const GraphId& x) const { return handle != x.handle; } >+}; >+ >+// Return an invalid graph id that will never be assigned by GraphCycles. >+inline GraphId InvalidGraphId() { >+ return GraphId{0}; >+} >+ >+class GraphCycles { >+ public: >+ GraphCycles(); >+ ~GraphCycles(); >+ >+ // Return the id to use for ptr, assigning one if necessary. >+ // Subsequent calls with the same ptr value will return the same id >+ // until Remove(). >+ GraphId GetId(void* ptr); >+ >+ // Remove "ptr" from the graph. Its corresponding node and all >+ // edges to and from it are removed. >+ void RemoveNode(void* ptr); >+ >+ // Return the pointer associated with id, or nullptr if id is not >+ // currently in the graph. >+ void* Ptr(GraphId id); >+ >+ // Attempt to insert an edge from source_node to dest_node. If the >+ // edge would introduce a cycle, return false without making any >+ // changes. Otherwise add the edge and return true. >+ bool InsertEdge(GraphId source_node, GraphId dest_node); >+ >+ // Remove any edge that exists from source_node to dest_node. >+ void RemoveEdge(GraphId source_node, GraphId dest_node); >+ >+ // Return whether node exists in the graph. >+ bool HasNode(GraphId node); >+ >+ // Return whether there is an edge directly from source_node to dest_node. >+ bool HasEdge(GraphId source_node, GraphId dest_node) const; >+ >+ // Return whether dest_node is reachable from source_node >+ // by following edges. >+ bool IsReachable(GraphId source_node, GraphId dest_node) const; >+ >+ // Find a path from "source" to "dest". If such a path exists, >+ // place the nodes on the path in the array path[], and return >+ // the number of nodes on the path. If the path is longer than >+ // max_path_len nodes, only the first max_path_len nodes are placed >+ // in path[]. The client should compare the return value with >+ // max_path_len" to see when this occurs. If no path exists, return >+ // 0. Any valid path stored in path[] will start with "source" and >+ // end with "dest". There is no guarantee that the path is the >+ // shortest, but no node will appear twice in the path, except the >+ // source and destination node if they are identical; therefore, the >+ // return value is at most one greater than the number of nodes in >+ // the graph. >+ int FindPath(GraphId source, GraphId dest, int max_path_len, >+ GraphId path[]) const; >+ >+ // Update the stack trace recorded for id with the current stack >+ // trace if the last time it was updated had a smaller priority >+ // than the priority passed on this call. >+ // >+ // *get_stack_trace is called to get the stack trace. >+ void UpdateStackTrace(GraphId id, int priority, >+ int (*get_stack_trace)(void**, int)); >+ >+ // Set *ptr to the beginning of the array that holds the recorded >+ // stack trace for id and return the depth of the stack trace. >+ int GetStackTrace(GraphId id, void*** ptr); >+ >+ // Check internal invariants. Crashes on failure, returns true on success. >+ // Expensive: should only be called from graphcycles_test.cc. >+ bool CheckInvariants() const; >+ >+ // ---------------------------------------------------- >+ struct Rep; >+ private: >+ Rep *rep_; // opaque representation >+ GraphCycles(const GraphCycles&) = delete; >+ GraphCycles& operator=(const GraphCycles&) = delete; >+}; >+ >+} // namespace synchronization_internal >+} // namespace absl >+ >+#endif >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..a239c25c3a81d5b25ac697bbc9170b21f2201c7b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_benchmark.cc >@@ -0,0 +1,44 @@ >+// 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/synchronization/internal/graphcycles.h" >+ >+#include <algorithm> >+#include <cstdint> >+#include <vector> >+ >+#include "benchmark/benchmark.h" >+#include "absl/base/internal/raw_logging.h" >+ >+namespace { >+ >+void BM_StressTest(benchmark::State& state) { >+ const int num_nodes = state.range(0); >+ while (state.KeepRunningBatch(num_nodes)) { >+ absl::synchronization_internal::GraphCycles g; >+ std::vector<absl::synchronization_internal::GraphId> nodes(num_nodes); >+ for (int i = 0; i < num_nodes; i++) { >+ nodes[i] = g.GetId(reinterpret_cast<void*>(static_cast<uintptr_t>(i))); >+ } >+ for (int i = 0; i < num_nodes; i++) { >+ int end = std::min(num_nodes, i + 5); >+ for (int j = i + 1; j < end; j++) { >+ ABSL_RAW_CHECK(g.InsertEdge(nodes[i], nodes[j]), ""); >+ } >+ } >+ } >+} >+BENCHMARK(BM_StressTest)->Range(2048, 1048576); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..9a85b39074d75847bd180c911538a39b325ac698 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc >@@ -0,0 +1,462 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/internal/graphcycles.h" >+ >+#include <map> >+#include <random> >+#include <unordered_set> >+#include <utility> >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/macros.h" >+ >+namespace absl { >+namespace synchronization_internal { >+ >+// We emulate a GraphCycles object with a node vector and an edge vector. >+// We then compare the two implementations. >+ >+using Nodes = std::vector<int>; >+struct Edge { >+ int from; >+ int to; >+}; >+using Edges = std::vector<Edge>; >+using RandomEngine = std::mt19937_64; >+ >+// Mapping from integer index to GraphId. >+typedef std::map<int, GraphId> IdMap; >+static GraphId Get(const IdMap& id, int num) { >+ auto iter = id.find(num); >+ return (iter == id.end()) ? InvalidGraphId() : iter->second; >+} >+ >+// Return whether "to" is reachable from "from". >+static bool IsReachable(Edges *edges, int from, int to, >+ std::unordered_set<int> *seen) { >+ seen->insert(from); // we are investigating "from"; don't do it again >+ if (from == to) return true; >+ for (const auto &edge : *edges) { >+ if (edge.from == from) { >+ if (edge.to == to) { // success via edge directly >+ return true; >+ } else if (seen->find(edge.to) == seen->end() && // success via edge >+ IsReachable(edges, edge.to, to, seen)) { >+ return true; >+ } >+ } >+ } >+ return false; >+} >+ >+static void PrintEdges(Edges *edges) { >+ ABSL_RAW_LOG(INFO, "EDGES (%zu)", edges->size()); >+ for (const auto &edge : *edges) { >+ int a = edge.from; >+ int b = edge.to; >+ ABSL_RAW_LOG(INFO, "%d %d", a, b); >+ } >+ ABSL_RAW_LOG(INFO, "---"); >+} >+ >+static void PrintGCEdges(Nodes *nodes, const IdMap &id, GraphCycles *gc) { >+ ABSL_RAW_LOG(INFO, "GC EDGES"); >+ for (int a : *nodes) { >+ for (int b : *nodes) { >+ if (gc->HasEdge(Get(id, a), Get(id, b))) { >+ ABSL_RAW_LOG(INFO, "%d %d", a, b); >+ } >+ } >+ } >+ ABSL_RAW_LOG(INFO, "---"); >+} >+ >+static void PrintTransitiveClosure(Nodes *nodes, Edges *edges) { >+ ABSL_RAW_LOG(INFO, "Transitive closure"); >+ for (int a : *nodes) { >+ for (int b : *nodes) { >+ std::unordered_set<int> seen; >+ if (IsReachable(edges, a, b, &seen)) { >+ ABSL_RAW_LOG(INFO, "%d %d", a, b); >+ } >+ } >+ } >+ ABSL_RAW_LOG(INFO, "---"); >+} >+ >+static void PrintGCTransitiveClosure(Nodes *nodes, const IdMap &id, >+ GraphCycles *gc) { >+ ABSL_RAW_LOG(INFO, "GC Transitive closure"); >+ for (int a : *nodes) { >+ for (int b : *nodes) { >+ if (gc->IsReachable(Get(id, a), Get(id, b))) { >+ ABSL_RAW_LOG(INFO, "%d %d", a, b); >+ } >+ } >+ } >+ ABSL_RAW_LOG(INFO, "---"); >+} >+ >+static void CheckTransitiveClosure(Nodes *nodes, Edges *edges, const IdMap &id, >+ GraphCycles *gc) { >+ std::unordered_set<int> seen; >+ for (const auto &a : *nodes) { >+ for (const auto &b : *nodes) { >+ seen.clear(); >+ bool gc_reachable = gc->IsReachable(Get(id, a), Get(id, b)); >+ bool reachable = IsReachable(edges, a, b, &seen); >+ if (gc_reachable != reachable) { >+ PrintEdges(edges); >+ PrintGCEdges(nodes, id, gc); >+ PrintTransitiveClosure(nodes, edges); >+ PrintGCTransitiveClosure(nodes, id, gc); >+ ABSL_RAW_LOG(FATAL, "gc_reachable %s reachable %s a %d b %d", >+ gc_reachable ? "true" : "false", >+ reachable ? "true" : "false", a, b); >+ } >+ } >+ } >+} >+ >+static void CheckEdges(Nodes *nodes, Edges *edges, const IdMap &id, >+ GraphCycles *gc) { >+ int count = 0; >+ for (const auto &edge : *edges) { >+ int a = edge.from; >+ int b = edge.to; >+ if (!gc->HasEdge(Get(id, a), Get(id, b))) { >+ PrintEdges(edges); >+ PrintGCEdges(nodes, id, gc); >+ ABSL_RAW_LOG(FATAL, "!gc->HasEdge(%d, %d)", a, b); >+ } >+ } >+ for (const auto &a : *nodes) { >+ for (const auto &b : *nodes) { >+ if (gc->HasEdge(Get(id, a), Get(id, b))) { >+ count++; >+ } >+ } >+ } >+ if (count != edges->size()) { >+ PrintEdges(edges); >+ PrintGCEdges(nodes, id, gc); >+ ABSL_RAW_LOG(FATAL, "edges->size() %zu count %d", edges->size(), count); >+ } >+} >+ >+static void CheckInvariants(const GraphCycles &gc) { >+ if (ABSL_PREDICT_FALSE(!gc.CheckInvariants())) >+ ABSL_RAW_LOG(FATAL, "CheckInvariants"); >+} >+ >+// Returns the index of a randomly chosen node in *nodes. >+// Requires *nodes be non-empty. >+static int RandomNode(RandomEngine* rng, Nodes *nodes) { >+ std::uniform_int_distribution<int> uniform(0, nodes->size()-1); >+ return uniform(*rng); >+} >+ >+// Returns the index of a randomly chosen edge in *edges. >+// Requires *edges be non-empty. >+static int RandomEdge(RandomEngine* rng, Edges *edges) { >+ std::uniform_int_distribution<int> uniform(0, edges->size()-1); >+ return uniform(*rng); >+} >+ >+// Returns the index of edge (from, to) in *edges or -1 if it is not in *edges. >+static int EdgeIndex(Edges *edges, int from, int to) { >+ int i = 0; >+ while (i != edges->size() && >+ ((*edges)[i].from != from || (*edges)[i].to != to)) { >+ i++; >+ } >+ return i == edges->size()? -1 : i; >+} >+ >+TEST(GraphCycles, RandomizedTest) { >+ int next_node = 0; >+ Nodes nodes; >+ Edges edges; // from, to >+ IdMap id; >+ GraphCycles graph_cycles; >+ static const int kMaxNodes = 7; // use <= 7 nodes to keep test short >+ static const int kDataOffset = 17; // an offset to the node-specific data >+ int n = 100000; >+ int op = 0; >+ RandomEngine rng(testing::UnitTest::GetInstance()->random_seed()); >+ std::uniform_int_distribution<int> uniform(0, 5); >+ >+ auto ptr = [](intptr_t i) { >+ return reinterpret_cast<void*>(i + kDataOffset); >+ }; >+ >+ for (int iter = 0; iter != n; iter++) { >+ for (const auto &node : nodes) { >+ ASSERT_EQ(graph_cycles.Ptr(Get(id, node)), ptr(node)) << " node " << node; >+ } >+ CheckEdges(&nodes, &edges, id, &graph_cycles); >+ CheckTransitiveClosure(&nodes, &edges, id, &graph_cycles); >+ op = uniform(rng); >+ switch (op) { >+ case 0: // Add a node >+ if (nodes.size() < kMaxNodes) { >+ int new_node = next_node++; >+ GraphId new_gnode = graph_cycles.GetId(ptr(new_node)); >+ ASSERT_NE(new_gnode, InvalidGraphId()); >+ id[new_node] = new_gnode; >+ ASSERT_EQ(ptr(new_node), graph_cycles.Ptr(new_gnode)); >+ nodes.push_back(new_node); >+ } >+ break; >+ >+ case 1: // Remove a node >+ if (nodes.size() > 0) { >+ int node_index = RandomNode(&rng, &nodes); >+ int node = nodes[node_index]; >+ nodes[node_index] = nodes.back(); >+ nodes.pop_back(); >+ graph_cycles.RemoveNode(ptr(node)); >+ ASSERT_EQ(graph_cycles.Ptr(Get(id, node)), nullptr); >+ id.erase(node); >+ int i = 0; >+ while (i != edges.size()) { >+ if (edges[i].from == node || edges[i].to == node) { >+ edges[i] = edges.back(); >+ edges.pop_back(); >+ } else { >+ i++; >+ } >+ } >+ } >+ break; >+ >+ case 2: // Add an edge >+ if (nodes.size() > 0) { >+ int from = RandomNode(&rng, &nodes); >+ int to = RandomNode(&rng, &nodes); >+ if (EdgeIndex(&edges, nodes[from], nodes[to]) == -1) { >+ if (graph_cycles.InsertEdge(id[nodes[from]], id[nodes[to]])) { >+ Edge new_edge; >+ new_edge.from = nodes[from]; >+ new_edge.to = nodes[to]; >+ edges.push_back(new_edge); >+ } else { >+ std::unordered_set<int> seen; >+ ASSERT_TRUE(IsReachable(&edges, nodes[to], nodes[from], &seen)) >+ << "Edge " << nodes[to] << "->" << nodes[from]; >+ } >+ } >+ } >+ break; >+ >+ case 3: // Remove an edge >+ if (edges.size() > 0) { >+ int i = RandomEdge(&rng, &edges); >+ int from = edges[i].from; >+ int to = edges[i].to; >+ ASSERT_EQ(i, EdgeIndex(&edges, from, to)); >+ edges[i] = edges.back(); >+ edges.pop_back(); >+ ASSERT_EQ(-1, EdgeIndex(&edges, from, to)); >+ graph_cycles.RemoveEdge(id[from], id[to]); >+ } >+ break; >+ >+ case 4: // Check a path >+ if (nodes.size() > 0) { >+ int from = RandomNode(&rng, &nodes); >+ int to = RandomNode(&rng, &nodes); >+ GraphId path[2*kMaxNodes]; >+ int path_len = graph_cycles.FindPath(id[nodes[from]], id[nodes[to]], >+ ABSL_ARRAYSIZE(path), path); >+ std::unordered_set<int> seen; >+ bool reachable = IsReachable(&edges, nodes[from], nodes[to], &seen); >+ bool gc_reachable = >+ graph_cycles.IsReachable(Get(id, nodes[from]), Get(id, nodes[to])); >+ ASSERT_EQ(path_len != 0, reachable); >+ ASSERT_EQ(path_len != 0, gc_reachable); >+ // In the following line, we add one because a node can appear >+ // twice, if the path is from that node to itself, perhaps via >+ // every other node. >+ ASSERT_LE(path_len, kMaxNodes + 1); >+ if (path_len != 0) { >+ ASSERT_EQ(id[nodes[from]], path[0]); >+ ASSERT_EQ(id[nodes[to]], path[path_len-1]); >+ for (int i = 1; i < path_len; i++) { >+ ASSERT_TRUE(graph_cycles.HasEdge(path[i-1], path[i])); >+ } >+ } >+ } >+ break; >+ >+ case 5: // Check invariants >+ CheckInvariants(graph_cycles); >+ break; >+ >+ default: >+ ABSL_RAW_LOG(FATAL, "op %d", op); >+ } >+ >+ // Very rarely, test graph expansion by adding then removing many nodes. >+ std::bernoulli_distribution one_in_1024(1.0 / 1024); >+ if (one_in_1024(rng)) { >+ CheckEdges(&nodes, &edges, id, &graph_cycles); >+ CheckTransitiveClosure(&nodes, &edges, id, &graph_cycles); >+ for (int i = 0; i != 256; i++) { >+ int new_node = next_node++; >+ GraphId new_gnode = graph_cycles.GetId(ptr(new_node)); >+ ASSERT_NE(InvalidGraphId(), new_gnode); >+ id[new_node] = new_gnode; >+ ASSERT_EQ(ptr(new_node), graph_cycles.Ptr(new_gnode)); >+ for (const auto &node : nodes) { >+ ASSERT_NE(node, new_node); >+ } >+ nodes.push_back(new_node); >+ } >+ for (int i = 0; i != 256; i++) { >+ ASSERT_GT(nodes.size(), 0); >+ int node_index = RandomNode(&rng, &nodes); >+ int node = nodes[node_index]; >+ nodes[node_index] = nodes.back(); >+ nodes.pop_back(); >+ graph_cycles.RemoveNode(ptr(node)); >+ id.erase(node); >+ int j = 0; >+ while (j != edges.size()) { >+ if (edges[j].from == node || edges[j].to == node) { >+ edges[j] = edges.back(); >+ edges.pop_back(); >+ } else { >+ j++; >+ } >+ } >+ } >+ CheckInvariants(graph_cycles); >+ } >+ } >+} >+ >+class GraphCyclesTest : public ::testing::Test { >+ public: >+ IdMap id_; >+ GraphCycles g_; >+ >+ static void* Ptr(int i) { >+ return reinterpret_cast<void*>(static_cast<uintptr_t>(i)); >+ } >+ >+ static int Num(void* ptr) { >+ return static_cast<int>(reinterpret_cast<uintptr_t>(ptr)); >+ } >+ >+ // Test relies on ith NewNode() call returning Node numbered i >+ GraphCyclesTest() { >+ for (int i = 0; i < 100; i++) { >+ id_[i] = g_.GetId(Ptr(i)); >+ } >+ CheckInvariants(g_); >+ } >+ >+ bool AddEdge(int x, int y) { >+ return g_.InsertEdge(Get(id_, x), Get(id_, y)); >+ } >+ >+ void AddMultiples() { >+ // For every node x > 0: add edge to 2*x, 3*x >+ for (int x = 1; x < 25; x++) { >+ EXPECT_TRUE(AddEdge(x, 2*x)) << x; >+ EXPECT_TRUE(AddEdge(x, 3*x)) << x; >+ } >+ CheckInvariants(g_); >+ } >+ >+ std::string Path(int x, int y) { >+ GraphId path[5]; >+ int np = g_.FindPath(Get(id_, x), Get(id_, y), ABSL_ARRAYSIZE(path), path); >+ std::string result; >+ for (int i = 0; i < np; i++) { >+ if (i >= ABSL_ARRAYSIZE(path)) { >+ result += " ..."; >+ break; >+ } >+ if (!result.empty()) result.push_back(' '); >+ char buf[20]; >+ snprintf(buf, sizeof(buf), "%d", Num(g_.Ptr(path[i]))); >+ result += buf; >+ } >+ return result; >+ } >+}; >+ >+TEST_F(GraphCyclesTest, NoCycle) { >+ AddMultiples(); >+ CheckInvariants(g_); >+} >+ >+TEST_F(GraphCyclesTest, SimpleCycle) { >+ AddMultiples(); >+ EXPECT_FALSE(AddEdge(8, 4)); >+ EXPECT_EQ("4 8", Path(4, 8)); >+ CheckInvariants(g_); >+} >+ >+TEST_F(GraphCyclesTest, IndirectCycle) { >+ AddMultiples(); >+ EXPECT_TRUE(AddEdge(16, 9)); >+ CheckInvariants(g_); >+ EXPECT_FALSE(AddEdge(9, 2)); >+ EXPECT_EQ("2 4 8 16 9", Path(2, 9)); >+ CheckInvariants(g_); >+} >+ >+TEST_F(GraphCyclesTest, LongPath) { >+ ASSERT_TRUE(AddEdge(2, 4)); >+ ASSERT_TRUE(AddEdge(4, 6)); >+ ASSERT_TRUE(AddEdge(6, 8)); >+ ASSERT_TRUE(AddEdge(8, 10)); >+ ASSERT_TRUE(AddEdge(10, 12)); >+ ASSERT_FALSE(AddEdge(12, 2)); >+ EXPECT_EQ("2 4 6 8 10 ...", Path(2, 12)); >+ CheckInvariants(g_); >+} >+ >+TEST_F(GraphCyclesTest, RemoveNode) { >+ ASSERT_TRUE(AddEdge(1, 2)); >+ ASSERT_TRUE(AddEdge(2, 3)); >+ ASSERT_TRUE(AddEdge(3, 4)); >+ ASSERT_TRUE(AddEdge(4, 5)); >+ g_.RemoveNode(g_.Ptr(id_[3])); >+ id_.erase(3); >+ ASSERT_TRUE(AddEdge(5, 1)); >+} >+ >+TEST_F(GraphCyclesTest, ManyEdges) { >+ const int N = 50; >+ for (int i = 0; i < N; i++) { >+ for (int j = 1; j < N; j++) { >+ ASSERT_TRUE(AddEdge(i, i+j)); >+ } >+ } >+ CheckInvariants(g_); >+ ASSERT_TRUE(AddEdge(2*N-1, 0)); >+ CheckInvariants(g_); >+ ASSERT_FALSE(AddEdge(10, 9)); >+ CheckInvariants(g_); >+} >+ >+} // namespace synchronization_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h >new file mode 100644 >index 0000000000000000000000000000000000000000..bb7080004c72da51cb2314cfc8ed69529d3347bd >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h >@@ -0,0 +1,151 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+// An optional absolute timeout, with nanosecond granularity, >+// compatible with absl::Time. Suitable for in-register >+// parameter-passing (e.g. syscalls.) >+// Constructible from a absl::Time (for a timeout to be respected) or {} >+// (for "no timeout".) >+// This is a private low-level API for use by a handful of low-level >+// components that are friends of this class. Higher-level components >+// should build APIs based on absl::Time and absl::Duration. >+ >+#ifndef ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_ >+#define ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_ >+ >+#include <time.h> >+#include <algorithm> >+#include <limits> >+ >+#include "absl/base/internal/raw_logging.h" >+#include "absl/time/clock.h" >+#include "absl/time/time.h" >+ >+namespace absl { >+namespace synchronization_internal { >+ >+class Futex; >+class Waiter; >+ >+class KernelTimeout { >+ public: >+ // A timeout that should expire at <t>. Any value, in the full >+ // InfinitePast() to InfiniteFuture() range, is valid here and will be >+ // respected. >+ explicit KernelTimeout(absl::Time t) : ns_(MakeNs(t)) {} >+ // No timeout. >+ KernelTimeout() : ns_(0) {} >+ >+ // A more explicit factory for those who prefer it. Equivalent to {}. >+ static KernelTimeout Never() { return {}; } >+ >+ // We explicitly do not support other custom formats: timespec, int64_t nanos. >+ // Unify on this and absl::Time, please. >+ bool has_timeout() const { return ns_ != 0; } >+ >+ private: >+ // internal rep, not user visible: ns after unix epoch. >+ // zero = no timeout. >+ // Negative we treat as an unlikely (and certainly expired!) but valid >+ // timeout. >+ int64_t ns_; >+ >+ static int64_t MakeNs(absl::Time t) { >+ // optimization--InfiniteFuture is common "no timeout" value >+ // and cheaper to compare than convert. >+ if (t == absl::InfiniteFuture()) return 0; >+ int64_t x = ToUnixNanos(t); >+ >+ // A timeout that lands exactly on the epoch (x=0) needs to be respected, >+ // so we alter it unnoticably to 1. Negative timeouts are in >+ // theory supported, but handled poorly by the kernel (long >+ // delays) so push them forward too; since all such times have >+ // already passed, it's indistinguishable. >+ if (x <= 0) x = 1; >+ // A time larger than what can be represented to the kernel is treated >+ // as no timeout. >+ if (x == std::numeric_limits<int64_t>::max()) x = 0; >+ return x; >+ } >+ >+ // Convert to parameter for sem_timedwait/futex/similar. Only for approved >+ // users. Do not call if !has_timeout. >+ struct timespec MakeAbsTimespec() { >+ int64_t n = ns_; >+ static const int64_t kNanosPerSecond = 1000 * 1000 * 1000; >+ if (n == 0) { >+ ABSL_RAW_LOG( >+ ERROR, >+ "Tried to create a timespec from a non-timeout; never do this."); >+ // But we'll try to continue sanely. no-timeout ~= saturated timeout. >+ n = std::numeric_limits<int64_t>::max(); >+ } >+ >+ // Kernel APIs validate timespecs as being at or after the epoch, >+ // despite the kernel time type being signed. However, no one can >+ // tell the difference between a timeout at or before the epoch (since >+ // all such timeouts have expired!) >+ if (n < 0) n = 0; >+ >+ struct timespec abstime; >+ int64_t seconds = std::min(n / kNanosPerSecond, >+ int64_t{std::numeric_limits<time_t>::max()}); >+ abstime.tv_sec = static_cast<time_t>(seconds); >+ abstime.tv_nsec = >+ static_cast<decltype(abstime.tv_nsec)>(n % kNanosPerSecond); >+ return abstime; >+ } >+ >+#ifdef _WIN32 >+ // Converts to milliseconds from now, or INFINITE when >+ // !has_timeout(). For use by SleepConditionVariableSRW on >+ // Windows. Callers should recognize that the return value is a >+ // relative duration (it should be recomputed by calling this method >+ // in the case of a spurious wakeup). >+ // This header file may be included transitively by public header files, >+ // so we define our own DWORD and INFINITE instead of getting them from >+ // <intsafe.h> and <WinBase.h>. >+ typedef unsigned long DWord; // NOLINT >+ DWord InMillisecondsFromNow() const { >+ constexpr DWord kInfinite = std::numeric_limits<DWord>::max(); >+ if (!has_timeout()) { >+ return kInfinite; >+ } >+ // The use of absl::Now() to convert from absolute time to >+ // relative time means that absl::Now() cannot use anything that >+ // depends on KernelTimeout (for example, Mutex) on Windows. >+ int64_t now = ToUnixNanos(absl::Now()); >+ if (ns_ >= now) { >+ // Round up so that Now() + ms_from_now >= ns_. >+ constexpr uint64_t max_nanos = >+ std::numeric_limits<int64_t>::max() - 999999u; >+ uint64_t ms_from_now = >+ (std::min<uint64_t>(max_nanos, ns_ - now) + 999999u) / 1000000u; >+ if (ms_from_now > kInfinite) { >+ return kInfinite; >+ } >+ return static_cast<DWord>(ms_from_now); >+ } >+ return 0; >+ } >+#endif >+ >+ friend class Futex; >+ friend class Waiter; >+}; >+ >+} // namespace synchronization_internal >+} // namespace absl >+#endif // ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/mutex_nonprod.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/mutex_nonprod.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..45c60326dba03303342b57a352508dccc13dd0aa >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/mutex_nonprod.cc >@@ -0,0 +1,318 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Implementation of a small subset of Mutex and CondVar functionality >+// for platforms where the production implementation hasn't been fully >+// ported yet. >+ >+#include "absl/synchronization/mutex.h" >+ >+#if defined(_WIN32) >+#include <chrono> // NOLINT(build/c++11) >+#else >+#include <sys/time.h> >+#include <time.h> >+#endif >+ >+#include <algorithm> >+ >+#include "absl/base/internal/raw_logging.h" >+#include "absl/time/time.h" >+ >+namespace absl { >+namespace synchronization_internal { >+ >+namespace { >+ >+// Return the current time plus the timeout. >+absl::Time DeadlineFromTimeout(absl::Duration timeout) { >+ return absl::Now() + timeout; >+} >+ >+// Limit the deadline to a positive, 32-bit time_t value to accommodate >+// implementation restrictions. This also deals with InfinitePast and >+// InfiniteFuture. >+absl::Time LimitedDeadline(absl::Time deadline) { >+ deadline = std::max(absl::FromTimeT(0), deadline); >+ deadline = std::min(deadline, absl::FromTimeT(0x7fffffff)); >+ return deadline; >+} >+ >+} // namespace >+ >+#if defined(_WIN32) >+ >+MutexImpl::MutexImpl() {} >+ >+MutexImpl::~MutexImpl() { >+ if (locked_) { >+ std_mutex_.unlock(); >+ } >+} >+ >+void MutexImpl::Lock() { >+ std_mutex_.lock(); >+ locked_ = true; >+} >+ >+bool MutexImpl::TryLock() { >+ bool locked = std_mutex_.try_lock(); >+ if (locked) locked_ = true; >+ return locked; >+} >+ >+void MutexImpl::Unlock() { >+ locked_ = false; >+ released_.SignalAll(); >+ std_mutex_.unlock(); >+} >+ >+CondVarImpl::CondVarImpl() {} >+ >+CondVarImpl::~CondVarImpl() {} >+ >+void CondVarImpl::Signal() { std_cv_.notify_one(); } >+ >+void CondVarImpl::SignalAll() { std_cv_.notify_all(); } >+ >+void CondVarImpl::Wait(MutexImpl* mu) { >+ mu->released_.SignalAll(); >+ std_cv_.wait(mu->std_mutex_); >+} >+ >+bool CondVarImpl::WaitWithDeadline(MutexImpl* mu, absl::Time deadline) { >+ mu->released_.SignalAll(); >+ time_t when = ToTimeT(deadline); >+ int64_t nanos = ToInt64Nanoseconds(deadline - absl::FromTimeT(when)); >+ std::chrono::system_clock::time_point deadline_tp = >+ std::chrono::system_clock::from_time_t(when) + >+ std::chrono::duration_cast<std::chrono::system_clock::duration>( >+ std::chrono::nanoseconds(nanos)); >+ auto deadline_since_epoch = >+ std::chrono::duration_cast<std::chrono::duration<double>>( >+ deadline_tp - std::chrono::system_clock::from_time_t(0)); >+ return std_cv_.wait_until(mu->std_mutex_, deadline_tp) == >+ std::cv_status::timeout; >+} >+ >+#else // ! _WIN32 >+ >+MutexImpl::MutexImpl() { >+ ABSL_RAW_CHECK(pthread_mutex_init(&pthread_mutex_, nullptr) == 0, >+ "pthread error"); >+} >+ >+MutexImpl::~MutexImpl() { >+ if (locked_) { >+ ABSL_RAW_CHECK(pthread_mutex_unlock(&pthread_mutex_) == 0, "pthread error"); >+ } >+ ABSL_RAW_CHECK(pthread_mutex_destroy(&pthread_mutex_) == 0, "pthread error"); >+} >+ >+void MutexImpl::Lock() { >+ ABSL_RAW_CHECK(pthread_mutex_lock(&pthread_mutex_) == 0, "pthread error"); >+ locked_ = true; >+} >+ >+bool MutexImpl::TryLock() { >+ bool locked = (0 == pthread_mutex_trylock(&pthread_mutex_)); >+ if (locked) locked_ = true; >+ return locked; >+} >+ >+void MutexImpl::Unlock() { >+ locked_ = false; >+ released_.SignalAll(); >+ ABSL_RAW_CHECK(pthread_mutex_unlock(&pthread_mutex_) == 0, "pthread error"); >+} >+ >+CondVarImpl::CondVarImpl() { >+ ABSL_RAW_CHECK(pthread_cond_init(&pthread_cv_, nullptr) == 0, >+ "pthread error"); >+} >+ >+CondVarImpl::~CondVarImpl() { >+ ABSL_RAW_CHECK(pthread_cond_destroy(&pthread_cv_) == 0, "pthread error"); >+} >+ >+void CondVarImpl::Signal() { >+ ABSL_RAW_CHECK(pthread_cond_signal(&pthread_cv_) == 0, "pthread error"); >+} >+ >+void CondVarImpl::SignalAll() { >+ ABSL_RAW_CHECK(pthread_cond_broadcast(&pthread_cv_) == 0, "pthread error"); >+} >+ >+void CondVarImpl::Wait(MutexImpl* mu) { >+ mu->released_.SignalAll(); >+ ABSL_RAW_CHECK(pthread_cond_wait(&pthread_cv_, &mu->pthread_mutex_) == 0, >+ "pthread error"); >+} >+ >+bool CondVarImpl::WaitWithDeadline(MutexImpl* mu, absl::Time deadline) { >+ mu->released_.SignalAll(); >+ struct timespec ts = ToTimespec(deadline); >+ int rc = pthread_cond_timedwait(&pthread_cv_, &mu->pthread_mutex_, &ts); >+ if (rc == ETIMEDOUT) return true; >+ ABSL_RAW_CHECK(rc == 0, "pthread error"); >+ return false; >+} >+ >+#endif // ! _WIN32 >+ >+void MutexImpl::Await(const Condition& cond) { >+ if (cond.Eval()) return; >+ released_.SignalAll(); >+ do { >+ released_.Wait(this); >+ } while (!cond.Eval()); >+} >+ >+bool MutexImpl::AwaitWithDeadline(const Condition& cond, absl::Time deadline) { >+ if (cond.Eval()) return true; >+ released_.SignalAll(); >+ while (true) { >+ if (released_.WaitWithDeadline(this, deadline)) return false; >+ if (cond.Eval()) return true; >+ } >+} >+ >+} // namespace synchronization_internal >+ >+Mutex::Mutex() {} >+ >+Mutex::~Mutex() {} >+ >+void Mutex::Lock() { impl()->Lock(); } >+ >+void Mutex::Unlock() { impl()->Unlock(); } >+ >+bool Mutex::TryLock() { return impl()->TryLock(); } >+ >+void Mutex::ReaderLock() { Lock(); } >+ >+void Mutex::ReaderUnlock() { Unlock(); } >+ >+void Mutex::Await(const Condition& cond) { impl()->Await(cond); } >+ >+void Mutex::LockWhen(const Condition& cond) { >+ Lock(); >+ Await(cond); >+} >+ >+bool Mutex::AwaitWithDeadline(const Condition& cond, absl::Time deadline) { >+ return impl()->AwaitWithDeadline( >+ cond, synchronization_internal::LimitedDeadline(deadline)); >+} >+ >+bool Mutex::AwaitWithTimeout(const Condition& cond, absl::Duration timeout) { >+ return AwaitWithDeadline( >+ cond, synchronization_internal::DeadlineFromTimeout(timeout)); >+} >+ >+bool Mutex::LockWhenWithDeadline(const Condition& cond, absl::Time deadline) { >+ Lock(); >+ return AwaitWithDeadline(cond, deadline); >+} >+ >+bool Mutex::LockWhenWithTimeout(const Condition& cond, absl::Duration timeout) { >+ return LockWhenWithDeadline( >+ cond, synchronization_internal::DeadlineFromTimeout(timeout)); >+} >+ >+void Mutex::ReaderLockWhen(const Condition& cond) { >+ ReaderLock(); >+ Await(cond); >+} >+ >+bool Mutex::ReaderLockWhenWithTimeout(const Condition& cond, >+ absl::Duration timeout) { >+ return LockWhenWithTimeout(cond, timeout); >+} >+bool Mutex::ReaderLockWhenWithDeadline(const Condition& cond, >+ absl::Time deadline) { >+ return LockWhenWithDeadline(cond, deadline); >+} >+ >+void Mutex::EnableDebugLog(const char*) {} >+void Mutex::EnableInvariantDebugging(void (*)(void*), void*) {} >+void Mutex::ForgetDeadlockInfo() {} >+void Mutex::AssertHeld() const {} >+void Mutex::AssertReaderHeld() const {} >+void Mutex::AssertNotHeld() const {} >+ >+CondVar::CondVar() {} >+ >+CondVar::~CondVar() {} >+ >+void CondVar::Signal() { impl()->Signal(); } >+ >+void CondVar::SignalAll() { impl()->SignalAll(); } >+ >+void CondVar::Wait(Mutex* mu) { return impl()->Wait(mu->impl()); } >+ >+bool CondVar::WaitWithDeadline(Mutex* mu, absl::Time deadline) { >+ return impl()->WaitWithDeadline( >+ mu->impl(), synchronization_internal::LimitedDeadline(deadline)); >+} >+ >+bool CondVar::WaitWithTimeout(Mutex* mu, absl::Duration timeout) { >+ return WaitWithDeadline(mu, absl::Now() + timeout); >+} >+ >+void CondVar::EnableDebugLog(const char*) {} >+ >+#ifdef THREAD_SANITIZER >+extern "C" void __tsan_read1(void *addr); >+#else >+#define __tsan_read1(addr) // do nothing if TSan not enabled >+#endif >+ >+// A function that just returns its argument, dereferenced >+static bool Dereference(void *arg) { >+ // ThreadSanitizer does not instrument this file for memory accesses. >+ // This function dereferences a user variable that can participate >+ // in a data race, so we need to manually tell TSan about this memory access. >+ __tsan_read1(arg); >+ return *(static_cast<bool *>(arg)); >+} >+ >+Condition::Condition() {} // null constructor, used for kTrue only >+const Condition Condition::kTrue; >+ >+Condition::Condition(bool (*func)(void *), void *arg) >+ : eval_(&CallVoidPtrFunction), >+ function_(func), >+ method_(nullptr), >+ arg_(arg) {} >+ >+bool Condition::CallVoidPtrFunction(const Condition *c) { >+ return (*c->function_)(c->arg_); >+} >+ >+Condition::Condition(const bool *cond) >+ : eval_(CallVoidPtrFunction), >+ function_(Dereference), >+ method_(nullptr), >+ // const_cast is safe since Dereference does not modify arg >+ arg_(const_cast<bool *>(cond)) {} >+ >+bool Condition::Eval() const { >+ // eval_ == null for kTrue >+ return (this->eval_ == nullptr) || (*this->eval_)(this); >+} >+ >+void RegisterSymbolizer(bool (*)(const void*, char*, int)) {} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/mutex_nonprod.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/mutex_nonprod.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..0aab3d1314e68824abc39178efaa215ed4207f04 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/mutex_nonprod.inc >@@ -0,0 +1,256 @@ >+// Do not include. This is an implementation detail of base/mutex.h. >+// >+// Declares three classes: >+// >+// base::internal::MutexImpl - implementation helper for Mutex >+// base::internal::CondVarImpl - implementation helper for CondVar >+// base::internal::SynchronizationStorage<T> - implementation helper for >+// Mutex, CondVar >+ >+#include <type_traits> >+ >+#if defined(_WIN32) >+#include <condition_variable> >+#include <mutex> >+#else >+#include <pthread.h> >+#endif >+ >+#include "absl/base/call_once.h" >+#include "absl/time/time.h" >+ >+// Declare that Mutex::ReaderLock is actually Lock(). Intended primarily >+// for tests, and even then as a last resort. >+#ifdef ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE >+#error ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE cannot be directly set >+#else >+#define ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE 1 >+#endif >+ >+// Declare that Mutex::EnableInvariantDebugging is not implemented. >+// Intended primarily for tests, and even then as a last resort. >+#ifdef ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED >+#error ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED cannot be directly set >+#else >+#define ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED 1 >+#endif >+ >+namespace absl { >+class Condition; >+ >+namespace synchronization_internal { >+ >+class MutexImpl; >+ >+// Do not use this implementation detail of CondVar. Provides most of the >+// implementation, but should not be placed directly in static storage >+// because it will not linker initialize properly. See >+// SynchronizationStorage<T> below for what we mean by linker >+// initialization. >+class CondVarImpl { >+ public: >+ CondVarImpl(); >+ CondVarImpl(const CondVarImpl&) = delete; >+ CondVarImpl& operator=(const CondVarImpl&) = delete; >+ ~CondVarImpl(); >+ >+ void Signal(); >+ void SignalAll(); >+ void Wait(MutexImpl* mutex); >+ bool WaitWithDeadline(MutexImpl* mutex, absl::Time deadline); >+ >+ private: >+#if defined(_WIN32) >+ std::condition_variable_any std_cv_; >+#else >+ pthread_cond_t pthread_cv_; >+#endif >+}; >+ >+// Do not use this implementation detail of Mutex. Provides most of the >+// implementation, but should not be placed directly in static storage >+// because it will not linker initialize properly. See >+// SynchronizationStorage<T> below for what we mean by linker >+// initialization. >+class MutexImpl { >+ public: >+ MutexImpl(); >+ MutexImpl(const MutexImpl&) = delete; >+ MutexImpl& operator=(const MutexImpl&) = delete; >+ ~MutexImpl(); >+ >+ void Lock(); >+ bool TryLock(); >+ void Unlock(); >+ void Await(const Condition& cond); >+ bool AwaitWithDeadline(const Condition& cond, absl::Time deadline); >+ >+ private: >+ friend class CondVarImpl; >+ >+#if defined(_WIN32) >+ std::mutex std_mutex_; >+#else >+ pthread_mutex_t pthread_mutex_; >+#endif >+ >+ // True if the underlying mutex is locked. If the destructor is entered >+ // while locked_, the underlying mutex is unlocked. Mutex supports >+ // destruction while locked, but the same is undefined behavior for both >+ // pthread_mutex_t and std::mutex. >+ bool locked_ = false; >+ >+ // Signaled before releasing the lock, in support of Await. >+ CondVarImpl released_; >+}; >+ >+// Do not use this implementation detail of CondVar and Mutex. A storage >+// space for T that supports a LinkerInitialized constructor. T must >+// have a default constructor, which is called by the first call to >+// get(). T's destructor is never called if the LinkerInitialized >+// constructor is called. >+// >+// Objects constructed with the default constructor are constructed and >+// destructed like any other object, and should never be allocated in >+// static storage. >+// >+// Objects constructed with the LinkerInitialized constructor should >+// always be in static storage. For such objects, calls to get() are always >+// valid, except from signal handlers. >+// >+// Note that this implementation relies on undefined language behavior that >+// are known to hold for the set of supported compilers. An analysis >+// follows. >+// >+// From the C++11 standard: >+// >+// [basic.life] says an object has non-trivial initialization if it is of >+// class type and it is initialized by a constructor other than a trivial >+// default constructor. (the LinkerInitialized constructor is >+// non-trivial) >+// >+// [basic.life] says the lifetime of an object with a non-trivial >+// constructor begins when the call to the constructor is complete. >+// >+// [basic.life] says the lifetime of an object with non-trivial destructor >+// ends when the call to the destructor begins. >+// >+// [basic.life] p5 specifies undefined behavior when accessing non-static >+// members of an instance outside its >+// lifetime. (SynchronizationStorage::get() access non-static members) >+// >+// So, LinkerInitialized object of SynchronizationStorage uses a >+// non-trivial constructor, which is called at some point during dynamic >+// initialization, and is therefore subject to order of dynamic >+// initialization bugs, where get() is called before the object's >+// constructor is, resulting in undefined behavior. >+// >+// Similarly, a LinkerInitialized SynchronizationStorage object has a >+// non-trivial destructor, and so its lifetime ends at some point during >+// destruction of objects with static storage duration [basic.start.term] >+// p4. There is a window where other exit code could call get() after this >+// occurs, resulting in undefined behavior. >+// >+// Combined, these statements imply that LinkerInitialized instances >+// of SynchronizationStorage<T> rely on undefined behavior. >+// >+// However, in practice, the implementation works on all supported >+// compilers. Specifically, we rely on: >+// >+// a) zero-initialization being sufficient to initialize >+// LinkerInitialized instances for the purposes of calling >+// get(), regardless of when the constructor is called. This is >+// because the is_dynamic_ boolean is correctly zero-initialized to >+// false. >+// >+// b) the LinkerInitialized constructor is a NOP, and immaterial to >+// even to concurrent calls to get(). >+// >+// c) the destructor being a NOP for LinkerInitialized objects >+// (guaranteed by a check for !is_dynamic_), and so any concurrent and >+// subsequent calls to get() functioning as if the destructor were not >+// called, by virtue of the instances' storage remaining valid after the >+// destructor runs. >+// >+// d) That a-c apply transitively when SynchronizationStorage<T> is the >+// only member of a class allocated in static storage. >+// >+// Nothing in the language standard guarantees that a-d hold. In practice, >+// these hold in all supported compilers. >+// >+// Future direction: >+// >+// Ideally, we would simply use std::mutex or a similar class, which when >+// allocated statically would support use immediately after static >+// initialization up until static storage is reclaimed (i.e. the properties >+// we require of all "linker initialized" instances). >+// >+// Regarding construction in static storage, std::mutex is required to >+// provide a constexpr default constructor [thread.mutex.class], which >+// ensures the instance's lifetime begins with static initialization >+// [basic.start.init], and so is immune to any problems caused by the order >+// of dynamic initialization. However, as of this writing Microsoft's >+// Visual Studio does not provide a constexpr constructor for std::mutex. >+// See >+// https://blogs.msdn.microsoft.com/vcblog/2015/06/02/constexpr-complete-for-vs-2015-rtm-c11-compiler-c17-stl/ >+// >+// Regarding destruction of instances in static storage, [basic.life] does >+// say an object ends when storage in which the occupies is released, in >+// the case of non-trivial destructor. However, std::mutex is not specified >+// to have a trivial destructor. >+// >+// So, we would need a class with a constexpr default constructor and a >+// trivial destructor. Today, we can achieve neither desired property using >+// std::mutex directly. >+template <typename T> >+class SynchronizationStorage { >+ public: >+ // Instances allocated on the heap or on the stack should use the default >+ // constructor. >+ SynchronizationStorage() >+ : is_dynamic_(true), once_() {} >+ >+ // Instances allocated in static storage (not on the heap, not on the >+ // stack) should use this constructor. >+ explicit SynchronizationStorage(base_internal::LinkerInitialized) {} >+ >+ SynchronizationStorage(SynchronizationStorage&) = delete; >+ SynchronizationStorage& operator=(SynchronizationStorage&) = delete; >+ >+ ~SynchronizationStorage() { >+ if (is_dynamic_) { >+ get()->~T(); >+ } >+ } >+ >+ // Retrieve the object in storage. This is fast and thread safe, but does >+ // incur the cost of absl::call_once(). >+ // >+ // For instances in static storage constructed with the >+ // LinkerInitialized constructor, may be called at any time without >+ // regard for order of dynamic initialization or destruction of objects >+ // in static storage. See the class comment for caveats. >+ T* get() { >+ absl::call_once(once_, SynchronizationStorage::Construct, this); >+ return reinterpret_cast<T*>(&space_); >+ } >+ >+ private: >+ static void Construct(SynchronizationStorage<T>* self) { >+ new (&self->space_) T(); >+ } >+ >+ // When true, T's destructor is run when this is destructed. >+ // >+ // The LinkerInitialized constructor assumes this value will be set >+ // false by static initialization. >+ bool is_dynamic_; >+ >+ absl::once_flag once_; >+ >+ // An aligned space for T. >+ typename std::aligned_storage<sizeof(T), alignof(T)>::type space_; >+}; >+ >+} // namespace synchronization_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..caa2baf64bd3110f0ba8857cf25b22d17b596478 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc >@@ -0,0 +1,99 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// This file is a no-op if the required LowLevelAlloc support is missing. >+#include "absl/base/internal/low_level_alloc.h" >+#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING >+ >+#include "absl/synchronization/internal/per_thread_sem.h" >+ >+#include <atomic> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/internal/thread_identity.h" >+#include "absl/synchronization/internal/waiter.h" >+ >+namespace absl { >+namespace synchronization_internal { >+ >+void PerThreadSem::SetThreadBlockedCounter(std::atomic<int> *counter) { >+ base_internal::ThreadIdentity *identity; >+ identity = GetOrCreateCurrentThreadIdentity(); >+ identity->blocked_count_ptr = counter; >+} >+ >+std::atomic<int> *PerThreadSem::GetThreadBlockedCounter() { >+ base_internal::ThreadIdentity *identity; >+ identity = GetOrCreateCurrentThreadIdentity(); >+ return identity->blocked_count_ptr; >+} >+ >+void PerThreadSem::Init(base_internal::ThreadIdentity *identity) { >+ Waiter::GetWaiter(identity)->Init(); >+ identity->ticker.store(0, std::memory_order_relaxed); >+ identity->wait_start.store(0, std::memory_order_relaxed); >+ identity->is_idle.store(false, std::memory_order_relaxed); >+} >+ >+void PerThreadSem::Tick(base_internal::ThreadIdentity *identity) { >+ const int ticker = >+ identity->ticker.fetch_add(1, std::memory_order_relaxed) + 1; >+ const int wait_start = identity->wait_start.load(std::memory_order_relaxed); >+ const bool is_idle = identity->is_idle.load(std::memory_order_relaxed); >+ if (wait_start && (ticker - wait_start > Waiter::kIdlePeriods) && !is_idle) { >+ // Wakeup the waiting thread since it is time for it to become idle. >+ Waiter::GetWaiter(identity)->Poke(); >+ } >+} >+ >+} // namespace synchronization_internal >+} // namespace absl >+ >+extern "C" { >+ >+ABSL_ATTRIBUTE_WEAK void AbslInternalPerThreadSemPost( >+ absl::base_internal::ThreadIdentity *identity) { >+ absl::synchronization_internal::Waiter::GetWaiter(identity)->Post(); >+} >+ >+ABSL_ATTRIBUTE_WEAK bool AbslInternalPerThreadSemWait( >+ absl::synchronization_internal::KernelTimeout t) { >+ bool timeout = false; >+ absl::base_internal::ThreadIdentity *identity; >+ identity = absl::synchronization_internal::GetOrCreateCurrentThreadIdentity(); >+ >+ // Ensure wait_start != 0. >+ int ticker = identity->ticker.load(std::memory_order_relaxed); >+ identity->wait_start.store(ticker ? ticker : 1, std::memory_order_relaxed); >+ identity->is_idle.store(false, std::memory_order_relaxed); >+ >+ if (identity->blocked_count_ptr != nullptr) { >+ // Increment count of threads blocked in a given thread pool. >+ identity->blocked_count_ptr->fetch_add(1, std::memory_order_relaxed); >+ } >+ >+ timeout = >+ !absl::synchronization_internal::Waiter::GetWaiter(identity)->Wait(t); >+ >+ if (identity->blocked_count_ptr != nullptr) { >+ identity->blocked_count_ptr->fetch_sub(1, std::memory_order_relaxed); >+ } >+ identity->is_idle.store(false, std::memory_order_relaxed); >+ identity->wait_start.store(0, std::memory_order_relaxed); >+ return !timeout; >+} >+ >+} // extern "C" >+ >+#endif // ABSL_LOW_LEVEL_ALLOC_MISSING >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h >new file mode 100644 >index 0000000000000000000000000000000000000000..678b69e487a57fa5e06ff9a8cc2ba67e4a0faed2 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h >@@ -0,0 +1,107 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+// PerThreadSem is a low-level synchronization primitive controlling the >+// runnability of a single thread, used internally by Mutex and CondVar. >+// >+// This is NOT a general-purpose synchronization mechanism, and should not be >+// used directly by applications. Applications should use Mutex and CondVar. >+// >+// The semantics of PerThreadSem are the same as that of a counting semaphore. >+// Each thread maintains an abstract "count" value associated with its identity. >+ >+#ifndef ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_ >+#define ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_ >+ >+#include <atomic> >+ >+#include "absl/base/internal/thread_identity.h" >+#include "absl/synchronization/internal/create_thread_identity.h" >+#include "absl/synchronization/internal/kernel_timeout.h" >+ >+namespace absl { >+ >+class Mutex; >+ >+namespace synchronization_internal { >+ >+class PerThreadSem { >+ public: >+ PerThreadSem() = delete; >+ PerThreadSem(const PerThreadSem&) = delete; >+ PerThreadSem& operator=(const PerThreadSem&) = delete; >+ >+ // Routine invoked periodically (once a second) by a background thread. >+ // Has no effect on user-visible state. >+ static void Tick(base_internal::ThreadIdentity* identity); >+ >+ // --------------------------------------------------------------------------- >+ // Routines used by autosizing threadpools to detect when threads are >+ // blocked. Each thread has a counter pointer, initially zero. If non-zero, >+ // the implementation atomically increments the counter when it blocks on a >+ // semaphore, a decrements it again when it wakes. This allows a threadpool >+ // to keep track of how many of its threads are blocked. >+ // SetThreadBlockedCounter() should be used only by threadpool >+ // implementations. GetThreadBlockedCounter() should be used by modules that >+ // block threads; if the pointer returned is non-zero, the location should be >+ // incremented before the thread blocks, and decremented after it wakes. >+ static void SetThreadBlockedCounter(std::atomic<int> *counter); >+ static std::atomic<int> *GetThreadBlockedCounter(); >+ >+ private: >+ // Create the PerThreadSem associated with "identity". Initializes count=0. >+ // REQUIRES: May only be called by ThreadIdentity. >+ static void Init(base_internal::ThreadIdentity* identity); >+ >+ // Increments "identity"'s count. >+ static inline void Post(base_internal::ThreadIdentity* identity); >+ >+ // Waits until either our count > 0 or t has expired. >+ // If count > 0, decrements count and returns true. Otherwise returns false. >+ // !t.has_timeout() => Wait(t) will return true. >+ static inline bool Wait(KernelTimeout t); >+ >+ // White-listed callers. >+ friend class PerThreadSemTest; >+ friend class absl::Mutex; >+ friend absl::base_internal::ThreadIdentity* CreateThreadIdentity(); >+}; >+ >+} // namespace synchronization_internal >+} // namespace absl >+ >+// In some build configurations we pass --detect-odr-violations to the >+// gold linker. This causes it to flag weak symbol overrides as ODR >+// violations. Because ODR only applies to C++ and not C, >+// --detect-odr-violations ignores symbols not mangled with C++ names. >+// By changing our extension points to be extern "C", we dodge this >+// check. >+extern "C" { >+void AbslInternalPerThreadSemPost( >+ absl::base_internal::ThreadIdentity* identity); >+bool AbslInternalPerThreadSemWait( >+ absl::synchronization_internal::KernelTimeout t); >+} // extern "C" >+ >+void absl::synchronization_internal::PerThreadSem::Post( >+ absl::base_internal::ThreadIdentity* identity) { >+ AbslInternalPerThreadSemPost(identity); >+} >+ >+bool absl::synchronization_internal::PerThreadSem::Wait( >+ absl::synchronization_internal::KernelTimeout t) { >+ return AbslInternalPerThreadSemWait(t); >+} >+#endif // ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..2b52ea76ab0e942601eb50f160fe845b9b0685cf >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem_test.cc >@@ -0,0 +1,172 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/internal/per_thread_sem.h" >+ >+#include <atomic> >+#include <condition_variable> // NOLINT(build/c++11) >+#include <functional> >+#include <limits> >+#include <mutex> // NOLINT(build/c++11) >+#include <string> >+#include <thread> // NOLINT(build/c++11) >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/cycleclock.h" >+#include "absl/base/internal/thread_identity.h" >+#include "absl/strings/str_cat.h" >+#include "absl/time/clock.h" >+#include "absl/time/time.h" >+ >+// In this test we explicitly avoid the use of synchronization >+// primitives which might use PerThreadSem, most notably absl::Mutex. >+ >+namespace absl { >+namespace synchronization_internal { >+ >+class SimpleSemaphore { >+ public: >+ SimpleSemaphore() : count_(0) {} >+ >+ // Decrements (locks) the semaphore. If the semaphore's value is >+ // greater than zero, then the decrement proceeds, and the function >+ // returns, immediately. If the semaphore currently has the value >+ // zero, then the call blocks until it becomes possible to perform >+ // the decrement. >+ void Wait() { >+ std::unique_lock<std::mutex> lock(mu_); >+ cv_.wait(lock, [this]() { return count_ > 0; }); >+ --count_; >+ cv_.notify_one(); >+ } >+ >+ // Increments (unlocks) the semaphore. If the semaphore's value >+ // consequently becomes greater than zero, then another thread >+ // blocked Wait() call will be woken up and proceed to lock the >+ // semaphore. >+ void Post() { >+ std::lock_guard<std::mutex> lock(mu_); >+ ++count_; >+ cv_.notify_one(); >+ } >+ >+ private: >+ std::mutex mu_; >+ std::condition_variable cv_; >+ int count_; >+}; >+ >+struct ThreadData { >+ int num_iterations; // Number of replies to send. >+ SimpleSemaphore identity2_written; // Posted by thread writing identity2. >+ base_internal::ThreadIdentity *identity1; // First Post()-er. >+ base_internal::ThreadIdentity *identity2; // First Wait()-er. >+ KernelTimeout timeout; >+}; >+ >+// Need friendship with PerThreadSem. >+class PerThreadSemTest : public testing::Test { >+ public: >+ static void TimingThread(ThreadData* t) { >+ t->identity2 = GetOrCreateCurrentThreadIdentity(); >+ t->identity2_written.Post(); >+ while (t->num_iterations--) { >+ Wait(t->timeout); >+ Post(t->identity1); >+ } >+ } >+ >+ void TestTiming(const char *msg, bool timeout) { >+ static const int kNumIterations = 100; >+ ThreadData t; >+ t.num_iterations = kNumIterations; >+ t.timeout = timeout ? >+ KernelTimeout(absl::Now() + absl::Seconds(10000)) // far in the future >+ : KernelTimeout::Never(); >+ t.identity1 = GetOrCreateCurrentThreadIdentity(); >+ >+ // We can't use the Thread class here because it uses the Mutex >+ // class which will invoke PerThreadSem, so we use std::thread instead. >+ std::thread partner_thread(std::bind(TimingThread, &t)); >+ >+ // Wait for our partner thread to register their identity. >+ t.identity2_written.Wait(); >+ >+ int64_t min_cycles = std::numeric_limits<int64_t>::max(); >+ int64_t total_cycles = 0; >+ for (int i = 0; i < kNumIterations; ++i) { >+ absl::SleepFor(absl::Milliseconds(20)); >+ int64_t cycles = base_internal::CycleClock::Now(); >+ Post(t.identity2); >+ Wait(t.timeout); >+ cycles = base_internal::CycleClock::Now() - cycles; >+ min_cycles = std::min(min_cycles, cycles); >+ total_cycles += cycles; >+ } >+ std::string out = >+ StrCat(msg, "min cycle count=", min_cycles, " avg cycle count=", >+ absl::SixDigits(static_cast<double>(total_cycles) / >+ kNumIterations)); >+ printf("%s\n", out.c_str()); >+ >+ partner_thread.join(); >+ } >+ >+ protected: >+ static void Post(base_internal::ThreadIdentity *id) { >+ PerThreadSem::Post(id); >+ } >+ static bool Wait(KernelTimeout t) { >+ return PerThreadSem::Wait(t); >+ } >+ >+ // convenience overload >+ static bool Wait(absl::Time t) { >+ return Wait(KernelTimeout(t)); >+ } >+ >+ static void Tick(base_internal::ThreadIdentity *identity) { >+ PerThreadSem::Tick(identity); >+ } >+}; >+ >+namespace { >+ >+TEST_F(PerThreadSemTest, WithoutTimeout) { >+ PerThreadSemTest::TestTiming("Without timeout: ", false); >+} >+ >+TEST_F(PerThreadSemTest, WithTimeout) { >+ PerThreadSemTest::TestTiming("With timeout: ", true); >+} >+ >+TEST_F(PerThreadSemTest, Timeouts) { >+ absl::Time timeout = absl::Now() + absl::Milliseconds(50); >+ EXPECT_FALSE(Wait(timeout)); >+ EXPECT_LE(timeout, absl::Now()); >+ >+ absl::Time negative_timeout = absl::UnixEpoch() - absl::Milliseconds(100); >+ EXPECT_FALSE(Wait(negative_timeout)); >+ EXPECT_LE(negative_timeout, absl::Now()); // trivially true :) >+ >+ Post(GetOrCreateCurrentThreadIdentity()); >+ // The wait here has an expired timeout, but we have a wake to consume, >+ // so this should succeed >+ EXPECT_TRUE(Wait(negative_timeout)); >+} >+ >+} // namespace >+ >+} // namespace synchronization_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/thread_pool.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/thread_pool.h >new file mode 100644 >index 0000000000000000000000000000000000000000..846404277a03e78e58f3344edf690aeaef89c235 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/thread_pool.h >@@ -0,0 +1,90 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_SYNCHRONIZATION_INTERNAL_THREAD_POOL_H_ >+#define ABSL_SYNCHRONIZATION_INTERNAL_THREAD_POOL_H_ >+ >+#include <cassert> >+#include <functional> >+#include <queue> >+#include <thread> // NOLINT(build/c++11) >+#include <vector> >+ >+#include "absl/base/thread_annotations.h" >+#include "absl/synchronization/mutex.h" >+ >+namespace absl { >+namespace synchronization_internal { >+ >+// A simple ThreadPool implementation for tests. >+class ThreadPool { >+ public: >+ explicit ThreadPool(int num_threads) { >+ for (int i = 0; i < num_threads; ++i) { >+ threads_.push_back(std::thread(&ThreadPool::WorkLoop, this)); >+ } >+ } >+ >+ ThreadPool(const ThreadPool &) = delete; >+ ThreadPool &operator=(const ThreadPool &) = delete; >+ >+ ~ThreadPool() { >+ { >+ absl::MutexLock l(&mu_); >+ for (int i = 0; i < threads_.size(); ++i) { >+ queue_.push(nullptr); // Shutdown signal. >+ } >+ } >+ for (auto &t : threads_) { >+ t.join(); >+ } >+ } >+ >+ // Schedule a function to be run on a ThreadPool thread immediately. >+ void Schedule(std::function<void()> func) { >+ assert(func != nullptr); >+ absl::MutexLock l(&mu_); >+ queue_.push(std::move(func)); >+ } >+ >+ private: >+ bool WorkAvailable() const EXCLUSIVE_LOCKS_REQUIRED(mu_) { >+ return !queue_.empty(); >+ } >+ >+ void WorkLoop() { >+ while (true) { >+ std::function<void()> func; >+ { >+ absl::MutexLock l(&mu_); >+ mu_.Await(absl::Condition(this, &ThreadPool::WorkAvailable)); >+ func = std::move(queue_.front()); >+ queue_.pop(); >+ } >+ if (func == nullptr) { // Shutdown signal. >+ break; >+ } >+ func(); >+ } >+ } >+ >+ absl::Mutex mu_; >+ std::queue<std::function<void()>> queue_ GUARDED_BY(mu_); >+ std::vector<std::thread> threads_; >+}; >+ >+} // namespace synchronization_internal >+} // namespace absl >+ >+#endif // ABSL_SYNCHRONIZATION_INTERNAL_THREAD_POOL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/waiter.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/waiter.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..768c52085cd3967dd7f3d66b0c3111f9057130c7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/waiter.cc >@@ -0,0 +1,412 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/internal/waiter.h" >+ >+#include "absl/base/config.h" >+ >+#ifdef _WIN32 >+#include <windows.h> >+#else >+#include <pthread.h> >+#include <sys/time.h> >+#include <unistd.h> >+#endif >+ >+#ifdef __linux__ >+#include <linux/futex.h> >+#include <sys/syscall.h> >+#endif >+ >+#ifdef ABSL_HAVE_SEMAPHORE_H >+#include <semaphore.h> >+#endif >+ >+#include <errno.h> >+#include <stdio.h> >+#include <time.h> >+ >+#include <atomic> >+#include <cassert> >+#include <cstdint> >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/thread_identity.h" >+#include "absl/base/optimization.h" >+#include "absl/synchronization/internal/kernel_timeout.h" >+ >+namespace absl { >+namespace synchronization_internal { >+ >+static void MaybeBecomeIdle() { >+ base_internal::ThreadIdentity *identity = >+ base_internal::CurrentThreadIdentityIfPresent(); >+ assert(identity != nullptr); >+ const bool is_idle = identity->is_idle.load(std::memory_order_relaxed); >+ const int ticker = identity->ticker.load(std::memory_order_relaxed); >+ const int wait_start = identity->wait_start.load(std::memory_order_relaxed); >+ if (!is_idle && ticker - wait_start > Waiter::kIdlePeriods) { >+ identity->is_idle.store(true, std::memory_order_relaxed); >+ } >+} >+ >+#if ABSL_WAITER_MODE == ABSL_WAITER_MODE_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_WAIT_BITSET >+#define FUTEX_WAIT_BITSET 9 >+#endif >+#ifndef FUTEX_PRIVATE_FLAG >+#define FUTEX_PRIVATE_FLAG 128 >+#endif >+#ifndef FUTEX_CLOCK_REALTIME >+#define FUTEX_CLOCK_REALTIME 256 >+#endif >+#ifndef FUTEX_BITSET_MATCH_ANY >+#define FUTEX_BITSET_MATCH_ANY 0xFFFFFFFF >+#endif >+#endif >+class Futex { >+ public: >+ static int WaitUntil(std::atomic<int32_t> *v, int32_t val, >+ KernelTimeout t) { >+ int err = 0; >+ if (t.has_timeout()) { >+ // https://locklessinc.com/articles/futex_cheat_sheet/ >+ // Unlike FUTEX_WAIT, FUTEX_WAIT_BITSET uses absolute time. >+ struct timespec abs_timeout = t.MakeAbsTimespec(); >+ // Atomically check that the futex value is still 0, and if it >+ // is, sleep until abs_timeout or until woken by FUTEX_WAKE. >+ err = syscall( >+ SYS_futex, reinterpret_cast<int32_t *>(v), >+ FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME, val, >+ &abs_timeout, nullptr, FUTEX_BITSET_MATCH_ANY); >+ } else { >+ // Atomically check that the futex value is still 0, and if it >+ // is, sleep until woken by FUTEX_WAKE. >+ err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v), >+ FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, nullptr); >+ } >+ if (err != 0) { >+ err = -errno; >+ } >+ return err; >+ } >+ >+ static int Wake(std::atomic<int32_t> *v, int32_t count) { >+ int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v), >+ FUTEX_WAKE | FUTEX_PRIVATE_FLAG, count); >+ if (ABSL_PREDICT_FALSE(err < 0)) { >+ err = -errno; >+ } >+ return err; >+ } >+}; >+ >+void Waiter::Init() { >+ futex_.store(0, std::memory_order_relaxed); >+} >+ >+bool Waiter::Wait(KernelTimeout t) { >+ // Loop until we can atomically decrement futex from a positive >+ // value, waiting on a futex while we believe it is zero. >+ while (true) { >+ int32_t x = futex_.load(std::memory_order_relaxed); >+ if (x != 0) { >+ if (!futex_.compare_exchange_weak(x, x - 1, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ continue; // Raced with someone, retry. >+ } >+ return true; // Consumed a wakeup, we are done. >+ } >+ >+ const int err = Futex::WaitUntil(&futex_, 0, t); >+ if (err != 0) { >+ if (err == -EINTR || err == -EWOULDBLOCK) { >+ // Do nothing, the loop will retry. >+ } else if (err == -ETIMEDOUT) { >+ return false; >+ } else { >+ ABSL_RAW_LOG(FATAL, "Futex operation failed with error %d\n", err); >+ } >+ } >+ >+ MaybeBecomeIdle(); >+ } >+} >+ >+void Waiter::Post() { >+ if (futex_.fetch_add(1, std::memory_order_release) == 0) { >+ // We incremented from 0, need to wake a potential waker. >+ Poke(); >+ } >+} >+ >+void Waiter::Poke() { >+ // Wake one thread waiting on the futex. >+ const int err = Futex::Wake(&futex_, 1); >+ if (ABSL_PREDICT_FALSE(err < 0)) { >+ ABSL_RAW_LOG(FATAL, "Futex operation failed with error %d\n", err); >+ } >+} >+ >+#elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_CONDVAR >+ >+class PthreadMutexHolder { >+ public: >+ explicit PthreadMutexHolder(pthread_mutex_t *mu) : mu_(mu) { >+ const int err = pthread_mutex_lock(mu_); >+ if (err != 0) { >+ ABSL_RAW_LOG(FATAL, "pthread_mutex_lock failed: %d", err); >+ } >+ } >+ >+ PthreadMutexHolder(const PthreadMutexHolder &rhs) = delete; >+ PthreadMutexHolder &operator=(const PthreadMutexHolder &rhs) = delete; >+ >+ ~PthreadMutexHolder() { >+ const int err = pthread_mutex_unlock(mu_); >+ if (err != 0) { >+ ABSL_RAW_LOG(FATAL, "pthread_mutex_unlock failed: %d", err); >+ } >+ } >+ >+ private: >+ pthread_mutex_t *mu_; >+}; >+ >+void Waiter::Init() { >+ const int err = pthread_mutex_init(&mu_, 0); >+ if (err != 0) { >+ ABSL_RAW_LOG(FATAL, "pthread_mutex_init failed: %d", err); >+ } >+ >+ const int err2 = pthread_cond_init(&cv_, 0); >+ if (err2 != 0) { >+ ABSL_RAW_LOG(FATAL, "pthread_cond_init failed: %d", err2); >+ } >+ >+ waiter_count_.store(0, std::memory_order_relaxed); >+ wakeup_count_.store(0, std::memory_order_relaxed); >+} >+ >+bool Waiter::Wait(KernelTimeout t) { >+ struct timespec abs_timeout; >+ if (t.has_timeout()) { >+ abs_timeout = t.MakeAbsTimespec(); >+ } >+ >+ PthreadMutexHolder h(&mu_); >+ waiter_count_.fetch_add(1, std::memory_order_relaxed); >+ // Loop until we find a wakeup to consume or timeout. >+ while (true) { >+ int x = wakeup_count_.load(std::memory_order_relaxed); >+ if (x != 0) { >+ if (!wakeup_count_.compare_exchange_weak(x, x - 1, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ continue; // Raced with someone, retry. >+ } >+ // Successfully consumed a wakeup, we're done. >+ waiter_count_.fetch_sub(1, std::memory_order_relaxed); >+ return true; >+ } >+ >+ // No wakeups available, time to wait. >+ if (!t.has_timeout()) { >+ const int err = pthread_cond_wait(&cv_, &mu_); >+ if (err != 0) { >+ ABSL_RAW_LOG(FATAL, "pthread_cond_wait failed: %d", err); >+ } >+ } else { >+ const int err = pthread_cond_timedwait(&cv_, &mu_, &abs_timeout); >+ if (err == ETIMEDOUT) { >+ waiter_count_.fetch_sub(1, std::memory_order_relaxed); >+ return false; >+ } >+ if (err != 0) { >+ ABSL_RAW_LOG(FATAL, "pthread_cond_wait failed: %d", err); >+ } >+ } >+ MaybeBecomeIdle(); >+ } >+} >+ >+void Waiter::Post() { >+ wakeup_count_.fetch_add(1, std::memory_order_release); >+ Poke(); >+} >+ >+void Waiter::Poke() { >+ if (waiter_count_.load(std::memory_order_relaxed) == 0) { >+ return; >+ } >+ // Potentially a waker. Take the lock and check again. >+ PthreadMutexHolder h(&mu_); >+ if (waiter_count_.load(std::memory_order_relaxed) == 0) { >+ return; >+ } >+ const int err = pthread_cond_signal(&cv_); >+ if (err != 0) { >+ ABSL_RAW_LOG(FATAL, "pthread_cond_signal failed: %d", err); >+ } >+} >+ >+#elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_SEM >+ >+void Waiter::Init() { >+ if (sem_init(&sem_, 0, 0) != 0) { >+ ABSL_RAW_LOG(FATAL, "sem_init failed with errno %d\n", errno); >+ } >+ wakeups_.store(0, std::memory_order_relaxed); >+} >+ >+bool Waiter::Wait(KernelTimeout t) { >+ struct timespec abs_timeout; >+ if (t.has_timeout()) { >+ abs_timeout = t.MakeAbsTimespec(); >+ } >+ >+ // Loop until we timeout or consume a wakeup. >+ while (true) { >+ int x = wakeups_.load(std::memory_order_relaxed); >+ if (x != 0) { >+ if (!wakeups_.compare_exchange_weak(x, x - 1, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ continue; // Raced with someone, retry. >+ } >+ // Successfully consumed a wakeup, we're done. >+ return true; >+ } >+ >+ // Nothing to consume, wait (looping on EINTR). >+ while (true) { >+ if (!t.has_timeout()) { >+ if (sem_wait(&sem_) == 0) break; >+ if (errno == EINTR) continue; >+ ABSL_RAW_LOG(FATAL, "sem_wait failed: %d", errno); >+ } else { >+ if (sem_timedwait(&sem_, &abs_timeout) == 0) break; >+ if (errno == EINTR) continue; >+ if (errno == ETIMEDOUT) return false; >+ ABSL_RAW_LOG(FATAL, "sem_timedwait failed: %d", errno); >+ } >+ } >+ MaybeBecomeIdle(); >+ } >+} >+ >+void Waiter::Post() { >+ wakeups_.fetch_add(1, std::memory_order_release); // Post a wakeup. >+ Poke(); >+} >+ >+void Waiter::Poke() { >+ if (sem_post(&sem_) != 0) { // Wake any semaphore waiter. >+ ABSL_RAW_LOG(FATAL, "sem_post failed with errno %d\n", errno); >+ } >+} >+ >+#elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_WIN32 >+ >+class LockHolder { >+ public: >+ explicit LockHolder(SRWLOCK* mu) : mu_(mu) { >+ AcquireSRWLockExclusive(mu_); >+ } >+ >+ LockHolder(const LockHolder&) = delete; >+ LockHolder& operator=(const LockHolder&) = delete; >+ >+ ~LockHolder() { >+ ReleaseSRWLockExclusive(mu_); >+ } >+ >+ private: >+ SRWLOCK* mu_; >+}; >+ >+void Waiter::Init() { >+ InitializeSRWLock(&mu_); >+ InitializeConditionVariable(&cv_); >+ waiter_count_.store(0, std::memory_order_relaxed); >+ wakeup_count_.store(0, std::memory_order_relaxed); >+} >+ >+bool Waiter::Wait(KernelTimeout t) { >+ LockHolder h(&mu_); >+ waiter_count_.fetch_add(1, std::memory_order_relaxed); >+ >+ // Loop until we find a wakeup to consume or timeout. >+ while (true) { >+ int x = wakeup_count_.load(std::memory_order_relaxed); >+ if (x != 0) { >+ if (!wakeup_count_.compare_exchange_weak(x, x - 1, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ continue; // Raced with someone, retry. >+ } >+ // Successfully consumed a wakeup, we're done. >+ waiter_count_.fetch_sub(1, std::memory_order_relaxed); >+ return true; >+ } >+ >+ // No wakeups available, time to wait. >+ if (!SleepConditionVariableSRW( >+ &cv_, &mu_, t.InMillisecondsFromNow(), 0)) { >+ // GetLastError() returns a Win32 DWORD, but we assign to >+ // unsigned long to simplify the ABSL_RAW_LOG case below. The uniform >+ // initialization guarantees this is not a narrowing conversion. >+ const unsigned long err{GetLastError()}; // NOLINT(runtime/int) >+ if (err == ERROR_TIMEOUT) { >+ waiter_count_.fetch_sub(1, std::memory_order_relaxed); >+ return false; >+ } else { >+ ABSL_RAW_LOG(FATAL, "SleepConditionVariableSRW failed: %lu", err); >+ } >+ } >+ >+ MaybeBecomeIdle(); >+ } >+} >+ >+void Waiter::Post() { >+ wakeup_count_.fetch_add(1, std::memory_order_release); >+ Poke(); >+} >+ >+void Waiter::Poke() { >+ if (waiter_count_.load(std::memory_order_relaxed) == 0) { >+ return; >+ } >+ // Potentially a waker. Take the lock and check again. >+ LockHolder h(&mu_); >+ if (waiter_count_.load(std::memory_order_relaxed) == 0) { >+ return; >+ } >+ WakeConditionVariable(&cv_); >+} >+ >+#else >+#error Unknown ABSL_WAITER_MODE >+#endif >+ >+} // namespace synchronization_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/waiter.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/waiter.h >new file mode 100644 >index 0000000000000000000000000000000000000000..23166f4bfa3786a2415c16bb153d1b8ad781cf29 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/internal/waiter.h >@@ -0,0 +1,139 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+ >+#ifndef ABSL_SYNCHRONIZATION_INTERNAL_WAITER_H_ >+#define ABSL_SYNCHRONIZATION_INTERNAL_WAITER_H_ >+ >+#include "absl/base/config.h" >+ >+#ifdef _WIN32 >+#include <windows.h> >+#else >+#include <pthread.h> >+#endif >+ >+#ifdef ABSL_HAVE_SEMAPHORE_H >+#include <semaphore.h> >+#endif >+ >+#include <atomic> >+#include <cstdint> >+ >+#include "absl/base/internal/thread_identity.h" >+#include "absl/synchronization/internal/kernel_timeout.h" >+ >+// May be chosen at compile time via -DABSL_FORCE_WAITER_MODE=<index> >+#define ABSL_WAITER_MODE_FUTEX 0 >+#define ABSL_WAITER_MODE_SEM 1 >+#define ABSL_WAITER_MODE_CONDVAR 2 >+#define ABSL_WAITER_MODE_WIN32 3 >+ >+#if defined(ABSL_FORCE_WAITER_MODE) >+#define ABSL_WAITER_MODE ABSL_FORCE_WAITER_MODE >+#elif defined(_WIN32) >+#define ABSL_WAITER_MODE ABSL_WAITER_MODE_WIN32 >+#elif defined(__linux__) >+#define ABSL_WAITER_MODE ABSL_WAITER_MODE_FUTEX >+#elif defined(ABSL_HAVE_SEMAPHORE_H) >+#define ABSL_WAITER_MODE ABSL_WAITER_MODE_SEM >+#else >+#define ABSL_WAITER_MODE ABSL_WAITER_MODE_CONDVAR >+#endif >+ >+namespace absl { >+namespace synchronization_internal { >+ >+// Waiter is an OS-specific semaphore. >+class Waiter { >+ public: >+ // No constructor, instances use the reserved space in ThreadIdentity. >+ // All initialization logic belongs in `Init()`. >+ Waiter() = delete; >+ Waiter(const Waiter&) = delete; >+ Waiter& operator=(const Waiter&) = delete; >+ >+ // Prepare any data to track waits. >+ void Init(); >+ >+ // Blocks the calling thread until a matching call to `Post()` or >+ // `t` has passed. Returns `true` if woken (`Post()` called), >+ // `false` on timeout. >+ bool Wait(KernelTimeout t); >+ >+ // Restart the caller of `Wait()` as with a normal semaphore. >+ void Post(); >+ >+ // If anyone is waiting, wake them up temporarily and cause them to >+ // call `MaybeBecomeIdle()`. They will then return to waiting for a >+ // `Post()` or timeout. >+ void Poke(); >+ >+ // Returns the Waiter associated with the identity. >+ static Waiter* GetWaiter(base_internal::ThreadIdentity* identity) { >+ static_assert( >+ sizeof(Waiter) <= sizeof(base_internal::ThreadIdentity::WaiterState), >+ "Insufficient space for Waiter"); >+ return reinterpret_cast<Waiter*>(identity->waiter_state.data); >+ } >+ >+ // How many periods to remain idle before releasing resources >+#ifndef THREAD_SANITIZER >+ static const int kIdlePeriods = 60; >+#else >+ // Memory consumption under ThreadSanitizer is a serious concern, >+ // so we release resources sooner. The value of 1 leads to 1 to 2 second >+ // delay before marking a thread as idle. >+ static const int kIdlePeriods = 1; >+#endif >+ >+ private: >+#if ABSL_WAITER_MODE == ABSL_WAITER_MODE_FUTEX >+ // Futexes are defined by specification to be 32-bits. >+ // Thus std::atomic<int32_t> must be just an int32_t with lockfree methods. >+ std::atomic<int32_t> futex_; >+ static_assert(sizeof(int32_t) == sizeof(futex_), "Wrong size for futex"); >+ >+#elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_CONDVAR >+ pthread_mutex_t mu_; >+ pthread_cond_t cv_; >+ std::atomic<int> waiter_count_; >+ std::atomic<int> wakeup_count_; // Unclaimed wakeups, written under lock. >+ >+#elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_SEM >+ sem_t sem_; >+ // This seems superfluous, but for Poke() we need to cause spurious >+ // wakeups on the semaphore. Hence we can't actually use the >+ // semaphore's count. >+ std::atomic<int> wakeups_; >+ >+#elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_WIN32 >+ // The Windows API has lots of choices for synchronization >+ // primivitives. We are using SRWLOCK and CONDITION_VARIABLE >+ // because they don't require a destructor to release system >+ // resources. >+ SRWLOCK mu_; >+ CONDITION_VARIABLE cv_; >+ std::atomic<int> waiter_count_; >+ std::atomic<int> wakeup_count_; >+ >+#else >+ #error Unknown ABSL_WAITER_MODE >+#endif >+}; >+ >+} // namespace synchronization_internal >+} // namespace absl >+ >+#endif // ABSL_SYNCHRONIZATION_INTERNAL_WAITER_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..90c9009b18fafc9ea295cab146c65dd682cbf572 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc >@@ -0,0 +1,132 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <cstdlib> >+#include <thread> // NOLINT(build/c++11), Abseil test >+#include <type_traits> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/thread_annotations.h" >+#include "absl/synchronization/mutex.h" >+#include "absl/synchronization/notification.h" >+ >+namespace { >+ >+// A two-threaded test which checks that Mutex, CondVar, and Notification have >+// correct basic functionality. The intent is to establish that they >+// function correctly in various phases of construction and destruction. >+// >+// Thread one acquires a lock on 'mutex', wakes thread two via 'notification', >+// then waits for 'state' to be set, as signalled by 'condvar'. >+// >+// Thread two waits on 'notification', then sets 'state' inside the 'mutex', >+// signalling the change via 'condvar'. >+// >+// These tests use ABSL_RAW_CHECK to validate invariants, rather than EXPECT or >+// ASSERT from gUnit, because we need to invoke them during global destructors, >+// when gUnit teardown would have already begun. >+void ThreadOne(absl::Mutex* mutex, absl::CondVar* condvar, >+ absl::Notification* notification, bool* state) { >+ // Test that the notification is in a valid initial state. >+ ABSL_RAW_CHECK(!notification->HasBeenNotified(), "invalid Notification"); >+ ABSL_RAW_CHECK(*state == false, "*state not initialized"); >+ >+ { >+ absl::MutexLock lock(mutex); >+ >+ notification->Notify(); >+ ABSL_RAW_CHECK(notification->HasBeenNotified(), "invalid Notification"); >+ >+ while (*state == false) { >+ condvar->Wait(mutex); >+ } >+ } >+} >+ >+void ThreadTwo(absl::Mutex* mutex, absl::CondVar* condvar, >+ absl::Notification* notification, bool* state) { >+ ABSL_RAW_CHECK(*state == false, "*state not initialized"); >+ >+ // Wake thread one >+ notification->WaitForNotification(); >+ ABSL_RAW_CHECK(notification->HasBeenNotified(), "invalid Notification"); >+ { >+ absl::MutexLock lock(mutex); >+ *state = true; >+ condvar->Signal(); >+ } >+} >+ >+// Launch thread 1 and thread 2, and block on their completion. >+// If any of 'mutex', 'condvar', or 'notification' is nullptr, use a locally >+// constructed instance instead. >+void RunTests(absl::Mutex* mutex, absl::CondVar* condvar, >+ absl::Notification* notification) { >+ absl::Mutex default_mutex; >+ absl::CondVar default_condvar; >+ absl::Notification default_notification; >+ if (!mutex) { >+ mutex = &default_mutex; >+ } >+ if (!condvar) { >+ condvar = &default_condvar; >+ } >+ if (!notification) { >+ notification = &default_notification; >+ } >+ bool state = false; >+ std::thread thread_one(ThreadOne, mutex, condvar, notification, &state); >+ std::thread thread_two(ThreadTwo, mutex, condvar, notification, &state); >+ thread_one.join(); >+ thread_two.join(); >+} >+ >+void TestLocals() { >+ absl::Mutex mutex; >+ absl::CondVar condvar; >+ absl::Notification notification; >+ RunTests(&mutex, &condvar, ¬ification); >+} >+ >+// Global variables during start and termination >+// >+// In a translation unit, static storage duration variables are initialized in >+// the order of their definitions, and destroyed in the reverse order of their >+// definitions. We can use this to arrange for tests to be run on these objects >+// before they are created, and after they are destroyed. >+ >+using Function = void (*)(); >+ >+class OnConstruction { >+ public: >+ explicit OnConstruction(Function fn) { fn(); } >+}; >+ >+class OnDestruction { >+ public: >+ explicit OnDestruction(Function fn) : fn_(fn) {} >+ ~OnDestruction() { fn_(); } >+ private: >+ Function fn_; >+}; >+ >+} // namespace >+ >+int main() { >+ TestLocals(); >+ // Explicitly call exit(0) here, to make it clear that we intend for the >+ // above global object destructors to run. >+ std::exit(0); >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..80f34f035fc6b679eeb0b14d89cfaeaa1f80f051 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex.cc >@@ -0,0 +1,2687 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/mutex.h" >+ >+#ifdef _WIN32 >+#include <windows.h> >+#ifdef ERROR >+#undef ERROR >+#endif >+#else >+#include <fcntl.h> >+#include <pthread.h> >+#include <sched.h> >+#include <sys/time.h> >+#endif >+ >+#include <assert.h> >+#include <errno.h> >+#include <stdio.h> >+#include <stdlib.h> >+#include <string.h> >+#include <time.h> >+ >+#include <algorithm> >+#include <atomic> >+#include <cinttypes> >+#include <thread> // NOLINT(build/c++11) >+ >+#include "absl/base/attributes.h" >+#include "absl/base/config.h" >+#include "absl/base/dynamic_annotations.h" >+#include "absl/base/internal/atomic_hook.h" >+#include "absl/base/internal/cycleclock.h" >+#include "absl/base/internal/hide_ptr.h" >+#include "absl/base/internal/low_level_alloc.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/spinlock.h" >+#include "absl/base/internal/sysinfo.h" >+#include "absl/base/internal/thread_identity.h" >+#include "absl/base/port.h" >+#include "absl/debugging/stacktrace.h" >+#include "absl/debugging/symbolize.h" >+#include "absl/synchronization/internal/graphcycles.h" >+#include "absl/synchronization/internal/per_thread_sem.h" >+#include "absl/time/time.h" >+ >+using absl::base_internal::CurrentThreadIdentityIfPresent; >+using absl::base_internal::PerThreadSynch; >+using absl::base_internal::ThreadIdentity; >+using absl::synchronization_internal::GetOrCreateCurrentThreadIdentity; >+using absl::synchronization_internal::GraphCycles; >+using absl::synchronization_internal::GraphId; >+using absl::synchronization_internal::InvalidGraphId; >+using absl::synchronization_internal::KernelTimeout; >+using absl::synchronization_internal::PerThreadSem; >+ >+extern "C" { >+ABSL_ATTRIBUTE_WEAK void AbslInternalMutexYield() { std::this_thread::yield(); } >+} // extern "C" >+ >+namespace absl { >+ >+namespace { >+ >+#if defined(THREAD_SANITIZER) >+constexpr OnDeadlockCycle kDeadlockDetectionDefault = OnDeadlockCycle::kIgnore; >+#else >+constexpr OnDeadlockCycle kDeadlockDetectionDefault = OnDeadlockCycle::kAbort; >+#endif >+ >+ABSL_CONST_INIT std::atomic<OnDeadlockCycle> synch_deadlock_detection( >+ kDeadlockDetectionDefault); >+ABSL_CONST_INIT std::atomic<bool> synch_check_invariants(false); >+ >+// ------------------------------------------ spinlock support >+ >+// Make sure read-only globals used in the Mutex code are contained on the >+// same cacheline and cacheline aligned to eliminate any false sharing with >+// other globals from this and other modules. >+static struct MutexGlobals { >+ MutexGlobals() { >+ // Find machine-specific data needed for Delay() and >+ // TryAcquireWithSpinning(). This runs in the global constructor >+ // sequence, and before that zeros are safe values. >+ num_cpus = absl::base_internal::NumCPUs(); >+ spinloop_iterations = num_cpus > 1 ? 1500 : 0; >+ } >+ int num_cpus; >+ int spinloop_iterations; >+ // Pad this struct to a full cacheline to prevent false sharing. >+ char padding[ABSL_CACHELINE_SIZE - 2 * sizeof(int)]; >+} ABSL_CACHELINE_ALIGNED mutex_globals; >+static_assert( >+ sizeof(MutexGlobals) == ABSL_CACHELINE_SIZE, >+ "MutexGlobals must occupy an entire cacheline to prevent false sharing"); >+ >+ABSL_CONST_INIT absl::base_internal::AtomicHook<void (*)(int64_t wait_cycles)> >+ submit_profile_data; >+ABSL_CONST_INIT absl::base_internal::AtomicHook< >+ void (*)(const char *msg, const void *obj, int64_t wait_cycles)> mutex_tracer; >+ABSL_CONST_INIT absl::base_internal::AtomicHook< >+ void (*)(const char *msg, const void *cv)> cond_var_tracer; >+ABSL_CONST_INIT absl::base_internal::AtomicHook< >+ bool (*)(const void *pc, char *out, int out_size)> >+ symbolizer(absl::Symbolize); >+ >+} // namespace >+ >+void RegisterMutexProfiler(void (*fn)(int64_t wait_timestamp)) { >+ submit_profile_data.Store(fn); >+} >+ >+void RegisterMutexTracer(void (*fn)(const char *msg, const void *obj, >+ int64_t wait_cycles)) { >+ mutex_tracer.Store(fn); >+} >+ >+void RegisterCondVarTracer(void (*fn)(const char *msg, const void *cv)) { >+ cond_var_tracer.Store(fn); >+} >+ >+void RegisterSymbolizer(bool (*fn)(const void *pc, char *out, int out_size)) { >+ symbolizer.Store(fn); >+} >+ >+// spinlock delay on iteration c. Returns new c. >+namespace { >+ enum DelayMode { AGGRESSIVE, GENTLE }; >+}; >+static int Delay(int32_t c, DelayMode mode) { >+ // If this a uniprocessor, only yield/sleep. Otherwise, if the mode is >+ // aggressive then spin many times before yielding. If the mode is >+ // gentle then spin only a few times before yielding. Aggressive spinning is >+ // used to ensure that an Unlock() call, which must get the spin lock for >+ // any thread to make progress gets it without undue delay. >+ int32_t limit = (mutex_globals.num_cpus > 1) ? >+ ((mode == AGGRESSIVE) ? 5000 : 250) : 0; >+ if (c < limit) { >+ c++; // spin >+ } else { >+ ABSL_TSAN_MUTEX_PRE_DIVERT(0, 0); >+ if (c == limit) { // yield once >+ AbslInternalMutexYield(); >+ c++; >+ } else { // then wait >+ absl::SleepFor(absl::Microseconds(10)); >+ c = 0; >+ } >+ ABSL_TSAN_MUTEX_POST_DIVERT(0, 0); >+ } >+ return (c); >+} >+ >+// --------------------------Generic atomic ops >+// Ensure that "(*pv & bits) == bits" by doing an atomic update of "*pv" to >+// "*pv | bits" if necessary. Wait until (*pv & wait_until_clear)==0 >+// before making any change. >+// This is used to set flags in mutex and condition variable words. >+static void AtomicSetBits(std::atomic<intptr_t>* pv, intptr_t bits, >+ intptr_t wait_until_clear) { >+ intptr_t v; >+ do { >+ v = pv->load(std::memory_order_relaxed); >+ } while ((v & bits) != bits && >+ ((v & wait_until_clear) != 0 || >+ !pv->compare_exchange_weak(v, v | bits, >+ std::memory_order_release, >+ std::memory_order_relaxed))); >+} >+ >+// Ensure that "(*pv & bits) == 0" by doing an atomic update of "*pv" to >+// "*pv & ~bits" if necessary. Wait until (*pv & wait_until_clear)==0 >+// before making any change. >+// This is used to unset flags in mutex and condition variable words. >+static void AtomicClearBits(std::atomic<intptr_t>* pv, intptr_t bits, >+ intptr_t wait_until_clear) { >+ intptr_t v; >+ do { >+ v = pv->load(std::memory_order_relaxed); >+ } while ((v & bits) != 0 && >+ ((v & wait_until_clear) != 0 || >+ !pv->compare_exchange_weak(v, v & ~bits, >+ std::memory_order_release, >+ std::memory_order_relaxed))); >+} >+ >+//------------------------------------------------------------------ >+ >+// Data for doing deadlock detection. >+static absl::base_internal::SpinLock deadlock_graph_mu( >+ absl::base_internal::kLinkerInitialized); >+ >+// graph used to detect deadlocks. >+static GraphCycles *deadlock_graph GUARDED_BY(deadlock_graph_mu) >+ PT_GUARDED_BY(deadlock_graph_mu); >+ >+//------------------------------------------------------------------ >+// An event mechanism for debugging mutex use. >+// It also allows mutexes to be given names for those who can't handle >+// addresses, and instead like to give their data structures names like >+// "Henry", "Fido", or "Rupert IV, King of Yondavia". >+ >+namespace { // to prevent name pollution >+enum { // Mutex and CondVar events passed as "ev" to PostSynchEvent >+ // Mutex events >+ SYNCH_EV_TRYLOCK_SUCCESS, >+ SYNCH_EV_TRYLOCK_FAILED, >+ SYNCH_EV_READERTRYLOCK_SUCCESS, >+ SYNCH_EV_READERTRYLOCK_FAILED, >+ SYNCH_EV_LOCK, >+ SYNCH_EV_LOCK_RETURNING, >+ SYNCH_EV_READERLOCK, >+ SYNCH_EV_READERLOCK_RETURNING, >+ SYNCH_EV_UNLOCK, >+ SYNCH_EV_READERUNLOCK, >+ >+ // CondVar events >+ SYNCH_EV_WAIT, >+ SYNCH_EV_WAIT_RETURNING, >+ SYNCH_EV_SIGNAL, >+ SYNCH_EV_SIGNALALL, >+}; >+ >+enum { // Event flags >+ SYNCH_F_R = 0x01, // reader event >+ SYNCH_F_LCK = 0x02, // PostSynchEvent called with mutex held >+ SYNCH_F_ACQ = 0x04, // event is an acquire >+ >+ SYNCH_F_LCK_W = SYNCH_F_LCK, >+ SYNCH_F_LCK_R = SYNCH_F_LCK | SYNCH_F_R, >+ SYNCH_F_ACQ_W = SYNCH_F_ACQ, >+ SYNCH_F_ACQ_R = SYNCH_F_ACQ | SYNCH_F_R, >+}; >+} // anonymous namespace >+ >+// Properties of the events. >+static const struct { >+ int flags; >+ const char *msg; >+} event_properties[] = { >+ { SYNCH_F_LCK_W|SYNCH_F_ACQ_W, "TryLock succeeded " }, >+ { 0, "TryLock failed " }, >+ { SYNCH_F_LCK_R|SYNCH_F_ACQ_R, "ReaderTryLock succeeded " }, >+ { 0, "ReaderTryLock failed " }, >+ { SYNCH_F_ACQ_W, "Lock blocking " }, >+ { SYNCH_F_LCK_W, "Lock returning " }, >+ { SYNCH_F_ACQ_R, "ReaderLock blocking " }, >+ { SYNCH_F_LCK_R, "ReaderLock returning " }, >+ { SYNCH_F_LCK_W, "Unlock " }, >+ { SYNCH_F_LCK_R, "ReaderUnlock " }, >+ { 0, "Wait on " }, >+ { 0, "Wait unblocked " }, >+ { 0, "Signal on " }, >+ { 0, "SignalAll on " }, >+}; >+static absl::base_internal::SpinLock synch_event_mu( >+ absl::base_internal::kLinkerInitialized); >+// protects synch_event >+ >+// Hash table size; should be prime > 2. >+// Can't be too small, as it's used for deadlock detection information. >+static const uint32_t kNSynchEvent = 1031; >+ >+static struct SynchEvent { // this is a trivial hash table for the events >+ // struct is freed when refcount reaches 0 >+ int refcount GUARDED_BY(synch_event_mu); >+ >+ // buckets have linear, 0-terminated chains >+ SynchEvent *next GUARDED_BY(synch_event_mu); >+ >+ // Constant after initialization >+ uintptr_t masked_addr; // object at this address is called "name" >+ >+ // No explicit synchronization used. Instead we assume that the >+ // client who enables/disables invariants/logging on a Mutex does so >+ // while the Mutex is not being concurrently accessed by others. >+ void (*invariant)(void *arg); // called on each event >+ void *arg; // first arg to (*invariant)() >+ bool log; // logging turned on >+ >+ // Constant after initialization >+ char name[1]; // actually longer---null-terminated std::string >+} *synch_event[kNSynchEvent] GUARDED_BY(synch_event_mu); >+ >+// Ensure that the object at "addr" has a SynchEvent struct associated with it, >+// set "bits" in the word there (waiting until lockbit is clear before doing >+// so), and return a refcounted reference that will remain valid until >+// UnrefSynchEvent() is called. If a new SynchEvent is allocated, >+// the std::string name is copied into it. >+// When used with a mutex, the caller should also ensure that kMuEvent >+// is set in the mutex word, and similarly for condition variables and kCVEvent. >+static SynchEvent *EnsureSynchEvent(std::atomic<intptr_t> *addr, >+ const char *name, intptr_t bits, >+ intptr_t lockbit) { >+ uint32_t h = reinterpret_cast<intptr_t>(addr) % kNSynchEvent; >+ SynchEvent *e; >+ // first look for existing SynchEvent struct.. >+ synch_event_mu.Lock(); >+ for (e = synch_event[h]; >+ e != nullptr && e->masked_addr != base_internal::HidePtr(addr); >+ e = e->next) { >+ } >+ if (e == nullptr) { // no SynchEvent struct found; make one. >+ if (name == nullptr) { >+ name = ""; >+ } >+ size_t l = strlen(name); >+ e = reinterpret_cast<SynchEvent *>( >+ base_internal::LowLevelAlloc::Alloc(sizeof(*e) + l)); >+ e->refcount = 2; // one for return value, one for linked list >+ e->masked_addr = base_internal::HidePtr(addr); >+ e->invariant = nullptr; >+ e->arg = nullptr; >+ e->log = false; >+ strcpy(e->name, name); // NOLINT(runtime/printf) >+ e->next = synch_event[h]; >+ AtomicSetBits(addr, bits, lockbit); >+ synch_event[h] = e; >+ } else { >+ e->refcount++; // for return value >+ } >+ synch_event_mu.Unlock(); >+ return e; >+} >+ >+// Deallocate the SynchEvent *e, whose refcount has fallen to zero. >+static void DeleteSynchEvent(SynchEvent *e) { >+ base_internal::LowLevelAlloc::Free(e); >+} >+ >+// Decrement the reference count of *e, or do nothing if e==null. >+static void UnrefSynchEvent(SynchEvent *e) { >+ if (e != nullptr) { >+ synch_event_mu.Lock(); >+ bool del = (--(e->refcount) == 0); >+ synch_event_mu.Unlock(); >+ if (del) { >+ DeleteSynchEvent(e); >+ } >+ } >+} >+ >+// Forget the mapping from the object (Mutex or CondVar) at address addr >+// to SynchEvent object, and clear "bits" in its word (waiting until lockbit >+// is clear before doing so). >+static void ForgetSynchEvent(std::atomic<intptr_t> *addr, intptr_t bits, >+ intptr_t lockbit) { >+ uint32_t h = reinterpret_cast<intptr_t>(addr) % kNSynchEvent; >+ SynchEvent **pe; >+ SynchEvent *e; >+ synch_event_mu.Lock(); >+ for (pe = &synch_event[h]; >+ (e = *pe) != nullptr && e->masked_addr != base_internal::HidePtr(addr); >+ pe = &e->next) { >+ } >+ bool del = false; >+ if (e != nullptr) { >+ *pe = e->next; >+ del = (--(e->refcount) == 0); >+ } >+ AtomicClearBits(addr, bits, lockbit); >+ synch_event_mu.Unlock(); >+ if (del) { >+ DeleteSynchEvent(e); >+ } >+} >+ >+// Return a refcounted reference to the SynchEvent of the object at address >+// "addr", if any. The pointer returned is valid until the UnrefSynchEvent() is >+// called. >+static SynchEvent *GetSynchEvent(const void *addr) { >+ uint32_t h = reinterpret_cast<intptr_t>(addr) % kNSynchEvent; >+ SynchEvent *e; >+ synch_event_mu.Lock(); >+ for (e = synch_event[h]; >+ e != nullptr && e->masked_addr != base_internal::HidePtr(addr); >+ e = e->next) { >+ } >+ if (e != nullptr) { >+ e->refcount++; >+ } >+ synch_event_mu.Unlock(); >+ return e; >+} >+ >+// Called when an event "ev" occurs on a Mutex of CondVar "obj" >+// if event recording is on >+static void PostSynchEvent(void *obj, int ev) { >+ SynchEvent *e = GetSynchEvent(obj); >+ // logging is on if event recording is on and either there's no event struct, >+ // or it explicitly says to log >+ if (e == nullptr || e->log) { >+ void *pcs[40]; >+ int n = absl::GetStackTrace(pcs, ABSL_ARRAYSIZE(pcs), 1); >+ // A buffer with enough space for the ASCII for all the PCs, even on a >+ // 64-bit machine. >+ char buffer[ABSL_ARRAYSIZE(pcs) * 24]; >+ int pos = snprintf(buffer, sizeof (buffer), " @"); >+ for (int i = 0; i != n; i++) { >+ pos += snprintf(&buffer[pos], sizeof (buffer) - pos, " %p", pcs[i]); >+ } >+ ABSL_RAW_LOG(INFO, "%s%p %s %s", event_properties[ev].msg, obj, >+ (e == nullptr ? "" : e->name), buffer); >+ } >+ if ((event_properties[ev].flags & SYNCH_F_LCK) != 0 && e != nullptr && >+ e->invariant != nullptr) { >+ (*e->invariant)(e->arg); >+ } >+ UnrefSynchEvent(e); >+} >+ >+//------------------------------------------------------------------ >+ >+// The SynchWaitParams struct encapsulates the way in which a thread is waiting: >+// whether it has a timeout, the condition, exclusive/shared, and whether a >+// condition variable wait has an associated Mutex (as opposed to another >+// type of lock). It also points to the PerThreadSynch struct of its thread. >+// cv_word tells Enqueue() to enqueue on a CondVar using CondVarEnqueue(). >+// >+// This structure is held on the stack rather than directly in >+// PerThreadSynch because a thread can be waiting on multiple Mutexes if, >+// while waiting on one Mutex, the implementation calls a client callback >+// (such as a Condition function) that acquires another Mutex. We don't >+// strictly need to allow this, but programmers become confused if we do not >+// allow them to use functions such a LOG() within Condition functions. The >+// PerThreadSynch struct points at the most recent SynchWaitParams struct when >+// the thread is on a Mutex's waiter queue. >+struct SynchWaitParams { >+ SynchWaitParams(Mutex::MuHow how_arg, const Condition *cond_arg, >+ KernelTimeout timeout_arg, Mutex *cvmu_arg, >+ PerThreadSynch *thread_arg, >+ std::atomic<intptr_t> *cv_word_arg) >+ : how(how_arg), >+ cond(cond_arg), >+ timeout(timeout_arg), >+ cvmu(cvmu_arg), >+ thread(thread_arg), >+ cv_word(cv_word_arg), >+ contention_start_cycles(base_internal::CycleClock::Now()) {} >+ >+ const Mutex::MuHow how; // How this thread needs to wait. >+ const Condition *cond; // The condition that this thread is waiting for. >+ // In Mutex, this field is set to zero if a timeout >+ // expires. >+ KernelTimeout timeout; // timeout expiry---absolute time >+ // In Mutex, this field is set to zero if a timeout >+ // expires. >+ Mutex *const cvmu; // used for transfer from cond var to mutex >+ PerThreadSynch *const thread; // thread that is waiting >+ >+ // If not null, thread should be enqueued on the CondVar whose state >+ // word is cv_word instead of queueing normally on the Mutex. >+ std::atomic<intptr_t> *cv_word; >+ >+ int64_t contention_start_cycles; // Time (in cycles) when this thread started >+ // to contend for the mutex. >+}; >+ >+struct SynchLocksHeld { >+ int n; // number of valid entries in locks[] >+ bool overflow; // true iff we overflowed the array at some point >+ struct { >+ Mutex *mu; // lock acquired >+ int32_t count; // times acquired >+ GraphId id; // deadlock_graph id of acquired lock >+ } locks[40]; >+ // If a thread overfills the array during deadlock detection, we >+ // continue, discarding information as needed. If no overflow has >+ // taken place, we can provide more error checking, such as >+ // detecting when a thread releases a lock it does not hold. >+}; >+ >+// A sentinel value in lists that is not 0. >+// A 0 value is used to mean "not on a list". >+static PerThreadSynch *const kPerThreadSynchNull = >+ reinterpret_cast<PerThreadSynch *>(1); >+ >+static SynchLocksHeld *LocksHeldAlloc() { >+ SynchLocksHeld *ret = reinterpret_cast<SynchLocksHeld *>( >+ base_internal::LowLevelAlloc::Alloc(sizeof(SynchLocksHeld))); >+ ret->n = 0; >+ ret->overflow = false; >+ return ret; >+} >+ >+// Return the PerThreadSynch-struct for this thread. >+static PerThreadSynch *Synch_GetPerThread() { >+ ThreadIdentity *identity = GetOrCreateCurrentThreadIdentity(); >+ return &identity->per_thread_synch; >+} >+ >+static PerThreadSynch *Synch_GetPerThreadAnnotated(Mutex *mu) { >+ if (mu) { >+ ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0); >+ } >+ PerThreadSynch *w = Synch_GetPerThread(); >+ if (mu) { >+ ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0); >+ } >+ return w; >+} >+ >+static SynchLocksHeld *Synch_GetAllLocks() { >+ PerThreadSynch *s = Synch_GetPerThread(); >+ if (s->all_locks == nullptr) { >+ s->all_locks = LocksHeldAlloc(); // Freed by ReclaimThreadIdentity. >+ } >+ return s->all_locks; >+} >+ >+// Post on "w"'s associated PerThreadSem. >+inline void Mutex::IncrementSynchSem(Mutex *mu, PerThreadSynch *w) { >+ if (mu) { >+ ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0); >+ } >+ PerThreadSem::Post(w->thread_identity()); >+ if (mu) { >+ ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0); >+ } >+} >+ >+// Wait on "w"'s associated PerThreadSem; returns false if timeout expired. >+bool Mutex::DecrementSynchSem(Mutex *mu, PerThreadSynch *w, KernelTimeout t) { >+ if (mu) { >+ ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0); >+ } >+ assert(w == Synch_GetPerThread()); >+ static_cast<void>(w); >+ bool res = PerThreadSem::Wait(t); >+ if (mu) { >+ ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0); >+ } >+ return res; >+} >+ >+// We're in a fatal signal handler that hopes to use Mutex and to get >+// lucky by not deadlocking. We try to improve its chances of success >+// by effectively disabling some of the consistency checks. This will >+// prevent certain ABSL_RAW_CHECK() statements from being triggered when >+// re-rentry is detected. The ABSL_RAW_CHECK() statements are those in the >+// Mutex code checking that the "waitp" field has not been reused. >+void Mutex::InternalAttemptToUseMutexInFatalSignalHandler() { >+ // Fix the per-thread state only if it exists. >+ ThreadIdentity *identity = CurrentThreadIdentityIfPresent(); >+ if (identity != nullptr) { >+ identity->per_thread_synch.suppress_fatal_errors = true; >+ } >+ // Don't do deadlock detection when we are already failing. >+ synch_deadlock_detection.store(OnDeadlockCycle::kIgnore, >+ std::memory_order_release); >+} >+ >+// --------------------------time support >+ >+// Return the current time plus the timeout. Use the same clock as >+// PerThreadSem::Wait() for consistency. Unfortunately, we don't have >+// such a choice when a deadline is given directly. >+static absl::Time DeadlineFromTimeout(absl::Duration timeout) { >+#ifndef _WIN32 >+ struct timeval tv; >+ gettimeofday(&tv, nullptr); >+ return absl::TimeFromTimeval(tv) + timeout; >+#else >+ return absl::Now() + timeout; >+#endif >+} >+ >+// --------------------------Mutexes >+ >+// In the layout below, the msb of the bottom byte is currently unused. Also, >+// the following constraints were considered in choosing the layout: >+// o Both the debug allocator's "uninitialized" and "freed" patterns (0xab and >+// 0xcd) are illegal: reader and writer lock both held. >+// o kMuWriter and kMuEvent should exceed kMuDesig and kMuWait, to enable the >+// bit-twiddling trick in Mutex::Unlock(). >+// o kMuWriter / kMuReader == kMuWrWait / kMuWait, >+// to enable the bit-twiddling trick in CheckForMutexCorruption(). >+static const intptr_t kMuReader = 0x0001L; // a reader holds the lock >+static const intptr_t kMuDesig = 0x0002L; // there's a designated waker >+static const intptr_t kMuWait = 0x0004L; // threads are waiting >+static const intptr_t kMuWriter = 0x0008L; // a writer holds the lock >+static const intptr_t kMuEvent = 0x0010L; // record this mutex's events >+// INVARIANT1: there's a thread that was blocked on the mutex, is >+// no longer, yet has not yet acquired the mutex. If there's a >+// designated waker, all threads can avoid taking the slow path in >+// unlock because the designated waker will subsequently acquire >+// the lock and wake someone. To maintain INVARIANT1 the bit is >+// set when a thread is unblocked(INV1a), and threads that were >+// unblocked reset the bit when they either acquire or re-block >+// (INV1b). >+static const intptr_t kMuWrWait = 0x0020L; // runnable writer is waiting >+ // for a reader >+static const intptr_t kMuSpin = 0x0040L; // spinlock protects wait list >+static const intptr_t kMuLow = 0x00ffL; // mask all mutex bits >+static const intptr_t kMuHigh = ~kMuLow; // mask pointer/reader count >+ >+// Hack to make constant values available to gdb pretty printer >+enum { >+ kGdbMuSpin = kMuSpin, >+ kGdbMuEvent = kMuEvent, >+ kGdbMuWait = kMuWait, >+ kGdbMuWriter = kMuWriter, >+ kGdbMuDesig = kMuDesig, >+ kGdbMuWrWait = kMuWrWait, >+ kGdbMuReader = kMuReader, >+ kGdbMuLow = kMuLow, >+}; >+ >+// kMuWrWait implies kMuWait. >+// kMuReader and kMuWriter are mutually exclusive. >+// If kMuReader is zero, there are no readers. >+// Otherwise, if kMuWait is zero, the high order bits contain a count of the >+// number of readers. Otherwise, the reader count is held in >+// PerThreadSynch::readers of the most recently queued waiter, again in the >+// bits above kMuLow. >+static const intptr_t kMuOne = 0x0100; // a count of one reader >+ >+// flags passed to Enqueue and LockSlow{,WithTimeout,Loop} >+static const int kMuHasBlocked = 0x01; // already blocked (MUST == 1) >+static const int kMuIsCond = 0x02; // conditional waiter (CV or Condition) >+ >+static_assert(PerThreadSynch::kAlignment > kMuLow, >+ "PerThreadSynch::kAlignment must be greater than kMuLow"); >+ >+// This struct contains various bitmasks to be used in >+// acquiring and releasing a mutex in a particular mode. >+struct MuHowS { >+ // if all the bits in fast_need_zero are zero, the lock can be acquired by >+ // adding fast_add and oring fast_or. The bit kMuDesig should be reset iff >+ // this is the designated waker. >+ intptr_t fast_need_zero; >+ intptr_t fast_or; >+ intptr_t fast_add; >+ >+ intptr_t slow_need_zero; // fast_need_zero with events (e.g. logging) >+ >+ intptr_t slow_inc_need_zero; // if all the bits in slow_inc_need_zero are >+ // zero a reader can acquire a read share by >+ // setting the reader bit and incrementing >+ // the reader count (in last waiter since >+ // we're now slow-path). kMuWrWait be may >+ // be ignored if we already waited once. >+}; >+ >+static const MuHowS kSharedS = { >+ // shared or read lock >+ kMuWriter | kMuWait | kMuEvent, // fast_need_zero >+ kMuReader, // fast_or >+ kMuOne, // fast_add >+ kMuWriter | kMuWait, // slow_need_zero >+ kMuSpin | kMuWriter | kMuWrWait, // slow_inc_need_zero >+}; >+static const MuHowS kExclusiveS = { >+ // exclusive or write lock >+ kMuWriter | kMuReader | kMuEvent, // fast_need_zero >+ kMuWriter, // fast_or >+ 0, // fast_add >+ kMuWriter | kMuReader, // slow_need_zero >+ ~static_cast<intptr_t>(0), // slow_inc_need_zero >+}; >+static const Mutex::MuHow kShared = &kSharedS; // shared lock >+static const Mutex::MuHow kExclusive = &kExclusiveS; // exclusive lock >+ >+#ifdef NDEBUG >+static constexpr bool kDebugMode = false; >+#else >+static constexpr bool kDebugMode = true; >+#endif >+ >+#ifdef THREAD_SANITIZER >+static unsigned TsanFlags(Mutex::MuHow how) { >+ return how == kShared ? __tsan_mutex_read_lock : 0; >+} >+#endif >+ >+static bool DebugOnlyIsExiting() { >+ return false; >+} >+ >+Mutex::~Mutex() { >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ if ((v & kMuEvent) != 0 && !DebugOnlyIsExiting()) { >+ ForgetSynchEvent(&this->mu_, kMuEvent, kMuSpin); >+ } >+ if (kDebugMode) { >+ this->ForgetDeadlockInfo(); >+ } >+ ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static); >+} >+ >+void Mutex::EnableDebugLog(const char *name) { >+ SynchEvent *e = EnsureSynchEvent(&this->mu_, name, kMuEvent, kMuSpin); >+ e->log = true; >+ UnrefSynchEvent(e); >+} >+ >+void EnableMutexInvariantDebugging(bool enabled) { >+ synch_check_invariants.store(enabled, std::memory_order_release); >+} >+ >+void Mutex::EnableInvariantDebugging(void (*invariant)(void *), >+ void *arg) { >+ if (synch_check_invariants.load(std::memory_order_acquire) && >+ invariant != nullptr) { >+ SynchEvent *e = EnsureSynchEvent(&this->mu_, nullptr, kMuEvent, kMuSpin); >+ e->invariant = invariant; >+ e->arg = arg; >+ UnrefSynchEvent(e); >+ } >+} >+ >+void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode) { >+ synch_deadlock_detection.store(mode, std::memory_order_release); >+} >+ >+// Return true iff threads x and y are waiting on the same condition for the >+// same type of lock. Requires that x and y be waiting on the same Mutex >+// queue. >+static bool MuSameCondition(PerThreadSynch *x, PerThreadSynch *y) { >+ return x->waitp->how == y->waitp->how && >+ Condition::GuaranteedEqual(x->waitp->cond, y->waitp->cond); >+} >+ >+// Given the contents of a mutex word containing a PerThreadSynch pointer, >+// return the pointer. >+static inline PerThreadSynch *GetPerThreadSynch(intptr_t v) { >+ return reinterpret_cast<PerThreadSynch *>(v & kMuHigh); >+} >+ >+// The next several routines maintain the per-thread next and skip fields >+// used in the Mutex waiter queue. >+// The queue is a circular singly-linked list, of which the "head" is the >+// last element, and head->next if the first element. >+// The skip field has the invariant: >+// For thread x, x->skip is one of: >+// - invalid (iff x is not in a Mutex wait queue), >+// - null, or >+// - a pointer to a distinct thread waiting later in the same Mutex queue >+// such that all threads in [x, x->skip] have the same condition and >+// lock type (MuSameCondition() is true for all pairs in [x, x->skip]). >+// In addition, if x->skip is valid, (x->may_skip || x->skip == null) >+// >+// By the spec of MuSameCondition(), it is not necessary when removing the >+// first runnable thread y from the front a Mutex queue to adjust the skip >+// field of another thread x because if x->skip==y, x->skip must (have) become >+// invalid before y is removed. The function TryRemove can remove a specified >+// thread from an arbitrary position in the queue whether runnable or not, so >+// it fixes up skip fields that would otherwise be left dangling. >+// The statement >+// if (x->may_skip && MuSameCondition(x, x->next)) { x->skip = x->next; } >+// maintains the invariant provided x is not the last waiter in a Mutex queue >+// The statement >+// if (x->skip != null) { x->skip = x->skip->skip; } >+// maintains the invariant. >+ >+// Returns the last thread y in a mutex waiter queue such that all threads in >+// [x, y] inclusive share the same condition. Sets skip fields of some threads >+// in that range to optimize future evaluation of Skip() on x values in >+// the range. Requires thread x is in a mutex waiter queue. >+// The locking is unusual. Skip() is called under these conditions: >+// - spinlock is held in call from Enqueue(), with maybe_unlocking == false >+// - Mutex is held in call from UnlockSlow() by last unlocker, with >+// maybe_unlocking == true >+// - both Mutex and spinlock are held in call from DequeueAllWakeable() (from >+// UnlockSlow()) and TryRemove() >+// These cases are mutually exclusive, so Skip() never runs concurrently >+// with itself on the same Mutex. The skip chain is used in these other places >+// that cannot occur concurrently: >+// - FixSkip() (from TryRemove()) - spinlock and Mutex are held) >+// - Dequeue() (with spinlock and Mutex held) >+// - UnlockSlow() (with spinlock and Mutex held) >+// A more complex case is Enqueue() >+// - Enqueue() (with spinlock held and maybe_unlocking == false) >+// This is the first case in which Skip is called, above. >+// - Enqueue() (without spinlock held; but queue is empty and being freshly >+// formed) >+// - Enqueue() (with spinlock held and maybe_unlocking == true) >+// The first case has mutual exclusion, and the second isolation through >+// working on an otherwise unreachable data structure. >+// In the last case, Enqueue() is required to change no skip/next pointers >+// except those in the added node and the former "head" node. This implies >+// that the new node is added after head, and so must be the new head or the >+// new front of the queue. >+static PerThreadSynch *Skip(PerThreadSynch *x) { >+ PerThreadSynch *x0 = nullptr; >+ PerThreadSynch *x1 = x; >+ PerThreadSynch *x2 = x->skip; >+ if (x2 != nullptr) { >+ // Each iteration attempts to advance sequence (x0,x1,x2) to next sequence >+ // such that x1 == x0->skip && x2 == x1->skip >+ while ((x0 = x1, x1 = x2, x2 = x2->skip) != nullptr) { >+ x0->skip = x2; // short-circuit skip from x0 to x2 >+ } >+ x->skip = x1; // short-circuit skip from x to result >+ } >+ return x1; >+} >+ >+// "ancestor" appears before "to_be_removed" in the same Mutex waiter queue. >+// The latter is going to be removed out of order, because of a timeout. >+// Check whether "ancestor" has a skip field pointing to "to_be_removed", >+// and fix it if it does. >+static void FixSkip(PerThreadSynch *ancestor, PerThreadSynch *to_be_removed) { >+ if (ancestor->skip == to_be_removed) { // ancestor->skip left dangling >+ if (to_be_removed->skip != nullptr) { >+ ancestor->skip = to_be_removed->skip; // can skip past to_be_removed >+ } else if (ancestor->next != to_be_removed) { // they are not adjacent >+ ancestor->skip = ancestor->next; // can skip one past ancestor >+ } else { >+ ancestor->skip = nullptr; // can't skip at all >+ } >+ } >+} >+ >+static void CondVarEnqueue(SynchWaitParams *waitp); >+ >+// Enqueue thread "waitp->thread" on a waiter queue. >+// Called with mutex spinlock held if head != nullptr >+// If head==nullptr and waitp->cv_word==nullptr, then Enqueue() is >+// idempotent; it alters no state associated with the existing (empty) >+// queue. >+// >+// If waitp->cv_word == nullptr, queue the thread at either the front or >+// the end (according to its priority) of the circular mutex waiter queue whose >+// head is "head", and return the new head. mu is the previous mutex state, >+// which contains the reader count (perhaps adjusted for the operation in >+// progress) if the list was empty and a read lock held, and the holder hint if >+// the list was empty and a write lock held. (flags & kMuIsCond) indicates >+// whether this thread was transferred from a CondVar or is waiting for a >+// non-trivial condition. In this case, Enqueue() never returns nullptr >+// >+// If waitp->cv_word != nullptr, CondVarEnqueue() is called, and "head" is >+// returned. This mechanism is used by CondVar to queue a thread on the >+// condition variable queue instead of the mutex queue in implementing Wait(). >+// In this case, Enqueue() can return nullptr (if head==nullptr). >+static PerThreadSynch *Enqueue(PerThreadSynch *head, >+ SynchWaitParams *waitp, intptr_t mu, int flags) { >+ // If we have been given a cv_word, call CondVarEnqueue() and return >+ // the previous head of the Mutex waiter queue. >+ if (waitp->cv_word != nullptr) { >+ CondVarEnqueue(waitp); >+ return head; >+ } >+ >+ PerThreadSynch *s = waitp->thread; >+ ABSL_RAW_CHECK( >+ s->waitp == nullptr || // normal case >+ s->waitp == waitp || // Fer()---transfer from condition variable >+ s->suppress_fatal_errors, >+ "detected illegal recursion into Mutex code"); >+ s->waitp = waitp; >+ s->skip = nullptr; // maintain skip invariant (see above) >+ s->may_skip = true; // always true on entering queue >+ s->wake = false; // not being woken >+ s->cond_waiter = ((flags & kMuIsCond) != 0); >+ if (head == nullptr) { // s is the only waiter >+ s->next = s; // it's the only entry in the cycle >+ s->readers = mu; // reader count is from mu word >+ s->maybe_unlocking = false; // no one is searching an empty list >+ head = s; // s is new head >+ } else { >+ PerThreadSynch *enqueue_after = nullptr; // we'll put s after this element >+#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM >+ int64_t now_cycles = base_internal::CycleClock::Now(); >+ if (s->next_priority_read_cycles < now_cycles) { >+ // Every so often, update our idea of the thread's priority. >+ // pthread_getschedparam() is 5% of the block/wakeup time; >+ // base_internal::CycleClock::Now() is 0.5%. >+ int policy; >+ struct sched_param param; >+ pthread_getschedparam(pthread_self(), &policy, ¶m); >+ s->priority = param.sched_priority; >+ s->next_priority_read_cycles = >+ now_cycles + >+ static_cast<int64_t>(base_internal::CycleClock::Frequency()); >+ } >+ if (s->priority > head->priority) { // s's priority is above head's >+ // try to put s in priority-fifo order, or failing that at the front. >+ if (!head->maybe_unlocking) { >+ // No unlocker can be scanning the queue, so we can insert between >+ // skip-chains, and within a skip-chain if it has the same condition as >+ // s. We insert in priority-fifo order, examining the end of every >+ // skip-chain, plus every element with the same condition as s. >+ PerThreadSynch *advance_to = head; // next value of enqueue_after >+ PerThreadSynch *cur; // successor of enqueue_after >+ do { >+ enqueue_after = advance_to; >+ cur = enqueue_after->next; // this advance ensures progress >+ advance_to = Skip(cur); // normally, advance to end of skip chain >+ // (side-effect: optimizes skip chain) >+ if (advance_to != cur && s->priority > advance_to->priority && >+ MuSameCondition(s, cur)) { >+ // but this skip chain is not a singleton, s has higher priority >+ // than its tail and has the same condition as the chain, >+ // so we can insert within the skip-chain >+ advance_to = cur; // advance by just one >+ } >+ } while (s->priority <= advance_to->priority); >+ // termination guaranteed because s->priority > head->priority >+ // and head is the end of a skip chain >+ } else if (waitp->how == kExclusive && >+ Condition::GuaranteedEqual(waitp->cond, nullptr)) { >+ // An unlocker could be scanning the queue, but we know it will recheck >+ // the queue front for writers that have no condition, which is what s >+ // is, so an insert at front is safe. >+ enqueue_after = head; // add after head, at front >+ } >+ } >+#endif >+ if (enqueue_after != nullptr) { >+ s->next = enqueue_after->next; >+ enqueue_after->next = s; >+ >+ // enqueue_after can be: head, Skip(...), or cur. >+ // The first two imply enqueue_after->skip == nullptr, and >+ // the last is used only if MuSameCondition(s, cur). >+ // We require this because clearing enqueue_after->skip >+ // is impossible; enqueue_after's predecessors might also >+ // incorrectly skip over s if we were to allow other >+ // insertion points. >+ ABSL_RAW_CHECK( >+ enqueue_after->skip == nullptr || MuSameCondition(enqueue_after, s), >+ "Mutex Enqueue failure"); >+ >+ if (enqueue_after != head && enqueue_after->may_skip && >+ MuSameCondition(enqueue_after, enqueue_after->next)) { >+ // enqueue_after can skip to its new successor, s >+ enqueue_after->skip = enqueue_after->next; >+ } >+ if (MuSameCondition(s, s->next)) { // s->may_skip is known to be true >+ s->skip = s->next; // s may skip to its successor >+ } >+ } else { // enqueue not done any other way, so >+ // we're inserting s at the back >+ // s will become new head; copy data from head into it >+ s->next = head->next; // add s after head >+ head->next = s; >+ s->readers = head->readers; // reader count is from previous head >+ s->maybe_unlocking = head->maybe_unlocking; // same for unlock hint >+ if (head->may_skip && MuSameCondition(head, s)) { >+ // head now has successor; may skip >+ head->skip = s; >+ } >+ head = s; // s is new head >+ } >+ } >+ s->state.store(PerThreadSynch::kQueued, std::memory_order_relaxed); >+ return head; >+} >+ >+// Dequeue the successor pw->next of thread pw from the Mutex waiter queue >+// whose last element is head. The new head element is returned, or null >+// if the list is made empty. >+// Dequeue is called with both spinlock and Mutex held. >+static PerThreadSynch *Dequeue(PerThreadSynch *head, PerThreadSynch *pw) { >+ PerThreadSynch *w = pw->next; >+ pw->next = w->next; // snip w out of list >+ if (head == w) { // we removed the head >+ head = (pw == w) ? nullptr : pw; // either emptied list, or pw is new head >+ } else if (pw != head && MuSameCondition(pw, pw->next)) { >+ // pw can skip to its new successor >+ if (pw->next->skip != >+ nullptr) { // either skip to its successors skip target >+ pw->skip = pw->next->skip; >+ } else { // or to pw's successor >+ pw->skip = pw->next; >+ } >+ } >+ return head; >+} >+ >+// Traverse the elements [ pw->next, h] of the circular list whose last element >+// is head. >+// Remove all elements with wake==true and place them in the >+// singly-linked list wake_list in the order found. Assumes that >+// there is only one such element if the element has how == kExclusive. >+// Return the new head. >+static PerThreadSynch *DequeueAllWakeable(PerThreadSynch *head, >+ PerThreadSynch *pw, >+ PerThreadSynch **wake_tail) { >+ PerThreadSynch *orig_h = head; >+ PerThreadSynch *w = pw->next; >+ bool skipped = false; >+ do { >+ if (w->wake) { // remove this element >+ ABSL_RAW_CHECK(pw->skip == nullptr, "bad skip in DequeueAllWakeable"); >+ // we're removing pw's successor so either pw->skip is zero or we should >+ // already have removed pw since if pw->skip!=null, pw has the same >+ // condition as w. >+ head = Dequeue(head, pw); >+ w->next = *wake_tail; // keep list terminated >+ *wake_tail = w; // add w to wake_list; >+ wake_tail = &w->next; // next addition to end >+ if (w->waitp->how == kExclusive) { // wake at most 1 writer >+ break; >+ } >+ } else { // not waking this one; skip >+ pw = Skip(w); // skip as much as possible >+ skipped = true; >+ } >+ w = pw->next; >+ // We want to stop processing after we've considered the original head, >+ // orig_h. We can't test for w==orig_h in the loop because w may skip over >+ // it; we are guaranteed only that w's predecessor will not skip over >+ // orig_h. When we've considered orig_h, either we've processed it and >+ // removed it (so orig_h != head), or we considered it and skipped it (so >+ // skipped==true && pw == head because skipping from head always skips by >+ // just one, leaving pw pointing at head). So we want to >+ // continue the loop with the negation of that expression. >+ } while (orig_h == head && (pw != head || !skipped)); >+ return head; >+} >+ >+// Try to remove thread s from the list of waiters on this mutex. >+// Does nothing if s is not on the waiter list. >+void Mutex::TryRemove(PerThreadSynch *s) { >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ // acquire spinlock & lock >+ if ((v & (kMuWait | kMuSpin | kMuWriter | kMuReader)) == kMuWait && >+ mu_.compare_exchange_strong(v, v | kMuSpin | kMuWriter, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ PerThreadSynch *h = GetPerThreadSynch(v); >+ if (h != nullptr) { >+ PerThreadSynch *pw = h; // pw is w's predecessor >+ PerThreadSynch *w; >+ if ((w = pw->next) != s) { // search for thread, >+ do { // processing at least one element >+ if (!MuSameCondition(s, w)) { // seeking different condition >+ pw = Skip(w); // so skip all that won't match >+ // we don't have to worry about dangling skip fields >+ // in the threads we skipped; none can point to s >+ // because their condition differs from s >+ } else { // seeking same condition >+ FixSkip(w, s); // fix up any skip pointer from w to s >+ pw = w; >+ } >+ // don't search further if we found the thread, or we're about to >+ // process the first thread again. >+ } while ((w = pw->next) != s && pw != h); >+ } >+ if (w == s) { // found thread; remove it >+ // pw->skip may be non-zero here; the loop above ensured that >+ // no ancestor of s can skip to s, so removal is safe anyway. >+ h = Dequeue(h, pw); >+ s->next = nullptr; >+ s->state.store(PerThreadSynch::kAvailable, std::memory_order_release); >+ } >+ } >+ intptr_t nv; >+ do { // release spinlock and lock >+ v = mu_.load(std::memory_order_relaxed); >+ nv = v & (kMuDesig | kMuEvent); >+ if (h != nullptr) { >+ nv |= kMuWait | reinterpret_cast<intptr_t>(h); >+ h->readers = 0; // we hold writer lock >+ h->maybe_unlocking = false; // finished unlocking >+ } >+ } while (!mu_.compare_exchange_weak(v, nv, >+ std::memory_order_release, >+ std::memory_order_relaxed)); >+ } >+} >+ >+// Wait until thread "s", which must be the current thread, is removed from the >+// this mutex's waiter queue. If "s->waitp->timeout" has a timeout, wake up >+// if the wait extends past the absolute time specified, even if "s" is still >+// on the mutex queue. In this case, remove "s" from the queue and return >+// true, otherwise return false. >+void Mutex::Block(PerThreadSynch *s) { >+ while (s->state.load(std::memory_order_acquire) == PerThreadSynch::kQueued) { >+ if (!DecrementSynchSem(this, s, s->waitp->timeout)) { >+ // After a timeout, we go into a spin loop until we remove ourselves >+ // from the queue, or someone else removes us. We can't be sure to be >+ // able to remove ourselves in a single lock acquisition because this >+ // mutex may be held, and the holder has the right to read the centre >+ // of the waiter queue without holding the spinlock. >+ this->TryRemove(s); >+ int c = 0; >+ while (s->next != nullptr) { >+ c = Delay(c, GENTLE); >+ this->TryRemove(s); >+ } >+ if (kDebugMode) { >+ // This ensures that we test the case that TryRemove() is called when s >+ // is not on the queue. >+ this->TryRemove(s); >+ } >+ s->waitp->timeout = KernelTimeout::Never(); // timeout is satisfied >+ s->waitp->cond = nullptr; // condition no longer relevant for wakeups >+ } >+ } >+ ABSL_RAW_CHECK(s->waitp != nullptr || s->suppress_fatal_errors, >+ "detected illegal recursion in Mutex code"); >+ s->waitp = nullptr; >+} >+ >+// Wake thread w, and return the next thread in the list. >+PerThreadSynch *Mutex::Wakeup(PerThreadSynch *w) { >+ PerThreadSynch *next = w->next; >+ w->next = nullptr; >+ w->state.store(PerThreadSynch::kAvailable, std::memory_order_release); >+ IncrementSynchSem(this, w); >+ >+ return next; >+} >+ >+static GraphId GetGraphIdLocked(Mutex *mu) >+ EXCLUSIVE_LOCKS_REQUIRED(deadlock_graph_mu) { >+ if (!deadlock_graph) { // (re)create the deadlock graph. >+ deadlock_graph = >+ new (base_internal::LowLevelAlloc::Alloc(sizeof(*deadlock_graph))) >+ GraphCycles; >+ } >+ return deadlock_graph->GetId(mu); >+} >+ >+static GraphId GetGraphId(Mutex *mu) LOCKS_EXCLUDED(deadlock_graph_mu) { >+ deadlock_graph_mu.Lock(); >+ GraphId id = GetGraphIdLocked(mu); >+ deadlock_graph_mu.Unlock(); >+ return id; >+} >+ >+// Record a lock acquisition. This is used in debug mode for deadlock >+// detection. The held_locks pointer points to the relevant data >+// structure for each case. >+static void LockEnter(Mutex* mu, GraphId id, SynchLocksHeld *held_locks) { >+ int n = held_locks->n; >+ int i = 0; >+ while (i != n && held_locks->locks[i].id != id) { >+ i++; >+ } >+ if (i == n) { >+ if (n == ABSL_ARRAYSIZE(held_locks->locks)) { >+ held_locks->overflow = true; // lost some data >+ } else { // we have room for lock >+ held_locks->locks[i].mu = mu; >+ held_locks->locks[i].count = 1; >+ held_locks->locks[i].id = id; >+ held_locks->n = n + 1; >+ } >+ } else { >+ held_locks->locks[i].count++; >+ } >+} >+ >+// Record a lock release. Each call to LockEnter(mu, id, x) should be >+// eventually followed by a call to LockLeave(mu, id, x) by the same thread. >+// It does not process the event if is not needed when deadlock detection is >+// disabled. >+static void LockLeave(Mutex* mu, GraphId id, SynchLocksHeld *held_locks) { >+ int n = held_locks->n; >+ int i = 0; >+ while (i != n && held_locks->locks[i].id != id) { >+ i++; >+ } >+ if (i == n) { >+ if (!held_locks->overflow) { >+ // The deadlock id may have been reassigned after ForgetDeadlockInfo, >+ // but in that case mu should still be present. >+ i = 0; >+ while (i != n && held_locks->locks[i].mu != mu) { >+ i++; >+ } >+ if (i == n) { // mu missing means releasing unheld lock >+ SynchEvent *mu_events = GetSynchEvent(mu); >+ ABSL_RAW_LOG(FATAL, >+ "thread releasing lock it does not hold: %p %s; " >+ , >+ static_cast<void *>(mu), >+ mu_events == nullptr ? "" : mu_events->name); >+ } >+ } >+ } else if (held_locks->locks[i].count == 1) { >+ held_locks->n = n - 1; >+ held_locks->locks[i] = held_locks->locks[n - 1]; >+ held_locks->locks[n - 1].id = InvalidGraphId(); >+ held_locks->locks[n - 1].mu = >+ nullptr; // clear mu to please the leak detector. >+ } else { >+ assert(held_locks->locks[i].count > 0); >+ held_locks->locks[i].count--; >+ } >+} >+ >+// Call LockEnter() if in debug mode and deadlock detection is enabled. >+static inline void DebugOnlyLockEnter(Mutex *mu) { >+ if (kDebugMode) { >+ if (synch_deadlock_detection.load(std::memory_order_acquire) != >+ OnDeadlockCycle::kIgnore) { >+ LockEnter(mu, GetGraphId(mu), Synch_GetAllLocks()); >+ } >+ } >+} >+ >+// Call LockEnter() if in debug mode and deadlock detection is enabled. >+static inline void DebugOnlyLockEnter(Mutex *mu, GraphId id) { >+ if (kDebugMode) { >+ if (synch_deadlock_detection.load(std::memory_order_acquire) != >+ OnDeadlockCycle::kIgnore) { >+ LockEnter(mu, id, Synch_GetAllLocks()); >+ } >+ } >+} >+ >+// Call LockLeave() if in debug mode and deadlock detection is enabled. >+static inline void DebugOnlyLockLeave(Mutex *mu) { >+ if (kDebugMode) { >+ if (synch_deadlock_detection.load(std::memory_order_acquire) != >+ OnDeadlockCycle::kIgnore) { >+ LockLeave(mu, GetGraphId(mu), Synch_GetAllLocks()); >+ } >+ } >+} >+ >+static char *StackString(void **pcs, int n, char *buf, int maxlen, >+ bool symbolize) { >+ static const int kSymLen = 200; >+ char sym[kSymLen]; >+ int len = 0; >+ for (int i = 0; i != n; i++) { >+ if (symbolize) { >+ if (!symbolizer(pcs[i], sym, kSymLen)) { >+ sym[0] = '\0'; >+ } >+ snprintf(buf + len, maxlen - len, "%s\t@ %p %s\n", >+ (i == 0 ? "\n" : ""), >+ pcs[i], sym); >+ } else { >+ snprintf(buf + len, maxlen - len, " %p", pcs[i]); >+ } >+ len += strlen(&buf[len]); >+ } >+ return buf; >+} >+ >+static char *CurrentStackString(char *buf, int maxlen, bool symbolize) { >+ void *pcs[40]; >+ return StackString(pcs, absl::GetStackTrace(pcs, ABSL_ARRAYSIZE(pcs), 2), buf, >+ maxlen, symbolize); >+} >+ >+namespace { >+enum { kMaxDeadlockPathLen = 10 }; // maximum length of a deadlock cycle; >+ // a path this long would be remarkable >+// Buffers required to report a deadlock. >+// We do not allocate them on stack to avoid large stack frame. >+struct DeadlockReportBuffers { >+ char buf[6100]; >+ GraphId path[kMaxDeadlockPathLen]; >+}; >+ >+struct ScopedDeadlockReportBuffers { >+ ScopedDeadlockReportBuffers() { >+ b = reinterpret_cast<DeadlockReportBuffers *>( >+ base_internal::LowLevelAlloc::Alloc(sizeof(*b))); >+ } >+ ~ScopedDeadlockReportBuffers() { base_internal::LowLevelAlloc::Free(b); } >+ DeadlockReportBuffers *b; >+}; >+ >+// Helper to pass to GraphCycles::UpdateStackTrace. >+int GetStack(void** stack, int max_depth) { >+ return absl::GetStackTrace(stack, max_depth, 3); >+} >+} // anonymous namespace >+ >+// Called in debug mode when a thread is about to acquire a lock in a way that >+// may block. >+static GraphId DeadlockCheck(Mutex *mu) { >+ if (synch_deadlock_detection.load(std::memory_order_acquire) == >+ OnDeadlockCycle::kIgnore) { >+ return InvalidGraphId(); >+ } >+ >+ SynchLocksHeld *all_locks = Synch_GetAllLocks(); >+ >+ absl::base_internal::SpinLockHolder lock(&deadlock_graph_mu); >+ const GraphId mu_id = GetGraphIdLocked(mu); >+ >+ if (all_locks->n == 0) { >+ // There are no other locks held. Return now so that we don't need to >+ // call GetSynchEvent(). This way we do not record the stack trace >+ // for this Mutex. It's ok, since if this Mutex is involved in a deadlock, >+ // it can't always be the first lock acquired by a thread. >+ return mu_id; >+ } >+ >+ // We prefer to keep stack traces that show a thread holding and acquiring >+ // as many locks as possible. This increases the chances that a given edge >+ // in the acquires-before graph will be represented in the stack traces >+ // recorded for the locks. >+ deadlock_graph->UpdateStackTrace(mu_id, all_locks->n + 1, GetStack); >+ >+ // For each other mutex already held by this thread: >+ for (int i = 0; i != all_locks->n; i++) { >+ const GraphId other_node_id = all_locks->locks[i].id; >+ const Mutex *other = >+ static_cast<const Mutex *>(deadlock_graph->Ptr(other_node_id)); >+ if (other == nullptr) { >+ // Ignore stale lock >+ continue; >+ } >+ >+ // Add the acquired-before edge to the graph. >+ if (!deadlock_graph->InsertEdge(other_node_id, mu_id)) { >+ ScopedDeadlockReportBuffers scoped_buffers; >+ DeadlockReportBuffers *b = scoped_buffers.b; >+ static int number_of_reported_deadlocks = 0; >+ number_of_reported_deadlocks++; >+ // Symbolize only 2 first deadlock report to avoid huge slowdowns. >+ bool symbolize = number_of_reported_deadlocks <= 2; >+ ABSL_RAW_LOG(ERROR, "Potential Mutex deadlock: %s", >+ CurrentStackString(b->buf, sizeof (b->buf), symbolize)); >+ int len = 0; >+ for (int j = 0; j != all_locks->n; j++) { >+ void* pr = deadlock_graph->Ptr(all_locks->locks[j].id); >+ if (pr != nullptr) { >+ snprintf(b->buf + len, sizeof (b->buf) - len, " %p", pr); >+ len += static_cast<int>(strlen(&b->buf[len])); >+ } >+ } >+ ABSL_RAW_LOG(ERROR, "Acquiring %p Mutexes held: %s", >+ static_cast<void *>(mu), b->buf); >+ ABSL_RAW_LOG(ERROR, "Cycle: "); >+ int path_len = deadlock_graph->FindPath( >+ mu_id, other_node_id, ABSL_ARRAYSIZE(b->path), b->path); >+ for (int j = 0; j != path_len; j++) { >+ GraphId id = b->path[j]; >+ Mutex *path_mu = static_cast<Mutex *>(deadlock_graph->Ptr(id)); >+ if (path_mu == nullptr) continue; >+ void** stack; >+ int depth = deadlock_graph->GetStackTrace(id, &stack); >+ snprintf(b->buf, sizeof(b->buf), >+ "mutex@%p stack: ", static_cast<void *>(path_mu)); >+ StackString(stack, depth, b->buf + strlen(b->buf), >+ static_cast<int>(sizeof(b->buf) - strlen(b->buf)), >+ symbolize); >+ ABSL_RAW_LOG(ERROR, "%s", b->buf); >+ } >+ if (synch_deadlock_detection.load(std::memory_order_acquire) == >+ OnDeadlockCycle::kAbort) { >+ deadlock_graph_mu.Unlock(); // avoid deadlock in fatal sighandler >+ ABSL_RAW_LOG(FATAL, "dying due to potential deadlock"); >+ return mu_id; >+ } >+ break; // report at most one potential deadlock per acquisition >+ } >+ } >+ >+ return mu_id; >+} >+ >+// Invoke DeadlockCheck() iff we're in debug mode and >+// deadlock checking has been enabled. >+static inline GraphId DebugOnlyDeadlockCheck(Mutex *mu) { >+ if (kDebugMode && synch_deadlock_detection.load(std::memory_order_acquire) != >+ OnDeadlockCycle::kIgnore) { >+ return DeadlockCheck(mu); >+ } else { >+ return InvalidGraphId(); >+ } >+} >+ >+void Mutex::ForgetDeadlockInfo() { >+ if (kDebugMode && synch_deadlock_detection.load(std::memory_order_acquire) != >+ OnDeadlockCycle::kIgnore) { >+ deadlock_graph_mu.Lock(); >+ if (deadlock_graph != nullptr) { >+ deadlock_graph->RemoveNode(this); >+ } >+ deadlock_graph_mu.Unlock(); >+ } >+} >+ >+void Mutex::AssertNotHeld() const { >+ // We have the data to allow this check only if in debug mode and deadlock >+ // detection is enabled. >+ if (kDebugMode && >+ (mu_.load(std::memory_order_relaxed) & (kMuWriter | kMuReader)) != 0 && >+ synch_deadlock_detection.load(std::memory_order_acquire) != >+ OnDeadlockCycle::kIgnore) { >+ GraphId id = GetGraphId(const_cast<Mutex *>(this)); >+ SynchLocksHeld *locks = Synch_GetAllLocks(); >+ for (int i = 0; i != locks->n; i++) { >+ if (locks->locks[i].id == id) { >+ SynchEvent *mu_events = GetSynchEvent(this); >+ ABSL_RAW_LOG(FATAL, "thread should not hold mutex %p %s", >+ static_cast<const void *>(this), >+ (mu_events == nullptr ? "" : mu_events->name)); >+ } >+ } >+ } >+} >+ >+// Attempt to acquire *mu, and return whether successful. The implementation >+// may spin for a short while if the lock cannot be acquired immediately. >+static bool TryAcquireWithSpinning(std::atomic<intptr_t>* mu) { >+ int c = mutex_globals.spinloop_iterations; >+ int result = -1; // result of operation: 0=false, 1=true, -1=unknown >+ >+ do { // do/while somewhat faster on AMD >+ intptr_t v = mu->load(std::memory_order_relaxed); >+ if ((v & (kMuReader|kMuEvent)) != 0) { // a reader or tracing -> give up >+ result = 0; >+ } else if (((v & kMuWriter) == 0) && // no holder -> try to acquire >+ mu->compare_exchange_strong(v, kMuWriter | v, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ result = 1; >+ } >+ } while (result == -1 && --c > 0); >+ return result == 1; >+} >+ >+ABSL_XRAY_LOG_ARGS(1) void Mutex::Lock() { >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, 0); >+ GraphId id = DebugOnlyDeadlockCheck(this); >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ // try fast acquire, then spin loop >+ if ((v & (kMuWriter | kMuReader | kMuEvent)) != 0 || >+ !mu_.compare_exchange_strong(v, kMuWriter | v, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ // try spin acquire, then slow loop >+ if (!TryAcquireWithSpinning(&this->mu_)) { >+ this->LockSlow(kExclusive, nullptr, 0); >+ } >+ } >+ DebugOnlyLockEnter(this, id); >+ ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0); >+} >+ >+ABSL_XRAY_LOG_ARGS(1) void Mutex::ReaderLock() { >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock); >+ GraphId id = DebugOnlyDeadlockCheck(this); >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ // try fast acquire, then slow loop >+ if ((v & (kMuWriter | kMuWait | kMuEvent)) != 0 || >+ !mu_.compare_exchange_strong(v, (kMuReader | v) + kMuOne, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ this->LockSlow(kShared, nullptr, 0); >+ } >+ DebugOnlyLockEnter(this, id); >+ ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0); >+} >+ >+void Mutex::LockWhen(const Condition &cond) { >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, 0); >+ GraphId id = DebugOnlyDeadlockCheck(this); >+ this->LockSlow(kExclusive, &cond, 0); >+ DebugOnlyLockEnter(this, id); >+ ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0); >+} >+ >+bool Mutex::LockWhenWithTimeout(const Condition &cond, absl::Duration timeout) { >+ return LockWhenWithDeadline(cond, DeadlineFromTimeout(timeout)); >+} >+ >+bool Mutex::LockWhenWithDeadline(const Condition &cond, absl::Time deadline) { >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, 0); >+ GraphId id = DebugOnlyDeadlockCheck(this); >+ bool res = LockSlowWithDeadline(kExclusive, &cond, >+ KernelTimeout(deadline), 0); >+ DebugOnlyLockEnter(this, id); >+ ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0); >+ return res; >+} >+ >+void Mutex::ReaderLockWhen(const Condition &cond) { >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock); >+ GraphId id = DebugOnlyDeadlockCheck(this); >+ this->LockSlow(kShared, &cond, 0); >+ DebugOnlyLockEnter(this, id); >+ ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0); >+} >+ >+bool Mutex::ReaderLockWhenWithTimeout(const Condition &cond, >+ absl::Duration timeout) { >+ return ReaderLockWhenWithDeadline(cond, DeadlineFromTimeout(timeout)); >+} >+ >+bool Mutex::ReaderLockWhenWithDeadline(const Condition &cond, >+ absl::Time deadline) { >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock); >+ GraphId id = DebugOnlyDeadlockCheck(this); >+ bool res = LockSlowWithDeadline(kShared, &cond, KernelTimeout(deadline), 0); >+ DebugOnlyLockEnter(this, id); >+ ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0); >+ return res; >+} >+ >+void Mutex::Await(const Condition &cond) { >+ if (cond.Eval()) { // condition already true; nothing to do >+ if (kDebugMode) { >+ this->AssertReaderHeld(); >+ } >+ } else { // normal case >+ ABSL_RAW_CHECK(this->AwaitCommon(cond, KernelTimeout::Never()), >+ "condition untrue on return from Await"); >+ } >+} >+ >+bool Mutex::AwaitWithTimeout(const Condition &cond, absl::Duration timeout) { >+ return AwaitWithDeadline(cond, DeadlineFromTimeout(timeout)); >+} >+ >+bool Mutex::AwaitWithDeadline(const Condition &cond, absl::Time deadline) { >+ if (cond.Eval()) { // condition already true; nothing to do >+ if (kDebugMode) { >+ this->AssertReaderHeld(); >+ } >+ return true; >+ } >+ >+ KernelTimeout t{deadline}; >+ bool res = this->AwaitCommon(cond, t); >+ ABSL_RAW_CHECK(res || t.has_timeout(), >+ "condition untrue on return from Await"); >+ return res; >+} >+ >+bool Mutex::AwaitCommon(const Condition &cond, KernelTimeout t) { >+ this->AssertReaderHeld(); >+ MuHow how = >+ (mu_.load(std::memory_order_relaxed) & kMuWriter) ? kExclusive : kShared; >+ ABSL_TSAN_MUTEX_PRE_UNLOCK(this, TsanFlags(how)); >+ SynchWaitParams waitp( >+ how, &cond, t, nullptr /*no cvmu*/, Synch_GetPerThreadAnnotated(this), >+ nullptr /*no cv_word*/); >+ int flags = kMuHasBlocked; >+ if (!Condition::GuaranteedEqual(&cond, nullptr)) { >+ flags |= kMuIsCond; >+ } >+ this->UnlockSlow(&waitp); >+ this->Block(waitp.thread); >+ ABSL_TSAN_MUTEX_POST_UNLOCK(this, TsanFlags(how)); >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, TsanFlags(how)); >+ this->LockSlowLoop(&waitp, flags); >+ bool res = waitp.cond != nullptr || // => cond known true from LockSlowLoop >+ cond.Eval(); >+ ABSL_TSAN_MUTEX_POST_LOCK(this, TsanFlags(how), 0); >+ return res; >+} >+ >+ABSL_XRAY_LOG_ARGS(1) bool Mutex::TryLock() { >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock); >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ if ((v & (kMuWriter | kMuReader | kMuEvent)) == 0 && // try fast acquire >+ mu_.compare_exchange_strong(v, kMuWriter | v, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ DebugOnlyLockEnter(this); >+ ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_try_lock, 0); >+ return true; >+ } >+ if ((v & kMuEvent) != 0) { // we're recording events >+ if ((v & kExclusive->slow_need_zero) == 0 && // try fast acquire >+ mu_.compare_exchange_strong( >+ v, (kExclusive->fast_or | v) + kExclusive->fast_add, >+ std::memory_order_acquire, std::memory_order_relaxed)) { >+ DebugOnlyLockEnter(this); >+ PostSynchEvent(this, SYNCH_EV_TRYLOCK_SUCCESS); >+ ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_try_lock, 0); >+ return true; >+ } else { >+ PostSynchEvent(this, SYNCH_EV_TRYLOCK_FAILED); >+ } >+ } >+ ABSL_TSAN_MUTEX_POST_LOCK( >+ this, __tsan_mutex_try_lock | __tsan_mutex_try_lock_failed, 0); >+ return false; >+} >+ >+ABSL_XRAY_LOG_ARGS(1) bool Mutex::ReaderTryLock() { >+ ABSL_TSAN_MUTEX_PRE_LOCK(this, >+ __tsan_mutex_read_lock | __tsan_mutex_try_lock); >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ // The while-loops (here and below) iterate only if the mutex word keeps >+ // changing (typically because the reader count changes) under the CAS. We >+ // limit the number of attempts to avoid having to think about livelock. >+ int loop_limit = 5; >+ while ((v & (kMuWriter|kMuWait|kMuEvent)) == 0 && loop_limit != 0) { >+ if (mu_.compare_exchange_strong(v, (kMuReader | v) + kMuOne, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ DebugOnlyLockEnter(this); >+ ABSL_TSAN_MUTEX_POST_LOCK( >+ this, __tsan_mutex_read_lock | __tsan_mutex_try_lock, 0); >+ return true; >+ } >+ loop_limit--; >+ v = mu_.load(std::memory_order_relaxed); >+ } >+ if ((v & kMuEvent) != 0) { // we're recording events >+ loop_limit = 5; >+ while ((v & kShared->slow_need_zero) == 0 && loop_limit != 0) { >+ if (mu_.compare_exchange_strong(v, (kMuReader | v) + kMuOne, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ DebugOnlyLockEnter(this); >+ PostSynchEvent(this, SYNCH_EV_READERTRYLOCK_SUCCESS); >+ ABSL_TSAN_MUTEX_POST_LOCK( >+ this, __tsan_mutex_read_lock | __tsan_mutex_try_lock, 0); >+ return true; >+ } >+ loop_limit--; >+ v = mu_.load(std::memory_order_relaxed); >+ } >+ if ((v & kMuEvent) != 0) { >+ PostSynchEvent(this, SYNCH_EV_READERTRYLOCK_FAILED); >+ } >+ } >+ ABSL_TSAN_MUTEX_POST_LOCK(this, >+ __tsan_mutex_read_lock | __tsan_mutex_try_lock | >+ __tsan_mutex_try_lock_failed, >+ 0); >+ return false; >+} >+ >+ABSL_XRAY_LOG_ARGS(1) void Mutex::Unlock() { >+ ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0); >+ DebugOnlyLockLeave(this); >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ >+ if (kDebugMode && ((v & (kMuWriter | kMuReader)) != kMuWriter)) { >+ ABSL_RAW_LOG(FATAL, "Mutex unlocked when destroyed or not locked: v=0x%x", >+ static_cast<unsigned>(v)); >+ } >+ >+ // should_try_cas is whether we'll try a compare-and-swap immediately. >+ // NOTE: optimized out when kDebugMode is false. >+ bool should_try_cas = ((v & (kMuEvent | kMuWriter)) == kMuWriter && >+ (v & (kMuWait | kMuDesig)) != kMuWait); >+ // But, we can use an alternate computation of it, that compilers >+ // currently don't find on their own. When that changes, this function >+ // can be simplified. >+ intptr_t x = (v ^ (kMuWriter | kMuWait)) & (kMuWriter | kMuEvent); >+ intptr_t y = (v ^ (kMuWriter | kMuWait)) & (kMuWait | kMuDesig); >+ // Claim: "x == 0 && y > 0" is equal to should_try_cas. >+ // Also, because kMuWriter and kMuEvent exceed kMuDesig and kMuWait, >+ // all possible non-zero values for x exceed all possible values for y. >+ // Therefore, (x == 0 && y > 0) == (x < y). >+ if (kDebugMode && should_try_cas != (x < y)) { >+ // We would usually use PRIdPTR here, but is not correctly implemented >+ // within the android toolchain. >+ ABSL_RAW_LOG(FATAL, "internal logic error %llx %llx %llx\n", >+ static_cast<long long>(v), static_cast<long long>(x), >+ static_cast<long long>(y)); >+ } >+ if (x < y && >+ mu_.compare_exchange_strong(v, v & ~(kMuWrWait | kMuWriter), >+ std::memory_order_release, >+ std::memory_order_relaxed)) { >+ // fast writer release (writer with no waiters or with designated waker) >+ } else { >+ this->UnlockSlow(nullptr /*no waitp*/); // take slow path >+ } >+ ABSL_TSAN_MUTEX_POST_UNLOCK(this, 0); >+} >+ >+// Requires v to represent a reader-locked state. >+static bool ExactlyOneReader(intptr_t v) { >+ assert((v & (kMuWriter|kMuReader)) == kMuReader); >+ assert((v & kMuHigh) != 0); >+ // The more straightforward "(v & kMuHigh) == kMuOne" also works, but >+ // on some architectures the following generates slightly smaller code. >+ // It may be faster too. >+ constexpr intptr_t kMuMultipleWaitersMask = kMuHigh ^ kMuOne; >+ return (v & kMuMultipleWaitersMask) == 0; >+} >+ >+ABSL_XRAY_LOG_ARGS(1) void Mutex::ReaderUnlock() { >+ ABSL_TSAN_MUTEX_PRE_UNLOCK(this, __tsan_mutex_read_lock); >+ DebugOnlyLockLeave(this); >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ assert((v & (kMuWriter|kMuReader)) == kMuReader); >+ if ((v & (kMuReader|kMuWait|kMuEvent)) == kMuReader) { >+ // fast reader release (reader with no waiters) >+ intptr_t clear = ExactlyOneReader(v) ? kMuReader|kMuOne : kMuOne; >+ if (mu_.compare_exchange_strong(v, v - clear, >+ std::memory_order_release, >+ std::memory_order_relaxed)) { >+ ABSL_TSAN_MUTEX_POST_UNLOCK(this, __tsan_mutex_read_lock); >+ return; >+ } >+ } >+ this->UnlockSlow(nullptr /*no waitp*/); // take slow path >+ ABSL_TSAN_MUTEX_POST_UNLOCK(this, __tsan_mutex_read_lock); >+} >+ >+// The zap_desig_waker bitmask is used to clear the designated waker flag in >+// the mutex if this thread has blocked, and therefore may be the designated >+// waker. >+static const intptr_t zap_desig_waker[] = { >+ ~static_cast<intptr_t>(0), // not blocked >+ ~static_cast<intptr_t>( >+ kMuDesig) // blocked; turn off the designated waker bit >+}; >+ >+// The ignore_waiting_writers bitmask is used to ignore the existence >+// of waiting writers if a reader that has already blocked once >+// wakes up. >+static const intptr_t ignore_waiting_writers[] = { >+ ~static_cast<intptr_t>(0), // not blocked >+ ~static_cast<intptr_t>( >+ kMuWrWait) // blocked; pretend there are no waiting writers >+}; >+ >+// Internal version of LockWhen(). See LockSlowWithDeadline() >+void Mutex::LockSlow(MuHow how, const Condition *cond, int flags) { >+ ABSL_RAW_CHECK( >+ this->LockSlowWithDeadline(how, cond, KernelTimeout::Never(), flags), >+ "condition untrue on return from LockSlow"); >+} >+ >+// Compute cond->Eval() and tell race detectors that we do it under mutex mu. >+static inline bool EvalConditionAnnotated(const Condition *cond, Mutex *mu, >+ bool locking, Mutex::MuHow how) { >+ // Delicate annotation dance. >+ // We are currently inside of read/write lock/unlock operation. >+ // All memory accesses are ignored inside of mutex operations + for unlock >+ // operation tsan considers that we've already released the mutex. >+ bool res = false; >+ if (locking) { >+ // For lock we pretend that we have finished the operation, >+ // evaluate the predicate, then unlock the mutex and start locking it again >+ // to match the annotation at the end of outer lock operation. >+ // Note: we can't simply do POST_LOCK, Eval, PRE_LOCK, because then tsan >+ // will think the lock acquisition is recursive which will trigger >+ // deadlock detector. >+ ABSL_TSAN_MUTEX_POST_LOCK(mu, TsanFlags(how), 0); >+ res = cond->Eval(); >+ ABSL_TSAN_MUTEX_PRE_UNLOCK(mu, TsanFlags(how)); >+ ABSL_TSAN_MUTEX_POST_UNLOCK(mu, TsanFlags(how)); >+ ABSL_TSAN_MUTEX_PRE_LOCK(mu, TsanFlags(how)); >+ } else { >+ // Similarly, for unlock we pretend that we have unlocked the mutex, >+ // lock the mutex, evaluate the predicate, and start unlocking it again >+ // to match the annotation at the end of outer unlock operation. >+ ABSL_TSAN_MUTEX_POST_UNLOCK(mu, TsanFlags(how)); >+ ABSL_TSAN_MUTEX_PRE_LOCK(mu, TsanFlags(how)); >+ ABSL_TSAN_MUTEX_POST_LOCK(mu, TsanFlags(how), 0); >+ res = cond->Eval(); >+ ABSL_TSAN_MUTEX_PRE_UNLOCK(mu, TsanFlags(how)); >+ } >+ // Prevent unused param warnings in non-TSAN builds. >+ static_cast<void>(mu); >+ static_cast<void>(how); >+ return res; >+} >+ >+// Compute cond->Eval() hiding it from race detectors. >+// We are hiding it because inside of UnlockSlow we can evaluate a predicate >+// that was just added by a concurrent Lock operation; Lock adds the predicate >+// to the internal Mutex list without actually acquiring the Mutex >+// (it only acquires the internal spinlock, which is rightfully invisible for >+// tsan). As the result there is no tsan-visible synchronization between the >+// addition and this thread. So if we would enable race detection here, >+// it would race with the predicate initialization. >+static inline bool EvalConditionIgnored(Mutex *mu, const Condition *cond) { >+ // Memory accesses are already ignored inside of lock/unlock operations, >+ // but synchronization operations are also ignored. When we evaluate the >+ // predicate we must ignore only memory accesses but not synchronization, >+ // because missed synchronization can lead to false reports later. >+ // So we "divert" (which un-ignores both memory accesses and synchronization) >+ // and then separately turn on ignores of memory accesses. >+ ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0); >+ ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN(); >+ bool res = cond->Eval(); >+ ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END(); >+ ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0); >+ static_cast<void>(mu); // Prevent unused param warning in non-TSAN builds. >+ return res; >+} >+ >+// Internal equivalent of *LockWhenWithDeadline(), where >+// "t" represents the absolute timeout; !t.has_timeout() means "forever". >+// "how" is "kShared" (for ReaderLockWhen) or "kExclusive" (for LockWhen) >+// In flags, bits are ored together: >+// - kMuHasBlocked indicates that the client has already blocked on the call so >+// the designated waker bit must be cleared and waiting writers should not >+// obstruct this call >+// - kMuIsCond indicates that this is a conditional acquire (condition variable, >+// Await, LockWhen) so contention profiling should be suppressed. >+bool Mutex::LockSlowWithDeadline(MuHow how, const Condition *cond, >+ KernelTimeout t, int flags) { >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ bool unlock = false; >+ if ((v & how->fast_need_zero) == 0 && // try fast acquire >+ mu_.compare_exchange_strong( >+ v, (how->fast_or | (v & zap_desig_waker[flags & kMuHasBlocked])) + >+ how->fast_add, >+ std::memory_order_acquire, std::memory_order_relaxed)) { >+ if (cond == nullptr || EvalConditionAnnotated(cond, this, true, how)) { >+ return true; >+ } >+ unlock = true; >+ } >+ SynchWaitParams waitp( >+ how, cond, t, nullptr /*no cvmu*/, Synch_GetPerThreadAnnotated(this), >+ nullptr /*no cv_word*/); >+ if (!Condition::GuaranteedEqual(cond, nullptr)) { >+ flags |= kMuIsCond; >+ } >+ if (unlock) { >+ this->UnlockSlow(&waitp); >+ this->Block(waitp.thread); >+ flags |= kMuHasBlocked; >+ } >+ this->LockSlowLoop(&waitp, flags); >+ return waitp.cond != nullptr || // => cond known true from LockSlowLoop >+ cond == nullptr || EvalConditionAnnotated(cond, this, true, how); >+} >+ >+// RAW_CHECK_FMT() takes a condition, a printf-style format std::string, and >+// the printf-style argument list. The format std::string must be a literal. >+// Arguments after the first are not evaluated unless the condition is true. >+#define RAW_CHECK_FMT(cond, ...) \ >+ do { \ >+ if (ABSL_PREDICT_FALSE(!(cond))) { \ >+ ABSL_RAW_LOG(FATAL, "Check " #cond " failed: " __VA_ARGS__); \ >+ } \ >+ } while (0) >+ >+static void CheckForMutexCorruption(intptr_t v, const char* label) { >+ // Test for either of two situations that should not occur in v: >+ // kMuWriter and kMuReader >+ // kMuWrWait and !kMuWait >+ const intptr_t w = v ^ kMuWait; >+ // By flipping that bit, we can now test for: >+ // kMuWriter and kMuReader in w >+ // kMuWrWait and kMuWait in w >+ // We've chosen these two pairs of values to be so that they will overlap, >+ // respectively, when the word is left shifted by three. This allows us to >+ // save a branch in the common (correct) case of them not being coincident. >+ static_assert(kMuReader << 3 == kMuWriter, "must match"); >+ static_assert(kMuWait << 3 == kMuWrWait, "must match"); >+ if (ABSL_PREDICT_TRUE((w & (w << 3) & (kMuWriter | kMuWrWait)) == 0)) return; >+ RAW_CHECK_FMT((v & (kMuWriter | kMuReader)) != (kMuWriter | kMuReader), >+ "%s: Mutex corrupt: both reader and writer lock held: %p", >+ label, reinterpret_cast<void *>(v)); >+ RAW_CHECK_FMT((v & (kMuWait | kMuWrWait)) != kMuWrWait, >+ "%s: Mutex corrupt: waiting writer with no waiters: %p", >+ label, reinterpret_cast<void *>(v)); >+ assert(false); >+} >+ >+void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) { >+ int c = 0; >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ if ((v & kMuEvent) != 0) { >+ PostSynchEvent(this, >+ waitp->how == kExclusive? SYNCH_EV_LOCK: SYNCH_EV_READERLOCK); >+ } >+ ABSL_RAW_CHECK( >+ waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors, >+ "detected illegal recursion into Mutex code"); >+ for (;;) { >+ v = mu_.load(std::memory_order_relaxed); >+ CheckForMutexCorruption(v, "Lock"); >+ if ((v & waitp->how->slow_need_zero) == 0) { >+ if (mu_.compare_exchange_strong( >+ v, (waitp->how->fast_or | >+ (v & zap_desig_waker[flags & kMuHasBlocked])) + >+ waitp->how->fast_add, >+ std::memory_order_acquire, std::memory_order_relaxed)) { >+ if (waitp->cond == nullptr || >+ EvalConditionAnnotated(waitp->cond, this, true, waitp->how)) { >+ break; // we timed out, or condition true, so return >+ } >+ this->UnlockSlow(waitp); // got lock but condition false >+ this->Block(waitp->thread); >+ flags |= kMuHasBlocked; >+ c = 0; >+ } >+ } else { // need to access waiter list >+ bool dowait = false; >+ if ((v & (kMuSpin|kMuWait)) == 0) { // no waiters >+ // This thread tries to become the one and only waiter. >+ PerThreadSynch *new_h = Enqueue(nullptr, waitp, v, flags); >+ intptr_t nv = (v & zap_desig_waker[flags & kMuHasBlocked] & kMuLow) | >+ kMuWait; >+ ABSL_RAW_CHECK(new_h != nullptr, "Enqueue to empty list failed"); >+ if (waitp->how == kExclusive && (v & kMuReader) != 0) { >+ nv |= kMuWrWait; >+ } >+ if (mu_.compare_exchange_strong( >+ v, reinterpret_cast<intptr_t>(new_h) | nv, >+ std::memory_order_release, std::memory_order_relaxed)) { >+ dowait = true; >+ } else { // attempted Enqueue() failed >+ // zero out the waitp field set by Enqueue() >+ waitp->thread->waitp = nullptr; >+ } >+ } else if ((v & waitp->how->slow_inc_need_zero & >+ ignore_waiting_writers[flags & kMuHasBlocked]) == 0) { >+ // This is a reader that needs to increment the reader count, >+ // but the count is currently held in the last waiter. >+ if (mu_.compare_exchange_strong( >+ v, (v & zap_desig_waker[flags & kMuHasBlocked]) | kMuSpin | >+ kMuReader, >+ std::memory_order_acquire, std::memory_order_relaxed)) { >+ PerThreadSynch *h = GetPerThreadSynch(v); >+ h->readers += kMuOne; // inc reader count in waiter >+ do { // release spinlock >+ v = mu_.load(std::memory_order_relaxed); >+ } while (!mu_.compare_exchange_weak(v, (v & ~kMuSpin) | kMuReader, >+ std::memory_order_release, >+ std::memory_order_relaxed)); >+ if (waitp->cond == nullptr || >+ EvalConditionAnnotated(waitp->cond, this, true, waitp->how)) { >+ break; // we timed out, or condition true, so return >+ } >+ this->UnlockSlow(waitp); // got lock but condition false >+ this->Block(waitp->thread); >+ flags |= kMuHasBlocked; >+ c = 0; >+ } >+ } else if ((v & kMuSpin) == 0 && // attempt to queue ourselves >+ mu_.compare_exchange_strong( >+ v, (v & zap_desig_waker[flags & kMuHasBlocked]) | kMuSpin | >+ kMuWait, >+ std::memory_order_acquire, std::memory_order_relaxed)) { >+ PerThreadSynch *h = GetPerThreadSynch(v); >+ PerThreadSynch *new_h = Enqueue(h, waitp, v, flags); >+ intptr_t wr_wait = 0; >+ ABSL_RAW_CHECK(new_h != nullptr, "Enqueue to list failed"); >+ if (waitp->how == kExclusive && (v & kMuReader) != 0) { >+ wr_wait = kMuWrWait; // give priority to a waiting writer >+ } >+ do { // release spinlock >+ v = mu_.load(std::memory_order_relaxed); >+ } while (!mu_.compare_exchange_weak( >+ v, (v & (kMuLow & ~kMuSpin)) | kMuWait | wr_wait | >+ reinterpret_cast<intptr_t>(new_h), >+ std::memory_order_release, std::memory_order_relaxed)); >+ dowait = true; >+ } >+ if (dowait) { >+ this->Block(waitp->thread); // wait until removed from list or timeout >+ flags |= kMuHasBlocked; >+ c = 0; >+ } >+ } >+ ABSL_RAW_CHECK( >+ waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors, >+ "detected illegal recursion into Mutex code"); >+ c = Delay(c, GENTLE); // delay, then try again >+ } >+ ABSL_RAW_CHECK( >+ waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors, >+ "detected illegal recursion into Mutex code"); >+ if ((v & kMuEvent) != 0) { >+ PostSynchEvent(this, >+ waitp->how == kExclusive? SYNCH_EV_LOCK_RETURNING : >+ SYNCH_EV_READERLOCK_RETURNING); >+ } >+} >+ >+// Unlock this mutex, which is held by the current thread. >+// If waitp is non-zero, it must be the wait parameters for the current thread >+// which holds the lock but is not runnable because its condition is false >+// or it n the process of blocking on a condition variable; it must requeue >+// itself on the mutex/condvar to wait for its condition to become true. >+void Mutex::UnlockSlow(SynchWaitParams *waitp) { >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ this->AssertReaderHeld(); >+ CheckForMutexCorruption(v, "Unlock"); >+ if ((v & kMuEvent) != 0) { >+ PostSynchEvent(this, >+ (v & kMuWriter) != 0? SYNCH_EV_UNLOCK: SYNCH_EV_READERUNLOCK); >+ } >+ int c = 0; >+ // the waiter under consideration to wake, or zero >+ PerThreadSynch *w = nullptr; >+ // the predecessor to w or zero >+ PerThreadSynch *pw = nullptr; >+ // head of the list searched previously, or zero >+ PerThreadSynch *old_h = nullptr; >+ // a condition that's known to be false. >+ const Condition *known_false = nullptr; >+ PerThreadSynch *wake_list = kPerThreadSynchNull; // list of threads to wake >+ intptr_t wr_wait = 0; // set to kMuWrWait if we wake a reader and a >+ // later writer could have acquired the lock >+ // (starvation avoidance) >+ ABSL_RAW_CHECK(waitp == nullptr || waitp->thread->waitp == nullptr || >+ waitp->thread->suppress_fatal_errors, >+ "detected illegal recursion into Mutex code"); >+ // This loop finds threads wake_list to wakeup if any, and removes them from >+ // the list of waiters. In addition, it places waitp.thread on the queue of >+ // waiters if waitp is non-zero. >+ for (;;) { >+ v = mu_.load(std::memory_order_relaxed); >+ if ((v & kMuWriter) != 0 && (v & (kMuWait | kMuDesig)) != kMuWait && >+ waitp == nullptr) { >+ // fast writer release (writer with no waiters or with designated waker) >+ if (mu_.compare_exchange_strong(v, v & ~(kMuWrWait | kMuWriter), >+ std::memory_order_release, >+ std::memory_order_relaxed)) { >+ return; >+ } >+ } else if ((v & (kMuReader | kMuWait)) == kMuReader && waitp == nullptr) { >+ // fast reader release (reader with no waiters) >+ intptr_t clear = ExactlyOneReader(v) ? kMuReader | kMuOne : kMuOne; >+ if (mu_.compare_exchange_strong(v, v - clear, >+ std::memory_order_release, >+ std::memory_order_relaxed)) { >+ return; >+ } >+ } else if ((v & kMuSpin) == 0 && // attempt to get spinlock >+ mu_.compare_exchange_strong(v, v | kMuSpin, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ if ((v & kMuWait) == 0) { // no one to wake >+ intptr_t nv; >+ bool do_enqueue = true; // always Enqueue() the first time >+ ABSL_RAW_CHECK(waitp != nullptr, >+ "UnlockSlow is confused"); // about to sleep >+ do { // must loop to release spinlock as reader count may change >+ v = mu_.load(std::memory_order_relaxed); >+ // decrement reader count if there are readers >+ intptr_t new_readers = (v >= kMuOne)? v - kMuOne : v; >+ PerThreadSynch *new_h = nullptr; >+ if (do_enqueue) { >+ // If we are enqueuing on a CondVar (waitp->cv_word != nullptr) then >+ // we must not retry here. The initial attempt will always have >+ // succeeded, further attempts would enqueue us against *this due to >+ // Fer() handling. >+ do_enqueue = (waitp->cv_word == nullptr); >+ new_h = Enqueue(nullptr, waitp, new_readers, kMuIsCond); >+ } >+ intptr_t clear = kMuWrWait | kMuWriter; // by default clear write bit >+ if ((v & kMuWriter) == 0 && ExactlyOneReader(v)) { // last reader >+ clear = kMuWrWait | kMuReader; // clear read bit >+ } >+ nv = (v & kMuLow & ~clear & ~kMuSpin); >+ if (new_h != nullptr) { >+ nv |= kMuWait | reinterpret_cast<intptr_t>(new_h); >+ } else { // new_h could be nullptr if we queued ourselves on a >+ // CondVar >+ // In that case, we must place the reader count back in the mutex >+ // word, as Enqueue() did not store it in the new waiter. >+ nv |= new_readers & kMuHigh; >+ } >+ // release spinlock & our lock; retry if reader-count changed >+ // (writer count cannot change since we hold lock) >+ } while (!mu_.compare_exchange_weak(v, nv, >+ std::memory_order_release, >+ std::memory_order_relaxed)); >+ break; >+ } >+ >+ // There are waiters. >+ // Set h to the head of the circular waiter list. >+ PerThreadSynch *h = GetPerThreadSynch(v); >+ if ((v & kMuReader) != 0 && (h->readers & kMuHigh) > kMuOne) { >+ // a reader but not the last >+ h->readers -= kMuOne; // release our lock >+ intptr_t nv = v; // normally just release spinlock >+ if (waitp != nullptr) { // but waitp!=nullptr => must queue ourselves >+ PerThreadSynch *new_h = Enqueue(h, waitp, v, kMuIsCond); >+ ABSL_RAW_CHECK(new_h != nullptr, >+ "waiters disappeared during Enqueue()!"); >+ nv &= kMuLow; >+ nv |= kMuWait | reinterpret_cast<intptr_t>(new_h); >+ } >+ mu_.store(nv, std::memory_order_release); // release spinlock >+ // can release with a store because there were waiters >+ break; >+ } >+ >+ // Either we didn't search before, or we marked the queue >+ // as "maybe_unlocking" and no one else should have changed it. >+ ABSL_RAW_CHECK(old_h == nullptr || h->maybe_unlocking, >+ "Mutex queue changed beneath us"); >+ >+ // The lock is becoming free, and there's a waiter >+ if (old_h != nullptr && >+ !old_h->may_skip) { // we used old_h as a terminator >+ old_h->may_skip = true; // allow old_h to skip once more >+ ABSL_RAW_CHECK(old_h->skip == nullptr, "illegal skip from head"); >+ if (h != old_h && MuSameCondition(old_h, old_h->next)) { >+ old_h->skip = old_h->next; // old_h not head & can skip to successor >+ } >+ } >+ if (h->next->waitp->how == kExclusive && >+ Condition::GuaranteedEqual(h->next->waitp->cond, nullptr)) { >+ // easy case: writer with no condition; no need to search >+ pw = h; // wake w, the successor of h (=pw) >+ w = h->next; >+ w->wake = true; >+ // We are waking up a writer. This writer may be racing against >+ // an already awake reader for the lock. We want the >+ // writer to usually win this race, >+ // because if it doesn't, we can potentially keep taking a reader >+ // perpetually and writers will starve. Worse than >+ // that, this can also starve other readers if kMuWrWait gets set >+ // later. >+ wr_wait = kMuWrWait; >+ } else if (w != nullptr && (w->waitp->how == kExclusive || h == old_h)) { >+ // we found a waiter w to wake on a previous iteration and either it's >+ // a writer, or we've searched the entire list so we have all the >+ // readers. >+ if (pw == nullptr) { // if w's predecessor is unknown, it must be h >+ pw = h; >+ } >+ } else { >+ // At this point we don't know all the waiters to wake, and the first >+ // waiter has a condition or is a reader. We avoid searching over >+ // waiters we've searched on previous iterations by starting at >+ // old_h if it's set. If old_h==h, there's no one to wakeup at all. >+ if (old_h == h) { // we've searched before, and nothing's new >+ // so there's no one to wake. >+ intptr_t nv = (v & ~(kMuReader|kMuWriter|kMuWrWait)); >+ h->readers = 0; >+ h->maybe_unlocking = false; // finished unlocking >+ if (waitp != nullptr) { // we must queue ourselves and sleep >+ PerThreadSynch *new_h = Enqueue(h, waitp, v, kMuIsCond); >+ nv &= kMuLow; >+ if (new_h != nullptr) { >+ nv |= kMuWait | reinterpret_cast<intptr_t>(new_h); >+ } // else new_h could be nullptr if we queued ourselves on a >+ // CondVar >+ } >+ // release spinlock & lock >+ // can release with a store because there were waiters >+ mu_.store(nv, std::memory_order_release); >+ break; >+ } >+ >+ // set up to walk the list >+ PerThreadSynch *w_walk; // current waiter during list walk >+ PerThreadSynch *pw_walk; // previous waiter during list walk >+ if (old_h != nullptr) { // we've searched up to old_h before >+ pw_walk = old_h; >+ w_walk = old_h->next; >+ } else { // no prior search, start at beginning >+ pw_walk = >+ nullptr; // h->next's predecessor may change; don't record it >+ w_walk = h->next; >+ } >+ >+ h->may_skip = false; // ensure we never skip past h in future searches >+ // even if other waiters are queued after it. >+ ABSL_RAW_CHECK(h->skip == nullptr, "illegal skip from head"); >+ >+ h->maybe_unlocking = true; // we're about to scan the waiter list >+ // without the spinlock held. >+ // Enqueue must be conservative about >+ // priority queuing. >+ >+ // We must release the spinlock to evaluate the conditions. >+ mu_.store(v, std::memory_order_release); // release just spinlock >+ // can release with a store because there were waiters >+ >+ // h is the last waiter queued, and w_walk the first unsearched waiter. >+ // Without the spinlock, the locations mu_ and h->next may now change >+ // underneath us, but since we hold the lock itself, the only legal >+ // change is to add waiters between h and w_walk. Therefore, it's safe >+ // to walk the path from w_walk to h inclusive. (TryRemove() can remove >+ // a waiter anywhere, but it acquires both the spinlock and the Mutex) >+ >+ old_h = h; // remember we searched to here >+ >+ // Walk the path upto and including h looking for waiters we can wake. >+ while (pw_walk != h) { >+ w_walk->wake = false; >+ if (w_walk->waitp->cond == >+ nullptr || // no condition => vacuously true OR >+ (w_walk->waitp->cond != known_false && >+ // this thread's condition is not known false, AND >+ // is in fact true >+ EvalConditionIgnored(this, w_walk->waitp->cond))) { >+ if (w == nullptr) { >+ w_walk->wake = true; // can wake this waiter >+ w = w_walk; >+ pw = pw_walk; >+ if (w_walk->waitp->how == kExclusive) { >+ wr_wait = kMuWrWait; >+ break; // bail if waking this writer >+ } >+ } else if (w_walk->waitp->how == kShared) { // wake if a reader >+ w_walk->wake = true; >+ } else { // writer with true condition >+ wr_wait = kMuWrWait; >+ } >+ } else { // can't wake; condition false >+ known_false = w_walk->waitp->cond; // remember last false condition >+ } >+ if (w_walk->wake) { // we're waking reader w_walk >+ pw_walk = w_walk; // don't skip similar waiters >+ } else { // not waking; skip as much as possible >+ pw_walk = Skip(w_walk); >+ } >+ // If pw_walk == h, then load of pw_walk->next can race with >+ // concurrent write in Enqueue(). However, at the same time >+ // we do not need to do the load, because we will bail out >+ // from the loop anyway. >+ if (pw_walk != h) { >+ w_walk = pw_walk->next; >+ } >+ } >+ >+ continue; // restart for(;;)-loop to wakeup w or to find more waiters >+ } >+ ABSL_RAW_CHECK(pw->next == w, "pw not w's predecessor"); >+ // The first (and perhaps only) waiter we've chosen to wake is w, whose >+ // predecessor is pw. If w is a reader, we must wake all the other >+ // waiters with wake==true as well. We may also need to queue >+ // ourselves if waitp != null. The spinlock and the lock are still >+ // held. >+ >+ // This traverses the list in [ pw->next, h ], where h is the head, >+ // removing all elements with wake==true and placing them in the >+ // singly-linked list wake_list. Returns the new head. >+ h = DequeueAllWakeable(h, pw, &wake_list); >+ >+ intptr_t nv = (v & kMuEvent) | kMuDesig; >+ // assume no waiters left, >+ // set kMuDesig for INV1a >+ >+ if (waitp != nullptr) { // we must queue ourselves and sleep >+ h = Enqueue(h, waitp, v, kMuIsCond); >+ // h is new last waiter; could be null if we queued ourselves on a >+ // CondVar >+ } >+ >+ ABSL_RAW_CHECK(wake_list != kPerThreadSynchNull, >+ "unexpected empty wake list"); >+ >+ if (h != nullptr) { // there are waiters left >+ h->readers = 0; >+ h->maybe_unlocking = false; // finished unlocking >+ nv |= wr_wait | kMuWait | reinterpret_cast<intptr_t>(h); >+ } >+ >+ // release both spinlock & lock >+ // can release with a store because there were waiters >+ mu_.store(nv, std::memory_order_release); >+ break; // out of for(;;)-loop >+ } >+ c = Delay(c, AGGRESSIVE); // aggressive here; no one can proceed till we do >+ } // end of for(;;)-loop >+ >+ if (wake_list != kPerThreadSynchNull) { >+ int64_t enqueue_timestamp = wake_list->waitp->contention_start_cycles; >+ bool cond_waiter = wake_list->cond_waiter; >+ do { >+ wake_list = Wakeup(wake_list); // wake waiters >+ } while (wake_list != kPerThreadSynchNull); >+ if (!cond_waiter) { >+ // Sample lock contention events only if the (first) waiter was trying to >+ // acquire the lock, not waiting on a condition variable or Condition. >+ int64_t wait_cycles = base_internal::CycleClock::Now() - enqueue_timestamp; >+ mutex_tracer("slow release", this, wait_cycles); >+ ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0); >+ submit_profile_data(enqueue_timestamp); >+ ABSL_TSAN_MUTEX_POST_DIVERT(this, 0); >+ } >+ } >+} >+ >+// Used by CondVar implementation to reacquire mutex after waking from >+// condition variable. This routine is used instead of Lock() because the >+// waiting thread may have been moved from the condition variable queue to the >+// mutex queue without a wakeup, by Trans(). In that case, when the thread is >+// finally woken, the woken thread will believe it has been woken from the >+// condition variable (i.e. its PC will be in when in the CondVar code), when >+// in fact it has just been woken from the mutex. Thus, it must enter the slow >+// path of the mutex in the same state as if it had just woken from the mutex. >+// That is, it must ensure to clear kMuDesig (INV1b). >+void Mutex::Trans(MuHow how) { >+ this->LockSlow(how, nullptr, kMuHasBlocked | kMuIsCond); >+} >+ >+// Used by CondVar implementation to effectively wake thread w from the >+// condition variable. If this mutex is free, we simply wake the thread. >+// It will later acquire the mutex with high probability. Otherwise, we >+// enqueue thread w on this mutex. >+void Mutex::Fer(PerThreadSynch *w) { >+ int c = 0; >+ ABSL_RAW_CHECK(w->waitp->cond == nullptr, >+ "Mutex::Fer while waiting on Condition"); >+ ABSL_RAW_CHECK(!w->waitp->timeout.has_timeout(), >+ "Mutex::Fer while in timed wait"); >+ ABSL_RAW_CHECK(w->waitp->cv_word == nullptr, >+ "Mutex::Fer with pending CondVar queueing"); >+ for (;;) { >+ intptr_t v = mu_.load(std::memory_order_relaxed); >+ // Note: must not queue if the mutex is unlocked (nobody will wake it). >+ // For example, we can have only kMuWait (conditional) or maybe >+ // kMuWait|kMuWrWait. >+ // conflicting != 0 implies that the waking thread cannot currently take >+ // the mutex, which in turn implies that someone else has it and can wake >+ // us if we queue. >+ const intptr_t conflicting = >+ kMuWriter | (w->waitp->how == kShared ? 0 : kMuReader); >+ if ((v & conflicting) == 0) { >+ w->next = nullptr; >+ w->state.store(PerThreadSynch::kAvailable, std::memory_order_release); >+ IncrementSynchSem(this, w); >+ return; >+ } else { >+ if ((v & (kMuSpin|kMuWait)) == 0) { // no waiters >+ // This thread tries to become the one and only waiter. >+ PerThreadSynch *new_h = Enqueue(nullptr, w->waitp, v, kMuIsCond); >+ ABSL_RAW_CHECK(new_h != nullptr, >+ "Enqueue failed"); // we must queue ourselves >+ if (mu_.compare_exchange_strong( >+ v, reinterpret_cast<intptr_t>(new_h) | (v & kMuLow) | kMuWait, >+ std::memory_order_release, std::memory_order_relaxed)) { >+ return; >+ } >+ } else if ((v & kMuSpin) == 0 && >+ mu_.compare_exchange_strong(v, v | kMuSpin | kMuWait)) { >+ PerThreadSynch *h = GetPerThreadSynch(v); >+ PerThreadSynch *new_h = Enqueue(h, w->waitp, v, kMuIsCond); >+ ABSL_RAW_CHECK(new_h != nullptr, >+ "Enqueue failed"); // we must queue ourselves >+ do { >+ v = mu_.load(std::memory_order_relaxed); >+ } while (!mu_.compare_exchange_weak( >+ v, >+ (v & kMuLow & ~kMuSpin) | kMuWait | >+ reinterpret_cast<intptr_t>(new_h), >+ std::memory_order_release, std::memory_order_relaxed)); >+ return; >+ } >+ } >+ c = Delay(c, GENTLE); >+ } >+} >+ >+void Mutex::AssertHeld() const { >+ if ((mu_.load(std::memory_order_relaxed) & kMuWriter) == 0) { >+ SynchEvent *e = GetSynchEvent(this); >+ ABSL_RAW_LOG(FATAL, "thread should hold write lock on Mutex %p %s", >+ static_cast<const void *>(this), >+ (e == nullptr ? "" : e->name)); >+ } >+} >+ >+void Mutex::AssertReaderHeld() const { >+ if ((mu_.load(std::memory_order_relaxed) & (kMuReader | kMuWriter)) == 0) { >+ SynchEvent *e = GetSynchEvent(this); >+ ABSL_RAW_LOG( >+ FATAL, "thread should hold at least a read lock on Mutex %p %s", >+ static_cast<const void *>(this), (e == nullptr ? "" : e->name)); >+ } >+} >+ >+// -------------------------------- condition variables >+static const intptr_t kCvSpin = 0x0001L; // spinlock protects waiter list >+static const intptr_t kCvEvent = 0x0002L; // record events >+ >+static const intptr_t kCvLow = 0x0003L; // low order bits of CV >+ >+// Hack to make constant values available to gdb pretty printer >+enum { kGdbCvSpin = kCvSpin, kGdbCvEvent = kCvEvent, kGdbCvLow = kCvLow, }; >+ >+static_assert(PerThreadSynch::kAlignment > kCvLow, >+ "PerThreadSynch::kAlignment must be greater than kCvLow"); >+ >+void CondVar::EnableDebugLog(const char *name) { >+ SynchEvent *e = EnsureSynchEvent(&this->cv_, name, kCvEvent, kCvSpin); >+ e->log = true; >+ UnrefSynchEvent(e); >+} >+ >+CondVar::~CondVar() { >+ if ((cv_.load(std::memory_order_relaxed) & kCvEvent) != 0) { >+ ForgetSynchEvent(&this->cv_, kCvEvent, kCvSpin); >+ } >+} >+ >+ >+// Remove thread s from the list of waiters on this condition variable. >+void CondVar::Remove(PerThreadSynch *s) { >+ intptr_t v; >+ int c = 0; >+ for (v = cv_.load(std::memory_order_relaxed);; >+ v = cv_.load(std::memory_order_relaxed)) { >+ if ((v & kCvSpin) == 0 && // attempt to acquire spinlock >+ cv_.compare_exchange_strong(v, v | kCvSpin, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ PerThreadSynch *h = reinterpret_cast<PerThreadSynch *>(v & ~kCvLow); >+ if (h != nullptr) { >+ PerThreadSynch *w = h; >+ while (w->next != s && w->next != h) { // search for thread >+ w = w->next; >+ } >+ if (w->next == s) { // found thread; remove it >+ w->next = s->next; >+ if (h == s) { >+ h = (w == s) ? nullptr : w; >+ } >+ s->next = nullptr; >+ s->state.store(PerThreadSynch::kAvailable, std::memory_order_release); >+ } >+ } >+ // release spinlock >+ cv_.store((v & kCvEvent) | reinterpret_cast<intptr_t>(h), >+ std::memory_order_release); >+ return; >+ } else { >+ c = Delay(c, GENTLE); // try again after a delay >+ } >+ } >+} >+ >+// Queue thread waitp->thread on condition variable word cv_word using >+// wait parameters waitp. >+// We split this into a separate routine, rather than simply doing it as part >+// of WaitCommon(). If we were to queue ourselves on the condition variable >+// before calling Mutex::UnlockSlow(), the Mutex code might be re-entered (via >+// the logging code, or via a Condition function) and might potentially attempt >+// to block this thread. That would be a problem if the thread were already on >+// a the condition variable waiter queue. Thus, we use the waitp->cv_word >+// to tell the unlock code to call CondVarEnqueue() to queue the thread on the >+// condition variable queue just before the mutex is to be unlocked, and (most >+// importantly) after any call to an external routine that might re-enter the >+// mutex code. >+static void CondVarEnqueue(SynchWaitParams *waitp) { >+ // This thread might be transferred to the Mutex queue by Fer() when >+ // we are woken. To make sure that is what happens, Enqueue() doesn't >+ // call CondVarEnqueue() again but instead uses its normal code. We >+ // must do this before we queue ourselves so that cv_word will be null >+ // when seen by the dequeuer, who may wish immediately to requeue >+ // this thread on another queue. >+ std::atomic<intptr_t> *cv_word = waitp->cv_word; >+ waitp->cv_word = nullptr; >+ >+ intptr_t v = cv_word->load(std::memory_order_relaxed); >+ int c = 0; >+ while ((v & kCvSpin) != 0 || // acquire spinlock >+ !cv_word->compare_exchange_weak(v, v | kCvSpin, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ c = Delay(c, GENTLE); >+ v = cv_word->load(std::memory_order_relaxed); >+ } >+ ABSL_RAW_CHECK(waitp->thread->waitp == nullptr, "waiting when shouldn't be"); >+ waitp->thread->waitp = waitp; // prepare ourselves for waiting >+ PerThreadSynch *h = reinterpret_cast<PerThreadSynch *>(v & ~kCvLow); >+ if (h == nullptr) { // add this thread to waiter list >+ waitp->thread->next = waitp->thread; >+ } else { >+ waitp->thread->next = h->next; >+ h->next = waitp->thread; >+ } >+ waitp->thread->state.store(PerThreadSynch::kQueued, >+ std::memory_order_relaxed); >+ cv_word->store((v & kCvEvent) | reinterpret_cast<intptr_t>(waitp->thread), >+ std::memory_order_release); >+} >+ >+bool CondVar::WaitCommon(Mutex *mutex, KernelTimeout t) { >+ bool rc = false; // return value; true iff we timed-out >+ >+ intptr_t mutex_v = mutex->mu_.load(std::memory_order_relaxed); >+ Mutex::MuHow mutex_how = ((mutex_v & kMuWriter) != 0) ? kExclusive : kShared; >+ ABSL_TSAN_MUTEX_PRE_UNLOCK(mutex, TsanFlags(mutex_how)); >+ >+ // maybe trace this call >+ intptr_t v = cv_.load(std::memory_order_relaxed); >+ cond_var_tracer("Wait", this); >+ if ((v & kCvEvent) != 0) { >+ PostSynchEvent(this, SYNCH_EV_WAIT); >+ } >+ >+ // Release mu and wait on condition variable. >+ SynchWaitParams waitp(mutex_how, nullptr, t, mutex, >+ Synch_GetPerThreadAnnotated(mutex), &cv_); >+ // UnlockSlow() will call CondVarEnqueue() just before releasing the >+ // Mutex, thus queuing this thread on the condition variable. See >+ // CondVarEnqueue() for the reasons. >+ mutex->UnlockSlow(&waitp); >+ >+ // wait for signal >+ while (waitp.thread->state.load(std::memory_order_acquire) == >+ PerThreadSynch::kQueued) { >+ if (!Mutex::DecrementSynchSem(mutex, waitp.thread, t)) { >+ this->Remove(waitp.thread); >+ rc = true; >+ } >+ } >+ >+ ABSL_RAW_CHECK(waitp.thread->waitp != nullptr, "not waiting when should be"); >+ waitp.thread->waitp = nullptr; // cleanup >+ >+ // maybe trace this call >+ cond_var_tracer("Unwait", this); >+ if ((v & kCvEvent) != 0) { >+ PostSynchEvent(this, SYNCH_EV_WAIT_RETURNING); >+ } >+ >+ // From synchronization point of view Wait is unlock of the mutex followed >+ // by lock of the mutex. We've annotated start of unlock in the beginning >+ // of the function. Now, finish unlock and annotate lock of the mutex. >+ // (Trans is effectively lock). >+ ABSL_TSAN_MUTEX_POST_UNLOCK(mutex, TsanFlags(mutex_how)); >+ ABSL_TSAN_MUTEX_PRE_LOCK(mutex, TsanFlags(mutex_how)); >+ mutex->Trans(mutex_how); // Reacquire mutex >+ ABSL_TSAN_MUTEX_POST_LOCK(mutex, TsanFlags(mutex_how), 0); >+ return rc; >+} >+ >+bool CondVar::WaitWithTimeout(Mutex *mu, absl::Duration timeout) { >+ return WaitWithDeadline(mu, DeadlineFromTimeout(timeout)); >+} >+ >+bool CondVar::WaitWithDeadline(Mutex *mu, absl::Time deadline) { >+ return WaitCommon(mu, KernelTimeout(deadline)); >+} >+ >+void CondVar::Wait(Mutex *mu) { >+ WaitCommon(mu, KernelTimeout::Never()); >+} >+ >+// Wake thread w >+// If it was a timed wait, w will be waiting on w->cv >+// Otherwise, if it was not a Mutex mutex, w will be waiting on w->sem >+// Otherwise, w is transferred to the Mutex mutex via Mutex::Fer(). >+void CondVar::Wakeup(PerThreadSynch *w) { >+ if (w->waitp->timeout.has_timeout() || w->waitp->cvmu == nullptr) { >+ // The waiting thread only needs to observe "w->state == kAvailable" to be >+ // released, we must cache "cvmu" before clearing "next". >+ Mutex *mu = w->waitp->cvmu; >+ w->next = nullptr; >+ w->state.store(PerThreadSynch::kAvailable, std::memory_order_release); >+ Mutex::IncrementSynchSem(mu, w); >+ } else { >+ w->waitp->cvmu->Fer(w); >+ } >+} >+ >+void CondVar::Signal() { >+ ABSL_TSAN_MUTEX_PRE_SIGNAL(0, 0); >+ intptr_t v; >+ int c = 0; >+ for (v = cv_.load(std::memory_order_relaxed); v != 0; >+ v = cv_.load(std::memory_order_relaxed)) { >+ if ((v & kCvSpin) == 0 && // attempt to acquire spinlock >+ cv_.compare_exchange_strong(v, v | kCvSpin, >+ std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ PerThreadSynch *h = reinterpret_cast<PerThreadSynch *>(v & ~kCvLow); >+ PerThreadSynch *w = nullptr; >+ if (h != nullptr) { // remove first waiter >+ w = h->next; >+ if (w == h) { >+ h = nullptr; >+ } else { >+ h->next = w->next; >+ } >+ } >+ // release spinlock >+ cv_.store((v & kCvEvent) | reinterpret_cast<intptr_t>(h), >+ std::memory_order_release); >+ if (w != nullptr) { >+ CondVar::Wakeup(w); // wake waiter, if there was one >+ cond_var_tracer("Signal wakeup", this); >+ } >+ if ((v & kCvEvent) != 0) { >+ PostSynchEvent(this, SYNCH_EV_SIGNAL); >+ } >+ ABSL_TSAN_MUTEX_POST_SIGNAL(0, 0); >+ return; >+ } else { >+ c = Delay(c, GENTLE); >+ } >+ } >+ ABSL_TSAN_MUTEX_POST_SIGNAL(0, 0); >+} >+ >+void CondVar::SignalAll () { >+ ABSL_TSAN_MUTEX_PRE_SIGNAL(0, 0); >+ intptr_t v; >+ int c = 0; >+ for (v = cv_.load(std::memory_order_relaxed); v != 0; >+ v = cv_.load(std::memory_order_relaxed)) { >+ // empty the list if spinlock free >+ // We do this by simply setting the list to empty using >+ // compare and swap. We then have the entire list in our hands, >+ // which cannot be changing since we grabbed it while no one >+ // held the lock. >+ if ((v & kCvSpin) == 0 && >+ cv_.compare_exchange_strong(v, v & kCvEvent, std::memory_order_acquire, >+ std::memory_order_relaxed)) { >+ PerThreadSynch *h = reinterpret_cast<PerThreadSynch *>(v & ~kCvLow); >+ if (h != nullptr) { >+ PerThreadSynch *w; >+ PerThreadSynch *n = h->next; >+ do { // for every thread, wake it up >+ w = n; >+ n = n->next; >+ CondVar::Wakeup(w); >+ } while (w != h); >+ cond_var_tracer("SignalAll wakeup", this); >+ } >+ if ((v & kCvEvent) != 0) { >+ PostSynchEvent(this, SYNCH_EV_SIGNALALL); >+ } >+ ABSL_TSAN_MUTEX_POST_SIGNAL(0, 0); >+ return; >+ } else { >+ c = Delay(c, GENTLE); // try again after a delay >+ } >+ } >+ ABSL_TSAN_MUTEX_POST_SIGNAL(0, 0); >+} >+ >+void ReleasableMutexLock::Release() { >+ ABSL_RAW_CHECK(this->mu_ != nullptr, >+ "ReleasableMutexLock::Release may only be called once"); >+ this->mu_->Unlock(); >+ this->mu_ = nullptr; >+} >+ >+#ifdef THREAD_SANITIZER >+extern "C" void __tsan_read1(void *addr); >+#else >+#define __tsan_read1(addr) // do nothing if TSan not enabled >+#endif >+ >+// A function that just returns its argument, dereferenced >+static bool Dereference(void *arg) { >+ // ThreadSanitizer does not instrument this file for memory accesses. >+ // This function dereferences a user variable that can participate >+ // in a data race, so we need to manually tell TSan about this memory access. >+ __tsan_read1(arg); >+ return *(static_cast<bool *>(arg)); >+} >+ >+Condition::Condition() {} // null constructor, used for kTrue only >+const Condition Condition::kTrue; >+ >+Condition::Condition(bool (*func)(void *), void *arg) >+ : eval_(&CallVoidPtrFunction), >+ function_(func), >+ method_(nullptr), >+ arg_(arg) {} >+ >+bool Condition::CallVoidPtrFunction(const Condition *c) { >+ return (*c->function_)(c->arg_); >+} >+ >+Condition::Condition(const bool *cond) >+ : eval_(CallVoidPtrFunction), >+ function_(Dereference), >+ method_(nullptr), >+ // const_cast is safe since Dereference does not modify arg >+ arg_(const_cast<bool *>(cond)) {} >+ >+bool Condition::Eval() const { >+ // eval_ == null for kTrue >+ return (this->eval_ == nullptr) || (*this->eval_)(this); >+} >+ >+bool Condition::GuaranteedEqual(const Condition *a, const Condition *b) { >+ if (a == nullptr) { >+ return b == nullptr || b->eval_ == nullptr; >+ } >+ if (b == nullptr || b->eval_ == nullptr) { >+ return a->eval_ == nullptr; >+ } >+ return a->eval_ == b->eval_ && a->function_ == b->function_ && >+ a->arg_ == b->arg_ && a->method_ == b->method_; >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex.h >new file mode 100644 >index 0000000000000000000000000000000000000000..83c214867ac53a9122dd4e9753fc8bf72e128be5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex.h >@@ -0,0 +1,1028 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// mutex.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines a `Mutex` -- a mutually exclusive lock -- and the >+// most common type of synchronization primitive for facilitating locks on >+// shared resources. A mutex is used to prevent multiple threads from accessing >+// and/or writing to a shared resource concurrently. >+// >+// Unlike a `std::mutex`, the Abseil `Mutex` provides the following additional >+// features: >+// * Conditional predicates intrinsic to the `Mutex` object >+// * Shared/reader locks, in addition to standard exclusive/writer locks >+// * Deadlock detection and debug support. >+// >+// The following helper classes are also defined within this file: >+// >+// MutexLock - An RAII wrapper to acquire and release a `Mutex` for exclusive/ >+// write access within the current scope. >+// ReaderMutexLock >+// - An RAII wrapper to acquire and release a `Mutex` for shared/read >+// access within the current scope. >+// >+// WriterMutexLock >+// - Alias for `MutexLock` above, designed for use in distinguishing >+// reader and writer locks within code. >+// >+// In addition to simple mutex locks, this file also defines ways to perform >+// locking under certain conditions. >+// >+// Condition - (Preferred) Used to wait for a particular predicate that >+// depends on state protected by the `Mutex` to become true. >+// CondVar - A lower-level variant of `Condition` that relies on >+// application code to explicitly signal the `CondVar` when >+// a condition has been met. >+// >+// See below for more information on using `Condition` or `CondVar`. >+// >+// Mutexes and mutex behavior can be quite complicated. The information within >+// this header file is limited, as a result. Please consult the Mutex guide for >+// more complete information and examples. >+ >+#ifndef ABSL_SYNCHRONIZATION_MUTEX_H_ >+#define ABSL_SYNCHRONIZATION_MUTEX_H_ >+ >+#include <atomic> >+#include <cstdint> >+#include <string> >+ >+#include "absl/base/internal/identity.h" >+#include "absl/base/internal/low_level_alloc.h" >+#include "absl/base/internal/thread_identity.h" >+#include "absl/base/internal/tsan_mutex_interface.h" >+#include "absl/base/port.h" >+#include "absl/base/thread_annotations.h" >+#include "absl/synchronization/internal/kernel_timeout.h" >+#include "absl/synchronization/internal/per_thread_sem.h" >+#include "absl/time/time.h" >+ >+// Decide if we should use the non-production implementation because >+// the production implementation hasn't been fully ported yet. >+#ifdef ABSL_INTERNAL_USE_NONPROD_MUTEX >+#error ABSL_INTERNAL_USE_NONPROD_MUTEX cannot be directly set >+#elif defined(ABSL_LOW_LEVEL_ALLOC_MISSING) >+#define ABSL_INTERNAL_USE_NONPROD_MUTEX 1 >+#include "absl/synchronization/internal/mutex_nonprod.inc" >+#endif >+ >+namespace absl { >+ >+class Condition; >+struct SynchWaitParams; >+ >+// ----------------------------------------------------------------------------- >+// Mutex >+// ----------------------------------------------------------------------------- >+// >+// A `Mutex` is a non-reentrant (aka non-recursive) Mutually Exclusive lock >+// on some resource, typically a variable or data structure with associated >+// invariants. Proper usage of mutexes prevents concurrent access by different >+// threads to the same resource. >+// >+// A `Mutex` has two basic operations: `Mutex::Lock()` and `Mutex::Unlock()`. >+// The `Lock()` operation *acquires* a `Mutex` (in a state known as an >+// *exclusive* -- or write -- lock), while the `Unlock()` operation *releases* a >+// Mutex. During the span of time between the Lock() and Unlock() operations, >+// a mutex is said to be *held*. By design all mutexes support exclusive/write >+// locks, as this is the most common way to use a mutex. >+// >+// The `Mutex` state machine for basic lock/unlock operations is quite simple: >+// >+// | | Lock() | Unlock() | >+// |----------------+------------+----------| >+// | Free | Exclusive | invalid | >+// | Exclusive | blocks | Free | >+// >+// Attempts to `Unlock()` must originate from the thread that performed the >+// corresponding `Lock()` operation. >+// >+// An "invalid" operation is disallowed by the API. The `Mutex` implementation >+// is allowed to do anything on an invalid call, including but not limited to >+// crashing with a useful error message, silently succeeding, or corrupting >+// data structures. In debug mode, the implementation attempts to crash with a >+// useful error message. >+// >+// `Mutex` is not guaranteed to be "fair" in prioritizing waiting threads; it >+// is, however, approximately fair over long periods, and starvation-free for >+// threads at the same priority. >+// >+// The lock/unlock primitives are now annotated with lock annotations >+// defined in (base/thread_annotations.h). When writing multi-threaded code, >+// you should use lock annotations whenever possible to document your lock >+// synchronization policy. Besides acting as documentation, these annotations >+// also help compilers or static analysis tools to identify and warn about >+// issues that could potentially result in race conditions and deadlocks. >+// >+// For more information about the lock annotations, please see >+// [Thread Safety Analysis](http://clang.llvm.org/docs/ThreadSafetyAnalysis.html) >+// in the Clang documentation. >+// >+// See also `MutexLock`, below, for scoped `Mutex` acquisition. >+ >+class LOCKABLE Mutex { >+ public: >+ Mutex(); >+ ~Mutex(); >+ >+ // Mutex::Lock() >+ // >+ // Blocks the calling thread, if necessary, until this `Mutex` is free, and >+ // then acquires it exclusively. (This lock is also known as a "write lock.") >+ void Lock() EXCLUSIVE_LOCK_FUNCTION(); >+ >+ // Mutex::Unlock() >+ // >+ // Releases this `Mutex` and returns it from the exclusive/write state to the >+ // free state. Caller must hold the `Mutex` exclusively. >+ void Unlock() UNLOCK_FUNCTION(); >+ >+ // Mutex::TryLock() >+ // >+ // If the mutex can be acquired without blocking, does so exclusively and >+ // returns `true`. Otherwise, returns `false`. Returns `true` with high >+ // probability if the `Mutex` was free. >+ bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true); >+ >+ // Mutex::AssertHeld() >+ // >+ // Return immediately if this thread holds the `Mutex` exclusively (in write >+ // mode). Otherwise, may report an error (typically by crashing with a >+ // diagnostic), or may return immediately. >+ void AssertHeld() const ASSERT_EXCLUSIVE_LOCK(); >+ >+ // --------------------------------------------------------------------------- >+ // Reader-Writer Locking >+ // --------------------------------------------------------------------------- >+ >+ // A Mutex can also be used as a starvation-free reader-writer lock. >+ // Neither read-locks nor write-locks are reentrant/recursive to avoid >+ // potential client programming errors. >+ // >+ // The Mutex API provides `Writer*()` aliases for the existing `Lock()`, >+ // `Unlock()` and `TryLock()` methods for use within applications mixing >+ // reader/writer locks. Using `Reader*()` and `Writer*()` operations in this >+ // manner can make locking behavior clearer when mixing read and write modes. >+ // >+ // Introducing reader locks necessarily complicates the `Mutex` state >+ // machine somewhat. The table below illustrates the allowed state transitions >+ // of a mutex in such cases. Note that ReaderLock() may block even if the lock >+ // is held in shared mode; this occurs when another thread is blocked on a >+ // call to WriterLock(). >+ // >+ // --------------------------------------------------------------------------- >+ // Operation: WriterLock() Unlock() ReaderLock() ReaderUnlock() >+ // --------------------------------------------------------------------------- >+ // State >+ // --------------------------------------------------------------------------- >+ // Free Exclusive invalid Shared(1) invalid >+ // Shared(1) blocks invalid Shared(2) or blocks Free >+ // Shared(n) n>1 blocks invalid Shared(n+1) or blocks Shared(n-1) >+ // Exclusive blocks Free blocks invalid >+ // --------------------------------------------------------------------------- >+ // >+ // In comments below, "shared" refers to a state of Shared(n) for any n > 0. >+ >+ // Mutex::ReaderLock() >+ // >+ // Blocks the calling thread, if necessary, until this `Mutex` is either free, >+ // or in shared mode, and then acquires a share of it. Note that >+ // `ReaderLock()` will block if some other thread has an exclusive/writer lock >+ // on the mutex. >+ >+ void ReaderLock() SHARED_LOCK_FUNCTION(); >+ >+ // Mutex::ReaderUnlock() >+ // >+ // Releases a read share of this `Mutex`. `ReaderUnlock` may return a mutex to >+ // the free state if this thread holds the last reader lock on the mutex. Note >+ // that you cannot call `ReaderUnlock()` on a mutex held in write mode. >+ void ReaderUnlock() UNLOCK_FUNCTION(); >+ >+ // Mutex::ReaderTryLock() >+ // >+ // If the mutex can be acquired without blocking, acquires this mutex for >+ // shared access and returns `true`. Otherwise, returns `false`. Returns >+ // `true` with high probability if the `Mutex` was free or shared. >+ bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true); >+ >+ // Mutex::AssertReaderHeld() >+ // >+ // Returns immediately if this thread holds the `Mutex` in at least shared >+ // mode (read mode). Otherwise, may report an error (typically by >+ // crashing with a diagnostic), or may return immediately. >+ void AssertReaderHeld() const ASSERT_SHARED_LOCK(); >+ >+ // Mutex::WriterLock() >+ // Mutex::WriterUnlock() >+ // Mutex::WriterTryLock() >+ // >+ // Aliases for `Mutex::Lock()`, `Mutex::Unlock()`, and `Mutex::TryLock()`. >+ // >+ // These methods may be used (along with the complementary `Reader*()` >+ // methods) to distingish simple exclusive `Mutex` usage (`Lock()`, >+ // etc.) from reader/writer lock usage. >+ void WriterLock() EXCLUSIVE_LOCK_FUNCTION() { this->Lock(); } >+ >+ void WriterUnlock() UNLOCK_FUNCTION() { this->Unlock(); } >+ >+ bool WriterTryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { >+ return this->TryLock(); >+ } >+ >+ // --------------------------------------------------------------------------- >+ // Conditional Critical Regions >+ // --------------------------------------------------------------------------- >+ >+ // Conditional usage of a `Mutex` can occur using two distinct paradigms: >+ // >+ // * Use of `Mutex` member functions with `Condition` objects. >+ // * Use of the separate `CondVar` abstraction. >+ // >+ // In general, prefer use of `Condition` and the `Mutex` member functions >+ // listed below over `CondVar`. When there are multiple threads waiting on >+ // distinctly different conditions, however, a battery of `CondVar`s may be >+ // more efficient. This section discusses use of `Condition` objects. >+ // >+ // `Mutex` contains member functions for performing lock operations only under >+ // certain conditions, of class `Condition`. For correctness, the `Condition` >+ // must return a boolean that is a pure function, only of state protected by >+ // the `Mutex`. The condition must be invariant w.r.t. environmental state >+ // such as thread, cpu id, or time, and must be `noexcept`. The condition will >+ // always be invoked with the mutex held in at least read mode, so you should >+ // not block it for long periods or sleep it on a timer. >+ // >+ // Since a condition must not depend directly on the current time, use >+ // `*WithTimeout()` member function variants to make your condition >+ // effectively true after a given duration, or `*WithDeadline()` variants to >+ // make your condition effectively true after a given time. >+ // >+ // The condition function should have no side-effects aside from debug >+ // logging; as a special exception, the function may acquire other mutexes >+ // provided it releases all those that it acquires. (This exception was >+ // required to allow logging.) >+ >+ // Mutex::Await() >+ // >+ // Unlocks this `Mutex` and blocks until simultaneously both `cond` is `true` >+ // and this `Mutex` can be reacquired, then reacquires this `Mutex` in the >+ // same mode in which it was previously held. If the condition is initially >+ // `true`, `Await()` *may* skip the release/re-acquire step. >+ // >+ // `Await()` requires that this thread holds this `Mutex` in some mode. >+ void Await(const Condition &cond); >+ >+ // Mutex::LockWhen() >+ // Mutex::ReaderLockWhen() >+ // Mutex::WriterLockWhen() >+ // >+ // Blocks until simultaneously both `cond` is `true` and this `Mutex` can >+ // be acquired, then atomically acquires this `Mutex`. `LockWhen()` is >+ // logically equivalent to `*Lock(); Await();` though they may have different >+ // performance characteristics. >+ void LockWhen(const Condition &cond) EXCLUSIVE_LOCK_FUNCTION(); >+ >+ void ReaderLockWhen(const Condition &cond) SHARED_LOCK_FUNCTION(); >+ >+ void WriterLockWhen(const Condition &cond) EXCLUSIVE_LOCK_FUNCTION() { >+ this->LockWhen(cond); >+ } >+ >+ // --------------------------------------------------------------------------- >+ // Mutex Variants with Timeouts/Deadlines >+ // --------------------------------------------------------------------------- >+ >+ // Mutex::AwaitWithTimeout() >+ // Mutex::AwaitWithDeadline() >+ // >+ // If `cond` is initially true, do nothing, or act as though `cond` is >+ // initially false. >+ // >+ // If `cond` is initially false, unlock this `Mutex` and block until >+ // simultaneously: >+ // - either `cond` is true or the {timeout has expired, deadline has passed} >+ // and >+ // - this `Mutex` can be reacquired, >+ // then reacquire this `Mutex` in the same mode in which it was previously >+ // held, returning `true` iff `cond` is `true` on return. >+ // >+ // Deadlines in the past are equivalent to an immediate deadline. >+ // Negative timeouts are equivalent to a zero timeout. >+ // >+ // This method requires that this thread holds this `Mutex` in some mode. >+ bool AwaitWithTimeout(const Condition &cond, absl::Duration timeout); >+ >+ bool AwaitWithDeadline(const Condition &cond, absl::Time deadline); >+ >+ // Mutex::LockWhenWithTimeout() >+ // Mutex::ReaderLockWhenWithTimeout() >+ // Mutex::WriterLockWhenWithTimeout() >+ // >+ // Blocks until simultaneously both: >+ // - either `cond` is `true` or the timeout has expired, and >+ // - this `Mutex` can be acquired, >+ // then atomically acquires this `Mutex`, returning `true` iff `cond` is >+ // `true` on return. >+ // >+ // Negative timeouts are equivalent to a zero timeout. >+ bool LockWhenWithTimeout(const Condition &cond, absl::Duration timeout) >+ EXCLUSIVE_LOCK_FUNCTION(); >+ bool ReaderLockWhenWithTimeout(const Condition &cond, absl::Duration timeout) >+ SHARED_LOCK_FUNCTION(); >+ bool WriterLockWhenWithTimeout(const Condition &cond, absl::Duration timeout) >+ EXCLUSIVE_LOCK_FUNCTION() { >+ return this->LockWhenWithTimeout(cond, timeout); >+ } >+ >+ // Mutex::LockWhenWithDeadline() >+ // Mutex::ReaderLockWhenWithDeadline() >+ // Mutex::WriterLockWhenWithDeadline() >+ // >+ // Blocks until simultaneously both: >+ // - either `cond` is `true` or the deadline has been passed, and >+ // - this `Mutex` can be acquired, >+ // then atomically acquires this Mutex, returning `true` iff `cond` is `true` >+ // on return. >+ // >+ // Deadlines in the past are equivalent to an immediate deadline. >+ bool LockWhenWithDeadline(const Condition &cond, absl::Time deadline) >+ EXCLUSIVE_LOCK_FUNCTION(); >+ bool ReaderLockWhenWithDeadline(const Condition &cond, absl::Time deadline) >+ SHARED_LOCK_FUNCTION(); >+ bool WriterLockWhenWithDeadline(const Condition &cond, absl::Time deadline) >+ EXCLUSIVE_LOCK_FUNCTION() { >+ return this->LockWhenWithDeadline(cond, deadline); >+ } >+ >+ // --------------------------------------------------------------------------- >+ // Debug Support: Invariant Checking, Deadlock Detection, Logging. >+ // --------------------------------------------------------------------------- >+ >+ // Mutex::EnableInvariantDebugging() >+ // >+ // If `invariant`!=null and if invariant debugging has been enabled globally, >+ // cause `(*invariant)(arg)` to be called at moments when the invariant for >+ // this `Mutex` should hold (for example: just after acquire, just before >+ // release). >+ // >+ // The routine `invariant` should have no side-effects since it is not >+ // guaranteed how many times it will be called; it should check the invariant >+ // and crash if it does not hold. Enabling global invariant debugging may >+ // substantially reduce `Mutex` performance; it should be set only for >+ // non-production runs. Optimization options may also disable invariant >+ // checks. >+ void EnableInvariantDebugging(void (*invariant)(void *), void *arg); >+ >+ // Mutex::EnableDebugLog() >+ // >+ // Cause all subsequent uses of this `Mutex` to be logged via >+ // `ABSL_RAW_LOG(INFO)`. Log entries are tagged with `name` if no previous >+ // call to `EnableInvariantDebugging()` or `EnableDebugLog()` has been made. >+ // >+ // Note: This method substantially reduces `Mutex` performance. >+ void EnableDebugLog(const char *name); >+ >+ // Deadlock detection >+ >+ // Mutex::ForgetDeadlockInfo() >+ // >+ // Forget any deadlock-detection information previously gathered >+ // about this `Mutex`. Call this method in debug mode when the lock ordering >+ // of a `Mutex` changes. >+ void ForgetDeadlockInfo(); >+ >+ // Mutex::AssertNotHeld() >+ // >+ // Return immediately if this thread does not hold this `Mutex` in any >+ // mode; otherwise, may report an error (typically by crashing with a >+ // diagnostic), or may return immediately. >+ // >+ // Currently this check is performed only if all of: >+ // - in debug mode >+ // - SetMutexDeadlockDetectionMode() has been set to kReport or kAbort >+ // - number of locks concurrently held by this thread is not large. >+ // are true. >+ void AssertNotHeld() const; >+ >+ // Special cases. >+ >+ // A `MuHow` is a constant that indicates how a lock should be acquired. >+ // Internal implementation detail. Clients should ignore. >+ typedef const struct MuHowS *MuHow; >+ >+ // Mutex::InternalAttemptToUseMutexInFatalSignalHandler() >+ // >+ // Causes the `Mutex` implementation to prepare itself for re-entry caused by >+ // future use of `Mutex` within a fatal signal handler. This method is >+ // intended for use only for last-ditch attempts to log crash information. >+ // It does not guarantee that attempts to use Mutexes within the handler will >+ // not deadlock; it merely makes other faults less likely. >+ // >+ // WARNING: This routine must be invoked from a signal handler, and the >+ // signal handler must either loop forever or terminate the process. >+ // Attempts to return from (or `longjmp` out of) the signal handler once this >+ // call has been made may cause arbitrary program behaviour including >+ // crashes and deadlocks. >+ static void InternalAttemptToUseMutexInFatalSignalHandler(); >+ >+ private: >+#ifdef ABSL_INTERNAL_USE_NONPROD_MUTEX >+ friend class CondVar; >+ >+ synchronization_internal::MutexImpl *impl() { return impl_.get(); } >+ >+ synchronization_internal::SynchronizationStorage< >+ synchronization_internal::MutexImpl> >+ impl_; >+#else >+ std::atomic<intptr_t> mu_; // The Mutex state. >+ >+ // Post()/Wait() versus associated PerThreadSem; in class for required >+ // friendship with PerThreadSem. >+ static inline void IncrementSynchSem(Mutex *mu, >+ base_internal::PerThreadSynch *w); >+ static inline bool DecrementSynchSem( >+ Mutex *mu, base_internal::PerThreadSynch *w, >+ synchronization_internal::KernelTimeout t); >+ >+ // slow path acquire >+ void LockSlowLoop(SynchWaitParams *waitp, int flags); >+ // wrappers around LockSlowLoop() >+ bool LockSlowWithDeadline(MuHow how, const Condition *cond, >+ synchronization_internal::KernelTimeout t, >+ int flags); >+ void LockSlow(MuHow how, const Condition *cond, >+ int flags) ABSL_ATTRIBUTE_COLD; >+ // slow path release >+ void UnlockSlow(SynchWaitParams *waitp) ABSL_ATTRIBUTE_COLD; >+ // Common code between Await() and AwaitWithTimeout/Deadline() >+ bool AwaitCommon(const Condition &cond, >+ synchronization_internal::KernelTimeout t); >+ // Attempt to remove thread s from queue. >+ void TryRemove(base_internal::PerThreadSynch *s); >+ // Block a thread on mutex. >+ void Block(base_internal::PerThreadSynch *s); >+ // Wake a thread; return successor. >+ base_internal::PerThreadSynch *Wakeup(base_internal::PerThreadSynch *w); >+ >+ friend class CondVar; // for access to Trans()/Fer(). >+ void Trans(MuHow how); // used for CondVar->Mutex transfer >+ void Fer( >+ base_internal::PerThreadSynch *w); // used for CondVar->Mutex transfer >+#endif >+ >+ // Catch the error of writing Mutex when intending MutexLock. >+ Mutex(const volatile Mutex * /*ignored*/) {} // NOLINT(runtime/explicit) >+ >+ Mutex(const Mutex&) = delete; >+ Mutex& operator=(const Mutex&) = delete; >+}; >+ >+// ----------------------------------------------------------------------------- >+// Mutex RAII Wrappers >+// ----------------------------------------------------------------------------- >+ >+// MutexLock >+// >+// `MutexLock` is a helper class, which acquires and releases a `Mutex` via >+// RAII. >+// >+// Example: >+// >+// Class Foo { >+// >+// Foo::Bar* Baz() { >+// MutexLock l(&lock_); >+// ... >+// return bar; >+// } >+// >+// private: >+// Mutex lock_; >+// }; >+class SCOPED_LOCKABLE MutexLock { >+ public: >+ explicit MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) { >+ this->mu_->Lock(); >+ } >+ >+ MutexLock(const MutexLock &) = delete; // NOLINT(runtime/mutex) >+ MutexLock(MutexLock&&) = delete; // NOLINT(runtime/mutex) >+ MutexLock& operator=(const MutexLock&) = delete; >+ MutexLock& operator=(MutexLock&&) = delete; >+ >+ ~MutexLock() UNLOCK_FUNCTION() { this->mu_->Unlock(); } >+ >+ private: >+ Mutex *const mu_; >+}; >+ >+// ReaderMutexLock >+// >+// The `ReaderMutexLock` is a helper class, like `MutexLock`, which acquires and >+// releases a shared lock on a `Mutex` via RAII. >+class SCOPED_LOCKABLE ReaderMutexLock { >+ public: >+ explicit ReaderMutexLock(Mutex *mu) SHARED_LOCK_FUNCTION(mu) >+ : mu_(mu) { >+ mu->ReaderLock(); >+ } >+ >+ ReaderMutexLock(const ReaderMutexLock&) = delete; >+ ReaderMutexLock(ReaderMutexLock&&) = delete; >+ ReaderMutexLock& operator=(const ReaderMutexLock&) = delete; >+ ReaderMutexLock& operator=(ReaderMutexLock&&) = delete; >+ >+ ~ReaderMutexLock() UNLOCK_FUNCTION() { >+ this->mu_->ReaderUnlock(); >+ } >+ >+ private: >+ Mutex *const mu_; >+}; >+ >+// WriterMutexLock >+// >+// The `WriterMutexLock` is a helper class, like `MutexLock`, which acquires and >+// releases a write (exclusive) lock on a `Mutex` via RAII. >+class SCOPED_LOCKABLE WriterMutexLock { >+ public: >+ explicit WriterMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) >+ : mu_(mu) { >+ mu->WriterLock(); >+ } >+ >+ WriterMutexLock(const WriterMutexLock&) = delete; >+ WriterMutexLock(WriterMutexLock&&) = delete; >+ WriterMutexLock& operator=(const WriterMutexLock&) = delete; >+ WriterMutexLock& operator=(WriterMutexLock&&) = delete; >+ >+ ~WriterMutexLock() UNLOCK_FUNCTION() { >+ this->mu_->WriterUnlock(); >+ } >+ >+ private: >+ Mutex *const mu_; >+}; >+ >+// ----------------------------------------------------------------------------- >+// Condition >+// ----------------------------------------------------------------------------- >+// >+// As noted above, `Mutex` contains a number of member functions which take a >+// `Condition` as a argument; clients can wait for conditions to become `true` >+// before attempting to acquire the mutex. These sections are known as >+// "condition critical" sections. To use a `Condition`, you simply need to >+// construct it, and use within an appropriate `Mutex` member function; >+// everything else in the `Condition` class is an implementation detail. >+// >+// A `Condition` is specified as a function pointer which returns a boolean. >+// `Condition` functions should be pure functions -- their results should depend >+// only on passed arguments, should not consult any external state (such as >+// clocks), and should have no side-effects, aside from debug logging. Any >+// objects that the function may access should be limited to those which are >+// constant while the mutex is blocked on the condition (e.g. a stack variable), >+// or objects of state protected explicitly by the mutex. >+// >+// No matter which construction is used for `Condition`, the underlying >+// function pointer / functor / callable must not throw any >+// exceptions. Correctness of `Mutex` / `Condition` is not guaranteed in >+// the face of a throwing `Condition`. (When Abseil is allowed to depend >+// on C++17, these function pointers will be explicitly marked >+// `noexcept`; until then this requirement cannot be enforced in the >+// type system.) >+// >+// Note: to use a `Condition`, you need only construct it and pass it within the >+// appropriate `Mutex' member function, such as `Mutex::Await()`. >+// >+// Example: >+// >+// // assume count_ is not internal reference count >+// int count_ GUARDED_BY(mu_); >+// >+// mu_.LockWhen(Condition(+[](int* count) { return *count == 0; }, >+// &count_)); >+// >+// When multiple threads are waiting on exactly the same condition, make sure >+// that they are constructed with the same parameters (same pointer to function >+// + arg, or same pointer to object + method), so that the mutex implementation >+// can avoid redundantly evaluating the same condition for each thread. >+class Condition { >+ public: >+ // A Condition that returns the result of "(*func)(arg)" >+ Condition(bool (*func)(void *), void *arg); >+ >+ // Templated version for people who are averse to casts. >+ // >+ // To use a lambda, prepend it with unary plus, which converts the lambda >+ // into a function pointer: >+ // Condition(+[](T* t) { return ...; }, arg). >+ // >+ // Note: lambdas in this case must contain no bound variables. >+ // >+ // See class comment for performance advice. >+ template<typename T> >+ Condition(bool (*func)(T *), T *arg); >+ >+ // Templated version for invoking a method that returns a `bool`. >+ // >+ // `Condition(object, &Class::Method)` constructs a `Condition` that evaluates >+ // `object->Method()`. >+ // >+ // Implementation Note: `absl::internal::identity` is used to allow methods to >+ // come from base classes. A simpler signature like >+ // `Condition(T*, bool (T::*)())` does not suffice. >+ template<typename T> >+ Condition(T *object, bool (absl::internal::identity<T>::type::* method)()); >+ >+ // Same as above, for const members >+ template<typename T> >+ Condition(const T *object, >+ bool (absl::internal::identity<T>::type::* method)() const); >+ >+ // A Condition that returns the value of `*cond` >+ explicit Condition(const bool *cond); >+ >+ // Templated version for invoking a functor that returns a `bool`. >+ // This approach accepts pointers to non-mutable lambdas, `std::function`, >+ // the result of` std::bind` and user-defined functors that define >+ // `bool F::operator()() const`. >+ // >+ // Example: >+ // >+ // auto reached = [this, current]() { >+ // mu_.AssertReaderHeld(); // For annotalysis. >+ // return processed_ >= current; >+ // }; >+ // mu_.Await(Condition(&reached)); >+ >+ // See class comment for performance advice. In particular, if there >+ // might be more than one waiter for the same condition, make sure >+ // that all waiters construct the condition with the same pointers. >+ >+ // Implementation note: The second template parameter ensures that this >+ // constructor doesn't participate in overload resolution if T doesn't have >+ // `bool operator() const`. >+ template <typename T, typename E = decltype( >+ static_cast<bool (T::*)() const>(&T::operator()))> >+ explicit Condition(const T *obj) >+ : Condition(obj, static_cast<bool (T::*)() const>(&T::operator())) {} >+ >+ // A Condition that always returns `true`. >+ static const Condition kTrue; >+ >+ // Evaluates the condition. >+ bool Eval() const; >+ >+ // Returns `true` if the two conditions are guaranteed to return the same >+ // value if evaluated at the same time, `false` if the evaluation *may* return >+ // different results. >+ // >+ // Two `Condition` values are guaranteed equal if both their `func` and `arg` >+ // components are the same. A null pointer is equivalent to a `true` >+ // condition. >+ static bool GuaranteedEqual(const Condition *a, const Condition *b); >+ >+ private: >+ typedef bool (*InternalFunctionType)(void * arg); >+ typedef bool (Condition::*InternalMethodType)(); >+ typedef bool (*InternalMethodCallerType)(void * arg, >+ InternalMethodType internal_method); >+ >+ bool (*eval_)(const Condition*); // Actual evaluator >+ InternalFunctionType function_; // function taking pointer returning bool >+ InternalMethodType method_; // method returning bool >+ void *arg_; // arg of function_ or object of method_ >+ >+ Condition(); // null constructor used only to create kTrue >+ >+ // Various functions eval_ can point to: >+ static bool CallVoidPtrFunction(const Condition*); >+ template <typename T> static bool CastAndCallFunction(const Condition* c); >+ template <typename T> static bool CastAndCallMethod(const Condition* c); >+}; >+ >+// ----------------------------------------------------------------------------- >+// CondVar >+// ----------------------------------------------------------------------------- >+// >+// A condition variable, reflecting state evaluated separately outside of the >+// `Mutex` object, which can be signaled to wake callers. >+// This class is not normally needed; use `Mutex` member functions such as >+// `Mutex::Await()` and intrinsic `Condition` abstractions. In rare cases >+// with many threads and many conditions, `CondVar` may be faster. >+// >+// The implementation may deliver signals to any condition variable at >+// any time, even when no call to `Signal()` or `SignalAll()` is made; as a >+// result, upon being awoken, you must check the logical condition you have >+// been waiting upon. >+// >+// Examples: >+// >+// Usage for a thread waiting for some condition C protected by mutex mu: >+// mu.Lock(); >+// while (!C) { cv->Wait(&mu); } // releases and reacquires mu >+// // C holds; process data >+// mu.Unlock(); >+// >+// Usage to wake T is: >+// mu.Lock(); >+// // process data, possibly establishing C >+// if (C) { cv->Signal(); } >+// mu.Unlock(); >+// >+// If C may be useful to more than one waiter, use `SignalAll()` instead of >+// `Signal()`. >+// >+// With this implementation it is efficient to use `Signal()/SignalAll()` inside >+// the locked region; this usage can make reasoning about your program easier. >+// >+class CondVar { >+ public: >+ CondVar(); >+ ~CondVar(); >+ >+ // CondVar::Wait() >+ // >+ // Atomically releases a `Mutex` and blocks on this condition variable. >+ // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a >+ // spurious wakeup), then reacquires the `Mutex` and returns. >+ // >+ // Requires and ensures that the current thread holds the `Mutex`. >+ void Wait(Mutex *mu); >+ >+ // CondVar::WaitWithTimeout() >+ // >+ // Atomically releases a `Mutex` and blocks on this condition variable. >+ // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a >+ // spurious wakeup), or until the timeout has expired, then reacquires >+ // the `Mutex` and returns. >+ // >+ // Returns true if the timeout has expired without this `CondVar` >+ // being signalled in any manner. If both the timeout has expired >+ // and this `CondVar` has been signalled, the implementation is free >+ // to return `true` or `false`. >+ // >+ // Requires and ensures that the current thread holds the `Mutex`. >+ bool WaitWithTimeout(Mutex *mu, absl::Duration timeout); >+ >+ // CondVar::WaitWithDeadline() >+ // >+ // Atomically releases a `Mutex` and blocks on this condition variable. >+ // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a >+ // spurious wakeup), or until the deadline has passed, then reacquires >+ // the `Mutex` and returns. >+ // >+ // Deadlines in the past are equivalent to an immediate deadline. >+ // >+ // Returns true if the deadline has passed without this `CondVar` >+ // being signalled in any manner. If both the deadline has passed >+ // and this `CondVar` has been signalled, the implementation is free >+ // to return `true` or `false`. >+ // >+ // Requires and ensures that the current thread holds the `Mutex`. >+ bool WaitWithDeadline(Mutex *mu, absl::Time deadline); >+ >+ // CondVar::Signal() >+ // >+ // Signal this `CondVar`; wake at least one waiter if one exists. >+ void Signal(); >+ >+ // CondVar::SignalAll() >+ // >+ // Signal this `CondVar`; wake all waiters. >+ void SignalAll(); >+ >+ // CondVar::EnableDebugLog() >+ // >+ // Causes all subsequent uses of this `CondVar` to be logged via >+ // `ABSL_RAW_LOG(INFO)`. Log entries are tagged with `name` if `name != 0`. >+ // Note: this method substantially reduces `CondVar` performance. >+ void EnableDebugLog(const char *name); >+ >+ private: >+#ifdef ABSL_INTERNAL_USE_NONPROD_MUTEX >+ synchronization_internal::CondVarImpl *impl() { return impl_.get(); } >+ synchronization_internal::SynchronizationStorage< >+ synchronization_internal::CondVarImpl> >+ impl_; >+#else >+ bool WaitCommon(Mutex *mutex, synchronization_internal::KernelTimeout t); >+ void Remove(base_internal::PerThreadSynch *s); >+ void Wakeup(base_internal::PerThreadSynch *w); >+ std::atomic<intptr_t> cv_; // Condition variable state. >+#endif >+ CondVar(const CondVar&) = delete; >+ CondVar& operator=(const CondVar&) = delete; >+}; >+ >+ >+// Variants of MutexLock. >+// >+// If you find yourself using one of these, consider instead using >+// Mutex::Unlock() and/or if-statements for clarity. >+ >+// MutexLockMaybe >+// >+// MutexLockMaybe is like MutexLock, but is a no-op when mu is null. >+class SCOPED_LOCKABLE MutexLockMaybe { >+ public: >+ explicit MutexLockMaybe(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) >+ : mu_(mu) { if (this->mu_ != nullptr) { this->mu_->Lock(); } } >+ ~MutexLockMaybe() UNLOCK_FUNCTION() { >+ if (this->mu_ != nullptr) { this->mu_->Unlock(); } >+ } >+ private: >+ Mutex *const mu_; >+ MutexLockMaybe(const MutexLockMaybe&) = delete; >+ MutexLockMaybe(MutexLockMaybe&&) = delete; >+ MutexLockMaybe& operator=(const MutexLockMaybe&) = delete; >+ MutexLockMaybe& operator=(MutexLockMaybe&&) = delete; >+}; >+ >+// ReleasableMutexLock >+// >+// ReleasableMutexLock is like MutexLock, but permits `Release()` of its >+// mutex before destruction. `Release()` may be called at most once. >+class SCOPED_LOCKABLE ReleasableMutexLock { >+ public: >+ explicit ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) >+ : mu_(mu) { >+ this->mu_->Lock(); >+ } >+ ~ReleasableMutexLock() UNLOCK_FUNCTION() { >+ if (this->mu_ != nullptr) { this->mu_->Unlock(); } >+ } >+ >+ void Release() UNLOCK_FUNCTION(); >+ >+ private: >+ Mutex *mu_; >+ ReleasableMutexLock(const ReleasableMutexLock&) = delete; >+ ReleasableMutexLock(ReleasableMutexLock&&) = delete; >+ ReleasableMutexLock& operator=(const ReleasableMutexLock&) = delete; >+ ReleasableMutexLock& operator=(ReleasableMutexLock&&) = delete; >+}; >+ >+#ifdef ABSL_INTERNAL_USE_NONPROD_MUTEX >+#else >+inline Mutex::Mutex() : mu_(0) { >+ ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static); >+} >+ >+inline CondVar::CondVar() : cv_(0) {} >+#endif >+ >+// static >+template <typename T> >+bool Condition::CastAndCallMethod(const Condition *c) { >+ typedef bool (T::*MemberType)(); >+ MemberType rm = reinterpret_cast<MemberType>(c->method_); >+ T *x = static_cast<T *>(c->arg_); >+ return (x->*rm)(); >+} >+ >+// static >+template <typename T> >+bool Condition::CastAndCallFunction(const Condition *c) { >+ typedef bool (*FuncType)(T *); >+ FuncType fn = reinterpret_cast<FuncType>(c->function_); >+ T *x = static_cast<T *>(c->arg_); >+ return (*fn)(x); >+} >+ >+template <typename T> >+inline Condition::Condition(bool (*func)(T *), T *arg) >+ : eval_(&CastAndCallFunction<T>), >+ function_(reinterpret_cast<InternalFunctionType>(func)), >+ method_(nullptr), >+ arg_(const_cast<void *>(static_cast<const void *>(arg))) {} >+ >+template <typename T> >+inline Condition::Condition(T *object, >+ bool (absl::internal::identity<T>::type::*method)()) >+ : eval_(&CastAndCallMethod<T>), >+ function_(nullptr), >+ method_(reinterpret_cast<InternalMethodType>(method)), >+ arg_(object) {} >+ >+template <typename T> >+inline Condition::Condition(const T *object, >+ bool (absl::internal::identity<T>::type::*method)() >+ const) >+ : eval_(&CastAndCallMethod<T>), >+ function_(nullptr), >+ method_(reinterpret_cast<InternalMethodType>(method)), >+ arg_(reinterpret_cast<void *>(const_cast<T *>(object))) {} >+ >+// Register a hook for profiling support. >+// >+// The function pointer registered here will be called whenever a mutex is >+// contended. The callback is given the absl/base/cycleclock.h timestamp when >+// waiting began. >+// >+// Calls to this function do not race or block, but there is no ordering >+// guaranteed between calls to this function and call to the provided hook. >+// In particular, the previously registered hook may still be called for some >+// time after this function returns. >+void RegisterMutexProfiler(void (*fn)(int64_t wait_timestamp)); >+ >+// Register a hook for Mutex tracing. >+// >+// The function pointer registered here will be called whenever a mutex is >+// contended. The callback is given an opaque handle to the contended mutex, >+// an event name, and the number of wait cycles (as measured by >+// //absl/base/internal/cycleclock.h, and which may not be real >+// "cycle" counts.) >+// >+// The only event name currently sent is "slow release". >+// >+// This has the same memory ordering concerns as RegisterMutexProfiler() above. >+void RegisterMutexTracer(void (*fn)(const char *msg, const void *obj, >+ int64_t wait_cycles)); >+ >+// TODO(gfalcon): Combine RegisterMutexProfiler() and RegisterMutexTracer() >+// into a single interface, since they are only ever called in pairs. >+ >+// Register a hook for CondVar tracing. >+// >+// The function pointer registered here will be called here on various CondVar >+// events. The callback is given an opaque handle to the CondVar object and >+// a std::string identifying the event. This is thread-safe, but only a single >+// tracer can be registered. >+// >+// Events that can be sent are "Wait", "Unwait", "Signal wakeup", and >+// "SignalAll wakeup". >+// >+// This has the same memory ordering concerns as RegisterMutexProfiler() above. >+void RegisterCondVarTracer(void (*fn)(const char *msg, const void *cv)); >+ >+// Register a hook for symbolizing stack traces in deadlock detector reports. >+// >+// 'pc' is the program counter being symbolized, 'out' is the buffer to write >+// into, and 'out_size' is the size of the buffer. This function can return >+// false if symbolizing failed, or true if a null-terminated symbol was written >+// to 'out.' >+// >+// This has the same memory ordering concerns as RegisterMutexProfiler() above. >+// >+// DEPRECATED: The default symbolizer function is absl::Symbolize() and the >+// ability to register a different hook for symbolizing stack traces will be >+// removed on or after 2023-05-01. >+ABSL_DEPRECATED("absl::RegisterSymbolizer() is deprecated and will be removed " >+ "on or after 2023-05-01") >+void RegisterSymbolizer(bool (*fn)(const void *pc, char *out, int out_size)); >+ >+// EnableMutexInvariantDebugging() >+// >+// Enable or disable global support for Mutex invariant debugging. If enabled, >+// then invariant predicates can be registered per-Mutex for debug checking. >+// See Mutex::EnableInvariantDebugging(). >+void EnableMutexInvariantDebugging(bool enabled); >+ >+// When in debug mode, and when the feature has been enabled globally, the >+// implementation will keep track of lock ordering and complain (or optionally >+// crash) if a cycle is detected in the acquired-before graph. >+ >+// Possible modes of operation for the deadlock detector in debug mode. >+enum class OnDeadlockCycle { >+ kIgnore, // Neither report on nor attempt to track cycles in lock ordering >+ kReport, // Report lock cycles to stderr when detected >+ kAbort, // Report lock cycles to stderr when detected, then abort >+}; >+ >+// SetMutexDeadlockDetectionMode() >+// >+// Enable or disable global support for detection of potential deadlocks >+// due to Mutex lock ordering inversions. When set to 'kIgnore', tracking of >+// lock ordering is disabled. Otherwise, in debug builds, a lock ordering graph >+// will be maintained internally, and detected cycles will be reported in >+// the manner chosen here. >+void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode); >+ >+} // namespace absl >+ >+// In some build configurations we pass --detect-odr-violations to the >+// gold linker. This causes it to flag weak symbol overrides as ODR >+// violations. Because ODR only applies to C++ and not C, >+// --detect-odr-violations ignores symbols not mangled with C++ names. >+// By changing our extension points to be extern "C", we dodge this >+// check. >+extern "C" { >+void AbslInternalMutexYield(); >+} // extern "C" >+#endif // ABSL_SYNCHRONIZATION_MUTEX_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..1e019e001ae40274adc8b4e00e7539cd2576deca >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc >@@ -0,0 +1,94 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <vector> >+ >+#include "benchmark/benchmark.h" >+#include "absl/base/internal/sysinfo.h" >+#include "absl/synchronization/blocking_counter.h" >+#include "absl/synchronization/internal/thread_pool.h" >+#include "absl/synchronization/mutex.h" >+ >+namespace { >+ >+// Measure the overhead of conditions on mutex release (when they must be >+// evaluated). Mutex has (some) support for equivalence classes allowing >+// Conditions with the same function/argument to potentially not be multiply >+// evaluated. >+// >+// num_classes==0 is used for the special case of every waiter being distinct. >+void BM_ConditionWaiters(benchmark::State& state) { >+ int num_classes = state.range(0); >+ int num_waiters = state.range(1); >+ >+ struct Helper { >+ static void Waiter(absl::BlockingCounter* init, absl::Mutex* m, int* p) { >+ init->DecrementCount(); >+ m->LockWhen(absl::Condition( >+ static_cast<bool (*)(int*)>([](int* v) { return *v == 0; }), p)); >+ m->Unlock(); >+ } >+ }; >+ >+ if (num_classes == 0) { >+ // No equivalence classes. >+ num_classes = num_waiters; >+ } >+ >+ absl::BlockingCounter init(num_waiters); >+ absl::Mutex mu; >+ std::vector<int> equivalence_classes(num_classes, 1); >+ >+ // Must be declared last to be destroyed first. >+ absl::synchronization_internal::ThreadPool pool(num_waiters); >+ >+ for (int i = 0; i < num_waiters; i++) { >+ // Mutex considers Conditions with the same function and argument >+ // to be equivalent. >+ pool.Schedule([&, i] { >+ Helper::Waiter(&init, &mu, &equivalence_classes[i % num_classes]); >+ }); >+ } >+ init.Wait(); >+ >+ for (auto _ : state) { >+ mu.Lock(); >+ mu.Unlock(); // Each unlock requires Condition evaluation for our waiters. >+ } >+ >+ mu.Lock(); >+ for (int i = 0; i < num_classes; i++) { >+ equivalence_classes[i] = 0; >+ } >+ mu.Unlock(); >+} >+ >+// Some configurations have higher thread limits than others. >+#if defined(__linux__) && !defined(THREAD_SANITIZER) >+constexpr int kMaxConditionWaiters = 8192; >+#else >+constexpr int kMaxConditionWaiters = 1024; >+#endif >+BENCHMARK(BM_ConditionWaiters)->RangePair(0, 2, 1, kMaxConditionWaiters); >+ >+void BM_ContendedMutex(benchmark::State& state) { >+ static absl::Mutex* mu = new absl::Mutex; >+ for (auto _ : state) { >+ absl::MutexLock lock(mu); >+ } >+} >+BENCHMARK(BM_ContendedMutex)->Threads(1); >+BENCHMARK(BM_ContendedMutex)->ThreadPerCpu(); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..b2820e2068d56e9013219c188e64f4613f0ea379 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/mutex_test.cc >@@ -0,0 +1,1660 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/mutex.h" >+ >+#ifdef WIN32 >+#include <windows.h> >+#endif >+ >+#include <algorithm> >+#include <atomic> >+#include <cstdlib> >+#include <functional> >+#include <memory> >+#include <random> >+#include <string> >+#include <thread> // NOLINT(build/c++11) >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/base/attributes.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/base/internal/sysinfo.h" >+#include "absl/memory/memory.h" >+#include "absl/synchronization/internal/thread_pool.h" >+#include "absl/time/clock.h" >+#include "absl/time/time.h" >+ >+namespace { >+ >+// TODO(dmauro): Replace with a commandline flag. >+static constexpr bool kExtendedTest = false; >+ >+std::unique_ptr<absl::synchronization_internal::ThreadPool> CreatePool( >+ int threads) { >+ return absl::make_unique<absl::synchronization_internal::ThreadPool>(threads); >+} >+ >+std::unique_ptr<absl::synchronization_internal::ThreadPool> >+CreateDefaultPool() { >+ return CreatePool(kExtendedTest ? 32 : 10); >+} >+ >+// Hack to schedule a function to run on a thread pool thread after a >+// duration has elapsed. >+static void ScheduleAfter(absl::synchronization_internal::ThreadPool *tp, >+ absl::Duration after, >+ const std::function<void()> &func) { >+ tp->Schedule([func, after] { >+ absl::SleepFor(after); >+ func(); >+ }); >+} >+ >+struct TestContext { >+ int iterations; >+ int threads; >+ int g0; // global 0 >+ int g1; // global 1 >+ absl::Mutex mu; >+ absl::CondVar cv; >+}; >+ >+// To test whether the invariant check call occurs >+static std::atomic<bool> invariant_checked; >+ >+static bool GetInvariantChecked() { >+ return invariant_checked.load(std::memory_order_relaxed); >+} >+ >+static void SetInvariantChecked(bool new_value) { >+ invariant_checked.store(new_value, std::memory_order_relaxed); >+} >+ >+static void CheckSumG0G1(void *v) { >+ TestContext *cxt = static_cast<TestContext *>(v); >+ ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in CheckSumG0G1"); >+ SetInvariantChecked(true); >+} >+ >+static void TestMu(TestContext *cxt, int c) { >+ for (int i = 0; i != cxt->iterations; i++) { >+ absl::MutexLock l(&cxt->mu); >+ int a = cxt->g0 + 1; >+ cxt->g0 = a; >+ cxt->g1--; >+ } >+} >+ >+static void TestTry(TestContext *cxt, int c) { >+ for (int i = 0; i != cxt->iterations; i++) { >+ do { >+ std::this_thread::yield(); >+ } while (!cxt->mu.TryLock()); >+ int a = cxt->g0 + 1; >+ cxt->g0 = a; >+ cxt->g1--; >+ cxt->mu.Unlock(); >+ } >+} >+ >+static void TestR20ms(TestContext *cxt, int c) { >+ for (int i = 0; i != cxt->iterations; i++) { >+ absl::ReaderMutexLock l(&cxt->mu); >+ absl::SleepFor(absl::Milliseconds(20)); >+ cxt->mu.AssertReaderHeld(); >+ } >+} >+ >+static void TestRW(TestContext *cxt, int c) { >+ if ((c & 1) == 0) { >+ for (int i = 0; i != cxt->iterations; i++) { >+ absl::WriterMutexLock l(&cxt->mu); >+ cxt->g0++; >+ cxt->g1--; >+ cxt->mu.AssertHeld(); >+ cxt->mu.AssertReaderHeld(); >+ } >+ } else { >+ for (int i = 0; i != cxt->iterations; i++) { >+ absl::ReaderMutexLock l(&cxt->mu); >+ ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in TestRW"); >+ cxt->mu.AssertReaderHeld(); >+ } >+ } >+} >+ >+struct MyContext { >+ int target; >+ TestContext *cxt; >+ bool MyTurn(); >+}; >+ >+bool MyContext::MyTurn() { >+ TestContext *cxt = this->cxt; >+ return cxt->g0 == this->target || cxt->g0 == cxt->iterations; >+} >+ >+static void TestAwait(TestContext *cxt, int c) { >+ MyContext mc; >+ mc.target = c; >+ mc.cxt = cxt; >+ absl::MutexLock l(&cxt->mu); >+ cxt->mu.AssertHeld(); >+ while (cxt->g0 < cxt->iterations) { >+ cxt->mu.Await(absl::Condition(&mc, &MyContext::MyTurn)); >+ ABSL_RAW_CHECK(mc.MyTurn(), "Error in TestAwait"); >+ cxt->mu.AssertHeld(); >+ if (cxt->g0 < cxt->iterations) { >+ int a = cxt->g0 + 1; >+ cxt->g0 = a; >+ mc.target += cxt->threads; >+ } >+ } >+} >+ >+static void TestSignalAll(TestContext *cxt, int c) { >+ int target = c; >+ absl::MutexLock l(&cxt->mu); >+ cxt->mu.AssertHeld(); >+ while (cxt->g0 < cxt->iterations) { >+ while (cxt->g0 != target && cxt->g0 != cxt->iterations) { >+ cxt->cv.Wait(&cxt->mu); >+ } >+ if (cxt->g0 < cxt->iterations) { >+ int a = cxt->g0 + 1; >+ cxt->g0 = a; >+ cxt->cv.SignalAll(); >+ target += cxt->threads; >+ } >+ } >+} >+ >+static void TestSignal(TestContext *cxt, int c) { >+ ABSL_RAW_CHECK(cxt->threads == 2, "TestSignal should use 2 threads"); >+ int target = c; >+ absl::MutexLock l(&cxt->mu); >+ cxt->mu.AssertHeld(); >+ while (cxt->g0 < cxt->iterations) { >+ while (cxt->g0 != target && cxt->g0 != cxt->iterations) { >+ cxt->cv.Wait(&cxt->mu); >+ } >+ if (cxt->g0 < cxt->iterations) { >+ int a = cxt->g0 + 1; >+ cxt->g0 = a; >+ cxt->cv.Signal(); >+ target += cxt->threads; >+ } >+ } >+} >+ >+static void TestCVTimeout(TestContext *cxt, int c) { >+ int target = c; >+ absl::MutexLock l(&cxt->mu); >+ cxt->mu.AssertHeld(); >+ while (cxt->g0 < cxt->iterations) { >+ while (cxt->g0 != target && cxt->g0 != cxt->iterations) { >+ cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100)); >+ } >+ if (cxt->g0 < cxt->iterations) { >+ int a = cxt->g0 + 1; >+ cxt->g0 = a; >+ cxt->cv.SignalAll(); >+ target += cxt->threads; >+ } >+ } >+} >+ >+static bool G0GE2(TestContext *cxt) { return cxt->g0 >= 2; } >+ >+static void TestTime(TestContext *cxt, int c, bool use_cv) { >+ ABSL_RAW_CHECK(cxt->iterations == 1, "TestTime should only use 1 iteration"); >+ ABSL_RAW_CHECK(cxt->threads > 2, "TestTime should use more than 2 threads"); >+ const bool kFalse = false; >+ absl::Condition false_cond(&kFalse); >+ absl::Condition g0ge2(G0GE2, cxt); >+ if (c == 0) { >+ absl::MutexLock l(&cxt->mu); >+ >+ absl::Time start = absl::Now(); >+ if (use_cv) { >+ cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1)); >+ } else { >+ ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)), >+ "TestTime failed"); >+ } >+ absl::Duration elapsed = absl::Now() - start; >+ ABSL_RAW_CHECK( >+ absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0), >+ "TestTime failed"); >+ ABSL_RAW_CHECK(cxt->g0 == 1, "TestTime failed"); >+ >+ start = absl::Now(); >+ if (use_cv) { >+ cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1)); >+ } else { >+ ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)), >+ "TestTime failed"); >+ } >+ elapsed = absl::Now() - start; >+ ABSL_RAW_CHECK( >+ absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0), >+ "TestTime failed"); >+ cxt->g0++; >+ if (use_cv) { >+ cxt->cv.Signal(); >+ } >+ >+ start = absl::Now(); >+ if (use_cv) { >+ cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(4)); >+ } else { >+ ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4)), >+ "TestTime failed"); >+ } >+ elapsed = absl::Now() - start; >+ ABSL_RAW_CHECK( >+ absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0), >+ "TestTime failed"); >+ ABSL_RAW_CHECK(cxt->g0 >= 3, "TestTime failed"); >+ >+ start = absl::Now(); >+ if (use_cv) { >+ cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1)); >+ } else { >+ ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)), >+ "TestTime failed"); >+ } >+ elapsed = absl::Now() - start; >+ ABSL_RAW_CHECK( >+ absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0), >+ "TestTime failed"); >+ if (use_cv) { >+ cxt->cv.SignalAll(); >+ } >+ >+ start = absl::Now(); >+ if (use_cv) { >+ cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1)); >+ } else { >+ ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)), >+ "TestTime failed"); >+ } >+ elapsed = absl::Now() - start; >+ ABSL_RAW_CHECK(absl::Seconds(0.9) <= elapsed && >+ elapsed <= absl::Seconds(2.0), "TestTime failed"); >+ ABSL_RAW_CHECK(cxt->g0 == cxt->threads, "TestTime failed"); >+ >+ } else if (c == 1) { >+ absl::MutexLock l(&cxt->mu); >+ const absl::Time start = absl::Now(); >+ if (use_cv) { >+ cxt->cv.WaitWithTimeout(&cxt->mu, absl::Milliseconds(500)); >+ } else { >+ ABSL_RAW_CHECK( >+ !cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500)), >+ "TestTime failed"); >+ } >+ const absl::Duration elapsed = absl::Now() - start; >+ ABSL_RAW_CHECK( >+ absl::Seconds(0.4) <= elapsed && elapsed <= absl::Seconds(0.9), >+ "TestTime failed"); >+ cxt->g0++; >+ } else if (c == 2) { >+ absl::MutexLock l(&cxt->mu); >+ if (use_cv) { >+ while (cxt->g0 < 2) { >+ cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100)); >+ } >+ } else { >+ ABSL_RAW_CHECK(cxt->mu.AwaitWithTimeout(g0ge2, absl::Seconds(100)), >+ "TestTime failed"); >+ } >+ cxt->g0++; >+ } else { >+ absl::MutexLock l(&cxt->mu); >+ if (use_cv) { >+ while (cxt->g0 < 2) { >+ cxt->cv.Wait(&cxt->mu); >+ } >+ } else { >+ cxt->mu.Await(g0ge2); >+ } >+ cxt->g0++; >+ } >+} >+ >+static void TestMuTime(TestContext *cxt, int c) { TestTime(cxt, c, false); } >+ >+static void TestCVTime(TestContext *cxt, int c) { TestTime(cxt, c, true); } >+ >+static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv, >+ const std::function<void(int)>& cb) { >+ mu->Lock(); >+ int c = (*c0)++; >+ mu->Unlock(); >+ cb(c); >+ absl::MutexLock l(mu); >+ (*c1)++; >+ cv->Signal(); >+} >+ >+// Code common to RunTest() and RunTestWithInvariantDebugging(). >+static int RunTestCommon(TestContext *cxt, void (*test)(TestContext *cxt, int), >+ int threads, int iterations, int operations) { >+ absl::Mutex mu2; >+ absl::CondVar cv2; >+ int c0 = 0; >+ int c1 = 0; >+ cxt->g0 = 0; >+ cxt->g1 = 0; >+ cxt->iterations = iterations; >+ cxt->threads = threads; >+ absl::synchronization_internal::ThreadPool tp(threads); >+ for (int i = 0; i != threads; i++) { >+ tp.Schedule(std::bind(&EndTest, &c0, &c1, &mu2, &cv2, >+ std::function<void(int)>( >+ std::bind(test, cxt, std::placeholders::_1)))); >+ } >+ mu2.Lock(); >+ while (c1 != threads) { >+ cv2.Wait(&mu2); >+ } >+ mu2.Unlock(); >+ return cxt->g0; >+} >+ >+// Basis for the parameterized tests configured below. >+static int RunTest(void (*test)(TestContext *cxt, int), int threads, >+ int iterations, int operations) { >+ TestContext cxt; >+ return RunTestCommon(&cxt, test, threads, iterations, operations); >+} >+ >+// Like RunTest(), but sets an invariant on the tested Mutex and >+// verifies that the invariant check happened. The invariant function >+// will be passed the TestContext* as its arg and must call >+// SetInvariantChecked(true); >+#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED) >+static int RunTestWithInvariantDebugging(void (*test)(TestContext *cxt, int), >+ int threads, int iterations, >+ int operations, >+ void (*invariant)(void *)) { >+ absl::EnableMutexInvariantDebugging(true); >+ SetInvariantChecked(false); >+ TestContext cxt; >+ cxt.mu.EnableInvariantDebugging(invariant, &cxt); >+ int ret = RunTestCommon(&cxt, test, threads, iterations, operations); >+ ABSL_RAW_CHECK(GetInvariantChecked(), "Invariant not checked"); >+ absl::EnableMutexInvariantDebugging(false); // Restore. >+ return ret; >+} >+#endif >+ >+// -------------------------------------------------------- >+// Test for fix of bug in TryRemove() >+struct TimeoutBugStruct { >+ absl::Mutex mu; >+ bool a; >+ int a_waiter_count; >+}; >+ >+static void WaitForA(TimeoutBugStruct *x) { >+ x->mu.LockWhen(absl::Condition(&x->a)); >+ x->a_waiter_count--; >+ x->mu.Unlock(); >+} >+ >+static bool NoAWaiters(TimeoutBugStruct *x) { return x->a_waiter_count == 0; } >+ >+// Test that a CondVar.Wait(&mutex) can un-block a call to mutex.Await() in >+// another thread. >+TEST(Mutex, CondVarWaitSignalsAwait) { >+ // Use a struct so the lock annotations apply. >+ struct { >+ absl::Mutex barrier_mu; >+ bool barrier GUARDED_BY(barrier_mu) = false; >+ >+ absl::Mutex release_mu; >+ bool release GUARDED_BY(release_mu) = false; >+ absl::CondVar released_cv; >+ } state; >+ >+ auto pool = CreateDefaultPool(); >+ >+ // Thread A. Sets barrier, waits for release using Mutex::Await, then >+ // signals released_cv. >+ pool->Schedule([&state] { >+ state.release_mu.Lock(); >+ >+ state.barrier_mu.Lock(); >+ state.barrier = true; >+ state.barrier_mu.Unlock(); >+ >+ state.release_mu.Await(absl::Condition(&state.release)); >+ state.released_cv.Signal(); >+ state.release_mu.Unlock(); >+ }); >+ >+ state.barrier_mu.LockWhen(absl::Condition(&state.barrier)); >+ state.barrier_mu.Unlock(); >+ state.release_mu.Lock(); >+ // Thread A is now blocked on release by way of Mutex::Await(). >+ >+ // Set release. Calling released_cv.Wait() should un-block thread A, >+ // which will signal released_cv. If not, the test will hang. >+ state.release = true; >+ state.released_cv.Wait(&state.release_mu); >+ state.release_mu.Unlock(); >+} >+ >+// Test that a CondVar.WaitWithTimeout(&mutex) can un-block a call to >+// mutex.Await() in another thread. >+TEST(Mutex, CondVarWaitWithTimeoutSignalsAwait) { >+ // Use a struct so the lock annotations apply. >+ struct { >+ absl::Mutex barrier_mu; >+ bool barrier GUARDED_BY(barrier_mu) = false; >+ >+ absl::Mutex release_mu; >+ bool release GUARDED_BY(release_mu) = false; >+ absl::CondVar released_cv; >+ } state; >+ >+ auto pool = CreateDefaultPool(); >+ >+ // Thread A. Sets barrier, waits for release using Mutex::Await, then >+ // signals released_cv. >+ pool->Schedule([&state] { >+ state.release_mu.Lock(); >+ >+ state.barrier_mu.Lock(); >+ state.barrier = true; >+ state.barrier_mu.Unlock(); >+ >+ state.release_mu.Await(absl::Condition(&state.release)); >+ state.released_cv.Signal(); >+ state.release_mu.Unlock(); >+ }); >+ >+ state.barrier_mu.LockWhen(absl::Condition(&state.barrier)); >+ state.barrier_mu.Unlock(); >+ state.release_mu.Lock(); >+ // Thread A is now blocked on release by way of Mutex::Await(). >+ >+ // Set release. Calling released_cv.Wait() should un-block thread A, >+ // which will signal released_cv. If not, the test will hang. >+ state.release = true; >+ EXPECT_TRUE( >+ !state.released_cv.WaitWithTimeout(&state.release_mu, absl::Seconds(10))) >+ << "; Unrecoverable test failure: CondVar::WaitWithTimeout did not " >+ "unblock the absl::Mutex::Await call in another thread."; >+ >+ state.release_mu.Unlock(); >+} >+ >+// Test for regression of a bug in loop of TryRemove() >+TEST(Mutex, MutexTimeoutBug) { >+ auto tp = CreateDefaultPool(); >+ >+ TimeoutBugStruct x; >+ x.a = false; >+ x.a_waiter_count = 2; >+ tp->Schedule(std::bind(&WaitForA, &x)); >+ tp->Schedule(std::bind(&WaitForA, &x)); >+ absl::SleepFor(absl::Seconds(1)); // Allow first two threads to hang. >+ // The skip field of the second will point to the first because there are >+ // only two. >+ >+ // Now cause a thread waiting on an always-false to time out >+ // This would deadlock when the bug was present. >+ bool always_false = false; >+ x.mu.LockWhenWithTimeout(absl::Condition(&always_false), >+ absl::Milliseconds(500)); >+ >+ // if we get here, the bug is not present. Cleanup the state. >+ >+ x.a = true; // wakeup the two waiters on A >+ x.mu.Await(absl::Condition(&NoAWaiters, &x)); // wait for them to exit >+ x.mu.Unlock(); >+} >+ >+struct CondVarWaitDeadlock : testing::TestWithParam<int> { >+ absl::Mutex mu; >+ absl::CondVar cv; >+ bool cond1 = false; >+ bool cond2 = false; >+ bool read_lock1; >+ bool read_lock2; >+ bool signal_unlocked; >+ >+ CondVarWaitDeadlock() { >+ read_lock1 = GetParam() & (1 << 0); >+ read_lock2 = GetParam() & (1 << 1); >+ signal_unlocked = GetParam() & (1 << 2); >+ } >+ >+ void Waiter1() { >+ if (read_lock1) { >+ mu.ReaderLock(); >+ while (!cond1) { >+ cv.Wait(&mu); >+ } >+ mu.ReaderUnlock(); >+ } else { >+ mu.Lock(); >+ while (!cond1) { >+ cv.Wait(&mu); >+ } >+ mu.Unlock(); >+ } >+ } >+ >+ void Waiter2() { >+ if (read_lock2) { >+ mu.ReaderLockWhen(absl::Condition(&cond2)); >+ mu.ReaderUnlock(); >+ } else { >+ mu.LockWhen(absl::Condition(&cond2)); >+ mu.Unlock(); >+ } >+ } >+}; >+ >+// Test for a deadlock bug in Mutex::Fer(). >+// The sequence of events that lead to the deadlock is: >+// 1. waiter1 blocks on cv in read mode (mu bits = 0). >+// 2. waiter2 blocks on mu in either mode (mu bits = kMuWait). >+// 3. main thread locks mu, sets cond1, unlocks mu (mu bits = kMuWait). >+// 4. main thread signals on cv and this eventually calls Mutex::Fer(). >+// Currently Fer wakes waiter1 since mu bits = kMuWait (mutex is unlocked). >+// Before the bug fix Fer neither woke waiter1 nor queued it on mutex, >+// which resulted in deadlock. >+TEST_P(CondVarWaitDeadlock, Test) { >+ auto waiter1 = CreatePool(1); >+ auto waiter2 = CreatePool(1); >+ waiter1->Schedule([this] { this->Waiter1(); }); >+ waiter2->Schedule([this] { this->Waiter2(); }); >+ >+ // Wait while threads block (best-effort is fine). >+ absl::SleepFor(absl::Milliseconds(100)); >+ >+ // Wake condwaiter. >+ mu.Lock(); >+ cond1 = true; >+ if (signal_unlocked) { >+ mu.Unlock(); >+ cv.Signal(); >+ } else { >+ cv.Signal(); >+ mu.Unlock(); >+ } >+ waiter1.reset(); // "join" waiter1 >+ >+ // Wake waiter. >+ mu.Lock(); >+ cond2 = true; >+ mu.Unlock(); >+ waiter2.reset(); // "join" waiter2 >+} >+ >+INSTANTIATE_TEST_CASE_P(CondVarWaitDeadlockTest, CondVarWaitDeadlock, >+ ::testing::Range(0, 8), >+ ::testing::PrintToStringParamName()); >+ >+// -------------------------------------------------------- >+// Test for fix of bug in DequeueAllWakeable() >+// Bug was that if there was more than one waiting reader >+// and all should be woken, the most recently blocked one >+// would not be. >+ >+struct DequeueAllWakeableBugStruct { >+ absl::Mutex mu; >+ absl::Mutex mu2; // protects all fields below >+ int unfinished_count; // count of unfinished readers; under mu2 >+ bool done1; // unfinished_count == 0; under mu2 >+ int finished_count; // count of finished readers, under mu2 >+ bool done2; // finished_count == 0; under mu2 >+}; >+ >+// Test for regression of a bug in loop of DequeueAllWakeable() >+static void AcquireAsReader(DequeueAllWakeableBugStruct *x) { >+ x->mu.ReaderLock(); >+ x->mu2.Lock(); >+ x->unfinished_count--; >+ x->done1 = (x->unfinished_count == 0); >+ x->mu2.Unlock(); >+ // make sure that both readers acquired mu before we release it. >+ absl::SleepFor(absl::Seconds(2)); >+ x->mu.ReaderUnlock(); >+ >+ x->mu2.Lock(); >+ x->finished_count--; >+ x->done2 = (x->finished_count == 0); >+ x->mu2.Unlock(); >+} >+ >+// Test for regression of a bug in loop of DequeueAllWakeable() >+TEST(Mutex, MutexReaderWakeupBug) { >+ auto tp = CreateDefaultPool(); >+ >+ DequeueAllWakeableBugStruct x; >+ x.unfinished_count = 2; >+ x.done1 = false; >+ x.finished_count = 2; >+ x.done2 = false; >+ x.mu.Lock(); // acquire mu exclusively >+ // queue two thread that will block on reader locks on x.mu >+ tp->Schedule(std::bind(&AcquireAsReader, &x)); >+ tp->Schedule(std::bind(&AcquireAsReader, &x)); >+ absl::SleepFor(absl::Seconds(1)); // give time for reader threads to block >+ x.mu.Unlock(); // wake them up >+ >+ // both readers should finish promptly >+ EXPECT_TRUE( >+ x.mu2.LockWhenWithTimeout(absl::Condition(&x.done1), absl::Seconds(10))); >+ x.mu2.Unlock(); >+ >+ EXPECT_TRUE( >+ x.mu2.LockWhenWithTimeout(absl::Condition(&x.done2), absl::Seconds(10))); >+ x.mu2.Unlock(); >+} >+ >+struct LockWhenTestStruct { >+ absl::Mutex mu1; >+ bool cond = false; >+ >+ absl::Mutex mu2; >+ bool waiting = false; >+}; >+ >+static bool LockWhenTestIsCond(LockWhenTestStruct* s) { >+ s->mu2.Lock(); >+ s->waiting = true; >+ s->mu2.Unlock(); >+ return s->cond; >+} >+ >+static void LockWhenTestWaitForIsCond(LockWhenTestStruct* s) { >+ s->mu1.LockWhen(absl::Condition(&LockWhenTestIsCond, s)); >+ s->mu1.Unlock(); >+} >+ >+TEST(Mutex, LockWhen) { >+ LockWhenTestStruct s; >+ >+ std::thread t(LockWhenTestWaitForIsCond, &s); >+ s.mu2.LockWhen(absl::Condition(&s.waiting)); >+ s.mu2.Unlock(); >+ >+ s.mu1.Lock(); >+ s.cond = true; >+ s.mu1.Unlock(); >+ >+ t.join(); >+} >+ >+// -------------------------------------------------------- >+// The following test requires Mutex::ReaderLock to be a real shared >+// lock, which is not the case in all builds. >+#if !defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE) >+ >+// Test for fix of bug in UnlockSlow() that incorrectly decremented the reader >+// count when putting a thread to sleep waiting for a false condition when the >+// lock was not held. >+ >+// For this bug to strike, we make a thread wait on a free mutex with no >+// waiters by causing its wakeup condition to be false. Then the >+// next two acquirers must be readers. The bug causes the lock >+// to be released when one reader unlocks, rather than both. >+ >+struct ReaderDecrementBugStruct { >+ bool cond; // to delay first thread (under mu) >+ int done; // reference count (under mu) >+ absl::Mutex mu; >+ >+ bool waiting_on_cond; // under mu2 >+ bool have_reader_lock; // under mu2 >+ bool complete; // under mu2 >+ absl::Mutex mu2; // > mu >+}; >+ >+// L >= mu, L < mu_waiting_on_cond >+static bool IsCond(void *v) { >+ ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v); >+ x->mu2.Lock(); >+ x->waiting_on_cond = true; >+ x->mu2.Unlock(); >+ return x->cond; >+} >+ >+// L >= mu >+static bool AllDone(void *v) { >+ ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v); >+ return x->done == 0; >+} >+ >+// L={} >+static void WaitForCond(ReaderDecrementBugStruct *x) { >+ absl::Mutex dummy; >+ absl::MutexLock l(&dummy); >+ x->mu.LockWhen(absl::Condition(&IsCond, x)); >+ x->done--; >+ x->mu.Unlock(); >+} >+ >+// L={} >+static void GetReadLock(ReaderDecrementBugStruct *x) { >+ x->mu.ReaderLock(); >+ x->mu2.Lock(); >+ x->have_reader_lock = true; >+ x->mu2.Await(absl::Condition(&x->complete)); >+ x->mu2.Unlock(); >+ x->mu.ReaderUnlock(); >+ x->mu.Lock(); >+ x->done--; >+ x->mu.Unlock(); >+} >+ >+// Test for reader counter being decremented incorrectly by waiter >+// with false condition. >+TEST(Mutex, MutexReaderDecrementBug) NO_THREAD_SAFETY_ANALYSIS { >+ ReaderDecrementBugStruct x; >+ x.cond = false; >+ x.waiting_on_cond = false; >+ x.have_reader_lock = false; >+ x.complete = false; >+ x.done = 2; // initial ref count >+ >+ // Run WaitForCond() and wait for it to sleep >+ std::thread thread1(WaitForCond, &x); >+ x.mu2.LockWhen(absl::Condition(&x.waiting_on_cond)); >+ x.mu2.Unlock(); >+ >+ // Run GetReadLock(), and wait for it to get the read lock >+ std::thread thread2(GetReadLock, &x); >+ x.mu2.LockWhen(absl::Condition(&x.have_reader_lock)); >+ x.mu2.Unlock(); >+ >+ // Get the reader lock ourselves, and release it. >+ x.mu.ReaderLock(); >+ x.mu.ReaderUnlock(); >+ >+ // The lock should be held in read mode by GetReadLock(). >+ // If we have the bug, the lock will be free. >+ x.mu.AssertReaderHeld(); >+ >+ // Wake up all the threads. >+ x.mu2.Lock(); >+ x.complete = true; >+ x.mu2.Unlock(); >+ >+ // TODO(delesley): turn on analysis once lock upgrading is supported. >+ // (This call upgrades the lock from shared to exclusive.) >+ x.mu.Lock(); >+ x.cond = true; >+ x.mu.Await(absl::Condition(&AllDone, &x)); >+ x.mu.Unlock(); >+ >+ thread1.join(); >+ thread2.join(); >+} >+#endif // !ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE >+ >+// Test that we correctly handle the situation when a lock is >+// held and then destroyed (w/o unlocking). >+TEST(Mutex, LockedMutexDestructionBug) NO_THREAD_SAFETY_ANALYSIS { >+ for (int i = 0; i != 10; i++) { >+ // Create, lock and destroy 10 locks. >+ const int kNumLocks = 10; >+ auto mu = absl::make_unique<absl::Mutex[]>(kNumLocks); >+ for (int j = 0; j != kNumLocks; j++) { >+ if ((j % 2) == 0) { >+ mu[j].WriterLock(); >+ } else { >+ mu[j].ReaderLock(); >+ } >+ } >+ } >+} >+ >+// -------------------------------------------------------- >+// Test for bug with pattern of readers using a condvar. The bug was that if a >+// reader went to sleep on a condition variable while one or more other readers >+// held the lock, but there were no waiters, the reader count (held in the >+// mutex word) would be lost. (This is because Enqueue() had at one time >+// always placed the thread on the Mutex queue. Later (CL 4075610), to >+// tolerate re-entry into Mutex from a Condition predicate, Enqueue() was >+// changed so that it could also place a thread on a condition-variable. This >+// introduced the case where Enqueue() returned with an empty queue, and this >+// case was handled incorrectly in one place.) >+ >+static void ReaderForReaderOnCondVar(absl::Mutex *mu, absl::CondVar *cv, >+ int *running) { >+ std::random_device dev; >+ std::mt19937 gen(dev()); >+ std::uniform_int_distribution<int> random_millis(0, 15); >+ mu->ReaderLock(); >+ while (*running == 3) { >+ absl::SleepFor(absl::Milliseconds(random_millis(gen))); >+ cv->WaitWithTimeout(mu, absl::Milliseconds(random_millis(gen))); >+ } >+ mu->ReaderUnlock(); >+ mu->Lock(); >+ (*running)--; >+ mu->Unlock(); >+} >+ >+struct True { >+ template <class... Args> >+ bool operator()(Args...) const { >+ return true; >+ } >+}; >+ >+struct DerivedTrue : True {}; >+ >+TEST(Mutex, FunctorCondition) { >+ { // Variadic >+ True f; >+ EXPECT_TRUE(absl::Condition(&f).Eval()); >+ } >+ >+ { // Inherited >+ DerivedTrue g; >+ EXPECT_TRUE(absl::Condition(&g).Eval()); >+ } >+ >+ { // lambda >+ int value = 3; >+ auto is_zero = [&value] { return value == 0; }; >+ absl::Condition c(&is_zero); >+ EXPECT_FALSE(c.Eval()); >+ value = 0; >+ EXPECT_TRUE(c.Eval()); >+ } >+ >+ { // bind >+ int value = 0; >+ auto is_positive = std::bind(std::less<int>(), 0, std::cref(value)); >+ absl::Condition c(&is_positive); >+ EXPECT_FALSE(c.Eval()); >+ value = 1; >+ EXPECT_TRUE(c.Eval()); >+ } >+ >+ { // std::function >+ int value = 3; >+ std::function<bool()> is_zero = [&value] { return value == 0; }; >+ absl::Condition c(&is_zero); >+ EXPECT_FALSE(c.Eval()); >+ value = 0; >+ EXPECT_TRUE(c.Eval()); >+ } >+} >+ >+static bool IntIsZero(int *x) { return *x == 0; } >+ >+// Test for reader waiting condition variable when there are other readers >+// but no waiters. >+TEST(Mutex, TestReaderOnCondVar) { >+ auto tp = CreateDefaultPool(); >+ absl::Mutex mu; >+ absl::CondVar cv; >+ int running = 3; >+ tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running)); >+ tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running)); >+ absl::SleepFor(absl::Seconds(2)); >+ mu.Lock(); >+ running--; >+ mu.Await(absl::Condition(&IntIsZero, &running)); >+ mu.Unlock(); >+} >+ >+// -------------------------------------------------------- >+struct AcquireFromConditionStruct { >+ absl::Mutex mu0; // protects value, done >+ int value; // times condition function is called; under mu0, >+ bool done; // done with test? under mu0 >+ absl::Mutex mu1; // used to attempt to mess up state of mu0 >+ absl::CondVar cv; // so the condition function can be invoked from >+ // CondVar::Wait(). >+}; >+ >+static bool ConditionWithAcquire(AcquireFromConditionStruct *x) { >+ x->value++; // count times this function is called >+ >+ if (x->value == 2 || x->value == 3) { >+ // On the second and third invocation of this function, sleep for 100ms, >+ // but with the side-effect of altering the state of a Mutex other than >+ // than one for which this is a condition. The spec now explicitly allows >+ // this side effect; previously it did not. it was illegal. >+ bool always_false = false; >+ x->mu1.LockWhenWithTimeout(absl::Condition(&always_false), >+ absl::Milliseconds(100)); >+ x->mu1.Unlock(); >+ } >+ ABSL_RAW_CHECK(x->value < 4, "should not be invoked a fourth time"); >+ >+ // We arrange for the condition to return true on only the 2nd and 3rd calls. >+ return x->value == 2 || x->value == 3; >+} >+ >+static void WaitForCond2(AcquireFromConditionStruct *x) { >+ // wait for cond0 to become true >+ x->mu0.LockWhen(absl::Condition(&ConditionWithAcquire, x)); >+ x->done = true; >+ x->mu0.Unlock(); >+} >+ >+// Test for Condition whose function acquires other Mutexes >+TEST(Mutex, AcquireFromCondition) { >+ auto tp = CreateDefaultPool(); >+ >+ AcquireFromConditionStruct x; >+ x.value = 0; >+ x.done = false; >+ tp->Schedule( >+ std::bind(&WaitForCond2, &x)); // run WaitForCond2() in a thread T >+ // T will hang because the first invocation of ConditionWithAcquire() will >+ // return false. >+ absl::SleepFor(absl::Milliseconds(500)); // allow T time to hang >+ >+ x.mu0.Lock(); >+ x.cv.WaitWithTimeout(&x.mu0, absl::Milliseconds(500)); // wake T >+ // T will be woken because the Wait() will call ConditionWithAcquire() >+ // for the second time, and it will return true. >+ >+ x.mu0.Unlock(); >+ >+ // T will then acquire the lock and recheck its own condition. >+ // It will find the condition true, as this is the third invocation, >+ // but the use of another Mutex by the calling function will >+ // cause the old mutex implementation to think that the outer >+ // LockWhen() has timed out because the inner LockWhenWithTimeout() did. >+ // T will then check the condition a fourth time because it finds a >+ // timeout occurred. This should not happen in the new >+ // implementation that allows the Condition function to use Mutexes. >+ >+ // It should also succeed, even though the Condition function >+ // is being invoked from CondVar::Wait, and thus this thread >+ // is conceptually waiting both on the condition variable, and on mu2. >+ >+ x.mu0.LockWhen(absl::Condition(&x.done)); >+ x.mu0.Unlock(); >+} >+ >+// The deadlock detector is not part of non-prod builds, so do not test it. >+#if !defined(ABSL_INTERNAL_USE_NONPROD_MUTEX) >+ >+TEST(Mutex, DeadlockDetector) { >+ absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort); >+ >+ // check that we can call ForgetDeadlockInfo() on a lock with the lock held >+ absl::Mutex m1; >+ absl::Mutex m2; >+ absl::Mutex m3; >+ absl::Mutex m4; >+ >+ m1.Lock(); // m1 gets ID1 >+ m2.Lock(); // m2 gets ID2 >+ m3.Lock(); // m3 gets ID3 >+ m3.Unlock(); >+ m2.Unlock(); >+ // m1 still held >+ m1.ForgetDeadlockInfo(); // m1 loses ID >+ m2.Lock(); // m2 gets ID2 >+ m3.Lock(); // m3 gets ID3 >+ m4.Lock(); // m4 gets ID4 >+ m3.Unlock(); >+ m2.Unlock(); >+ m4.Unlock(); >+ m1.Unlock(); >+} >+ >+// Bazel has a test "warning" file that programs can write to if the >+// test should pass with a warning. This class disables the warning >+// file until it goes out of scope. >+class ScopedDisableBazelTestWarnings { >+ public: >+ ScopedDisableBazelTestWarnings() { >+#ifdef WIN32 >+ char file[MAX_PATH]; >+ if (GetEnvironmentVariable(kVarName, file, sizeof(file)) < sizeof(file)) { >+ warnings_output_file_ = file; >+ SetEnvironmentVariable(kVarName, nullptr); >+ } >+#else >+ const char *file = getenv(kVarName); >+ if (file != nullptr) { >+ warnings_output_file_ = file; >+ unsetenv(kVarName); >+ } >+#endif >+ } >+ >+ ~ScopedDisableBazelTestWarnings() { >+ if (!warnings_output_file_.empty()) { >+#ifdef WIN32 >+ SetEnvironmentVariable(kVarName, warnings_output_file_.c_str()); >+#else >+ setenv(kVarName, warnings_output_file_.c_str(), 0); >+#endif >+ } >+ } >+ >+ private: >+ static const char kVarName[]; >+ std::string warnings_output_file_; >+}; >+const char ScopedDisableBazelTestWarnings::kVarName[] = >+ "TEST_WARNINGS_OUTPUT_FILE"; >+ >+TEST(Mutex, DeadlockDetectorBazelWarning) { >+ absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kReport); >+ >+ // Cause deadlock detection to detect something, if it's >+ // compiled in and enabled. But turn off the bazel warning. >+ ScopedDisableBazelTestWarnings disable_bazel_test_warnings; >+ >+ absl::Mutex mu0; >+ absl::Mutex mu1; >+ bool got_mu0 = mu0.TryLock(); >+ mu1.Lock(); // acquire mu1 while holding mu0 >+ if (got_mu0) { >+ mu0.Unlock(); >+ } >+ if (mu0.TryLock()) { // try lock shouldn't cause deadlock detector to fire >+ mu0.Unlock(); >+ } >+ mu0.Lock(); // acquire mu0 while holding mu1; should get one deadlock >+ // report here >+ mu0.Unlock(); >+ mu1.Unlock(); >+ >+ absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort); >+} >+ >+// This test is tagged with NO_THREAD_SAFETY_ANALYSIS because the >+// annotation-based static thread-safety analysis is not currently >+// predicate-aware and cannot tell if the two for-loops that acquire and >+// release the locks have the same predicates. >+TEST(Mutex, DeadlockDetectorStessTest) NO_THREAD_SAFETY_ANALYSIS { >+ // Stress test: Here we create a large number of locks and use all of them. >+ // If a deadlock detector keeps a full graph of lock acquisition order, >+ // it will likely be too slow for this test to pass. >+ const int n_locks = 1 << 17; >+ auto array_of_locks = absl::make_unique<absl::Mutex[]>(n_locks); >+ for (int i = 0; i < n_locks; i++) { >+ int end = std::min(n_locks, i + 5); >+ // acquire and then release locks i, i+1, ..., i+4 >+ for (int j = i; j < end; j++) { >+ array_of_locks[j].Lock(); >+ } >+ for (int j = i; j < end; j++) { >+ array_of_locks[j].Unlock(); >+ } >+ } >+} >+ >+TEST(Mutex, DeadlockIdBug) NO_THREAD_SAFETY_ANALYSIS { >+ // Test a scenario where a cached deadlock graph node id in the >+ // list of held locks is not invalidated when the corresponding >+ // mutex is deleted. >+ absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort); >+ // Mutex that will be destroyed while being held >+ absl::Mutex *a = new absl::Mutex; >+ // Other mutexes needed by test >+ absl::Mutex b, c; >+ >+ // Hold mutex. >+ a->Lock(); >+ >+ // Force deadlock id assignment by acquiring another lock. >+ b.Lock(); >+ b.Unlock(); >+ >+ // Delete the mutex. The Mutex destructor tries to remove held locks, >+ // but the attempt isn't foolproof. It can fail if: >+ // (a) Deadlock detection is currently disabled. >+ // (b) The destruction is from another thread. >+ // We exploit (a) by temporarily disabling deadlock detection. >+ absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kIgnore); >+ delete a; >+ absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort); >+ >+ // Now acquire another lock which will force a deadlock id assignment. >+ // We should end up getting assigned the same deadlock id that was >+ // freed up when "a" was deleted, which will cause a spurious deadlock >+ // report if the held lock entry for "a" was not invalidated. >+ c.Lock(); >+ c.Unlock(); >+} >+#endif // !defined(ABSL_INTERNAL_USE_NONPROD_MUTEX) >+ >+// -------------------------------------------------------- >+// Test for timeouts/deadlines on condition waits that are specified using >+// absl::Duration and absl::Time. For each waiting function we test with >+// a timeout/deadline that has already expired/passed, one that is infinite >+// and so never expires/passes, and one that will expire/pass in the near >+// future. >+ >+static absl::Duration TimeoutTestAllowedSchedulingDelay() { >+ // Note: we use a function here because Microsoft Visual Studio fails to >+ // properly initialize constexpr static absl::Duration variables. >+ return absl::Milliseconds(150); >+} >+ >+// Returns true if `actual_delay` is close enough to `expected_delay` to pass >+// the timeouts/deadlines test. Otherwise, logs warnings and returns false. >+ABSL_MUST_USE_RESULT >+static bool DelayIsWithinBounds(absl::Duration expected_delay, >+ absl::Duration actual_delay) { >+ bool pass = true; >+ // Do not allow the observed delay to be less than expected. This may occur >+ // in practice due to clock skew or when the synchronization primitives use a >+ // different clock than absl::Now(), but these cases should be handled by the >+ // the retry mechanism in each TimeoutTest. >+ if (actual_delay < expected_delay) { >+ ABSL_RAW_LOG(WARNING, >+ "Actual delay %s was too short, expected %s (difference %s)", >+ absl::FormatDuration(actual_delay).c_str(), >+ absl::FormatDuration(expected_delay).c_str(), >+ absl::FormatDuration(actual_delay - expected_delay).c_str()); >+ pass = false; >+ } >+ // If the expected delay is <= zero then allow a small error tolerance, since >+ // we do not expect context switches to occur during test execution. >+ // Otherwise, thread scheduling delays may be substantial in rare cases, so >+ // tolerate up to kTimeoutTestAllowedSchedulingDelay of error. >+ absl::Duration tolerance = expected_delay <= absl::ZeroDuration() >+ ? absl::Milliseconds(10) >+ : TimeoutTestAllowedSchedulingDelay(); >+ if (actual_delay > expected_delay + tolerance) { >+ ABSL_RAW_LOG(WARNING, >+ "Actual delay %s was too long, expected %s (difference %s)", >+ absl::FormatDuration(actual_delay).c_str(), >+ absl::FormatDuration(expected_delay).c_str(), >+ absl::FormatDuration(actual_delay - expected_delay).c_str()); >+ pass = false; >+ } >+ return pass; >+} >+ >+// Parameters for TimeoutTest, below. >+struct TimeoutTestParam { >+ // The file and line number (used for logging purposes only). >+ const char *from_file; >+ int from_line; >+ >+ // Should the absolute deadline API based on absl::Time be tested? If false, >+ // the relative deadline API based on absl::Duration is tested. >+ bool use_absolute_deadline; >+ >+ // The deadline/timeout used when calling the API being tested >+ // (e.g. Mutex::LockWhenWithDeadline). >+ absl::Duration wait_timeout; >+ >+ // The delay before the condition will be set true by the test code. If zero >+ // or negative, the condition is set true immediately (before calling the API >+ // being tested). Otherwise, if infinite, the condition is never set true. >+ // Otherwise a closure is scheduled for the future that sets the condition >+ // true. >+ absl::Duration satisfy_condition_delay; >+ >+ // The expected result of the condition after the call to the API being >+ // tested. Generally `true` means the condition was true when the API returns, >+ // `false` indicates an expected timeout. >+ bool expected_result; >+ >+ // The expected delay before the API under test returns. This is inherently >+ // flaky, so some slop is allowed (see `DelayIsWithinBounds` above), and the >+ // test keeps trying indefinitely until this constraint passes. >+ absl::Duration expected_delay; >+}; >+ >+// Print a `TimeoutTestParam` to a debug log. >+std::ostream &operator<<(std::ostream &os, const TimeoutTestParam ¶m) { >+ return os << "from: " << param.from_file << ":" << param.from_line >+ << " use_absolute_deadline: " >+ << (param.use_absolute_deadline ? "true" : "false") >+ << " wait_timeout: " << param.wait_timeout >+ << " satisfy_condition_delay: " << param.satisfy_condition_delay >+ << " expected_result: " >+ << (param.expected_result ? "true" : "false") >+ << " expected_delay: " << param.expected_delay; >+} >+ >+std::string FormatString(const TimeoutTestParam ¶m) { >+ std::ostringstream os; >+ os << param; >+ return os.str(); >+} >+ >+// Like `thread::Executor::ScheduleAt` except: >+// a) Delays zero or negative are executed immediately in the current thread. >+// b) Infinite delays are never scheduled. >+// c) Calls this test's `ScheduleAt` helper instead of using `pool` directly. >+static void RunAfterDelay(absl::Duration delay, >+ absl::synchronization_internal::ThreadPool *pool, >+ const std::function<void()> &callback) { >+ if (delay <= absl::ZeroDuration()) { >+ callback(); // immediate >+ } else if (delay != absl::InfiniteDuration()) { >+ ScheduleAfter(pool, delay, callback); >+ } >+} >+ >+class TimeoutTest : public ::testing::Test, >+ public ::testing::WithParamInterface<TimeoutTestParam> {}; >+ >+std::vector<TimeoutTestParam> MakeTimeoutTestParamValues() { >+ // The `finite` delay is a finite, relatively short, delay. We make it larger >+ // than our allowed scheduling delay (slop factor) to avoid confusion when >+ // diagnosing test failures. The other constants here have clear meanings. >+ const absl::Duration finite = 3 * TimeoutTestAllowedSchedulingDelay(); >+ const absl::Duration never = absl::InfiniteDuration(); >+ const absl::Duration negative = -absl::InfiniteDuration(); >+ const absl::Duration immediate = absl::ZeroDuration(); >+ >+ // Every test case is run twice; once using the absolute deadline API and once >+ // using the relative timeout API. >+ std::vector<TimeoutTestParam> values; >+ for (bool use_absolute_deadline : {false, true}) { >+ // Tests with a negative timeout (deadline in the past), which should >+ // immediately return current state of the condition. >+ >+ // The condition is already true: >+ values.push_back(TimeoutTestParam{ >+ __FILE__, __LINE__, use_absolute_deadline, >+ negative, // wait_timeout >+ immediate, // satisfy_condition_delay >+ true, // expected_result >+ immediate, // expected_delay >+ }); >+ >+ // The condition becomes true, but the timeout has already expired: >+ values.push_back(TimeoutTestParam{ >+ __FILE__, __LINE__, use_absolute_deadline, >+ negative, // wait_timeout >+ finite, // satisfy_condition_delay >+ false, // expected_result >+ immediate // expected_delay >+ }); >+ >+ // The condition never becomes true: >+ values.push_back(TimeoutTestParam{ >+ __FILE__, __LINE__, use_absolute_deadline, >+ negative, // wait_timeout >+ never, // satisfy_condition_delay >+ false, // expected_result >+ immediate // expected_delay >+ }); >+ >+ // Tests with an infinite timeout (deadline in the infinite future), which >+ // should only return when the condition becomes true. >+ >+ // The condition is already true: >+ values.push_back(TimeoutTestParam{ >+ __FILE__, __LINE__, use_absolute_deadline, >+ never, // wait_timeout >+ immediate, // satisfy_condition_delay >+ true, // expected_result >+ immediate // expected_delay >+ }); >+ >+ // The condition becomes true before the (infinite) expiry: >+ values.push_back(TimeoutTestParam{ >+ __FILE__, __LINE__, use_absolute_deadline, >+ never, // wait_timeout >+ finite, // satisfy_condition_delay >+ true, // expected_result >+ finite, // expected_delay >+ }); >+ >+ // Tests with a (small) finite timeout (deadline soon), with the condition >+ // becoming true both before and after its expiry. >+ >+ // The condition is already true: >+ values.push_back(TimeoutTestParam{ >+ __FILE__, __LINE__, use_absolute_deadline, >+ never, // wait_timeout >+ immediate, // satisfy_condition_delay >+ true, // expected_result >+ immediate // expected_delay >+ }); >+ >+ // The condition becomes true before the expiry: >+ values.push_back(TimeoutTestParam{ >+ __FILE__, __LINE__, use_absolute_deadline, >+ finite * 2, // wait_timeout >+ finite, // satisfy_condition_delay >+ true, // expected_result >+ finite // expected_delay >+ }); >+ >+ // The condition becomes true, but the timeout has already expired: >+ values.push_back(TimeoutTestParam{ >+ __FILE__, __LINE__, use_absolute_deadline, >+ finite, // wait_timeout >+ finite * 2, // satisfy_condition_delay >+ false, // expected_result >+ finite // expected_delay >+ }); >+ >+ // The condition never becomes true: >+ values.push_back(TimeoutTestParam{ >+ __FILE__, __LINE__, use_absolute_deadline, >+ finite, // wait_timeout >+ never, // satisfy_condition_delay >+ false, // expected_result >+ finite // expected_delay >+ }); >+ } >+ return values; >+} >+ >+// Instantiate `TimeoutTest` with `MakeTimeoutTestParamValues()`. >+INSTANTIATE_TEST_CASE_P(All, TimeoutTest, >+ testing::ValuesIn(MakeTimeoutTestParamValues())); >+ >+TEST_P(TimeoutTest, Await) { >+ const TimeoutTestParam params = GetParam(); >+ ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str()); >+ >+ // Because this test asserts bounds on scheduling delays it is flaky. To >+ // compensate it loops forever until it passes. Failures express as test >+ // timeouts, in which case the test log can be used to diagnose the issue. >+ for (int attempt = 1;; ++attempt) { >+ ABSL_RAW_LOG(INFO, "Attempt %d", attempt); >+ >+ absl::Mutex mu; >+ bool value = false; // condition value (under mu) >+ >+ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool = >+ CreateDefaultPool(); >+ RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] { >+ absl::MutexLock l(&mu); >+ value = true; >+ }); >+ >+ absl::MutexLock lock(&mu); >+ absl::Time start_time = absl::Now(); >+ absl::Condition cond(&value); >+ bool result = >+ params.use_absolute_deadline >+ ? mu.AwaitWithDeadline(cond, start_time + params.wait_timeout) >+ : mu.AwaitWithTimeout(cond, params.wait_timeout); >+ if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) { >+ EXPECT_EQ(params.expected_result, result); >+ break; >+ } >+ } >+} >+ >+TEST_P(TimeoutTest, LockWhen) { >+ const TimeoutTestParam params = GetParam(); >+ ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str()); >+ >+ // Because this test asserts bounds on scheduling delays it is flaky. To >+ // compensate it loops forever until it passes. Failures express as test >+ // timeouts, in which case the test log can be used to diagnose the issue. >+ for (int attempt = 1;; ++attempt) { >+ ABSL_RAW_LOG(INFO, "Attempt %d", attempt); >+ >+ absl::Mutex mu; >+ bool value = false; // condition value (under mu) >+ >+ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool = >+ CreateDefaultPool(); >+ RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] { >+ absl::MutexLock l(&mu); >+ value = true; >+ }); >+ >+ absl::Time start_time = absl::Now(); >+ absl::Condition cond(&value); >+ bool result = >+ params.use_absolute_deadline >+ ? mu.LockWhenWithDeadline(cond, start_time + params.wait_timeout) >+ : mu.LockWhenWithTimeout(cond, params.wait_timeout); >+ mu.Unlock(); >+ >+ if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) { >+ EXPECT_EQ(params.expected_result, result); >+ break; >+ } >+ } >+} >+ >+TEST_P(TimeoutTest, ReaderLockWhen) { >+ const TimeoutTestParam params = GetParam(); >+ ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str()); >+ >+ // Because this test asserts bounds on scheduling delays it is flaky. To >+ // compensate it loops forever until it passes. Failures express as test >+ // timeouts, in which case the test log can be used to diagnose the issue. >+ for (int attempt = 0;; ++attempt) { >+ ABSL_RAW_LOG(INFO, "Attempt %d", attempt); >+ >+ absl::Mutex mu; >+ bool value = false; // condition value (under mu) >+ >+ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool = >+ CreateDefaultPool(); >+ RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] { >+ absl::MutexLock l(&mu); >+ value = true; >+ }); >+ >+ absl::Time start_time = absl::Now(); >+ bool result = >+ params.use_absolute_deadline >+ ? mu.ReaderLockWhenWithDeadline(absl::Condition(&value), >+ start_time + params.wait_timeout) >+ : mu.ReaderLockWhenWithTimeout(absl::Condition(&value), >+ params.wait_timeout); >+ mu.ReaderUnlock(); >+ >+ if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) { >+ EXPECT_EQ(params.expected_result, result); >+ break; >+ } >+ } >+} >+ >+TEST_P(TimeoutTest, Wait) { >+ const TimeoutTestParam params = GetParam(); >+ ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str()); >+ >+ // Because this test asserts bounds on scheduling delays it is flaky. To >+ // compensate it loops forever until it passes. Failures express as test >+ // timeouts, in which case the test log can be used to diagnose the issue. >+ for (int attempt = 0;; ++attempt) { >+ ABSL_RAW_LOG(INFO, "Attempt %d", attempt); >+ >+ absl::Mutex mu; >+ bool value = false; // condition value (under mu) >+ absl::CondVar cv; // signals a change of `value` >+ >+ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool = >+ CreateDefaultPool(); >+ RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] { >+ absl::MutexLock l(&mu); >+ value = true; >+ cv.Signal(); >+ }); >+ >+ absl::MutexLock lock(&mu); >+ absl::Time start_time = absl::Now(); >+ absl::Duration timeout = params.wait_timeout; >+ absl::Time deadline = start_time + timeout; >+ while (!value) { >+ if (params.use_absolute_deadline ? cv.WaitWithDeadline(&mu, deadline) >+ : cv.WaitWithTimeout(&mu, timeout)) { >+ break; // deadline/timeout exceeded >+ } >+ timeout = deadline - absl::Now(); // recompute >+ } >+ bool result = value; // note: `mu` is still held >+ >+ if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) { >+ EXPECT_EQ(params.expected_result, result); >+ break; >+ } >+ } >+} >+ >+TEST(Mutex, Logging) { >+ // Allow user to look at logging output >+ absl::Mutex logged_mutex; >+ logged_mutex.EnableDebugLog("fido_mutex"); >+ absl::CondVar logged_cv; >+ logged_cv.EnableDebugLog("rover_cv"); >+ logged_mutex.Lock(); >+ logged_cv.WaitWithTimeout(&logged_mutex, absl::Milliseconds(20)); >+ logged_mutex.Unlock(); >+ logged_mutex.ReaderLock(); >+ logged_mutex.ReaderUnlock(); >+ logged_mutex.Lock(); >+ logged_mutex.Unlock(); >+ logged_cv.Signal(); >+ logged_cv.SignalAll(); >+} >+ >+// -------------------------------------------------------- >+ >+// Generate the vector of thread counts for tests parameterized on thread count. >+static std::vector<int> AllThreadCountValues() { >+ if (kExtendedTest) { >+ return {2, 4, 8, 10, 16, 20, 24, 30, 32}; >+ } >+ return {2, 4, 10}; >+} >+ >+// A test fixture parameterized by thread count. >+class MutexVariableThreadCountTest : public ::testing::TestWithParam<int> {}; >+ >+// Instantiate the above with AllThreadCountOptions(). >+INSTANTIATE_TEST_CASE_P(ThreadCounts, MutexVariableThreadCountTest, >+ ::testing::ValuesIn(AllThreadCountValues()), >+ ::testing::PrintToStringParamName()); >+ >+// Reduces iterations by some factor for slow platforms >+// (determined empirically). >+static int ScaleIterations(int x) { >+ // ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE is set in the implementation >+ // of Mutex that uses either std::mutex or pthread_mutex_t. Use >+ // these as keys to determine the slow implementation. >+#if defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE) >+ return x / 10; >+#else >+ return x; >+#endif >+} >+ >+TEST_P(MutexVariableThreadCountTest, Mutex) { >+ int threads = GetParam(); >+ int iterations = ScaleIterations(10000000) / threads; >+ int operations = threads * iterations; >+ EXPECT_EQ(RunTest(&TestMu, threads, iterations, operations), operations); >+#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED) >+ iterations = std::min(iterations, 10); >+ operations = threads * iterations; >+ EXPECT_EQ(RunTestWithInvariantDebugging(&TestMu, threads, iterations, >+ operations, CheckSumG0G1), >+ operations); >+#endif >+} >+ >+TEST_P(MutexVariableThreadCountTest, Try) { >+ int threads = GetParam(); >+ int iterations = 1000000 / threads; >+ int operations = iterations * threads; >+ EXPECT_EQ(RunTest(&TestTry, threads, iterations, operations), operations); >+#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED) >+ iterations = std::min(iterations, 10); >+ operations = threads * iterations; >+ EXPECT_EQ(RunTestWithInvariantDebugging(&TestTry, threads, iterations, >+ operations, CheckSumG0G1), >+ operations); >+#endif >+} >+ >+TEST_P(MutexVariableThreadCountTest, R20ms) { >+ int threads = GetParam(); >+ int iterations = 100; >+ int operations = iterations * threads; >+ EXPECT_EQ(RunTest(&TestR20ms, threads, iterations, operations), 0); >+} >+ >+TEST_P(MutexVariableThreadCountTest, RW) { >+ int threads = GetParam(); >+ int iterations = ScaleIterations(20000000) / threads; >+ int operations = iterations * threads; >+ EXPECT_EQ(RunTest(&TestRW, threads, iterations, operations), operations / 2); >+#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED) >+ iterations = std::min(iterations, 10); >+ operations = threads * iterations; >+ EXPECT_EQ(RunTestWithInvariantDebugging(&TestRW, threads, iterations, >+ operations, CheckSumG0G1), >+ operations / 2); >+#endif >+} >+ >+TEST_P(MutexVariableThreadCountTest, Await) { >+ int threads = GetParam(); >+ int iterations = ScaleIterations(500000); >+ int operations = iterations; >+ EXPECT_EQ(RunTest(&TestAwait, threads, iterations, operations), operations); >+} >+ >+TEST_P(MutexVariableThreadCountTest, SignalAll) { >+ int threads = GetParam(); >+ int iterations = 200000 / threads; >+ int operations = iterations; >+ EXPECT_EQ(RunTest(&TestSignalAll, threads, iterations, operations), >+ operations); >+} >+ >+TEST(Mutex, Signal) { >+ int threads = 2; // TestSignal must use two threads >+ int iterations = 200000; >+ int operations = iterations; >+ EXPECT_EQ(RunTest(&TestSignal, threads, iterations, operations), operations); >+} >+ >+TEST(Mutex, Timed) { >+ int threads = 10; // Use a fixed thread count of 10 >+ int iterations = 1000; >+ int operations = iterations; >+ EXPECT_EQ(RunTest(&TestCVTimeout, threads, iterations, operations), >+ operations); >+} >+ >+TEST(Mutex, CVTime) { >+ int threads = 10; // Use a fixed thread count of 10 >+ int iterations = 1; >+ EXPECT_EQ(RunTest(&TestCVTime, threads, iterations, 1), >+ threads * iterations); >+} >+ >+TEST(Mutex, MuTime) { >+ int threads = 10; // Use a fixed thread count of 10 >+ int iterations = 1; >+ EXPECT_EQ(RunTest(&TestMuTime, threads, iterations, 1), threads * iterations); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/notification.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/notification.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..ed8cc906774025b46b058d47d844ba769bc1bce7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/notification.cc >@@ -0,0 +1,84 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/notification.h" >+ >+#include <atomic> >+ >+#include "absl/base/attributes.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/synchronization/mutex.h" >+#include "absl/time/time.h" >+ >+namespace absl { >+void Notification::Notify() { >+ MutexLock l(&this->mutex_); >+ >+#ifndef NDEBUG >+ if (ABSL_PREDICT_FALSE(notified_yet_.load(std::memory_order_relaxed))) { >+ ABSL_RAW_LOG( >+ FATAL, >+ "Notify() method called more than once for Notification object %p", >+ static_cast<void *>(this)); >+ } >+#endif >+ >+ notified_yet_.store(true, std::memory_order_release); >+} >+ >+Notification::~Notification() { >+ // Make sure that the thread running Notify() exits before the object is >+ // destructed. >+ MutexLock l(&this->mutex_); >+} >+ >+static inline bool HasBeenNotifiedInternal( >+ const std::atomic<bool> *notified_yet) { >+ return notified_yet->load(std::memory_order_acquire); >+} >+ >+bool Notification::HasBeenNotified() const { >+ return HasBeenNotifiedInternal(&this->notified_yet_); >+} >+ >+void Notification::WaitForNotification() const { >+ if (!HasBeenNotifiedInternal(&this->notified_yet_)) { >+ this->mutex_.LockWhen(Condition(&HasBeenNotifiedInternal, >+ &this->notified_yet_)); >+ this->mutex_.Unlock(); >+ } >+} >+ >+bool Notification::WaitForNotificationWithTimeout( >+ absl::Duration timeout) const { >+ bool notified = HasBeenNotifiedInternal(&this->notified_yet_); >+ if (!notified) { >+ notified = this->mutex_.LockWhenWithTimeout( >+ Condition(&HasBeenNotifiedInternal, &this->notified_yet_), timeout); >+ this->mutex_.Unlock(); >+ } >+ return notified; >+} >+ >+bool Notification::WaitForNotificationWithDeadline(absl::Time deadline) const { >+ bool notified = HasBeenNotifiedInternal(&this->notified_yet_); >+ if (!notified) { >+ notified = this->mutex_.LockWhenWithDeadline( >+ Condition(&HasBeenNotifiedInternal, &this->notified_yet_), deadline); >+ this->mutex_.Unlock(); >+ } >+ return notified; >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/notification.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/notification.h >new file mode 100644 >index 0000000000000000000000000000000000000000..107932f2909e6e61bb11fc5b3f5372aa54172ca0 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/notification.h >@@ -0,0 +1,112 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// notification.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines a `Notification` abstraction, which allows threads >+// to receive notification of a single occurrence of a single event. >+// >+// The `Notification` object maintains a private boolean "notified" state that >+// transitions to `true` at most once. The `Notification` class provides the >+// following primary member functions: >+// * `HasBeenNotified() `to query its state >+// * `WaitForNotification*()` to have threads wait until the "notified" state >+// is `true`. >+// * `Notify()` to set the notification's "notified" state to `true` and >+// notify all waiting threads that the event has occurred. >+// This method may only be called once. >+// >+// Note that while `Notify()` may only be called once, it is perfectly valid to >+// call any of the `WaitForNotification*()` methods multiple times, from >+// multiple threads -- even after the notification's "notified" state has been >+// set -- in which case those methods will immediately return. >+// >+// Note that the lifetime of a `Notification` requires careful consideration; >+// it might not be safe to destroy a notification after calling `Notify()` since >+// it is still legal for other threads to call `WaitForNotification*()` methods >+// on the notification. However, observers responding to a "notified" state of >+// `true` can safely delete the notification without interfering with the call >+// to `Notify()` in the other thread. >+// >+// Memory ordering: For any threads X and Y, if X calls `Notify()`, then any >+// action taken by X before it calls `Notify()` is visible to thread Y after: >+// * Y returns from `WaitForNotification()`, or >+// * Y receives a `true` return value from either `HasBeenNotified()` or >+// `WaitForNotificationWithTimeout()`. >+ >+#ifndef ABSL_SYNCHRONIZATION_NOTIFICATION_H_ >+#define ABSL_SYNCHRONIZATION_NOTIFICATION_H_ >+ >+#include <atomic> >+ >+#include "absl/synchronization/mutex.h" >+#include "absl/time/time.h" >+ >+namespace absl { >+ >+// ----------------------------------------------------------------------------- >+// Notification >+// ----------------------------------------------------------------------------- >+class Notification { >+ public: >+ // Initializes the "notified" state to unnotified. >+ Notification() : notified_yet_(false) {} >+ explicit Notification(bool prenotify) : notified_yet_(prenotify) {} >+ Notification(const Notification&) = delete; >+ Notification& operator=(const Notification&) = delete; >+ ~Notification(); >+ >+ // Notification::HasBeenNotified() >+ // >+ // Returns the value of the notification's internal "notified" state. >+ bool HasBeenNotified() const; >+ >+ // Notification::WaitForNotification() >+ // >+ // Blocks the calling thread until the notification's "notified" state is >+ // `true`. Note that if `Notify()` has been previously called on this >+ // notification, this function will immediately return. >+ void WaitForNotification() const; >+ >+ // Notification::WaitForNotificationWithTimeout() >+ // >+ // Blocks until either the notification's "notified" state is `true` (which >+ // may occur immediately) or the timeout has elapsed, returning the value of >+ // its "notified" state in either case. >+ bool WaitForNotificationWithTimeout(absl::Duration timeout) const; >+ >+ // Notification::WaitForNotificationWithDeadline() >+ // >+ // Blocks until either the notification's "notified" state is `true` (which >+ // may occur immediately) or the deadline has expired, returning the value of >+ // its "notified" state in either case. >+ bool WaitForNotificationWithDeadline(absl::Time deadline) const; >+ >+ // Notification::Notify() >+ // >+ // Sets the "notified" state of this notification to `true` and wakes waiting >+ // threads. Note: do not call `Notify()` multiple times on the same >+ // `Notification`; calling `Notify()` more than once on the same notification >+ // results in undefined behavior. >+ void Notify(); >+ >+ private: >+ mutable Mutex mutex_; >+ std::atomic<bool> notified_yet_; // written under mutex_ >+}; >+ >+} // namespace absl >+#endif // ABSL_SYNCHRONIZATION_NOTIFICATION_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/notification_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/notification_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..9b3b6a5a9e84ec1a3655a2c8f43eb8fbc5832ef6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/synchronization/notification_test.cc >@@ -0,0 +1,124 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/synchronization/notification.h" >+ >+#include <thread> // NOLINT(build/c++11) >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/synchronization/mutex.h" >+ >+namespace absl { >+ >+// A thread-safe class that holds a counter. >+class ThreadSafeCounter { >+ public: >+ ThreadSafeCounter() : count_(0) {} >+ >+ void Increment() { >+ MutexLock lock(&mutex_); >+ ++count_; >+ } >+ >+ int Get() const { >+ MutexLock lock(&mutex_); >+ return count_; >+ } >+ >+ void WaitUntilGreaterOrEqual(int n) { >+ MutexLock lock(&mutex_); >+ auto cond = [this, n]() { return count_ >= n; }; >+ mutex_.Await(Condition(&cond)); >+ } >+ >+ private: >+ mutable Mutex mutex_; >+ int count_; >+}; >+ >+// Runs the |i|'th worker thread for the tests in BasicTests(). Increments the >+// |ready_counter|, waits on the |notification|, and then increments the >+// |done_counter|. >+static void RunWorker(int i, ThreadSafeCounter* ready_counter, >+ Notification* notification, >+ ThreadSafeCounter* done_counter) { >+ ready_counter->Increment(); >+ notification->WaitForNotification(); >+ done_counter->Increment(); >+} >+ >+// Tests that the |notification| properly blocks and awakens threads. Assumes >+// that the |notification| is not yet triggered. If |notify_before_waiting| is >+// true, the |notification| is triggered before any threads are created, so the >+// threads never block in WaitForNotification(). Otherwise, the |notification| >+// is triggered at a later point when most threads are likely to be blocking in >+// WaitForNotification(). >+static void BasicTests(bool notify_before_waiting, Notification* notification) { >+ EXPECT_FALSE(notification->HasBeenNotified()); >+ EXPECT_FALSE( >+ notification->WaitForNotificationWithTimeout(absl::Milliseconds(0))); >+ EXPECT_FALSE(notification->WaitForNotificationWithDeadline(absl::Now())); >+ >+ absl::Time start = absl::Now(); >+ EXPECT_FALSE( >+ notification->WaitForNotificationWithTimeout(absl::Milliseconds(50))); >+ EXPECT_LE(start + absl::Milliseconds(50), absl::Now()); >+ >+ ThreadSafeCounter ready_counter; >+ ThreadSafeCounter done_counter; >+ >+ if (notify_before_waiting) { >+ notification->Notify(); >+ } >+ >+ // Create a bunch of threads that increment the |done_counter| after being >+ // notified. >+ const int kNumThreads = 10; >+ std::vector<std::thread> workers; >+ for (int i = 0; i < kNumThreads; ++i) { >+ workers.push_back(std::thread(&RunWorker, i, &ready_counter, notification, >+ &done_counter)); >+ } >+ >+ if (!notify_before_waiting) { >+ ready_counter.WaitUntilGreaterOrEqual(kNumThreads); >+ >+ // Workers have not been notified yet, so the |done_counter| should be >+ // unmodified. >+ EXPECT_EQ(0, done_counter.Get()); >+ >+ notification->Notify(); >+ } >+ >+ // After notifying and then joining the workers, both counters should be >+ // fully incremented. >+ notification->WaitForNotification(); // should exit immediately >+ EXPECT_TRUE(notification->HasBeenNotified()); >+ EXPECT_TRUE(notification->WaitForNotificationWithTimeout(absl::Seconds(0))); >+ EXPECT_TRUE(notification->WaitForNotificationWithDeadline(absl::Now())); >+ for (std::thread& worker : workers) { >+ worker.join(); >+ } >+ EXPECT_EQ(kNumThreads, ready_counter.Get()); >+ EXPECT_EQ(kNumThreads, done_counter.Get()); >+} >+ >+TEST(NotificationTest, SanityTest) { >+ Notification local_notification1, local_notification2; >+ BasicTests(false, &local_notification1); >+ BasicTests(true, &local_notification2); >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..c7c16d4376c7fa34344757279fa617c7054c260e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/BUILD.bazel >@@ -0,0 +1,112 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+) >+ >+package(default_visibility = ["//visibility:public"]) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+cc_library( >+ name = "time", >+ srcs = [ >+ "clock.cc", >+ "duration.cc", >+ "format.cc", >+ "internal/get_current_time_chrono.inc", >+ "internal/get_current_time_posix.inc", >+ "time.cc", >+ ], >+ hdrs = [ >+ "clock.h", >+ "time.h", >+ ], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/base", >+ "//absl/base:core_headers", >+ "//absl/numeric:int128", >+ "//absl/strings", >+ "//absl/time/internal/cctz:civil_time", >+ "//absl/time/internal/cctz:time_zone", >+ ], >+) >+ >+cc_library( >+ name = "test_util", >+ testonly = 1, >+ srcs = [ >+ "internal/test_util.cc", >+ "internal/zoneinfo.inc", >+ ], >+ hdrs = ["internal/test_util.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ visibility = [ >+ "//absl/time:__pkg__", >+ ], >+ deps = [ >+ ":time", >+ "//absl/base", >+ "//absl/time/internal/cctz:time_zone", >+ "@com_google_googletest//:gtest", >+ ], >+) >+ >+cc_test( >+ name = "time_test", >+ srcs = [ >+ "clock_test.cc", >+ "duration_test.cc", >+ "format_test.cc", >+ "time_norm_test.cc", >+ "time_test.cc", >+ "time_zone_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":test_util", >+ ":time", >+ "//absl/base", >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ "//absl/time/internal/cctz:time_zone", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "time_benchmark", >+ srcs = [ >+ "clock_benchmark.cc", >+ "duration_benchmark.cc", >+ "format_benchmark.cc", >+ "time_benchmark.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ tags = [ >+ "benchmark", >+ ], >+ deps = [ >+ ":test_util", >+ ":time", >+ "//absl/base", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..9927af8343cb16099e022cd3780f486e7afa411d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/BUILD.gn >@@ -0,0 +1,70 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("time") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "clock.cc", >+ "duration.cc", >+ "format.cc", >+ "internal/get_current_time_chrono.inc", >+ "internal/get_current_time_posix.inc", >+ "time.cc", >+ ] >+ public = [ >+ "clock.h", >+ "time.h", >+ ] >+ deps = [ >+ "../base", >+ "../base:core_headers", >+ "../numeric:int128", >+ "../strings", >+ "../time/internal/cctz:civil_time", >+ "../time/internal/cctz:time_zone", >+ ] >+} >+ >+source_set("test_util") { >+ testonly = true >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/test_util.cc", >+ "internal/zoneinfo.inc", >+ ] >+ public = [ >+ "internal/test_util.h", >+ ] >+ deps = [ >+ ":time", >+ "../base", >+ "../time/internal/cctz:time_zone", >+ "//testing/gtest", >+ "//testing/gmock", >+ ] >+ visibility = [] >+ visibility += [ "../time:*" ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..06272364f14e9db25943584056763d1b073c6508 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/CMakeLists.txt >@@ -0,0 +1,96 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+list(APPEND TIME_PUBLIC_HEADERS >+ "clock.h" >+ "time.h" >+) >+ >+ >+list(APPEND TIME_INTERNAL_HEADERS >+ "internal/test_util.h" >+ "internal/cctz/include/cctz/civil_time.h" >+ "internal/cctz/include/cctz/civil_time_detail.h" >+ "internal/cctz/include/cctz/time_zone.h" >+ "internal/cctz/include/cctz/zone_info_source.h" >+) >+ >+list(APPEND TIME_SRC >+ "time.cc" >+ "clock.cc" >+ "duration.cc" >+ "format.cc" >+ "internal/cctz/src/civil_time_detail.cc" >+ "internal/cctz/src/time_zone_fixed.cc" >+ "internal/cctz/src/time_zone_fixed.h" >+ "internal/cctz/src/time_zone_format.cc" >+ "internal/cctz/src/time_zone_if.cc" >+ "internal/cctz/src/time_zone_if.h" >+ "internal/cctz/src/time_zone_impl.cc" >+ "internal/cctz/src/time_zone_impl.h" >+ "internal/cctz/src/time_zone_info.cc" >+ "internal/cctz/src/time_zone_info.h" >+ "internal/cctz/src/time_zone_libc.cc" >+ "internal/cctz/src/time_zone_libc.h" >+ "internal/cctz/src/time_zone_lookup.cc" >+ "internal/cctz/src/time_zone_posix.cc" >+ "internal/cctz/src/time_zone_posix.h" >+ "internal/cctz/src/tzfile.h" >+ "internal/cctz/src/zone_info_source.cc" >+ ${TIME_PUBLIC_HEADERS} >+ ${TIME_INTERNAL_HEADERS} >+) >+set(TIME_PUBLIC_LIBRARIES absl::base absl::stacktrace absl::int128 absl::strings) >+ >+absl_library( >+ TARGET >+ absl_time >+ SOURCES >+ ${TIME_SRC} >+ PUBLIC_LIBRARIES >+ ${TIME_PUBLIC_LIBRARIES} >+ EXPORT_NAME >+ time >+) >+ >+ >+ >+# >+## TESTS >+# >+ >+# test time_test >+list(APPEND TIME_TEST_SRC >+ "time_test.cc" >+ "clock_test.cc" >+ "duration_test.cc" >+ "format_test.cc" >+ "time_norm_test.cc" >+ "time_test.cc" >+ "time_zone_test.cc" >+ "internal/test_util.cc" >+) >+set(TIME_TEST_PUBLIC_LIBRARIES absl::time) >+ >+absl_test( >+ TARGET >+ time_test >+ SOURCES >+ ${TIME_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${TIME_TEST_PUBLIC_LIBRARIES} >+) >+ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..74ee1401b98c2e15e19d2832daa491e3e45c2fb6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock.cc >@@ -0,0 +1,561 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/clock.h" >+ >+#include "absl/base/attributes.h" >+ >+#ifdef _WIN32 >+#include <windows.h> >+#endif >+ >+#include <algorithm> >+#include <atomic> >+#include <cerrno> >+#include <cstdint> >+#include <ctime> >+#include <limits> >+ >+#include "absl/base/internal/spinlock.h" >+#include "absl/base/internal/unscaledcycleclock.h" >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+#include "absl/base/thread_annotations.h" >+ >+namespace absl { >+Time Now() { >+ // TODO(bww): Get a timespec instead so we don't have to divide. >+ int64_t n = absl::GetCurrentTimeNanos(); >+ if (n >= 0) { >+ return time_internal::FromUnixDuration( >+ time_internal::MakeDuration(n / 1000000000, n % 1000000000 * 4)); >+ } >+ return time_internal::FromUnixDuration(absl::Nanoseconds(n)); >+} >+} // namespace absl >+ >+// Decide if we should use the fast GetCurrentTimeNanos() algorithm >+// based on the cyclecounter, otherwise just get the time directly >+// from the OS on every call. This can be chosen at compile-time via >+// -DABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS=[0|1] >+#ifndef ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS >+#if ABSL_USE_UNSCALED_CYCLECLOCK >+#define ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS 1 >+#else >+#define ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS 0 >+#endif >+#endif >+ >+#if defined(__APPLE__) || defined(_WIN32) >+#include "absl/time/internal/get_current_time_chrono.inc" >+#else >+#include "absl/time/internal/get_current_time_posix.inc" >+#endif >+ >+// Allows override by test. >+#ifndef GET_CURRENT_TIME_NANOS_FROM_SYSTEM >+#define GET_CURRENT_TIME_NANOS_FROM_SYSTEM() \ >+ ::absl::time_internal::GetCurrentTimeNanosFromSystem() >+#endif >+ >+#if !ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS >+namespace absl { >+int64_t GetCurrentTimeNanos() { >+ return GET_CURRENT_TIME_NANOS_FROM_SYSTEM(); >+} >+} // namespace absl >+#else // Use the cyclecounter-based implementation below. >+ >+// Allows override by test. >+#ifndef GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW >+#define GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW() \ >+ ::absl::time_internal::UnscaledCycleClockWrapperForGetCurrentTime::Now() >+#endif >+ >+// The following counters are used only by the test code. >+static int64_t stats_initializations; >+static int64_t stats_reinitializations; >+static int64_t stats_calibrations; >+static int64_t stats_slow_paths; >+static int64_t stats_fast_slow_paths; >+ >+namespace absl { >+namespace time_internal { >+// This is a friend wrapper around UnscaledCycleClock::Now() >+// (needed to access UnscaledCycleClock). >+class UnscaledCycleClockWrapperForGetCurrentTime { >+ public: >+ static int64_t Now() { return base_internal::UnscaledCycleClock::Now(); } >+}; >+} // namespace time_internal >+ >+// uint64_t is used in this module to provide an extra bit in multiplications >+ >+// Return the time in ns as told by the kernel interface. Place in *cycleclock >+// the value of the cycleclock at about the time of the syscall. >+// This call represents the time base that this module synchronizes to. >+// Ensures that *cycleclock does not step back by up to (1 << 16) from >+// last_cycleclock, to discard small backward counter steps. (Larger steps are >+// assumed to be complete resyncs, which shouldn't happen. If they do, a full >+// reinitialization of the outer algorithm should occur.) >+static int64_t GetCurrentTimeNanosFromKernel(uint64_t last_cycleclock, >+ uint64_t *cycleclock) { >+ // We try to read clock values at about the same time as the kernel clock. >+ // This value gets adjusted up or down as estimate of how long that should >+ // take, so we can reject attempts that take unusually long. >+ static std::atomic<uint64_t> approx_syscall_time_in_cycles{10 * 1000}; >+ >+ uint64_t local_approx_syscall_time_in_cycles = // local copy >+ approx_syscall_time_in_cycles.load(std::memory_order_relaxed); >+ >+ int64_t current_time_nanos_from_system; >+ uint64_t before_cycles; >+ uint64_t after_cycles; >+ uint64_t elapsed_cycles; >+ int loops = 0; >+ do { >+ before_cycles = GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW(); >+ current_time_nanos_from_system = GET_CURRENT_TIME_NANOS_FROM_SYSTEM(); >+ after_cycles = GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW(); >+ // elapsed_cycles is unsigned, so is large on overflow >+ elapsed_cycles = after_cycles - before_cycles; >+ if (elapsed_cycles >= local_approx_syscall_time_in_cycles && >+ ++loops == 20) { // clock changed frequencies? Back off. >+ loops = 0; >+ if (local_approx_syscall_time_in_cycles < 1000 * 1000) { >+ local_approx_syscall_time_in_cycles = >+ (local_approx_syscall_time_in_cycles + 1) << 1; >+ } >+ approx_syscall_time_in_cycles.store( >+ local_approx_syscall_time_in_cycles, >+ std::memory_order_relaxed); >+ } >+ } while (elapsed_cycles >= local_approx_syscall_time_in_cycles || >+ last_cycleclock - after_cycles < (static_cast<uint64_t>(1) << 16)); >+ >+ // Number of times in a row we've seen a kernel time call take substantially >+ // less than approx_syscall_time_in_cycles. >+ static std::atomic<uint32_t> seen_smaller{ 0 }; >+ >+ // Adjust approx_syscall_time_in_cycles to be within a factor of 2 >+ // of the typical time to execute one iteration of the loop above. >+ if ((local_approx_syscall_time_in_cycles >> 1) < elapsed_cycles) { >+ // measured time is no smaller than half current approximation >+ seen_smaller.store(0, std::memory_order_relaxed); >+ } else if (seen_smaller.fetch_add(1, std::memory_order_relaxed) >= 3) { >+ // smaller delays several times in a row; reduce approximation by 12.5% >+ const uint64_t new_approximation = >+ local_approx_syscall_time_in_cycles - >+ (local_approx_syscall_time_in_cycles >> 3); >+ approx_syscall_time_in_cycles.store(new_approximation, >+ std::memory_order_relaxed); >+ seen_smaller.store(0, std::memory_order_relaxed); >+ } >+ >+ *cycleclock = after_cycles; >+ return current_time_nanos_from_system; >+} >+ >+ >+// --------------------------------------------------------------------- >+// An implementation of reader-write locks that use no atomic ops in the read >+// case. This is a generalization of Lamport's method for reading a multiword >+// clock. Increment a word on each write acquisition, using the low-order bit >+// as a spinlock; the word is the high word of the "clock". Readers read the >+// high word, then all other data, then the high word again, and repeat the >+// read if the reads of the high words yields different answers, or an odd >+// value (either case suggests possible interference from a writer). >+// Here we use a spinlock to ensure only one writer at a time, rather than >+// spinning on the bottom bit of the word to benefit from SpinLock >+// spin-delay tuning. >+ >+// Acquire seqlock (*seq) and return the value to be written to unlock. >+static inline uint64_t SeqAcquire(std::atomic<uint64_t> *seq) { >+ uint64_t x = seq->fetch_add(1, std::memory_order_relaxed); >+ >+ // We put a release fence between update to *seq and writes to shared data. >+ // Thus all stores to shared data are effectively release operations and >+ // update to *seq above cannot be re-ordered past any of them. Note that >+ // this barrier is not for the fetch_add above. A release barrier for the >+ // fetch_add would be before it, not after. >+ std::atomic_thread_fence(std::memory_order_release); >+ >+ return x + 2; // original word plus 2 >+} >+ >+// Release seqlock (*seq) by writing x to it---a value previously returned by >+// SeqAcquire. >+static inline void SeqRelease(std::atomic<uint64_t> *seq, uint64_t x) { >+ // The unlock store to *seq must have release ordering so that all >+ // updates to shared data must finish before this store. >+ seq->store(x, std::memory_order_release); // release lock for readers >+} >+ >+// --------------------------------------------------------------------- >+ >+// "nsscaled" is unit of time equal to a (2**kScale)th of a nanosecond. >+enum { kScale = 30 }; >+ >+// The minimum interval between samples of the time base. >+// We pick enough time to amortize the cost of the sample, >+// to get a reasonably accurate cycle counter rate reading, >+// and not so much that calculations will overflow 64-bits. >+static const uint64_t kMinNSBetweenSamples = 2000 << 20; >+ >+// We require that kMinNSBetweenSamples shifted by kScale >+// have at least a bit left over for 64-bit calculations. >+static_assert(((kMinNSBetweenSamples << (kScale + 1)) >> (kScale + 1)) == >+ kMinNSBetweenSamples, >+ "cannot represent kMaxBetweenSamplesNSScaled"); >+ >+// A reader-writer lock protecting the static locations below. >+// See SeqAcquire() and SeqRelease() above. >+static absl::base_internal::SpinLock lock( >+ absl::base_internal::kLinkerInitialized); >+static std::atomic<uint64_t> seq(0); >+ >+// data from a sample of the kernel's time value >+struct TimeSampleAtomic { >+ std::atomic<uint64_t> raw_ns; // raw kernel time >+ std::atomic<uint64_t> base_ns; // our estimate of time >+ std::atomic<uint64_t> base_cycles; // cycle counter reading >+ std::atomic<uint64_t> nsscaled_per_cycle; // cycle period >+ // cycles before we'll sample again (a scaled reciprocal of the period, >+ // to avoid a division on the fast path). >+ std::atomic<uint64_t> min_cycles_per_sample; >+}; >+// Same again, but with non-atomic types >+struct TimeSample { >+ uint64_t raw_ns; // raw kernel time >+ uint64_t base_ns; // our estimate of time >+ uint64_t base_cycles; // cycle counter reading >+ uint64_t nsscaled_per_cycle; // cycle period >+ uint64_t min_cycles_per_sample; // approx cycles before next sample >+}; >+ >+static struct TimeSampleAtomic last_sample; // the last sample; under seq >+ >+static int64_t GetCurrentTimeNanosSlowPath() ABSL_ATTRIBUTE_COLD; >+ >+// Read the contents of *atomic into *sample. >+// Each field is read atomically, but to maintain atomicity between fields, >+// the access must be done under a lock. >+static void ReadTimeSampleAtomic(const struct TimeSampleAtomic *atomic, >+ struct TimeSample *sample) { >+ sample->base_ns = atomic->base_ns.load(std::memory_order_relaxed); >+ sample->base_cycles = atomic->base_cycles.load(std::memory_order_relaxed); >+ sample->nsscaled_per_cycle = >+ atomic->nsscaled_per_cycle.load(std::memory_order_relaxed); >+ sample->min_cycles_per_sample = >+ atomic->min_cycles_per_sample.load(std::memory_order_relaxed); >+ sample->raw_ns = atomic->raw_ns.load(std::memory_order_relaxed); >+} >+ >+// Public routine. >+// Algorithm: We wish to compute real time from a cycle counter. In normal >+// operation, we construct a piecewise linear approximation to the kernel time >+// source, using the cycle counter value. The start of each line segment is at >+// the same point as the end of the last, but may have a different slope (that >+// is, a different idea of the cycle counter frequency). Every couple of >+// seconds, the kernel time source is sampled and compared with the current >+// approximation. A new slope is chosen that, if followed for another couple >+// of seconds, will correct the error at the current position. The information >+// for a sample is in the "last_sample" struct. The linear approximation is >+// estimated_time = last_sample.base_ns + >+// last_sample.ns_per_cycle * (counter_reading - last_sample.base_cycles) >+// (ns_per_cycle is actually stored in different units and scaled, to avoid >+// overflow). The base_ns of the next linear approximation is the >+// estimated_time using the last approximation; the base_cycles is the cycle >+// counter value at that time; the ns_per_cycle is the number of ns per cycle >+// measured since the last sample, but adjusted so that most of the difference >+// between the estimated_time and the kernel time will be corrected by the >+// estimated time to the next sample. In normal operation, this algorithm >+// relies on: >+// - the cycle counter and kernel time rates not changing a lot in a few >+// seconds. >+// - the client calling into the code often compared to a couple of seconds, so >+// the time to the next correction can be estimated. >+// Any time ns_per_cycle is not known, a major error is detected, or the >+// assumption about frequent calls is violated, the implementation returns the >+// kernel time. It records sufficient data that a linear approximation can >+// resume a little later. >+ >+int64_t GetCurrentTimeNanos() { >+ // read the data from the "last_sample" struct (but don't need raw_ns yet) >+ // The reads of "seq" and test of the values emulate a reader lock. >+ uint64_t base_ns; >+ uint64_t base_cycles; >+ uint64_t nsscaled_per_cycle; >+ uint64_t min_cycles_per_sample; >+ uint64_t seq_read0; >+ uint64_t seq_read1; >+ >+ // If we have enough information to interpolate, the value returned will be >+ // derived from this cycleclock-derived time estimate. On some platforms >+ // (POWER) the function to retrieve this value has enough complexity to >+ // contribute to register pressure - reading it early before initializing >+ // the other pieces of the calculation minimizes spill/restore instructions, >+ // minimizing icache cost. >+ uint64_t now_cycles = GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW(); >+ >+ // Acquire pairs with the barrier in SeqRelease - if this load sees that >+ // store, the shared-data reads necessarily see that SeqRelease's updates >+ // to the same shared data. >+ seq_read0 = seq.load(std::memory_order_acquire); >+ >+ base_ns = last_sample.base_ns.load(std::memory_order_relaxed); >+ base_cycles = last_sample.base_cycles.load(std::memory_order_relaxed); >+ nsscaled_per_cycle = >+ last_sample.nsscaled_per_cycle.load(std::memory_order_relaxed); >+ min_cycles_per_sample = >+ last_sample.min_cycles_per_sample.load(std::memory_order_relaxed); >+ >+ // This acquire fence pairs with the release fence in SeqAcquire. Since it >+ // is sequenced between reads of shared data and seq_read1, the reads of >+ // shared data are effectively acquiring. >+ std::atomic_thread_fence(std::memory_order_acquire); >+ >+ // The shared-data reads are effectively acquire ordered, and the >+ // shared-data writes are effectively release ordered. Therefore if our >+ // shared-data reads see any of a particular update's shared-data writes, >+ // seq_read1 is guaranteed to see that update's SeqAcquire. >+ seq_read1 = seq.load(std::memory_order_relaxed); >+ >+ // Fast path. Return if min_cycles_per_sample has not yet elapsed since the >+ // last sample, and we read a consistent sample. The fast path activates >+ // only when min_cycles_per_sample is non-zero, which happens when we get an >+ // estimate for the cycle time. The predicate will fail if now_cycles < >+ // base_cycles, or if some other thread is in the slow path. >+ // >+ // Since we now read now_cycles before base_ns, it is possible for now_cycles >+ // to be less than base_cycles (if we were interrupted between those loads and >+ // last_sample was updated). This is harmless, because delta_cycles will wrap >+ // and report a time much much bigger than min_cycles_per_sample. In that case >+ // we will take the slow path. >+ uint64_t delta_cycles = now_cycles - base_cycles; >+ if (seq_read0 == seq_read1 && (seq_read0 & 1) == 0 && >+ delta_cycles < min_cycles_per_sample) { >+ return base_ns + ((delta_cycles * nsscaled_per_cycle) >> kScale); >+ } >+ return GetCurrentTimeNanosSlowPath(); >+} >+ >+// Return (a << kScale)/b. >+// Zero is returned if b==0. Scaling is performed internally to >+// preserve precision without overflow. >+static uint64_t SafeDivideAndScale(uint64_t a, uint64_t b) { >+ // Find maximum safe_shift so that >+ // 0 <= safe_shift <= kScale and (a << safe_shift) does not overflow. >+ int safe_shift = kScale; >+ while (((a << safe_shift) >> safe_shift) != a) { >+ safe_shift--; >+ } >+ uint64_t scaled_b = b >> (kScale - safe_shift); >+ uint64_t quotient = 0; >+ if (scaled_b != 0) { >+ quotient = (a << safe_shift) / scaled_b; >+ } >+ return quotient; >+} >+ >+static uint64_t UpdateLastSample( >+ uint64_t now_cycles, uint64_t now_ns, uint64_t delta_cycles, >+ const struct TimeSample *sample) ABSL_ATTRIBUTE_COLD; >+ >+// The slow path of GetCurrentTimeNanos(). This is taken while gathering >+// initial samples, when enough time has elapsed since the last sample, and if >+// any other thread is writing to last_sample. >+// >+// Manually mark this 'noinline' to minimize stack frame size of the fast >+// path. Without this, sometimes a compiler may inline this big block of code >+// into the fast past. That causes lots of register spills and reloads that >+// are unnecessary unless the slow path is taken. >+// >+// TODO(absl-team): Remove this attribute when our compiler is smart enough >+// to do the right thing. >+ABSL_ATTRIBUTE_NOINLINE >+static int64_t GetCurrentTimeNanosSlowPath() LOCKS_EXCLUDED(lock) { >+ // Serialize access to slow-path. Fast-path readers are not blocked yet, and >+ // code below must not modify last_sample until the seqlock is acquired. >+ lock.Lock(); >+ >+ // Sample the kernel time base. This is the definition of >+ // "now" if we take the slow path. >+ static uint64_t last_now_cycles; // protected by lock >+ uint64_t now_cycles; >+ uint64_t now_ns = GetCurrentTimeNanosFromKernel(last_now_cycles, &now_cycles); >+ last_now_cycles = now_cycles; >+ >+ uint64_t estimated_base_ns; >+ >+ // ---------- >+ // Read the "last_sample" values again; this time holding the write lock. >+ struct TimeSample sample; >+ ReadTimeSampleAtomic(&last_sample, &sample); >+ >+ // ---------- >+ // Try running the fast path again; another thread may have updated the >+ // sample between our run of the fast path and the sample we just read. >+ uint64_t delta_cycles = now_cycles - sample.base_cycles; >+ if (delta_cycles < sample.min_cycles_per_sample) { >+ // Another thread updated the sample. This path does not take the seqlock >+ // so that blocked readers can make progress without blocking new readers. >+ estimated_base_ns = sample.base_ns + >+ ((delta_cycles * sample.nsscaled_per_cycle) >> kScale); >+ stats_fast_slow_paths++; >+ } else { >+ estimated_base_ns = >+ UpdateLastSample(now_cycles, now_ns, delta_cycles, &sample); >+ } >+ >+ lock.Unlock(); >+ >+ return estimated_base_ns; >+} >+ >+// Main part of the algorithm. Locks out readers, updates the approximation >+// using the new sample from the kernel, and stores the result in last_sample >+// for readers. Returns the new estimated time. >+static uint64_t UpdateLastSample(uint64_t now_cycles, uint64_t now_ns, >+ uint64_t delta_cycles, >+ const struct TimeSample *sample) >+ EXCLUSIVE_LOCKS_REQUIRED(lock) { >+ uint64_t estimated_base_ns = now_ns; >+ uint64_t lock_value = SeqAcquire(&seq); // acquire seqlock to block readers >+ >+ // The 5s in the next if-statement limits the time for which we will trust >+ // the cycle counter and our last sample to give a reasonable result. >+ // Errors in the rate of the source clock can be multiplied by the ratio >+ // between this limit and kMinNSBetweenSamples. >+ if (sample->raw_ns == 0 || // no recent sample, or clock went backwards >+ sample->raw_ns + static_cast<uint64_t>(5) * 1000 * 1000 * 1000 < now_ns || >+ now_ns < sample->raw_ns || now_cycles < sample->base_cycles) { >+ // record this sample, and forget any previously known slope. >+ last_sample.raw_ns.store(now_ns, std::memory_order_relaxed); >+ last_sample.base_ns.store(estimated_base_ns, std::memory_order_relaxed); >+ last_sample.base_cycles.store(now_cycles, std::memory_order_relaxed); >+ last_sample.nsscaled_per_cycle.store(0, std::memory_order_relaxed); >+ last_sample.min_cycles_per_sample.store(0, std::memory_order_relaxed); >+ stats_initializations++; >+ } else if (sample->raw_ns + 500 * 1000 * 1000 < now_ns && >+ sample->base_cycles + 100 < now_cycles) { >+ // Enough time has passed to compute the cycle time. >+ if (sample->nsscaled_per_cycle != 0) { // Have a cycle time estimate. >+ // Compute time from counter reading, but avoiding overflow >+ // delta_cycles may be larger than on the fast path. >+ uint64_t estimated_scaled_ns; >+ int s = -1; >+ do { >+ s++; >+ estimated_scaled_ns = (delta_cycles >> s) * sample->nsscaled_per_cycle; >+ } while (estimated_scaled_ns / sample->nsscaled_per_cycle != >+ (delta_cycles >> s)); >+ estimated_base_ns = sample->base_ns + >+ (estimated_scaled_ns >> (kScale - s)); >+ } >+ >+ // Compute the assumed cycle time kMinNSBetweenSamples ns into the future >+ // assuming the cycle counter rate stays the same as the last interval. >+ uint64_t ns = now_ns - sample->raw_ns; >+ uint64_t measured_nsscaled_per_cycle = SafeDivideAndScale(ns, delta_cycles); >+ >+ uint64_t assumed_next_sample_delta_cycles = >+ SafeDivideAndScale(kMinNSBetweenSamples, measured_nsscaled_per_cycle); >+ >+ int64_t diff_ns = now_ns - estimated_base_ns; // estimate low by this much >+ >+ // We want to set nsscaled_per_cycle so that our estimate of the ns time >+ // at the assumed cycle time is the assumed ns time. >+ // That is, we want to set nsscaled_per_cycle so: >+ // kMinNSBetweenSamples + diff_ns == >+ // (assumed_next_sample_delta_cycles * nsscaled_per_cycle) >> kScale >+ // But we wish to damp oscillations, so instead correct only most >+ // of our current error, by solving: >+ // kMinNSBetweenSamples + diff_ns - (diff_ns / 16) == >+ // (assumed_next_sample_delta_cycles * nsscaled_per_cycle) >> kScale >+ ns = kMinNSBetweenSamples + diff_ns - (diff_ns / 16); >+ uint64_t new_nsscaled_per_cycle = >+ SafeDivideAndScale(ns, assumed_next_sample_delta_cycles); >+ if (new_nsscaled_per_cycle != 0 && >+ diff_ns < 100 * 1000 * 1000 && -diff_ns < 100 * 1000 * 1000) { >+ // record the cycle time measurement >+ last_sample.nsscaled_per_cycle.store( >+ new_nsscaled_per_cycle, std::memory_order_relaxed); >+ uint64_t new_min_cycles_per_sample = >+ SafeDivideAndScale(kMinNSBetweenSamples, new_nsscaled_per_cycle); >+ last_sample.min_cycles_per_sample.store( >+ new_min_cycles_per_sample, std::memory_order_relaxed); >+ stats_calibrations++; >+ } else { // something went wrong; forget the slope >+ last_sample.nsscaled_per_cycle.store(0, std::memory_order_relaxed); >+ last_sample.min_cycles_per_sample.store(0, std::memory_order_relaxed); >+ estimated_base_ns = now_ns; >+ stats_reinitializations++; >+ } >+ last_sample.raw_ns.store(now_ns, std::memory_order_relaxed); >+ last_sample.base_ns.store(estimated_base_ns, std::memory_order_relaxed); >+ last_sample.base_cycles.store(now_cycles, std::memory_order_relaxed); >+ } else { >+ // have a sample, but no slope; waiting for enough time for a calibration >+ stats_slow_paths++; >+ } >+ >+ SeqRelease(&seq, lock_value); // release the readers >+ >+ return estimated_base_ns; >+} >+} // namespace absl >+#endif // ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS >+ >+namespace absl { >+namespace { >+ >+// Returns the maximum duration that SleepOnce() can sleep for. >+constexpr absl::Duration MaxSleep() { >+#ifdef _WIN32 >+ // Windows Sleep() takes unsigned long argument in milliseconds. >+ return absl::Milliseconds( >+ std::numeric_limits<unsigned long>::max()); // NOLINT(runtime/int) >+#else >+ return absl::Seconds(std::numeric_limits<time_t>::max()); >+#endif >+} >+ >+// Sleeps for the given duration. >+// REQUIRES: to_sleep <= MaxSleep(). >+void SleepOnce(absl::Duration to_sleep) { >+#ifdef _WIN32 >+ Sleep(to_sleep / absl::Milliseconds(1)); >+#else >+ struct timespec sleep_time = absl::ToTimespec(to_sleep); >+ while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) { >+ // Ignore signals and wait for the full interval to elapse. >+ } >+#endif >+} >+ >+} // namespace >+} // namespace absl >+ >+extern "C" { >+ >+ABSL_ATTRIBUTE_WEAK void AbslInternalSleepFor(absl::Duration duration) { >+ while (duration > absl::ZeroDuration()) { >+ absl::Duration to_sleep = std::min(duration, absl::MaxSleep()); >+ absl::SleepOnce(to_sleep); >+ duration -= to_sleep; >+ } >+} >+ >+} // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock.h >new file mode 100644 >index 0000000000000000000000000000000000000000..3753d4ee43ad68a5b4bbd2747cf98057bb48fb87 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock.h >@@ -0,0 +1,72 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: clock.h >+// ----------------------------------------------------------------------------- >+// >+// This header file contains utility functions for working with the system-wide >+// realtime clock. For descriptions of the main time abstractions used within >+// this header file, consult the time.h header file. >+#ifndef ABSL_TIME_CLOCK_H_ >+#define ABSL_TIME_CLOCK_H_ >+ >+#include "absl/base/macros.h" >+#include "absl/time/time.h" >+ >+namespace absl { >+ >+// Now() >+// >+// Returns the current time, expressed as an `absl::Time` absolute time value. >+absl::Time Now(); >+ >+// GetCurrentTimeNanos() >+// >+// Returns the current time, expressed as a count of nanoseconds since the Unix >+// Epoch (https://en.wikipedia.org/wiki/Unix_time). Prefer `absl::Now()` instead >+// for all but the most performance-sensitive cases (i.e. when you are calling >+// this function hundreds of thousands of times per second). >+int64_t GetCurrentTimeNanos(); >+ >+// SleepFor() >+// >+// Sleeps for the specified duration, expressed as an `absl::Duration`. >+// >+// Notes: >+// * Signal interruptions will not reduce the sleep duration. >+// * Returns immediately when passed a nonpositive duration. >+void SleepFor(absl::Duration duration); >+ >+} // namespace absl >+ >+// ----------------------------------------------------------------------------- >+// Implementation Details >+// ----------------------------------------------------------------------------- >+ >+// In some build configurations we pass --detect-odr-violations to the >+// gold linker. This causes it to flag weak symbol overrides as ODR >+// violations. Because ODR only applies to C++ and not C, >+// --detect-odr-violations ignores symbols not mangled with C++ names. >+// By changing our extension points to be extern "C", we dodge this >+// check. >+extern "C" { >+void AbslInternalSleepFor(absl::Duration duration); >+} // extern "C" >+ >+inline void absl::SleepFor(absl::Duration duration) { >+ AbslInternalSleepFor(duration); >+} >+ >+#endif // ABSL_TIME_CLOCK_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..3d3cd9d5c42cd7f892f48a02e7c1fcb21a388faf >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock_benchmark.cc >@@ -0,0 +1,72 @@ >+// Copyright 2018 The Abseil Authors. >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/clock.h" >+ >+#if !defined(_WIN32) >+#include <sys/time.h> >+#endif // _WIN32 >+#include <cstdio> >+ >+#include "absl/base/internal/cycleclock.h" >+#include "benchmark/benchmark.h" >+ >+namespace { >+ >+void BM_Clock_Now_AbslTime(benchmark::State& state) { >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Now()); >+ } >+} >+BENCHMARK(BM_Clock_Now_AbslTime); >+ >+void BM_Clock_Now_GetCurrentTimeNanos(benchmark::State& state) { >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::GetCurrentTimeNanos()); >+ } >+} >+BENCHMARK(BM_Clock_Now_GetCurrentTimeNanos); >+ >+void BM_Clock_Now_AbslTime_ToUnixNanos(benchmark::State& state) { >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ToUnixNanos(absl::Now())); >+ } >+} >+BENCHMARK(BM_Clock_Now_AbslTime_ToUnixNanos); >+ >+void BM_Clock_Now_CycleClock(benchmark::State& state) { >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::base_internal::CycleClock::Now()); >+ } >+} >+BENCHMARK(BM_Clock_Now_CycleClock); >+ >+#if !defined(_WIN32) >+static void BM_Clock_Now_gettimeofday(benchmark::State& state) { >+ struct timeval tv; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(gettimeofday(&tv, nullptr)); >+ } >+} >+BENCHMARK(BM_Clock_Now_gettimeofday); >+ >+static void BM_Clock_Now_clock_gettime(benchmark::State& state) { >+ struct timespec ts; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(clock_gettime(CLOCK_REALTIME, &ts)); >+ } >+} >+BENCHMARK(BM_Clock_Now_clock_gettime); >+#endif // _WIN32 >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..707166d0c289b162e745a63bf0dbfc3eda520e7b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/clock_test.cc >@@ -0,0 +1,118 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/clock.h" >+ >+#include "absl/base/config.h" >+#if defined(ABSL_HAVE_ALARM) >+#include <signal.h> >+#include <unistd.h> >+#elif defined(__linux__) || defined(__APPLE__) >+#error all known Linux and Apple targets have alarm >+#endif >+ >+#include "gtest/gtest.h" >+#include "absl/time/time.h" >+ >+namespace { >+ >+TEST(Time, Now) { >+ const absl::Time before = absl::FromUnixNanos(absl::GetCurrentTimeNanos()); >+ const absl::Time now = absl::Now(); >+ const absl::Time after = absl::FromUnixNanos(absl::GetCurrentTimeNanos()); >+ EXPECT_GE(now, before); >+ EXPECT_GE(after, now); >+} >+ >+enum class AlarmPolicy { kWithoutAlarm, kWithAlarm }; >+ >+#if defined(ABSL_HAVE_ALARM) >+bool alarm_handler_invoked = false; >+ >+void AlarmHandler(int signo) { >+ ASSERT_EQ(signo, SIGALRM); >+ alarm_handler_invoked = true; >+} >+#endif >+ >+// Does SleepFor(d) take between lower_bound and upper_bound at least >+// once between now and (now + timeout)? If requested (and supported), >+// add an alarm for the middle of the sleep period and expect it to fire. >+bool SleepForBounded(absl::Duration d, absl::Duration lower_bound, >+ absl::Duration upper_bound, absl::Duration timeout, >+ AlarmPolicy alarm_policy, int* attempts) { >+ const absl::Time deadline = absl::Now() + timeout; >+ while (absl::Now() < deadline) { >+#if defined(ABSL_HAVE_ALARM) >+ sig_t old_alarm = SIG_DFL; >+ if (alarm_policy == AlarmPolicy::kWithAlarm) { >+ alarm_handler_invoked = false; >+ old_alarm = signal(SIGALRM, AlarmHandler); >+ alarm(absl::ToInt64Seconds(d / 2)); >+ } >+#else >+ EXPECT_EQ(alarm_policy, AlarmPolicy::kWithoutAlarm); >+#endif >+ ++*attempts; >+ absl::Time start = absl::Now(); >+ absl::SleepFor(d); >+ absl::Duration actual = absl::Now() - start; >+#if defined(ABSL_HAVE_ALARM) >+ if (alarm_policy == AlarmPolicy::kWithAlarm) { >+ signal(SIGALRM, old_alarm); >+ if (!alarm_handler_invoked) continue; >+ } >+#endif >+ if (lower_bound <= actual && actual <= upper_bound) { >+ return true; // yes, the SleepFor() was correctly bounded >+ } >+ } >+ return false; >+} >+ >+testing::AssertionResult AssertSleepForBounded(absl::Duration d, >+ absl::Duration early, >+ absl::Duration late, >+ absl::Duration timeout, >+ AlarmPolicy alarm_policy) { >+ const absl::Duration lower_bound = d - early; >+ const absl::Duration upper_bound = d + late; >+ int attempts = 0; >+ if (SleepForBounded(d, lower_bound, upper_bound, timeout, alarm_policy, >+ &attempts)) { >+ return testing::AssertionSuccess(); >+ } >+ return testing::AssertionFailure() >+ << "SleepFor(" << d << ") did not return within [" << lower_bound >+ << ":" << upper_bound << "] in " << attempts << " attempt" >+ << (attempts == 1 ? "" : "s") << " over " << timeout >+ << (alarm_policy == AlarmPolicy::kWithAlarm ? " with" : " without") >+ << " an alarm"; >+} >+ >+// Tests that SleepFor() returns neither too early nor too late. >+TEST(SleepFor, Bounded) { >+ const absl::Duration d = absl::Milliseconds(2500); >+ const absl::Duration early = absl::Milliseconds(100); >+ const absl::Duration late = absl::Milliseconds(300); >+ const absl::Duration timeout = 48 * d; >+ EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout, >+ AlarmPolicy::kWithoutAlarm)); >+#if defined(ABSL_HAVE_ALARM) >+ EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout, >+ AlarmPolicy::kWithAlarm)); >+#endif >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/duration.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/duration.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..f402137b0a650d2b7ed605262fd954062aab29a0 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/duration.cc >@@ -0,0 +1,904 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// The implementation of the absl::Duration class, which is declared in >+// //absl/time.h. This class behaves like a numeric type; it has no public >+// methods and is used only through the operators defined here. >+// >+// Implementation notes: >+// >+// An absl::Duration is represented as >+// >+// rep_hi_ : (int64_t) Whole seconds >+// rep_lo_ : (uint32_t) Fractions of a second >+// >+// The seconds value (rep_hi_) may be positive or negative as appropriate. >+// The fractional seconds (rep_lo_) is always a positive offset from rep_hi_. >+// The API for Duration guarantees at least nanosecond resolution, which >+// means rep_lo_ could have a max value of 1B - 1 if it stored nanoseconds. >+// However, to utilize more of the available 32 bits of space in rep_lo_, >+// we instead store quarters of a nanosecond in rep_lo_ resulting in a max >+// value of 4B - 1. This allows us to correctly handle calculations like >+// 0.5 nanos + 0.5 nanos = 1 nano. The following example shows the actual >+// Duration rep using quarters of a nanosecond. >+// >+// 2.5 sec = {rep_hi_=2, rep_lo_=2000000000} // lo = 4 * 500000000 >+// -2.5 sec = {rep_hi_=-3, rep_lo_=2000000000} >+// >+// Infinite durations are represented as Durations with the rep_lo_ field set >+// to all 1s. >+// >+// +InfiniteDuration: >+// rep_hi_ : kint64max >+// rep_lo_ : ~0U >+// >+// -InfiniteDuration: >+// rep_hi_ : kint64min >+// rep_lo_ : ~0U >+// >+// Arithmetic overflows/underflows to +/- infinity and saturates. >+ >+#include <algorithm> >+#include <cassert> >+#include <cctype> >+#include <cerrno> >+#include <cmath> >+#include <cstdint> >+#include <cstdlib> >+#include <cstring> >+#include <ctime> >+#include <functional> >+#include <limits> >+#include <string> >+ >+#include "absl/base/casts.h" >+#include "absl/numeric/int128.h" >+#include "absl/time/time.h" >+ >+namespace absl { >+ >+namespace { >+ >+using time_internal::kTicksPerNanosecond; >+using time_internal::kTicksPerSecond; >+ >+constexpr int64_t kint64max = std::numeric_limits<int64_t>::max(); >+constexpr int64_t kint64min = std::numeric_limits<int64_t>::min(); >+ >+// Can't use std::isinfinite() because it doesn't exist on windows. >+inline bool IsFinite(double d) { >+ return d != std::numeric_limits<double>::infinity() && >+ d != -std::numeric_limits<double>::infinity(); >+} >+ >+// Can't use std::round() because it is only available in C++11. >+// Note that we ignore the possibility of floating-point over/underflow. >+template <typename Double> >+inline double Round(Double d) { >+ return d < 0 ? std::ceil(d - 0.5) : std::floor(d + 0.5); >+} >+ >+// *sec may be positive or negative. *ticks must be in the range >+// -kTicksPerSecond < *ticks < kTicksPerSecond. If *ticks is negative it >+// will be normalized to a positive value by adjusting *sec accordingly. >+inline void NormalizeTicks(int64_t* sec, int64_t* ticks) { >+ if (*ticks < 0) { >+ --*sec; >+ *ticks += kTicksPerSecond; >+ } >+} >+ >+// Makes a uint128 from the absolute value of the given scalar. >+inline uint128 MakeU128(int64_t a) { >+ uint128 u128 = 0; >+ if (a < 0) { >+ ++u128; >+ ++a; // Makes it safe to negate 'a' >+ a = -a; >+ } >+ u128 += static_cast<uint64_t>(a); >+ return u128; >+} >+ >+// Makes a uint128 count of ticks out of the absolute value of the Duration. >+inline uint128 MakeU128Ticks(Duration d) { >+ int64_t rep_hi = time_internal::GetRepHi(d); >+ uint32_t rep_lo = time_internal::GetRepLo(d); >+ if (rep_hi < 0) { >+ ++rep_hi; >+ rep_hi = -rep_hi; >+ rep_lo = kTicksPerSecond - rep_lo; >+ } >+ uint128 u128 = static_cast<uint64_t>(rep_hi); >+ u128 *= static_cast<uint64_t>(kTicksPerSecond); >+ u128 += rep_lo; >+ return u128; >+} >+ >+// Breaks a uint128 of ticks into a Duration. >+inline Duration MakeDurationFromU128(uint128 u128, bool is_neg) { >+ int64_t rep_hi; >+ uint32_t rep_lo; >+ const uint64_t h64 = Uint128High64(u128); >+ const uint64_t l64 = Uint128Low64(u128); >+ if (h64 == 0) { // fastpath >+ const uint64_t hi = l64 / kTicksPerSecond; >+ rep_hi = static_cast<int64_t>(hi); >+ rep_lo = static_cast<uint32_t>(l64 - hi * kTicksPerSecond); >+ } else { >+ // kMaxRepHi64 is the high 64 bits of (2^63 * kTicksPerSecond). >+ // Any positive tick count whose high 64 bits are >= kMaxRepHi64 >+ // is not representable as a Duration. A negative tick count can >+ // have its high 64 bits == kMaxRepHi64 but only when the low 64 >+ // bits are all zero, otherwise it is not representable either. >+ const uint64_t kMaxRepHi64 = 0x77359400UL; >+ if (h64 >= kMaxRepHi64) { >+ if (is_neg && h64 == kMaxRepHi64 && l64 == 0) { >+ // Avoid trying to represent -kint64min below. >+ return time_internal::MakeDuration(kint64min); >+ } >+ return is_neg ? -InfiniteDuration() : InfiniteDuration(); >+ } >+ const uint128 kTicksPerSecond128 = static_cast<uint64_t>(kTicksPerSecond); >+ const uint128 hi = u128 / kTicksPerSecond128; >+ rep_hi = static_cast<int64_t>(Uint128Low64(hi)); >+ rep_lo = >+ static_cast<uint32_t>(Uint128Low64(u128 - hi * kTicksPerSecond128)); >+ } >+ if (is_neg) { >+ rep_hi = -rep_hi; >+ if (rep_lo != 0) { >+ --rep_hi; >+ rep_lo = kTicksPerSecond - rep_lo; >+ } >+ } >+ return time_internal::MakeDuration(rep_hi, rep_lo); >+} >+ >+// Convert between int64_t and uint64_t, preserving representation. This >+// allows us to do arithmetic in the unsigned domain, where overflow has >+// well-defined behavior. See operator+=() and operator-=(). >+// >+// C99 7.20.1.1.1, as referenced by C++11 18.4.1.2, says, "The typedef >+// name intN_t designates a signed integer type with width N, no padding >+// bits, and a two's complement representation." So, we can convert to >+// and from the corresponding uint64_t value using a bit cast. >+inline uint64_t EncodeTwosComp(int64_t v) { >+ return absl::bit_cast<uint64_t>(v); >+} >+inline int64_t DecodeTwosComp(uint64_t v) { return absl::bit_cast<int64_t>(v); } >+ >+// Note: The overflow detection in this function is done using greater/less *or >+// equal* because kint64max/min is too large to be represented exactly in a >+// double (which only has 53 bits of precision). In order to avoid assigning to >+// rep->hi a double value that is too large for an int64_t (and therefore is >+// undefined), we must consider computations that equal kint64max/min as a >+// double as overflow cases. >+inline bool SafeAddRepHi(double a_hi, double b_hi, Duration* d) { >+ double c = a_hi + b_hi; >+ if (c >= kint64max) { >+ *d = InfiniteDuration(); >+ return false; >+ } >+ if (c <= kint64min) { >+ *d = -InfiniteDuration(); >+ return false; >+ } >+ *d = time_internal::MakeDuration(c, time_internal::GetRepLo(*d)); >+ return true; >+} >+ >+// A functor that's similar to std::multiplies<T>, except this returns the max >+// T value instead of overflowing. This is only defined for uint128. >+template <typename Ignored> >+struct SafeMultiply { >+ uint128 operator()(uint128 a, uint128 b) const { >+ // b hi is always zero because it originated as an int64_t. >+ assert(Uint128High64(b) == 0); >+ // Fastpath to avoid the expensive overflow check with division. >+ if (Uint128High64(a) == 0) { >+ return (((Uint128Low64(a) | Uint128Low64(b)) >> 32) == 0) >+ ? static_cast<uint128>(Uint128Low64(a) * Uint128Low64(b)) >+ : a * b; >+ } >+ return b == 0 ? b : (a > kuint128max / b) ? kuint128max : a * b; >+ } >+}; >+ >+// Scales (i.e., multiplies or divides, depending on the Operation template) >+// the Duration d by the int64_t r. >+template <template <typename> class Operation> >+inline Duration ScaleFixed(Duration d, int64_t r) { >+ const uint128 a = MakeU128Ticks(d); >+ const uint128 b = MakeU128(r); >+ const uint128 q = Operation<uint128>()(a, b); >+ const bool is_neg = (time_internal::GetRepHi(d) < 0) != (r < 0); >+ return MakeDurationFromU128(q, is_neg); >+} >+ >+// Scales (i.e., multiplies or divides, depending on the Operation template) >+// the Duration d by the double r. >+template <template <typename> class Operation> >+inline Duration ScaleDouble(Duration d, double r) { >+ Operation<double> op; >+ double hi_doub = op(time_internal::GetRepHi(d), r); >+ double lo_doub = op(time_internal::GetRepLo(d), r); >+ >+ double hi_int = 0; >+ double hi_frac = std::modf(hi_doub, &hi_int); >+ >+ // Moves hi's fractional bits to lo. >+ lo_doub /= kTicksPerSecond; >+ lo_doub += hi_frac; >+ >+ double lo_int = 0; >+ double lo_frac = std::modf(lo_doub, &lo_int); >+ >+ // Rolls lo into hi if necessary. >+ int64_t lo64 = Round(lo_frac * kTicksPerSecond); >+ >+ Duration ans; >+ if (!SafeAddRepHi(hi_int, lo_int, &ans)) return ans; >+ int64_t hi64 = time_internal::GetRepHi(ans); >+ if (!SafeAddRepHi(hi64, lo64 / kTicksPerSecond, &ans)) return ans; >+ hi64 = time_internal::GetRepHi(ans); >+ lo64 %= kTicksPerSecond; >+ NormalizeTicks(&hi64, &lo64); >+ return time_internal::MakeDuration(hi64, lo64); >+} >+ >+// Tries to divide num by den as fast as possible by looking for common, easy >+// cases. If the division was done, the quotient is in *q and the remainder is >+// in *rem and true will be returned. >+inline bool IDivFastPath(const Duration num, const Duration den, int64_t* q, >+ Duration* rem) { >+ // Bail if num or den is an infinity. >+ if (time_internal::IsInfiniteDuration(num) || >+ time_internal::IsInfiniteDuration(den)) >+ return false; >+ >+ int64_t num_hi = time_internal::GetRepHi(num); >+ uint32_t num_lo = time_internal::GetRepLo(num); >+ int64_t den_hi = time_internal::GetRepHi(den); >+ uint32_t den_lo = time_internal::GetRepLo(den); >+ >+ if (den_hi == 0 && den_lo == kTicksPerNanosecond) { >+ // Dividing by 1ns >+ if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000000000) { >+ *q = num_hi * 1000000000 + num_lo / kTicksPerNanosecond; >+ *rem = time_internal::MakeDuration(0, num_lo % den_lo); >+ return true; >+ } >+ } else if (den_hi == 0 && den_lo == 100 * kTicksPerNanosecond) { >+ // Dividing by 100ns (common when converting to Universal time) >+ if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 10000000) { >+ *q = num_hi * 10000000 + num_lo / (100 * kTicksPerNanosecond); >+ *rem = time_internal::MakeDuration(0, num_lo % den_lo); >+ return true; >+ } >+ } else if (den_hi == 0 && den_lo == 1000 * kTicksPerNanosecond) { >+ // Dividing by 1us >+ if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000000) { >+ *q = num_hi * 1000000 + num_lo / (1000 * kTicksPerNanosecond); >+ *rem = time_internal::MakeDuration(0, num_lo % den_lo); >+ return true; >+ } >+ } else if (den_hi == 0 && den_lo == 1000000 * kTicksPerNanosecond) { >+ // Dividing by 1ms >+ if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000) { >+ *q = num_hi * 1000 + num_lo / (1000000 * kTicksPerNanosecond); >+ *rem = time_internal::MakeDuration(0, num_lo % den_lo); >+ return true; >+ } >+ } else if (den_hi > 0 && den_lo == 0) { >+ // Dividing by positive multiple of 1s >+ if (num_hi >= 0) { >+ if (den_hi == 1) { >+ *q = num_hi; >+ *rem = time_internal::MakeDuration(0, num_lo); >+ return true; >+ } >+ *q = num_hi / den_hi; >+ *rem = time_internal::MakeDuration(num_hi % den_hi, num_lo); >+ return true; >+ } >+ if (num_lo != 0) { >+ num_hi += 1; >+ } >+ int64_t quotient = num_hi / den_hi; >+ int64_t rem_sec = num_hi % den_hi; >+ if (rem_sec > 0) { >+ rem_sec -= den_hi; >+ quotient += 1; >+ } >+ if (num_lo != 0) { >+ rem_sec -= 1; >+ } >+ *q = quotient; >+ *rem = time_internal::MakeDuration(rem_sec, num_lo); >+ return true; >+ } >+ >+ return false; >+} >+ >+} // namespace >+ >+namespace time_internal { >+ >+// The 'satq' argument indicates whether the quotient should saturate at the >+// bounds of int64_t. If it does saturate, the difference will spill over to >+// the remainder. If it does not saturate, the remainder remain accurate, >+// but the returned quotient will over/underflow int64_t and should not be used. >+int64_t IDivDuration(bool satq, const Duration num, const Duration den, >+ Duration* rem) { >+ int64_t q = 0; >+ if (IDivFastPath(num, den, &q, rem)) { >+ return q; >+ } >+ >+ const bool num_neg = num < ZeroDuration(); >+ const bool den_neg = den < ZeroDuration(); >+ const bool quotient_neg = num_neg != den_neg; >+ >+ if (time_internal::IsInfiniteDuration(num) || den == ZeroDuration()) { >+ *rem = num_neg ? -InfiniteDuration() : InfiniteDuration(); >+ return quotient_neg ? kint64min : kint64max; >+ } >+ if (time_internal::IsInfiniteDuration(den)) { >+ *rem = num; >+ return 0; >+ } >+ >+ const uint128 a = MakeU128Ticks(num); >+ const uint128 b = MakeU128Ticks(den); >+ uint128 quotient128 = a / b; >+ >+ if (satq) { >+ // Limits the quotient to the range of int64_t. >+ if (quotient128 > uint128(static_cast<uint64_t>(kint64max))) { >+ quotient128 = quotient_neg ? uint128(static_cast<uint64_t>(kint64min)) >+ : uint128(static_cast<uint64_t>(kint64max)); >+ } >+ } >+ >+ const uint128 remainder128 = a - quotient128 * b; >+ *rem = MakeDurationFromU128(remainder128, num_neg); >+ >+ if (!quotient_neg || quotient128 == 0) { >+ return Uint128Low64(quotient128) & kint64max; >+ } >+ // The quotient needs to be negated, but we need to carefully handle >+ // quotient128s with the top bit on. >+ return -static_cast<int64_t>(Uint128Low64(quotient128 - 1) & kint64max) - 1; >+} >+ >+} // namespace time_internal >+ >+// >+// Additive operators. >+// >+ >+Duration& Duration::operator+=(Duration rhs) { >+ if (time_internal::IsInfiniteDuration(*this)) return *this; >+ if (time_internal::IsInfiniteDuration(rhs)) return *this = rhs; >+ const int64_t orig_rep_hi = rep_hi_; >+ rep_hi_ = >+ DecodeTwosComp(EncodeTwosComp(rep_hi_) + EncodeTwosComp(rhs.rep_hi_)); >+ if (rep_lo_ >= kTicksPerSecond - rhs.rep_lo_) { >+ rep_hi_ = DecodeTwosComp(EncodeTwosComp(rep_hi_) + 1); >+ rep_lo_ -= kTicksPerSecond; >+ } >+ rep_lo_ += rhs.rep_lo_; >+ if (rhs.rep_hi_ < 0 ? rep_hi_ > orig_rep_hi : rep_hi_ < orig_rep_hi) { >+ return *this = rhs.rep_hi_ < 0 ? -InfiniteDuration() : InfiniteDuration(); >+ } >+ return *this; >+} >+ >+Duration& Duration::operator-=(Duration rhs) { >+ if (time_internal::IsInfiniteDuration(*this)) return *this; >+ if (time_internal::IsInfiniteDuration(rhs)) { >+ return *this = rhs.rep_hi_ >= 0 ? -InfiniteDuration() : InfiniteDuration(); >+ } >+ const int64_t orig_rep_hi = rep_hi_; >+ rep_hi_ = >+ DecodeTwosComp(EncodeTwosComp(rep_hi_) - EncodeTwosComp(rhs.rep_hi_)); >+ if (rep_lo_ < rhs.rep_lo_) { >+ rep_hi_ = DecodeTwosComp(EncodeTwosComp(rep_hi_) - 1); >+ rep_lo_ += kTicksPerSecond; >+ } >+ rep_lo_ -= rhs.rep_lo_; >+ if (rhs.rep_hi_ < 0 ? rep_hi_ < orig_rep_hi : rep_hi_ > orig_rep_hi) { >+ return *this = rhs.rep_hi_ >= 0 ? -InfiniteDuration() : InfiniteDuration(); >+ } >+ return *this; >+} >+ >+// >+// Multiplicative operators. >+// >+ >+Duration& Duration::operator*=(int64_t r) { >+ if (time_internal::IsInfiniteDuration(*this)) { >+ const bool is_neg = (r < 0) != (rep_hi_ < 0); >+ return *this = is_neg ? -InfiniteDuration() : InfiniteDuration(); >+ } >+ return *this = ScaleFixed<SafeMultiply>(*this, r); >+} >+ >+Duration& Duration::operator*=(double r) { >+ if (time_internal::IsInfiniteDuration(*this) || !IsFinite(r)) { >+ const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0); >+ return *this = is_neg ? -InfiniteDuration() : InfiniteDuration(); >+ } >+ return *this = ScaleDouble<std::multiplies>(*this, r); >+} >+ >+Duration& Duration::operator/=(int64_t r) { >+ if (time_internal::IsInfiniteDuration(*this) || r == 0) { >+ const bool is_neg = (r < 0) != (rep_hi_ < 0); >+ return *this = is_neg ? -InfiniteDuration() : InfiniteDuration(); >+ } >+ return *this = ScaleFixed<std::divides>(*this, r); >+} >+ >+Duration& Duration::operator/=(double r) { >+ if (time_internal::IsInfiniteDuration(*this) || r == 0.0) { >+ const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0); >+ return *this = is_neg ? -InfiniteDuration() : InfiniteDuration(); >+ } >+ return *this = ScaleDouble<std::divides>(*this, r); >+} >+ >+Duration& Duration::operator%=(Duration rhs) { >+ time_internal::IDivDuration(false, *this, rhs, this); >+ return *this; >+} >+ >+double FDivDuration(Duration num, Duration den) { >+ // Arithmetic with infinity is sticky. >+ if (time_internal::IsInfiniteDuration(num) || den == ZeroDuration()) { >+ return (num < ZeroDuration()) == (den < ZeroDuration()) >+ ? std::numeric_limits<double>::infinity() >+ : -std::numeric_limits<double>::infinity(); >+ } >+ if (time_internal::IsInfiniteDuration(den)) return 0.0; >+ >+ double a = >+ static_cast<double>(time_internal::GetRepHi(num)) * kTicksPerSecond + >+ time_internal::GetRepLo(num); >+ double b = >+ static_cast<double>(time_internal::GetRepHi(den)) * kTicksPerSecond + >+ time_internal::GetRepLo(den); >+ return a / b; >+} >+ >+// >+// Trunc/Floor/Ceil. >+// >+ >+Duration Trunc(Duration d, Duration unit) { >+ return d - (d % unit); >+} >+ >+Duration Floor(const Duration d, const Duration unit) { >+ const absl::Duration td = Trunc(d, unit); >+ return td <= d ? td : td - AbsDuration(unit); >+} >+ >+Duration Ceil(const Duration d, const Duration unit) { >+ const absl::Duration td = Trunc(d, unit); >+ return td >= d ? td : td + AbsDuration(unit); >+} >+ >+// >+// Factory functions. >+// >+ >+Duration DurationFromTimespec(timespec ts) { >+ if (static_cast<uint64_t>(ts.tv_nsec) < 1000 * 1000 * 1000) { >+ int64_t ticks = ts.tv_nsec * kTicksPerNanosecond; >+ return time_internal::MakeDuration(ts.tv_sec, ticks); >+ } >+ return Seconds(ts.tv_sec) + Nanoseconds(ts.tv_nsec); >+} >+ >+Duration DurationFromTimeval(timeval tv) { >+ if (static_cast<uint64_t>(tv.tv_usec) < 1000 * 1000) { >+ int64_t ticks = tv.tv_usec * 1000 * kTicksPerNanosecond; >+ return time_internal::MakeDuration(tv.tv_sec, ticks); >+ } >+ return Seconds(tv.tv_sec) + Microseconds(tv.tv_usec); >+} >+ >+// >+// Conversion to other duration types. >+// >+ >+int64_t ToInt64Nanoseconds(Duration d) { >+ if (time_internal::GetRepHi(d) >= 0 && >+ time_internal::GetRepHi(d) >> 33 == 0) { >+ return (time_internal::GetRepHi(d) * 1000 * 1000 * 1000) + >+ (time_internal::GetRepLo(d) / kTicksPerNanosecond); >+ } >+ return d / Nanoseconds(1); >+} >+int64_t ToInt64Microseconds(Duration d) { >+ if (time_internal::GetRepHi(d) >= 0 && >+ time_internal::GetRepHi(d) >> 43 == 0) { >+ return (time_internal::GetRepHi(d) * 1000 * 1000) + >+ (time_internal::GetRepLo(d) / (kTicksPerNanosecond * 1000)); >+ } >+ return d / Microseconds(1); >+} >+int64_t ToInt64Milliseconds(Duration d) { >+ if (time_internal::GetRepHi(d) >= 0 && >+ time_internal::GetRepHi(d) >> 53 == 0) { >+ return (time_internal::GetRepHi(d) * 1000) + >+ (time_internal::GetRepLo(d) / (kTicksPerNanosecond * 1000 * 1000)); >+ } >+ return d / Milliseconds(1); >+} >+int64_t ToInt64Seconds(Duration d) { >+ int64_t hi = time_internal::GetRepHi(d); >+ if (time_internal::IsInfiniteDuration(d)) return hi; >+ if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi; >+ return hi; >+} >+int64_t ToInt64Minutes(Duration d) { >+ int64_t hi = time_internal::GetRepHi(d); >+ if (time_internal::IsInfiniteDuration(d)) return hi; >+ if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi; >+ return hi / 60; >+} >+int64_t ToInt64Hours(Duration d) { >+ int64_t hi = time_internal::GetRepHi(d); >+ if (time_internal::IsInfiniteDuration(d)) return hi; >+ if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi; >+ return hi / (60 * 60); >+} >+ >+double ToDoubleNanoseconds(Duration d) { >+ return FDivDuration(d, Nanoseconds(1)); >+} >+double ToDoubleMicroseconds(Duration d) { >+ return FDivDuration(d, Microseconds(1)); >+} >+double ToDoubleMilliseconds(Duration d) { >+ return FDivDuration(d, Milliseconds(1)); >+} >+double ToDoubleSeconds(Duration d) { >+ return FDivDuration(d, Seconds(1)); >+} >+double ToDoubleMinutes(Duration d) { >+ return FDivDuration(d, Minutes(1)); >+} >+double ToDoubleHours(Duration d) { >+ return FDivDuration(d, Hours(1)); >+} >+ >+timespec ToTimespec(Duration d) { >+ timespec ts; >+ if (!time_internal::IsInfiniteDuration(d)) { >+ int64_t rep_hi = time_internal::GetRepHi(d); >+ uint32_t rep_lo = time_internal::GetRepLo(d); >+ if (rep_hi < 0) { >+ // Tweak the fields so that unsigned division of rep_lo >+ // maps to truncation (towards zero) for the timespec. >+ rep_lo += kTicksPerNanosecond - 1; >+ if (rep_lo >= kTicksPerSecond) { >+ rep_hi += 1; >+ rep_lo -= kTicksPerSecond; >+ } >+ } >+ ts.tv_sec = rep_hi; >+ if (ts.tv_sec == rep_hi) { // no time_t narrowing >+ ts.tv_nsec = rep_lo / kTicksPerNanosecond; >+ return ts; >+ } >+ } >+ if (d >= ZeroDuration()) { >+ ts.tv_sec = std::numeric_limits<time_t>::max(); >+ ts.tv_nsec = 1000 * 1000 * 1000 - 1; >+ } else { >+ ts.tv_sec = std::numeric_limits<time_t>::min(); >+ ts.tv_nsec = 0; >+ } >+ return ts; >+} >+ >+timeval ToTimeval(Duration d) { >+ timeval tv; >+ timespec ts = ToTimespec(d); >+ if (ts.tv_sec < 0) { >+ // Tweak the fields so that positive division of tv_nsec >+ // maps to truncation (towards zero) for the timeval. >+ ts.tv_nsec += 1000 - 1; >+ if (ts.tv_nsec >= 1000 * 1000 * 1000) { >+ ts.tv_sec += 1; >+ ts.tv_nsec -= 1000 * 1000 * 1000; >+ } >+ } >+ tv.tv_sec = ts.tv_sec; >+ if (tv.tv_sec != ts.tv_sec) { // narrowing >+ if (ts.tv_sec < 0) { >+ tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::min(); >+ tv.tv_usec = 0; >+ } else { >+ tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::max(); >+ tv.tv_usec = 1000 * 1000 - 1; >+ } >+ return tv; >+ } >+ tv.tv_usec = static_cast<int>(ts.tv_nsec / 1000); // suseconds_t >+ return tv; >+} >+ >+std::chrono::nanoseconds ToChronoNanoseconds(Duration d) { >+ return time_internal::ToChronoDuration<std::chrono::nanoseconds>(d); >+} >+std::chrono::microseconds ToChronoMicroseconds(Duration d) { >+ return time_internal::ToChronoDuration<std::chrono::microseconds>(d); >+} >+std::chrono::milliseconds ToChronoMilliseconds(Duration d) { >+ return time_internal::ToChronoDuration<std::chrono::milliseconds>(d); >+} >+std::chrono::seconds ToChronoSeconds(Duration d) { >+ return time_internal::ToChronoDuration<std::chrono::seconds>(d); >+} >+std::chrono::minutes ToChronoMinutes(Duration d) { >+ return time_internal::ToChronoDuration<std::chrono::minutes>(d); >+} >+std::chrono::hours ToChronoHours(Duration d) { >+ return time_internal::ToChronoDuration<std::chrono::hours>(d); >+} >+ >+// >+// To/From std::string formatting. >+// >+ >+namespace { >+ >+// Formats a positive 64-bit integer in the given field width. Note that >+// it is up to the caller of Format64() to ensure that there is sufficient >+// space before ep to hold the conversion. >+char* Format64(char* ep, int width, int64_t v) { >+ do { >+ --width; >+ *--ep = '0' + (v % 10); // contiguous digits >+ } while (v /= 10); >+ while (--width >= 0) *--ep = '0'; // zero pad >+ return ep; >+} >+ >+// Helpers for FormatDuration() that format 'n' and append it to 'out' >+// followed by the given 'unit'. If 'n' formats to "0", nothing is >+// appended (not even the unit). >+ >+// A type that encapsulates how to display a value of a particular unit. For >+// values that are displayed with fractional parts, the precision indicates >+// where to round the value. The precision varies with the display unit because >+// a Duration can hold only quarters of a nanosecond, so displaying information >+// beyond that is just noise. >+// >+// For example, a microsecond value of 42.00025xxxxx should not display beyond 5 >+// fractional digits, because it is in the noise of what a Duration can >+// represent. >+struct DisplayUnit { >+ const char* abbr; >+ int prec; >+ double pow10; >+}; >+const DisplayUnit kDisplayNano = {"ns", 2, 1e2}; >+const DisplayUnit kDisplayMicro = {"us", 5, 1e5}; >+const DisplayUnit kDisplayMilli = {"ms", 8, 1e8}; >+const DisplayUnit kDisplaySec = {"s", 11, 1e11}; >+const DisplayUnit kDisplayMin = {"m", -1, 0.0}; // prec ignored >+const DisplayUnit kDisplayHour = {"h", -1, 0.0}; // prec ignored >+ >+void AppendNumberUnit(std::string* out, int64_t n, DisplayUnit unit) { >+ char buf[sizeof("2562047788015216")]; // hours in max duration >+ char* const ep = buf + sizeof(buf); >+ char* bp = Format64(ep, 0, n); >+ if (*bp != '0' || bp + 1 != ep) { >+ out->append(bp, ep - bp); >+ out->append(unit.abbr); >+ } >+} >+ >+// Note: unit.prec is limited to double's digits10 value (typically 15) so it >+// always fits in buf[]. >+void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) { >+ const int buf_size = std::numeric_limits<double>::digits10; >+ const int prec = std::min(buf_size, unit.prec); >+ char buf[buf_size]; // also large enough to hold integer part >+ char* ep = buf + sizeof(buf); >+ double d = 0; >+ int64_t frac_part = Round(std::modf(n, &d) * unit.pow10); >+ int64_t int_part = d; >+ if (int_part != 0 || frac_part != 0) { >+ char* bp = Format64(ep, 0, int_part); // always < 1000 >+ out->append(bp, ep - bp); >+ if (frac_part != 0) { >+ out->push_back('.'); >+ bp = Format64(ep, prec, frac_part); >+ while (ep[-1] == '0') --ep; >+ out->append(bp, ep - bp); >+ } >+ out->append(unit.abbr); >+ } >+} >+ >+} // namespace >+ >+// From Go's doc at http://golang.org/pkg/time/#Duration.String >+// [FormatDuration] returns a std::string representing the duration in the >+// form "72h3m0.5s". Leading zero units are omitted. As a special >+// case, durations less than one second format use a smaller unit >+// (milli-, micro-, or nanoseconds) to ensure that the leading digit >+// is non-zero. The zero duration formats as 0, with no unit. >+std::string FormatDuration(Duration d) { >+ const Duration min_duration = Seconds(kint64min); >+ if (d == min_duration) { >+ // Avoid needing to negate kint64min by directly returning what the >+ // following code should produce in that case. >+ return "-2562047788015215h30m8s"; >+ } >+ std::string s; >+ if (d < ZeroDuration()) { >+ s.append("-"); >+ d = -d; >+ } >+ if (d == InfiniteDuration()) { >+ s.append("inf"); >+ } else if (d < Seconds(1)) { >+ // Special case for durations with a magnitude < 1 second. The duration >+ // is printed as a fraction of a single unit, e.g., "1.2ms". >+ if (d < Microseconds(1)) { >+ AppendNumberUnit(&s, FDivDuration(d, Nanoseconds(1)), kDisplayNano); >+ } else if (d < Milliseconds(1)) { >+ AppendNumberUnit(&s, FDivDuration(d, Microseconds(1)), kDisplayMicro); >+ } else { >+ AppendNumberUnit(&s, FDivDuration(d, Milliseconds(1)), kDisplayMilli); >+ } >+ } else { >+ AppendNumberUnit(&s, IDivDuration(d, Hours(1), &d), kDisplayHour); >+ AppendNumberUnit(&s, IDivDuration(d, Minutes(1), &d), kDisplayMin); >+ AppendNumberUnit(&s, FDivDuration(d, Seconds(1)), kDisplaySec); >+ } >+ if (s.empty() || s == "-") { >+ s = "0"; >+ } >+ return s; >+} >+ >+namespace { >+ >+// A helper for ParseDuration() that parses a leading number from the given >+// std::string and stores the result in *int_part/*frac_part/*frac_scale. The >+// given std::string pointer is modified to point to the first unconsumed char. >+bool ConsumeDurationNumber(const char** dpp, int64_t* int_part, >+ int64_t* frac_part, int64_t* frac_scale) { >+ *int_part = 0; >+ *frac_part = 0; >+ *frac_scale = 1; // invariant: *frac_part < *frac_scale >+ const char* start = *dpp; >+ for (; std::isdigit(**dpp); *dpp += 1) { >+ const int d = **dpp - '0'; // contiguous digits >+ if (*int_part > kint64max / 10) return false; >+ *int_part *= 10; >+ if (*int_part > kint64max - d) return false; >+ *int_part += d; >+ } >+ const bool int_part_empty = (*dpp == start); >+ if (**dpp != '.') return !int_part_empty; >+ for (*dpp += 1; std::isdigit(**dpp); *dpp += 1) { >+ const int d = **dpp - '0'; // contiguous digits >+ if (*frac_scale <= kint64max / 10) { >+ *frac_part *= 10; >+ *frac_part += d; >+ *frac_scale *= 10; >+ } >+ } >+ return !int_part_empty || *frac_scale != 1; >+} >+ >+// A helper for ParseDuration() that parses a leading unit designator (e.g., >+// ns, us, ms, s, m, h) from the given std::string and stores the resulting unit >+// in "*unit". The given std::string pointer is modified to point to the first >+// unconsumed char. >+bool ConsumeDurationUnit(const char** start, Duration* unit) { >+ const char *s = *start; >+ bool ok = true; >+ if (strncmp(s, "ns", 2) == 0) { >+ s += 2; >+ *unit = Nanoseconds(1); >+ } else if (strncmp(s, "us", 2) == 0) { >+ s += 2; >+ *unit = Microseconds(1); >+ } else if (strncmp(s, "ms", 2) == 0) { >+ s += 2; >+ *unit = Milliseconds(1); >+ } else if (strncmp(s, "s", 1) == 0) { >+ s += 1; >+ *unit = Seconds(1); >+ } else if (strncmp(s, "m", 1) == 0) { >+ s += 1; >+ *unit = Minutes(1); >+ } else if (strncmp(s, "h", 1) == 0) { >+ s += 1; >+ *unit = Hours(1); >+ } else { >+ ok = false; >+ } >+ *start = s; >+ return ok; >+} >+ >+} // namespace >+ >+// From Go's doc at http://golang.org/pkg/time/#ParseDuration >+// [ParseDuration] parses a duration std::string. A duration std::string is >+// a possibly signed sequence of decimal numbers, each with optional >+// fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". >+// Valid time units are "ns", "us" "ms", "s", "m", "h". >+bool ParseDuration(const std::string& dur_string, Duration* d) { >+ const char* start = dur_string.c_str(); >+ int sign = 1; >+ >+ if (*start == '-' || *start == '+') { >+ sign = *start == '-' ? -1 : 1; >+ ++start; >+ } >+ >+ // Can't parse a duration from an empty std::string. >+ if (*start == '\0') { >+ return false; >+ } >+ >+ // Special case for a std::string of "0". >+ if (*start == '0' && *(start + 1) == '\0') { >+ *d = ZeroDuration(); >+ return true; >+ } >+ >+ if (strcmp(start, "inf") == 0) { >+ *d = sign * InfiniteDuration(); >+ return true; >+ } >+ >+ Duration dur; >+ while (*start != '\0') { >+ int64_t int_part; >+ int64_t frac_part; >+ int64_t frac_scale; >+ Duration unit; >+ if (!ConsumeDurationNumber(&start, &int_part, &frac_part, &frac_scale) || >+ !ConsumeDurationUnit(&start, &unit)) { >+ return false; >+ } >+ if (int_part != 0) dur += sign * int_part * unit; >+ if (frac_part != 0) dur += sign * frac_part * unit / frac_scale; >+ } >+ *d = dur; >+ return true; >+} >+bool ParseFlag(const std::string& text, Duration* dst, std::string* ) { >+ return ParseDuration(text, dst); >+} >+ >+std::string UnparseFlag(Duration d) { return FormatDuration(d); } >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/duration_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/duration_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..d5657bd576a5b3eaefc84052039a7f3921b57fb7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/duration_benchmark.cc >@@ -0,0 +1,427 @@ >+// Copyright 2018 The Abseil Authors. >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <cmath> >+#include <cstddef> >+#include <cstdint> >+#include <ctime> >+#include <string> >+ >+#include "absl/time/time.h" >+#include "benchmark/benchmark.h" >+ >+namespace { >+ >+// >+// Factory functions >+// >+ >+void BM_Duration_Factory_Nanoseconds(benchmark::State& state) { >+ int64_t i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Nanoseconds(i)); >+ i += 314159; >+ } >+} >+BENCHMARK(BM_Duration_Factory_Nanoseconds); >+ >+void BM_Duration_Factory_Microseconds(benchmark::State& state) { >+ int64_t i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Microseconds(i)); >+ i += 314; >+ } >+} >+BENCHMARK(BM_Duration_Factory_Microseconds); >+ >+void BM_Duration_Factory_Milliseconds(benchmark::State& state) { >+ int64_t i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Milliseconds(i)); >+ i += 1; >+ } >+} >+BENCHMARK(BM_Duration_Factory_Milliseconds); >+ >+void BM_Duration_Factory_Seconds(benchmark::State& state) { >+ int64_t i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Seconds(i)); >+ i += 1; >+ } >+} >+BENCHMARK(BM_Duration_Factory_Seconds); >+ >+void BM_Duration_Factory_Minutes(benchmark::State& state) { >+ int64_t i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Minutes(i)); >+ i += 1; >+ } >+} >+BENCHMARK(BM_Duration_Factory_Minutes); >+ >+void BM_Duration_Factory_Hours(benchmark::State& state) { >+ int64_t i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Hours(i)); >+ i += 1; >+ } >+} >+BENCHMARK(BM_Duration_Factory_Hours); >+ >+void BM_Duration_Factory_DoubleNanoseconds(benchmark::State& state) { >+ double d = 1; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Nanoseconds(d)); >+ d = d * 1.00000001 + 1; >+ } >+} >+BENCHMARK(BM_Duration_Factory_DoubleNanoseconds); >+ >+void BM_Duration_Factory_DoubleMicroseconds(benchmark::State& state) { >+ double d = 1e-3; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Microseconds(d)); >+ d = d * 1.00000001 + 1e-3; >+ } >+} >+BENCHMARK(BM_Duration_Factory_DoubleMicroseconds); >+ >+void BM_Duration_Factory_DoubleMilliseconds(benchmark::State& state) { >+ double d = 1e-6; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Milliseconds(d)); >+ d = d * 1.00000001 + 1e-6; >+ } >+} >+BENCHMARK(BM_Duration_Factory_DoubleMilliseconds); >+ >+void BM_Duration_Factory_DoubleSeconds(benchmark::State& state) { >+ double d = 1e-9; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Seconds(d)); >+ d = d * 1.00000001 + 1e-9; >+ } >+} >+BENCHMARK(BM_Duration_Factory_DoubleSeconds); >+ >+void BM_Duration_Factory_DoubleMinutes(benchmark::State& state) { >+ double d = 1e-9; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Minutes(d)); >+ d = d * 1.00000001 + 1e-9; >+ } >+} >+BENCHMARK(BM_Duration_Factory_DoubleMinutes); >+ >+void BM_Duration_Factory_DoubleHours(benchmark::State& state) { >+ double d = 1e-9; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::Hours(d)); >+ d = d * 1.00000001 + 1e-9; >+ } >+} >+BENCHMARK(BM_Duration_Factory_DoubleHours); >+ >+// >+// Arithmetic >+// >+ >+void BM_Duration_Addition(benchmark::State& state) { >+ absl::Duration d = absl::Nanoseconds(1); >+ absl::Duration step = absl::Milliseconds(1); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(d += step); >+ } >+} >+BENCHMARK(BM_Duration_Addition); >+ >+void BM_Duration_Subtraction(benchmark::State& state) { >+ absl::Duration d = absl::Seconds(std::numeric_limits<int64_t>::max()); >+ absl::Duration step = absl::Milliseconds(1); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(d -= step); >+ } >+} >+BENCHMARK(BM_Duration_Subtraction); >+ >+void BM_Duration_Multiplication_Fixed(benchmark::State& state) { >+ absl::Duration d = absl::Milliseconds(1); >+ absl::Duration s; >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(s += d * (i + 1)); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_Multiplication_Fixed); >+ >+void BM_Duration_Multiplication_Double(benchmark::State& state) { >+ absl::Duration d = absl::Milliseconds(1); >+ absl::Duration s; >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(s += d * (i + 1.0)); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_Multiplication_Double); >+ >+void BM_Duration_Division_Fixed(benchmark::State& state) { >+ absl::Duration d = absl::Seconds(1); >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(d /= i + 1); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_Division_Fixed); >+ >+void BM_Duration_Division_Double(benchmark::State& state) { >+ absl::Duration d = absl::Seconds(1); >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(d /= i + 1.0); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_Division_Double); >+ >+void BM_Duration_FDivDuration_Nanoseconds(benchmark::State& state) { >+ double d = 1; >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize( >+ d += absl::FDivDuration(absl::Milliseconds(i), absl::Nanoseconds(1))); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_FDivDuration_Nanoseconds); >+ >+void BM_Duration_IDivDuration_Nanoseconds(benchmark::State& state) { >+ int64_t a = 1; >+ absl::Duration ignore; >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(a += >+ absl::IDivDuration(absl::Nanoseconds(i), >+ absl::Nanoseconds(1), &ignore)); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_IDivDuration_Nanoseconds); >+ >+void BM_Duration_IDivDuration_Microseconds(benchmark::State& state) { >+ int64_t a = 1; >+ absl::Duration ignore; >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(a += absl::IDivDuration(absl::Microseconds(i), >+ absl::Microseconds(1), >+ &ignore)); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_IDivDuration_Microseconds); >+ >+void BM_Duration_IDivDuration_Milliseconds(benchmark::State& state) { >+ int64_t a = 1; >+ absl::Duration ignore; >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(a += absl::IDivDuration(absl::Milliseconds(i), >+ absl::Milliseconds(1), >+ &ignore)); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_IDivDuration_Milliseconds); >+ >+void BM_Duration_IDivDuration_Seconds(benchmark::State& state) { >+ int64_t a = 1; >+ absl::Duration ignore; >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize( >+ a += absl::IDivDuration(absl::Seconds(i), absl::Seconds(1), &ignore)); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_IDivDuration_Seconds); >+ >+void BM_Duration_IDivDuration_Minutes(benchmark::State& state) { >+ int64_t a = 1; >+ absl::Duration ignore; >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize( >+ a += absl::IDivDuration(absl::Minutes(i), absl::Minutes(1), &ignore)); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_IDivDuration_Minutes); >+ >+void BM_Duration_IDivDuration_Hours(benchmark::State& state) { >+ int64_t a = 1; >+ absl::Duration ignore; >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize( >+ a += absl::IDivDuration(absl::Hours(i), absl::Hours(1), &ignore)); >+ ++i; >+ } >+} >+BENCHMARK(BM_Duration_IDivDuration_Hours); >+ >+void BM_Duration_ToInt64Nanoseconds(benchmark::State& state) { >+ absl::Duration d = absl::Seconds(100000); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ToInt64Nanoseconds(d)); >+ } >+} >+BENCHMARK(BM_Duration_ToInt64Nanoseconds); >+ >+void BM_Duration_ToInt64Microseconds(benchmark::State& state) { >+ absl::Duration d = absl::Seconds(100000); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ToInt64Microseconds(d)); >+ } >+} >+BENCHMARK(BM_Duration_ToInt64Microseconds); >+ >+void BM_Duration_ToInt64Milliseconds(benchmark::State& state) { >+ absl::Duration d = absl::Seconds(100000); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ToInt64Milliseconds(d)); >+ } >+} >+BENCHMARK(BM_Duration_ToInt64Milliseconds); >+ >+void BM_Duration_ToInt64Seconds(benchmark::State& state) { >+ absl::Duration d = absl::Seconds(100000); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ToInt64Seconds(d)); >+ } >+} >+BENCHMARK(BM_Duration_ToInt64Seconds); >+ >+void BM_Duration_ToInt64Minutes(benchmark::State& state) { >+ absl::Duration d = absl::Seconds(100000); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ToInt64Minutes(d)); >+ } >+} >+BENCHMARK(BM_Duration_ToInt64Minutes); >+ >+void BM_Duration_ToInt64Hours(benchmark::State& state) { >+ absl::Duration d = absl::Seconds(100000); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ToInt64Hours(d)); >+ } >+} >+BENCHMARK(BM_Duration_ToInt64Hours); >+ >+// >+// To/FromTimespec >+// >+ >+void BM_Duration_ToTimespec_AbslTime(benchmark::State& state) { >+ absl::Duration d = absl::Seconds(1); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ToTimespec(d)); >+ } >+} >+BENCHMARK(BM_Duration_ToTimespec_AbslTime); >+ >+ABSL_ATTRIBUTE_NOINLINE timespec DoubleToTimespec(double seconds) { >+ timespec ts; >+ ts.tv_sec = seconds; >+ ts.tv_nsec = (seconds - ts.tv_sec) * (1000 * 1000 * 1000); >+ return ts; >+} >+ >+void BM_Duration_ToTimespec_Double(benchmark::State& state) { >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(DoubleToTimespec(1.0)); >+ } >+} >+BENCHMARK(BM_Duration_ToTimespec_Double); >+ >+void BM_Duration_FromTimespec_AbslTime(benchmark::State& state) { >+ timespec ts; >+ ts.tv_sec = 0; >+ ts.tv_nsec = 0; >+ while (state.KeepRunning()) { >+ if (++ts.tv_nsec == 1000 * 1000 * 1000) { >+ ++ts.tv_sec; >+ ts.tv_nsec = 0; >+ } >+ benchmark::DoNotOptimize(absl::DurationFromTimespec(ts)); >+ } >+} >+BENCHMARK(BM_Duration_FromTimespec_AbslTime); >+ >+ABSL_ATTRIBUTE_NOINLINE double TimespecToDouble(timespec ts) { >+ return ts.tv_sec + (ts.tv_nsec / (1000 * 1000 * 1000)); >+} >+ >+void BM_Duration_FromTimespec_Double(benchmark::State& state) { >+ timespec ts; >+ ts.tv_sec = 0; >+ ts.tv_nsec = 0; >+ while (state.KeepRunning()) { >+ if (++ts.tv_nsec == 1000 * 1000 * 1000) { >+ ++ts.tv_sec; >+ ts.tv_nsec = 0; >+ } >+ benchmark::DoNotOptimize(TimespecToDouble(ts)); >+ } >+} >+BENCHMARK(BM_Duration_FromTimespec_Double); >+ >+// >+// String conversions >+// >+ >+const char* const kDurations[] = { >+ "0", // 0 >+ "123ns", // 1 >+ "1h2m3s", // 2 >+ "-2h3m4.005006007s", // 3 >+ "2562047788015215h30m7.99999999975s", // 4 >+}; >+const int kNumDurations = sizeof(kDurations) / sizeof(kDurations[0]); >+ >+void BM_Duration_FormatDuration(benchmark::State& state) { >+ const std::string s = kDurations[state.range(0)]; >+ state.SetLabel(s); >+ absl::Duration d; >+ absl::ParseDuration(kDurations[state.range(0)], &d); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::FormatDuration(d)); >+ } >+} >+BENCHMARK(BM_Duration_FormatDuration)->DenseRange(0, kNumDurations - 1); >+ >+void BM_Duration_ParseDuration(benchmark::State& state) { >+ const std::string s = kDurations[state.range(0)]; >+ state.SetLabel(s); >+ absl::Duration d; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ParseDuration(s, &d)); >+ } >+} >+BENCHMARK(BM_Duration_ParseDuration)->DenseRange(0, kNumDurations - 1); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/duration_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/duration_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..7ae25dc68f9a622128a4e4e889c0c6ffd2dff649 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/duration_test.cc >@@ -0,0 +1,1764 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <chrono> // NOLINT(build/c++11) >+#include <cmath> >+#include <cstdint> >+#include <ctime> >+#include <iomanip> >+#include <limits> >+#include <random> >+#include <string> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/time/time.h" >+ >+namespace { >+ >+constexpr int64_t kint64max = std::numeric_limits<int64_t>::max(); >+constexpr int64_t kint64min = std::numeric_limits<int64_t>::min(); >+ >+// Approximates the given number of years. This is only used to make some test >+// code more readable. >+absl::Duration ApproxYears(int64_t n) { return absl::Hours(n) * 365 * 24; } >+ >+// A gMock matcher to match timespec values. Use this matcher like: >+// timespec ts1, ts2; >+// EXPECT_THAT(ts1, TimespecMatcher(ts2)); >+MATCHER_P(TimespecMatcher, ts, "") { >+ if (ts.tv_sec == arg.tv_sec && ts.tv_nsec == arg.tv_nsec) >+ return true; >+ *result_listener << "expected: {" << ts.tv_sec << ", " << ts.tv_nsec << "} "; >+ *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_nsec << "}"; >+ return false; >+} >+ >+// A gMock matcher to match timeval values. Use this matcher like: >+// timeval tv1, tv2; >+// EXPECT_THAT(tv1, TimevalMatcher(tv2)); >+MATCHER_P(TimevalMatcher, tv, "") { >+ if (tv.tv_sec == arg.tv_sec && tv.tv_usec == arg.tv_usec) >+ return true; >+ *result_listener << "expected: {" << tv.tv_sec << ", " << tv.tv_usec << "} "; >+ *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_usec << "}"; >+ return false; >+} >+ >+TEST(Duration, ValueSemantics) { >+ // If this compiles, the test passes. >+ constexpr absl::Duration a; // Default construction >+ constexpr absl::Duration b = a; // Copy construction >+ constexpr absl::Duration c(b); // Copy construction (again) >+ >+ absl::Duration d; >+ d = c; // Assignment >+} >+ >+TEST(Duration, Factories) { >+ constexpr absl::Duration zero = absl::ZeroDuration(); >+ constexpr absl::Duration nano = absl::Nanoseconds(1); >+ constexpr absl::Duration micro = absl::Microseconds(1); >+ constexpr absl::Duration milli = absl::Milliseconds(1); >+ constexpr absl::Duration sec = absl::Seconds(1); >+ constexpr absl::Duration min = absl::Minutes(1); >+ constexpr absl::Duration hour = absl::Hours(1); >+ >+ EXPECT_EQ(zero, absl::Duration()); >+ EXPECT_EQ(zero, absl::Seconds(0)); >+ EXPECT_EQ(nano, absl::Nanoseconds(1)); >+ EXPECT_EQ(micro, absl::Nanoseconds(1000)); >+ EXPECT_EQ(milli, absl::Microseconds(1000)); >+ EXPECT_EQ(sec, absl::Milliseconds(1000)); >+ EXPECT_EQ(min, absl::Seconds(60)); >+ EXPECT_EQ(hour, absl::Minutes(60)); >+ >+ // Tests factory limits >+ const absl::Duration inf = absl::InfiniteDuration(); >+ >+ EXPECT_GT(inf, absl::Seconds(kint64max)); >+ EXPECT_LT(-inf, absl::Seconds(kint64min)); >+ EXPECT_LT(-inf, absl::Seconds(-kint64max)); >+ >+ EXPECT_EQ(inf, absl::Minutes(kint64max)); >+ EXPECT_EQ(-inf, absl::Minutes(kint64min)); >+ EXPECT_EQ(-inf, absl::Minutes(-kint64max)); >+ EXPECT_GT(inf, absl::Minutes(kint64max / 60)); >+ EXPECT_LT(-inf, absl::Minutes(kint64min / 60)); >+ EXPECT_LT(-inf, absl::Minutes(-kint64max / 60)); >+ >+ EXPECT_EQ(inf, absl::Hours(kint64max)); >+ EXPECT_EQ(-inf, absl::Hours(kint64min)); >+ EXPECT_EQ(-inf, absl::Hours(-kint64max)); >+ EXPECT_GT(inf, absl::Hours(kint64max / 3600)); >+ EXPECT_LT(-inf, absl::Hours(kint64min / 3600)); >+ EXPECT_LT(-inf, absl::Hours(-kint64max / 3600)); >+} >+ >+TEST(Duration, ToConversion) { >+#define TEST_DURATION_CONVERSION(UNIT) \ >+ do { \ >+ const absl::Duration d = absl::UNIT(1.5); \ >+ constexpr absl::Duration z = absl::ZeroDuration(); \ >+ constexpr absl::Duration inf = absl::InfiniteDuration(); \ >+ constexpr double dbl_inf = std::numeric_limits<double>::infinity(); \ >+ EXPECT_EQ(kint64min, absl::ToInt64##UNIT(-inf)); \ >+ EXPECT_EQ(-1, absl::ToInt64##UNIT(-d)); \ >+ EXPECT_EQ(0, absl::ToInt64##UNIT(z)); \ >+ EXPECT_EQ(1, absl::ToInt64##UNIT(d)); \ >+ EXPECT_EQ(kint64max, absl::ToInt64##UNIT(inf)); \ >+ EXPECT_EQ(-dbl_inf, absl::ToDouble##UNIT(-inf)); \ >+ EXPECT_EQ(-1.5, absl::ToDouble##UNIT(-d)); \ >+ EXPECT_EQ(0, absl::ToDouble##UNIT(z)); \ >+ EXPECT_EQ(1.5, absl::ToDouble##UNIT(d)); \ >+ EXPECT_EQ(dbl_inf, absl::ToDouble##UNIT(inf)); \ >+ } while (0) >+ >+ TEST_DURATION_CONVERSION(Nanoseconds); >+ TEST_DURATION_CONVERSION(Microseconds); >+ TEST_DURATION_CONVERSION(Milliseconds); >+ TEST_DURATION_CONVERSION(Seconds); >+ TEST_DURATION_CONVERSION(Minutes); >+ TEST_DURATION_CONVERSION(Hours); >+ >+#undef TEST_DURATION_CONVERSION >+} >+ >+template <int64_t N> >+void TestToConversion() { >+ constexpr absl::Duration nano = absl::Nanoseconds(N); >+ EXPECT_EQ(N, absl::ToInt64Nanoseconds(nano)); >+ EXPECT_EQ(0, absl::ToInt64Microseconds(nano)); >+ EXPECT_EQ(0, absl::ToInt64Milliseconds(nano)); >+ EXPECT_EQ(0, absl::ToInt64Seconds(nano)); >+ EXPECT_EQ(0, absl::ToInt64Minutes(nano)); >+ EXPECT_EQ(0, absl::ToInt64Hours(nano)); >+ const absl::Duration micro = absl::Microseconds(N); >+ EXPECT_EQ(N * 1000, absl::ToInt64Nanoseconds(micro)); >+ EXPECT_EQ(N, absl::ToInt64Microseconds(micro)); >+ EXPECT_EQ(0, absl::ToInt64Milliseconds(micro)); >+ EXPECT_EQ(0, absl::ToInt64Seconds(micro)); >+ EXPECT_EQ(0, absl::ToInt64Minutes(micro)); >+ EXPECT_EQ(0, absl::ToInt64Hours(micro)); >+ const absl::Duration milli = absl::Milliseconds(N); >+ EXPECT_EQ(N * 1000 * 1000, absl::ToInt64Nanoseconds(milli)); >+ EXPECT_EQ(N * 1000, absl::ToInt64Microseconds(milli)); >+ EXPECT_EQ(N, absl::ToInt64Milliseconds(milli)); >+ EXPECT_EQ(0, absl::ToInt64Seconds(milli)); >+ EXPECT_EQ(0, absl::ToInt64Minutes(milli)); >+ EXPECT_EQ(0, absl::ToInt64Hours(milli)); >+ const absl::Duration sec = absl::Seconds(N); >+ EXPECT_EQ(N * 1000 * 1000 * 1000, absl::ToInt64Nanoseconds(sec)); >+ EXPECT_EQ(N * 1000 * 1000, absl::ToInt64Microseconds(sec)); >+ EXPECT_EQ(N * 1000, absl::ToInt64Milliseconds(sec)); >+ EXPECT_EQ(N, absl::ToInt64Seconds(sec)); >+ EXPECT_EQ(0, absl::ToInt64Minutes(sec)); >+ EXPECT_EQ(0, absl::ToInt64Hours(sec)); >+ const absl::Duration min = absl::Minutes(N); >+ EXPECT_EQ(N * 60 * 1000 * 1000 * 1000, absl::ToInt64Nanoseconds(min)); >+ EXPECT_EQ(N * 60 * 1000 * 1000, absl::ToInt64Microseconds(min)); >+ EXPECT_EQ(N * 60 * 1000, absl::ToInt64Milliseconds(min)); >+ EXPECT_EQ(N * 60, absl::ToInt64Seconds(min)); >+ EXPECT_EQ(N, absl::ToInt64Minutes(min)); >+ EXPECT_EQ(0, absl::ToInt64Hours(min)); >+ const absl::Duration hour = absl::Hours(N); >+ EXPECT_EQ(N * 60 * 60 * 1000 * 1000 * 1000, absl::ToInt64Nanoseconds(hour)); >+ EXPECT_EQ(N * 60 * 60 * 1000 * 1000, absl::ToInt64Microseconds(hour)); >+ EXPECT_EQ(N * 60 * 60 * 1000, absl::ToInt64Milliseconds(hour)); >+ EXPECT_EQ(N * 60 * 60, absl::ToInt64Seconds(hour)); >+ EXPECT_EQ(N * 60, absl::ToInt64Minutes(hour)); >+ EXPECT_EQ(N, absl::ToInt64Hours(hour)); >+} >+ >+TEST(Duration, ToConversionDeprecated) { >+ TestToConversion<43>(); >+ TestToConversion<1>(); >+ TestToConversion<0>(); >+ TestToConversion<-1>(); >+ TestToConversion<-43>(); >+} >+ >+template <int64_t N> >+void TestFromChronoBasicEquality() { >+ using std::chrono::nanoseconds; >+ using std::chrono::microseconds; >+ using std::chrono::milliseconds; >+ using std::chrono::seconds; >+ using std::chrono::minutes; >+ using std::chrono::hours; >+ >+ static_assert(absl::Nanoseconds(N) == absl::FromChrono(nanoseconds(N)), ""); >+ static_assert(absl::Microseconds(N) == absl::FromChrono(microseconds(N)), ""); >+ static_assert(absl::Milliseconds(N) == absl::FromChrono(milliseconds(N)), ""); >+ static_assert(absl::Seconds(N) == absl::FromChrono(seconds(N)), ""); >+ static_assert(absl::Minutes(N) == absl::FromChrono(minutes(N)), ""); >+ static_assert(absl::Hours(N) == absl::FromChrono(hours(N)), ""); >+} >+ >+TEST(Duration, FromChrono) { >+ TestFromChronoBasicEquality<-123>(); >+ TestFromChronoBasicEquality<-1>(); >+ TestFromChronoBasicEquality<0>(); >+ TestFromChronoBasicEquality<1>(); >+ TestFromChronoBasicEquality<123>(); >+ >+ // Minutes (might, depending on the platform) saturate at +inf. >+ const auto chrono_minutes_max = std::chrono::minutes::max(); >+ const auto minutes_max = absl::FromChrono(chrono_minutes_max); >+ const int64_t minutes_max_count = chrono_minutes_max.count(); >+ if (minutes_max_count > kint64max / 60) { >+ EXPECT_EQ(absl::InfiniteDuration(), minutes_max); >+ } else { >+ EXPECT_EQ(absl::Minutes(minutes_max_count), minutes_max); >+ } >+ >+ // Minutes (might, depending on the platform) saturate at -inf. >+ const auto chrono_minutes_min = std::chrono::minutes::min(); >+ const auto minutes_min = absl::FromChrono(chrono_minutes_min); >+ const int64_t minutes_min_count = chrono_minutes_min.count(); >+ if (minutes_min_count < kint64min / 60) { >+ EXPECT_EQ(-absl::InfiniteDuration(), minutes_min); >+ } else { >+ EXPECT_EQ(absl::Minutes(minutes_min_count), minutes_min); >+ } >+ >+ // Hours (might, depending on the platform) saturate at +inf. >+ const auto chrono_hours_max = std::chrono::hours::max(); >+ const auto hours_max = absl::FromChrono(chrono_hours_max); >+ const int64_t hours_max_count = chrono_hours_max.count(); >+ if (hours_max_count > kint64max / 3600) { >+ EXPECT_EQ(absl::InfiniteDuration(), hours_max); >+ } else { >+ EXPECT_EQ(absl::Hours(hours_max_count), hours_max); >+ } >+ >+ // Hours (might, depending on the platform) saturate at -inf. >+ const auto chrono_hours_min = std::chrono::hours::min(); >+ const auto hours_min = absl::FromChrono(chrono_hours_min); >+ const int64_t hours_min_count = chrono_hours_min.count(); >+ if (hours_min_count < kint64min / 3600) { >+ EXPECT_EQ(-absl::InfiniteDuration(), hours_min); >+ } else { >+ EXPECT_EQ(absl::Hours(hours_min_count), hours_min); >+ } >+} >+ >+template <int64_t N> >+void TestToChrono() { >+ using std::chrono::nanoseconds; >+ using std::chrono::microseconds; >+ using std::chrono::milliseconds; >+ using std::chrono::seconds; >+ using std::chrono::minutes; >+ using std::chrono::hours; >+ >+ EXPECT_EQ(nanoseconds(N), absl::ToChronoNanoseconds(absl::Nanoseconds(N))); >+ EXPECT_EQ(microseconds(N), absl::ToChronoMicroseconds(absl::Microseconds(N))); >+ EXPECT_EQ(milliseconds(N), absl::ToChronoMilliseconds(absl::Milliseconds(N))); >+ EXPECT_EQ(seconds(N), absl::ToChronoSeconds(absl::Seconds(N))); >+ >+ constexpr auto absl_minutes = absl::Minutes(N); >+ auto chrono_minutes = minutes(N); >+ if (absl_minutes == -absl::InfiniteDuration()) { >+ chrono_minutes = minutes::min(); >+ } else if (absl_minutes == absl::InfiniteDuration()) { >+ chrono_minutes = minutes::max(); >+ } >+ EXPECT_EQ(chrono_minutes, absl::ToChronoMinutes(absl_minutes)); >+ >+ constexpr auto absl_hours = absl::Hours(N); >+ auto chrono_hours = hours(N); >+ if (absl_hours == -absl::InfiniteDuration()) { >+ chrono_hours = hours::min(); >+ } else if (absl_hours == absl::InfiniteDuration()) { >+ chrono_hours = hours::max(); >+ } >+ EXPECT_EQ(chrono_hours, absl::ToChronoHours(absl_hours)); >+} >+ >+TEST(Duration, ToChrono) { >+ using std::chrono::nanoseconds; >+ using std::chrono::microseconds; >+ using std::chrono::milliseconds; >+ using std::chrono::seconds; >+ using std::chrono::minutes; >+ using std::chrono::hours; >+ >+ TestToChrono<kint64min>(); >+ TestToChrono<-1>(); >+ TestToChrono<0>(); >+ TestToChrono<1>(); >+ TestToChrono<kint64max>(); >+ >+ // Verify truncation toward zero. >+ const auto tick = absl::Nanoseconds(1) / 4; >+ EXPECT_EQ(nanoseconds(0), absl::ToChronoNanoseconds(tick)); >+ EXPECT_EQ(nanoseconds(0), absl::ToChronoNanoseconds(-tick)); >+ EXPECT_EQ(microseconds(0), absl::ToChronoMicroseconds(tick)); >+ EXPECT_EQ(microseconds(0), absl::ToChronoMicroseconds(-tick)); >+ EXPECT_EQ(milliseconds(0), absl::ToChronoMilliseconds(tick)); >+ EXPECT_EQ(milliseconds(0), absl::ToChronoMilliseconds(-tick)); >+ EXPECT_EQ(seconds(0), absl::ToChronoSeconds(tick)); >+ EXPECT_EQ(seconds(0), absl::ToChronoSeconds(-tick)); >+ EXPECT_EQ(minutes(0), absl::ToChronoMinutes(tick)); >+ EXPECT_EQ(minutes(0), absl::ToChronoMinutes(-tick)); >+ EXPECT_EQ(hours(0), absl::ToChronoHours(tick)); >+ EXPECT_EQ(hours(0), absl::ToChronoHours(-tick)); >+ >+ // Verifies +/- infinity saturation at max/min. >+ constexpr auto inf = absl::InfiniteDuration(); >+ EXPECT_EQ(nanoseconds::min(), absl::ToChronoNanoseconds(-inf)); >+ EXPECT_EQ(nanoseconds::max(), absl::ToChronoNanoseconds(inf)); >+ EXPECT_EQ(microseconds::min(), absl::ToChronoMicroseconds(-inf)); >+ EXPECT_EQ(microseconds::max(), absl::ToChronoMicroseconds(inf)); >+ EXPECT_EQ(milliseconds::min(), absl::ToChronoMilliseconds(-inf)); >+ EXPECT_EQ(milliseconds::max(), absl::ToChronoMilliseconds(inf)); >+ EXPECT_EQ(seconds::min(), absl::ToChronoSeconds(-inf)); >+ EXPECT_EQ(seconds::max(), absl::ToChronoSeconds(inf)); >+ EXPECT_EQ(minutes::min(), absl::ToChronoMinutes(-inf)); >+ EXPECT_EQ(minutes::max(), absl::ToChronoMinutes(inf)); >+ EXPECT_EQ(hours::min(), absl::ToChronoHours(-inf)); >+ EXPECT_EQ(hours::max(), absl::ToChronoHours(inf)); >+} >+ >+TEST(Duration, FactoryOverloads) { >+ enum E { kOne = 1 }; >+#define TEST_FACTORY_OVERLOADS(NAME) \ >+ EXPECT_EQ(1, NAME(kOne) / NAME(kOne)); \ >+ EXPECT_EQ(1, NAME(static_cast<int8_t>(1)) / NAME(1)); \ >+ EXPECT_EQ(1, NAME(static_cast<int16_t>(1)) / NAME(1)); \ >+ EXPECT_EQ(1, NAME(static_cast<int32_t>(1)) / NAME(1)); \ >+ EXPECT_EQ(1, NAME(static_cast<int64_t>(1)) / NAME(1)); \ >+ EXPECT_EQ(1, NAME(static_cast<uint8_t>(1)) / NAME(1)); \ >+ EXPECT_EQ(1, NAME(static_cast<uint16_t>(1)) / NAME(1)); \ >+ EXPECT_EQ(1, NAME(static_cast<uint32_t>(1)) / NAME(1)); \ >+ EXPECT_EQ(1, NAME(static_cast<uint64_t>(1)) / NAME(1)); \ >+ EXPECT_EQ(NAME(1) / 2, NAME(static_cast<float>(0.5))); \ >+ EXPECT_EQ(NAME(1) / 2, NAME(static_cast<double>(0.5))); \ >+ EXPECT_EQ(1.5, absl::FDivDuration(NAME(static_cast<float>(1.5)), NAME(1))); \ >+ EXPECT_EQ(1.5, absl::FDivDuration(NAME(static_cast<double>(1.5)), NAME(1))); >+ >+ TEST_FACTORY_OVERLOADS(absl::Nanoseconds); >+ TEST_FACTORY_OVERLOADS(absl::Microseconds); >+ TEST_FACTORY_OVERLOADS(absl::Milliseconds); >+ TEST_FACTORY_OVERLOADS(absl::Seconds); >+ TEST_FACTORY_OVERLOADS(absl::Minutes); >+ TEST_FACTORY_OVERLOADS(absl::Hours); >+ >+#undef TEST_FACTORY_OVERLOADS >+ >+ EXPECT_EQ(absl::Milliseconds(1500), absl::Seconds(1.5)); >+ EXPECT_LT(absl::Nanoseconds(1), absl::Nanoseconds(1.5)); >+ EXPECT_GT(absl::Nanoseconds(2), absl::Nanoseconds(1.5)); >+ >+ const double dbl_inf = std::numeric_limits<double>::infinity(); >+ EXPECT_EQ(absl::InfiniteDuration(), absl::Nanoseconds(dbl_inf)); >+ EXPECT_EQ(absl::InfiniteDuration(), absl::Microseconds(dbl_inf)); >+ EXPECT_EQ(absl::InfiniteDuration(), absl::Milliseconds(dbl_inf)); >+ EXPECT_EQ(absl::InfiniteDuration(), absl::Seconds(dbl_inf)); >+ EXPECT_EQ(absl::InfiniteDuration(), absl::Minutes(dbl_inf)); >+ EXPECT_EQ(absl::InfiniteDuration(), absl::Hours(dbl_inf)); >+ EXPECT_EQ(-absl::InfiniteDuration(), absl::Nanoseconds(-dbl_inf)); >+ EXPECT_EQ(-absl::InfiniteDuration(), absl::Microseconds(-dbl_inf)); >+ EXPECT_EQ(-absl::InfiniteDuration(), absl::Milliseconds(-dbl_inf)); >+ EXPECT_EQ(-absl::InfiniteDuration(), absl::Seconds(-dbl_inf)); >+ EXPECT_EQ(-absl::InfiniteDuration(), absl::Minutes(-dbl_inf)); >+ EXPECT_EQ(-absl::InfiniteDuration(), absl::Hours(-dbl_inf)); >+} >+ >+TEST(Duration, InfinityExamples) { >+ // These examples are used in the documentation in time.h. They are >+ // written so that they can be copy-n-pasted easily. >+ >+ constexpr absl::Duration inf = absl::InfiniteDuration(); >+ constexpr absl::Duration d = absl::Seconds(1); // Any finite duration >+ >+ EXPECT_TRUE(inf == inf + inf); >+ EXPECT_TRUE(inf == inf + d); >+ EXPECT_TRUE(inf == inf - inf); >+ EXPECT_TRUE(-inf == d - inf); >+ >+ EXPECT_TRUE(inf == d * 1e100); >+ EXPECT_TRUE(0 == d / inf); // NOLINT(readability/check) >+ >+ // Division by zero returns infinity, or kint64min/MAX where necessary. >+ EXPECT_TRUE(inf == d / 0); >+ EXPECT_TRUE(kint64max == d / absl::ZeroDuration()); >+} >+ >+TEST(Duration, InfinityComparison) { >+ const absl::Duration inf = absl::InfiniteDuration(); >+ const absl::Duration any_dur = absl::Seconds(1); >+ >+ // Equality >+ EXPECT_EQ(inf, inf); >+ EXPECT_EQ(-inf, -inf); >+ EXPECT_NE(inf, -inf); >+ EXPECT_NE(any_dur, inf); >+ EXPECT_NE(any_dur, -inf); >+ >+ // Relational >+ EXPECT_GT(inf, any_dur); >+ EXPECT_LT(-inf, any_dur); >+ EXPECT_LT(-inf, inf); >+ EXPECT_GT(inf, -inf); >+} >+ >+TEST(Duration, InfinityAddition) { >+ const absl::Duration sec_max = absl::Seconds(kint64max); >+ const absl::Duration sec_min = absl::Seconds(kint64min); >+ const absl::Duration any_dur = absl::Seconds(1); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ >+ // Addition >+ EXPECT_EQ(inf, inf + inf); >+ EXPECT_EQ(inf, inf + -inf); >+ EXPECT_EQ(-inf, -inf + inf); >+ EXPECT_EQ(-inf, -inf + -inf); >+ >+ EXPECT_EQ(inf, inf + any_dur); >+ EXPECT_EQ(inf, any_dur + inf); >+ EXPECT_EQ(-inf, -inf + any_dur); >+ EXPECT_EQ(-inf, any_dur + -inf); >+ >+ // Interesting case >+ absl::Duration almost_inf = sec_max + absl::Nanoseconds(999999999); >+ EXPECT_GT(inf, almost_inf); >+ almost_inf += -absl::Nanoseconds(999999999); >+ EXPECT_GT(inf, almost_inf); >+ >+ // Addition overflow/underflow >+ EXPECT_EQ(inf, sec_max + absl::Seconds(1)); >+ EXPECT_EQ(inf, sec_max + sec_max); >+ EXPECT_EQ(-inf, sec_min + -absl::Seconds(1)); >+ EXPECT_EQ(-inf, sec_min + -sec_max); >+ >+ // For reference: IEEE 754 behavior >+ const double dbl_inf = std::numeric_limits<double>::infinity(); >+ EXPECT_TRUE(std::isinf(dbl_inf + dbl_inf)); >+ EXPECT_TRUE(std::isnan(dbl_inf + -dbl_inf)); // We return inf >+ EXPECT_TRUE(std::isnan(-dbl_inf + dbl_inf)); // We return inf >+ EXPECT_TRUE(std::isinf(-dbl_inf + -dbl_inf)); >+} >+ >+TEST(Duration, InfinitySubtraction) { >+ const absl::Duration sec_max = absl::Seconds(kint64max); >+ const absl::Duration sec_min = absl::Seconds(kint64min); >+ const absl::Duration any_dur = absl::Seconds(1); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ >+ // Subtraction >+ EXPECT_EQ(inf, inf - inf); >+ EXPECT_EQ(inf, inf - -inf); >+ EXPECT_EQ(-inf, -inf - inf); >+ EXPECT_EQ(-inf, -inf - -inf); >+ >+ EXPECT_EQ(inf, inf - any_dur); >+ EXPECT_EQ(-inf, any_dur - inf); >+ EXPECT_EQ(-inf, -inf - any_dur); >+ EXPECT_EQ(inf, any_dur - -inf); >+ >+ // Subtraction overflow/underflow >+ EXPECT_EQ(inf, sec_max - -absl::Seconds(1)); >+ EXPECT_EQ(inf, sec_max - -sec_max); >+ EXPECT_EQ(-inf, sec_min - absl::Seconds(1)); >+ EXPECT_EQ(-inf, sec_min - sec_max); >+ >+ // Interesting case >+ absl::Duration almost_neg_inf = sec_min; >+ EXPECT_LT(-inf, almost_neg_inf); >+ almost_neg_inf -= -absl::Nanoseconds(1); >+ EXPECT_LT(-inf, almost_neg_inf); >+ >+ // For reference: IEEE 754 behavior >+ const double dbl_inf = std::numeric_limits<double>::infinity(); >+ EXPECT_TRUE(std::isnan(dbl_inf - dbl_inf)); // We return inf >+ EXPECT_TRUE(std::isinf(dbl_inf - -dbl_inf)); >+ EXPECT_TRUE(std::isinf(-dbl_inf - dbl_inf)); >+ EXPECT_TRUE(std::isnan(-dbl_inf - -dbl_inf)); // We return inf >+} >+ >+TEST(Duration, InfinityMultiplication) { >+ const absl::Duration sec_max = absl::Seconds(kint64max); >+ const absl::Duration sec_min = absl::Seconds(kint64min); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ >+#define TEST_INF_MUL_WITH_TYPE(T) \ >+ EXPECT_EQ(inf, inf * static_cast<T>(2)); \ >+ EXPECT_EQ(-inf, inf * static_cast<T>(-2)); \ >+ EXPECT_EQ(-inf, -inf * static_cast<T>(2)); \ >+ EXPECT_EQ(inf, -inf * static_cast<T>(-2)); \ >+ EXPECT_EQ(inf, inf * static_cast<T>(0)); \ >+ EXPECT_EQ(-inf, -inf * static_cast<T>(0)); \ >+ EXPECT_EQ(inf, sec_max * static_cast<T>(2)); \ >+ EXPECT_EQ(inf, sec_min * static_cast<T>(-2)); \ >+ EXPECT_EQ(inf, (sec_max / static_cast<T>(2)) * static_cast<T>(3)); \ >+ EXPECT_EQ(-inf, sec_max * static_cast<T>(-2)); \ >+ EXPECT_EQ(-inf, sec_min * static_cast<T>(2)); \ >+ EXPECT_EQ(-inf, (sec_min / static_cast<T>(2)) * static_cast<T>(3)); >+ >+ TEST_INF_MUL_WITH_TYPE(int64_t); // NOLINT(readability/function) >+ TEST_INF_MUL_WITH_TYPE(double); // NOLINT(readability/function) >+ >+#undef TEST_INF_MUL_WITH_TYPE >+ >+ const double dbl_inf = std::numeric_limits<double>::infinity(); >+ EXPECT_EQ(inf, inf * dbl_inf); >+ EXPECT_EQ(-inf, -inf * dbl_inf); >+ EXPECT_EQ(-inf, inf * -dbl_inf); >+ EXPECT_EQ(inf, -inf * -dbl_inf); >+ >+ const absl::Duration any_dur = absl::Seconds(1); >+ EXPECT_EQ(inf, any_dur * dbl_inf); >+ EXPECT_EQ(-inf, -any_dur * dbl_inf); >+ EXPECT_EQ(-inf, any_dur * -dbl_inf); >+ EXPECT_EQ(inf, -any_dur * -dbl_inf); >+ >+ // Fixed-point multiplication will produce a finite value, whereas floating >+ // point fuzziness will overflow to inf. >+ EXPECT_NE(absl::InfiniteDuration(), absl::Seconds(1) * kint64max); >+ EXPECT_EQ(inf, absl::Seconds(1) * static_cast<double>(kint64max)); >+ EXPECT_NE(-absl::InfiniteDuration(), absl::Seconds(1) * kint64min); >+ EXPECT_EQ(-inf, absl::Seconds(1) * static_cast<double>(kint64min)); >+ >+ // Note that sec_max * or / by 1.0 overflows to inf due to the 53-bit >+ // limitations of double. >+ EXPECT_NE(inf, sec_max); >+ EXPECT_NE(inf, sec_max / 1); >+ EXPECT_EQ(inf, sec_max / 1.0); >+ EXPECT_NE(inf, sec_max * 1); >+ EXPECT_EQ(inf, sec_max * 1.0); >+} >+ >+TEST(Duration, InfinityDivision) { >+ const absl::Duration sec_max = absl::Seconds(kint64max); >+ const absl::Duration sec_min = absl::Seconds(kint64min); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ >+ // Division of Duration by a double >+#define TEST_INF_DIV_WITH_TYPE(T) \ >+ EXPECT_EQ(inf, inf / static_cast<T>(2)); \ >+ EXPECT_EQ(-inf, inf / static_cast<T>(-2)); \ >+ EXPECT_EQ(-inf, -inf / static_cast<T>(2)); \ >+ EXPECT_EQ(inf, -inf / static_cast<T>(-2)); >+ >+ TEST_INF_DIV_WITH_TYPE(int64_t); // NOLINT(readability/function) >+ TEST_INF_DIV_WITH_TYPE(double); // NOLINT(readability/function) >+ >+#undef TEST_INF_DIV_WITH_TYPE >+ >+ // Division of Duration by a double overflow/underflow >+ EXPECT_EQ(inf, sec_max / 0.5); >+ EXPECT_EQ(inf, sec_min / -0.5); >+ EXPECT_EQ(inf, ((sec_max / 0.5) + absl::Seconds(1)) / 0.5); >+ EXPECT_EQ(-inf, sec_max / -0.5); >+ EXPECT_EQ(-inf, sec_min / 0.5); >+ EXPECT_EQ(-inf, ((sec_min / 0.5) - absl::Seconds(1)) / 0.5); >+ >+ const double dbl_inf = std::numeric_limits<double>::infinity(); >+ EXPECT_EQ(inf, inf / dbl_inf); >+ EXPECT_EQ(-inf, inf / -dbl_inf); >+ EXPECT_EQ(-inf, -inf / dbl_inf); >+ EXPECT_EQ(inf, -inf / -dbl_inf); >+ >+ const absl::Duration any_dur = absl::Seconds(1); >+ EXPECT_EQ(absl::ZeroDuration(), any_dur / dbl_inf); >+ EXPECT_EQ(absl::ZeroDuration(), any_dur / -dbl_inf); >+ EXPECT_EQ(absl::ZeroDuration(), -any_dur / dbl_inf); >+ EXPECT_EQ(absl::ZeroDuration(), -any_dur / -dbl_inf); >+} >+ >+TEST(Duration, InfinityModulus) { >+ const absl::Duration sec_max = absl::Seconds(kint64max); >+ const absl::Duration any_dur = absl::Seconds(1); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ >+ EXPECT_EQ(inf, inf % inf); >+ EXPECT_EQ(inf, inf % -inf); >+ EXPECT_EQ(-inf, -inf % -inf); >+ EXPECT_EQ(-inf, -inf % inf); >+ >+ EXPECT_EQ(any_dur, any_dur % inf); >+ EXPECT_EQ(any_dur, any_dur % -inf); >+ EXPECT_EQ(-any_dur, -any_dur % inf); >+ EXPECT_EQ(-any_dur, -any_dur % -inf); >+ >+ EXPECT_EQ(inf, inf % -any_dur); >+ EXPECT_EQ(inf, inf % any_dur); >+ EXPECT_EQ(-inf, -inf % -any_dur); >+ EXPECT_EQ(-inf, -inf % any_dur); >+ >+ // Remainder isn't affected by overflow. >+ EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Seconds(1)); >+ EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Milliseconds(1)); >+ EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Microseconds(1)); >+ EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Nanoseconds(1)); >+ EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Nanoseconds(1) / 4); >+} >+ >+TEST(Duration, InfinityIDiv) { >+ const absl::Duration sec_max = absl::Seconds(kint64max); >+ const absl::Duration any_dur = absl::Seconds(1); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ const double dbl_inf = std::numeric_limits<double>::infinity(); >+ >+ // IDivDuration (int64_t return value + a remainer) >+ absl::Duration rem = absl::ZeroDuration(); >+ EXPECT_EQ(kint64max, absl::IDivDuration(inf, inf, &rem)); >+ EXPECT_EQ(inf, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(kint64max, absl::IDivDuration(-inf, -inf, &rem)); >+ EXPECT_EQ(-inf, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(kint64max, absl::IDivDuration(inf, any_dur, &rem)); >+ EXPECT_EQ(inf, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(0, absl::IDivDuration(any_dur, inf, &rem)); >+ EXPECT_EQ(any_dur, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(kint64max, absl::IDivDuration(-inf, -any_dur, &rem)); >+ EXPECT_EQ(-inf, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(0, absl::IDivDuration(-any_dur, -inf, &rem)); >+ EXPECT_EQ(-any_dur, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(kint64min, absl::IDivDuration(-inf, inf, &rem)); >+ EXPECT_EQ(-inf, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(kint64min, absl::IDivDuration(inf, -inf, &rem)); >+ EXPECT_EQ(inf, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(kint64min, absl::IDivDuration(-inf, any_dur, &rem)); >+ EXPECT_EQ(-inf, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(0, absl::IDivDuration(-any_dur, inf, &rem)); >+ EXPECT_EQ(-any_dur, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(kint64min, absl::IDivDuration(inf, -any_dur, &rem)); >+ EXPECT_EQ(inf, rem); >+ >+ rem = absl::ZeroDuration(); >+ EXPECT_EQ(0, absl::IDivDuration(any_dur, -inf, &rem)); >+ EXPECT_EQ(any_dur, rem); >+ >+ // IDivDuration overflow/underflow >+ rem = any_dur; >+ EXPECT_EQ(kint64max, >+ absl::IDivDuration(sec_max, absl::Nanoseconds(1) / 4, &rem)); >+ EXPECT_EQ(sec_max - absl::Nanoseconds(kint64max) / 4, rem); >+ >+ rem = any_dur; >+ EXPECT_EQ(kint64max, >+ absl::IDivDuration(sec_max, absl::Milliseconds(1), &rem)); >+ EXPECT_EQ(sec_max - absl::Milliseconds(kint64max), rem); >+ >+ rem = any_dur; >+ EXPECT_EQ(kint64max, >+ absl::IDivDuration(-sec_max, -absl::Milliseconds(1), &rem)); >+ EXPECT_EQ(-sec_max + absl::Milliseconds(kint64max), rem); >+ >+ rem = any_dur; >+ EXPECT_EQ(kint64min, >+ absl::IDivDuration(-sec_max, absl::Milliseconds(1), &rem)); >+ EXPECT_EQ(-sec_max - absl::Milliseconds(kint64min), rem); >+ >+ rem = any_dur; >+ EXPECT_EQ(kint64min, >+ absl::IDivDuration(sec_max, -absl::Milliseconds(1), &rem)); >+ EXPECT_EQ(sec_max + absl::Milliseconds(kint64min), rem); >+ >+ // >+ // operator/(Duration, Duration) is a wrapper for IDivDuration(). >+ // >+ >+ // IEEE 754 says inf / inf should be nan, but int64_t doesn't have >+ // nan so we'll return kint64max/kint64min instead. >+ EXPECT_TRUE(std::isnan(dbl_inf / dbl_inf)); >+ EXPECT_EQ(kint64max, inf / inf); >+ EXPECT_EQ(kint64max, -inf / -inf); >+ EXPECT_EQ(kint64min, -inf / inf); >+ EXPECT_EQ(kint64min, inf / -inf); >+ >+ EXPECT_TRUE(std::isinf(dbl_inf / 2.0)); >+ EXPECT_EQ(kint64max, inf / any_dur); >+ EXPECT_EQ(kint64max, -inf / -any_dur); >+ EXPECT_EQ(kint64min, -inf / any_dur); >+ EXPECT_EQ(kint64min, inf / -any_dur); >+ >+ EXPECT_EQ(0.0, 2.0 / dbl_inf); >+ EXPECT_EQ(0, any_dur / inf); >+ EXPECT_EQ(0, any_dur / -inf); >+ EXPECT_EQ(0, -any_dur / inf); >+ EXPECT_EQ(0, -any_dur / -inf); >+ EXPECT_EQ(0, absl::ZeroDuration() / inf); >+ >+ // Division of Duration by a Duration overflow/underflow >+ EXPECT_EQ(kint64max, sec_max / absl::Milliseconds(1)); >+ EXPECT_EQ(kint64max, -sec_max / -absl::Milliseconds(1)); >+ EXPECT_EQ(kint64min, -sec_max / absl::Milliseconds(1)); >+ EXPECT_EQ(kint64min, sec_max / -absl::Milliseconds(1)); >+} >+ >+TEST(Duration, InfinityFDiv) { >+ const absl::Duration any_dur = absl::Seconds(1); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ const double dbl_inf = std::numeric_limits<double>::infinity(); >+ >+ EXPECT_EQ(dbl_inf, absl::FDivDuration(inf, inf)); >+ EXPECT_EQ(dbl_inf, absl::FDivDuration(-inf, -inf)); >+ EXPECT_EQ(dbl_inf, absl::FDivDuration(inf, any_dur)); >+ EXPECT_EQ(0.0, absl::FDivDuration(any_dur, inf)); >+ EXPECT_EQ(dbl_inf, absl::FDivDuration(-inf, -any_dur)); >+ EXPECT_EQ(0.0, absl::FDivDuration(-any_dur, -inf)); >+ >+ EXPECT_EQ(-dbl_inf, absl::FDivDuration(-inf, inf)); >+ EXPECT_EQ(-dbl_inf, absl::FDivDuration(inf, -inf)); >+ EXPECT_EQ(-dbl_inf, absl::FDivDuration(-inf, any_dur)); >+ EXPECT_EQ(0.0, absl::FDivDuration(-any_dur, inf)); >+ EXPECT_EQ(-dbl_inf, absl::FDivDuration(inf, -any_dur)); >+ EXPECT_EQ(0.0, absl::FDivDuration(any_dur, -inf)); >+} >+ >+TEST(Duration, DivisionByZero) { >+ const absl::Duration zero = absl::ZeroDuration(); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ const absl::Duration any_dur = absl::Seconds(1); >+ const double dbl_inf = std::numeric_limits<double>::infinity(); >+ const double dbl_denorm = std::numeric_limits<double>::denorm_min(); >+ >+ // IEEE 754 behavior >+ double z = 0.0, two = 2.0; >+ EXPECT_TRUE(std::isinf(two / z)); >+ EXPECT_TRUE(std::isnan(z / z)); // We'll return inf >+ >+ // Operator/(Duration, double) >+ EXPECT_EQ(inf, zero / 0.0); >+ EXPECT_EQ(-inf, zero / -0.0); >+ EXPECT_EQ(inf, any_dur / 0.0); >+ EXPECT_EQ(-inf, any_dur / -0.0); >+ EXPECT_EQ(-inf, -any_dur / 0.0); >+ EXPECT_EQ(inf, -any_dur / -0.0); >+ >+ // Tests dividing by a number very close to, but not quite zero. >+ EXPECT_EQ(zero, zero / dbl_denorm); >+ EXPECT_EQ(zero, zero / -dbl_denorm); >+ EXPECT_EQ(inf, any_dur / dbl_denorm); >+ EXPECT_EQ(-inf, any_dur / -dbl_denorm); >+ EXPECT_EQ(-inf, -any_dur / dbl_denorm); >+ EXPECT_EQ(inf, -any_dur / -dbl_denorm); >+ >+ // IDiv >+ absl::Duration rem = zero; >+ EXPECT_EQ(kint64max, absl::IDivDuration(zero, zero, &rem)); >+ EXPECT_EQ(inf, rem); >+ >+ rem = zero; >+ EXPECT_EQ(kint64max, absl::IDivDuration(any_dur, zero, &rem)); >+ EXPECT_EQ(inf, rem); >+ >+ rem = zero; >+ EXPECT_EQ(kint64min, absl::IDivDuration(-any_dur, zero, &rem)); >+ EXPECT_EQ(-inf, rem); >+ >+ // Operator/(Duration, Duration) >+ EXPECT_EQ(kint64max, zero / zero); >+ EXPECT_EQ(kint64max, any_dur / zero); >+ EXPECT_EQ(kint64min, -any_dur / zero); >+ >+ // FDiv >+ EXPECT_EQ(dbl_inf, absl::FDivDuration(zero, zero)); >+ EXPECT_EQ(dbl_inf, absl::FDivDuration(any_dur, zero)); >+ EXPECT_EQ(-dbl_inf, absl::FDivDuration(-any_dur, zero)); >+} >+ >+TEST(Duration, Range) { >+ const absl::Duration range = ApproxYears(100 * 1e9); >+ const absl::Duration range_future = range; >+ const absl::Duration range_past = -range; >+ >+ EXPECT_LT(range_future, absl::InfiniteDuration()); >+ EXPECT_GT(range_past, -absl::InfiniteDuration()); >+ >+ const absl::Duration full_range = range_future - range_past; >+ EXPECT_GT(full_range, absl::ZeroDuration()); >+ EXPECT_LT(full_range, absl::InfiniteDuration()); >+ >+ const absl::Duration neg_full_range = range_past - range_future; >+ EXPECT_LT(neg_full_range, absl::ZeroDuration()); >+ EXPECT_GT(neg_full_range, -absl::InfiniteDuration()); >+ >+ EXPECT_LT(neg_full_range, full_range); >+ EXPECT_EQ(neg_full_range, -full_range); >+} >+ >+TEST(Duration, RelationalOperators) { >+#define TEST_REL_OPS(UNIT) \ >+ static_assert(UNIT(2) == UNIT(2), ""); \ >+ static_assert(UNIT(1) != UNIT(2), ""); \ >+ static_assert(UNIT(1) < UNIT(2), ""); \ >+ static_assert(UNIT(3) > UNIT(2), ""); \ >+ static_assert(UNIT(1) <= UNIT(2), ""); \ >+ static_assert(UNIT(2) <= UNIT(2), ""); \ >+ static_assert(UNIT(3) >= UNIT(2), ""); \ >+ static_assert(UNIT(2) >= UNIT(2), ""); >+ >+ TEST_REL_OPS(absl::Nanoseconds); >+ TEST_REL_OPS(absl::Microseconds); >+ TEST_REL_OPS(absl::Milliseconds); >+ TEST_REL_OPS(absl::Seconds); >+ TEST_REL_OPS(absl::Minutes); >+ TEST_REL_OPS(absl::Hours); >+ >+#undef TEST_REL_OPS >+} >+ >+TEST(Duration, Addition) { >+#define TEST_ADD_OPS(UNIT) \ >+ do { \ >+ EXPECT_EQ(UNIT(2), UNIT(1) + UNIT(1)); \ >+ EXPECT_EQ(UNIT(1), UNIT(2) - UNIT(1)); \ >+ EXPECT_EQ(UNIT(0), UNIT(2) - UNIT(2)); \ >+ EXPECT_EQ(UNIT(-1), UNIT(1) - UNIT(2)); \ >+ EXPECT_EQ(UNIT(-2), UNIT(0) - UNIT(2)); \ >+ EXPECT_EQ(UNIT(-2), UNIT(1) - UNIT(3)); \ >+ absl::Duration a = UNIT(1); \ >+ a += UNIT(1); \ >+ EXPECT_EQ(UNIT(2), a); \ >+ a -= UNIT(1); \ >+ EXPECT_EQ(UNIT(1), a); \ >+ } while (0) >+ >+ TEST_ADD_OPS(absl::Nanoseconds); >+ TEST_ADD_OPS(absl::Microseconds); >+ TEST_ADD_OPS(absl::Milliseconds); >+ TEST_ADD_OPS(absl::Seconds); >+ TEST_ADD_OPS(absl::Minutes); >+ TEST_ADD_OPS(absl::Hours); >+ >+#undef TEST_ADD_OPS >+ >+ EXPECT_EQ(absl::Seconds(2), absl::Seconds(3) - 2 * absl::Milliseconds(500)); >+ EXPECT_EQ(absl::Seconds(2) + absl::Milliseconds(500), >+ absl::Seconds(3) - absl::Milliseconds(500)); >+ >+ EXPECT_EQ(absl::Seconds(1) + absl::Milliseconds(998), >+ absl::Milliseconds(999) + absl::Milliseconds(999)); >+ >+ EXPECT_EQ(absl::Milliseconds(-1), >+ absl::Milliseconds(998) - absl::Milliseconds(999)); >+ >+ // Tests fractions of a nanoseconds. These are implementation details only. >+ EXPECT_GT(absl::Nanoseconds(1), absl::Nanoseconds(1) / 2); >+ EXPECT_EQ(absl::Nanoseconds(1), >+ absl::Nanoseconds(1) / 2 + absl::Nanoseconds(1) / 2); >+ EXPECT_GT(absl::Nanoseconds(1) / 4, absl::Nanoseconds(0)); >+ EXPECT_EQ(absl::Nanoseconds(1) / 8, absl::Nanoseconds(0)); >+ >+ // Tests subtraction that will cause wrap around of the rep_lo_ bits. >+ absl::Duration d_7_5 = absl::Seconds(7) + absl::Milliseconds(500); >+ absl::Duration d_3_7 = absl::Seconds(3) + absl::Milliseconds(700); >+ absl::Duration ans_3_8 = absl::Seconds(3) + absl::Milliseconds(800); >+ EXPECT_EQ(ans_3_8, d_7_5 - d_3_7); >+ >+ // Subtracting min_duration >+ absl::Duration min_dur = absl::Seconds(kint64min); >+ EXPECT_EQ(absl::Seconds(0), min_dur - min_dur); >+ EXPECT_EQ(absl::Seconds(kint64max), absl::Seconds(-1) - min_dur); >+} >+ >+TEST(Duration, Negation) { >+ // By storing negations of various values in constexpr variables we >+ // verify that the initializers are constant expressions. >+ constexpr absl::Duration negated_zero_duration = -absl::ZeroDuration(); >+ EXPECT_EQ(negated_zero_duration, absl::ZeroDuration()); >+ >+ constexpr absl::Duration negated_infinite_duration = >+ -absl::InfiniteDuration(); >+ EXPECT_NE(negated_infinite_duration, absl::InfiniteDuration()); >+ EXPECT_EQ(-negated_infinite_duration, absl::InfiniteDuration()); >+ >+ // The public APIs to check if a duration is infinite depend on using >+ // -InfiniteDuration(), but we're trying to test operator- here, so we >+ // need to use the lower-level internal query IsInfiniteDuration. >+ EXPECT_TRUE( >+ absl::time_internal::IsInfiniteDuration(negated_infinite_duration)); >+ >+ // The largest Duration is kint64max seconds and kTicksPerSecond - 1 ticks. >+ // Using the absl::time_internal::MakeDuration API is the cleanest way to >+ // construct that Duration. >+ constexpr absl::Duration max_duration = absl::time_internal::MakeDuration( >+ kint64max, absl::time_internal::kTicksPerSecond - 1); >+ constexpr absl::Duration negated_max_duration = -max_duration; >+ // The largest negatable value is one tick above the minimum representable; >+ // it's the negation of max_duration. >+ constexpr absl::Duration nearly_min_duration = >+ absl::time_internal::MakeDuration(kint64min, int64_t{1}); >+ constexpr absl::Duration negated_nearly_min_duration = -nearly_min_duration; >+ >+ EXPECT_EQ(negated_max_duration, nearly_min_duration); >+ EXPECT_EQ(negated_nearly_min_duration, max_duration); >+ EXPECT_EQ(-(-max_duration), max_duration); >+ >+ constexpr absl::Duration min_duration = >+ absl::time_internal::MakeDuration(kint64min); >+ constexpr absl::Duration negated_min_duration = -min_duration; >+ EXPECT_EQ(negated_min_duration, absl::InfiniteDuration()); >+} >+ >+TEST(Duration, AbsoluteValue) { >+ EXPECT_EQ(absl::ZeroDuration(), AbsDuration(absl::ZeroDuration())); >+ EXPECT_EQ(absl::Seconds(1), AbsDuration(absl::Seconds(1))); >+ EXPECT_EQ(absl::Seconds(1), AbsDuration(absl::Seconds(-1))); >+ >+ EXPECT_EQ(absl::InfiniteDuration(), AbsDuration(absl::InfiniteDuration())); >+ EXPECT_EQ(absl::InfiniteDuration(), AbsDuration(-absl::InfiniteDuration())); >+ >+ absl::Duration max_dur = >+ absl::Seconds(kint64max) + (absl::Seconds(1) - absl::Nanoseconds(1) / 4); >+ EXPECT_EQ(max_dur, AbsDuration(max_dur)); >+ >+ absl::Duration min_dur = absl::Seconds(kint64min); >+ EXPECT_EQ(absl::InfiniteDuration(), AbsDuration(min_dur)); >+ EXPECT_EQ(max_dur, AbsDuration(min_dur + absl::Nanoseconds(1) / 4)); >+} >+ >+TEST(Duration, Multiplication) { >+#define TEST_MUL_OPS(UNIT) \ >+ do { \ >+ EXPECT_EQ(UNIT(5), UNIT(2) * 2.5); \ >+ EXPECT_EQ(UNIT(2), UNIT(5) / 2.5); \ >+ EXPECT_EQ(UNIT(-5), UNIT(-2) * 2.5); \ >+ EXPECT_EQ(UNIT(-5), -UNIT(2) * 2.5); \ >+ EXPECT_EQ(UNIT(-5), UNIT(2) * -2.5); \ >+ EXPECT_EQ(UNIT(-2), UNIT(-5) / 2.5); \ >+ EXPECT_EQ(UNIT(-2), -UNIT(5) / 2.5); \ >+ EXPECT_EQ(UNIT(-2), UNIT(5) / -2.5); \ >+ EXPECT_EQ(UNIT(2), UNIT(11) % UNIT(3)); \ >+ absl::Duration a = UNIT(2); \ >+ a *= 2.5; \ >+ EXPECT_EQ(UNIT(5), a); \ >+ a /= 2.5; \ >+ EXPECT_EQ(UNIT(2), a); \ >+ a %= UNIT(1); \ >+ EXPECT_EQ(UNIT(0), a); \ >+ absl::Duration big = UNIT(1000000000); \ >+ big *= 3; \ >+ big /= 3; \ >+ EXPECT_EQ(UNIT(1000000000), big); \ >+ EXPECT_EQ(-UNIT(2), -UNIT(2)); \ >+ EXPECT_EQ(-UNIT(2), UNIT(2) * -1); \ >+ EXPECT_EQ(-UNIT(2), -1 * UNIT(2)); \ >+ EXPECT_EQ(-UNIT(-2), UNIT(2)); \ >+ EXPECT_EQ(2, UNIT(2) / UNIT(1)); \ >+ absl::Duration rem; \ >+ EXPECT_EQ(2, absl::IDivDuration(UNIT(2), UNIT(1), &rem)); \ >+ EXPECT_EQ(2.0, absl::FDivDuration(UNIT(2), UNIT(1))); \ >+ } while (0) >+ >+ TEST_MUL_OPS(absl::Nanoseconds); >+ TEST_MUL_OPS(absl::Microseconds); >+ TEST_MUL_OPS(absl::Milliseconds); >+ TEST_MUL_OPS(absl::Seconds); >+ TEST_MUL_OPS(absl::Minutes); >+ TEST_MUL_OPS(absl::Hours); >+ >+#undef TEST_MUL_OPS >+ >+ // Ensures that multiplication and division by 1 with a maxed-out durations >+ // doesn't lose precision. >+ absl::Duration max_dur = >+ absl::Seconds(kint64max) + (absl::Seconds(1) - absl::Nanoseconds(1) / 4); >+ absl::Duration min_dur = absl::Seconds(kint64min); >+ EXPECT_EQ(max_dur, max_dur * 1); >+ EXPECT_EQ(max_dur, max_dur / 1); >+ EXPECT_EQ(min_dur, min_dur * 1); >+ EXPECT_EQ(min_dur, min_dur / 1); >+ >+ // Tests division on a Duration with a large number of significant digits. >+ // Tests when the digits span hi and lo as well as only in hi. >+ absl::Duration sigfigs = absl::Seconds(2000000000) + absl::Nanoseconds(3); >+ EXPECT_EQ(absl::Seconds(666666666) + absl::Nanoseconds(666666667) + >+ absl::Nanoseconds(1) / 2, >+ sigfigs / 3); >+ sigfigs = absl::Seconds(7000000000LL); >+ EXPECT_EQ(absl::Seconds(2333333333) + absl::Nanoseconds(333333333) + >+ absl::Nanoseconds(1) / 4, >+ sigfigs / 3); >+ >+ EXPECT_EQ(absl::Seconds(7) + absl::Milliseconds(500), absl::Seconds(3) * 2.5); >+ EXPECT_EQ(absl::Seconds(8) * -1 + absl::Milliseconds(300), >+ (absl::Seconds(2) + absl::Milliseconds(200)) * -3.5); >+ EXPECT_EQ(-absl::Seconds(8) + absl::Milliseconds(300), >+ (absl::Seconds(2) + absl::Milliseconds(200)) * -3.5); >+ EXPECT_EQ(absl::Seconds(1) + absl::Milliseconds(875), >+ (absl::Seconds(7) + absl::Milliseconds(500)) / 4); >+ EXPECT_EQ(absl::Seconds(30), >+ (absl::Seconds(7) + absl::Milliseconds(500)) / 0.25); >+ EXPECT_EQ(absl::Seconds(3), >+ (absl::Seconds(7) + absl::Milliseconds(500)) / 2.5); >+ >+ // Tests division remainder. >+ EXPECT_EQ(absl::Nanoseconds(0), absl::Nanoseconds(7) % absl::Nanoseconds(1)); >+ EXPECT_EQ(absl::Nanoseconds(0), absl::Nanoseconds(0) % absl::Nanoseconds(10)); >+ EXPECT_EQ(absl::Nanoseconds(2), absl::Nanoseconds(7) % absl::Nanoseconds(5)); >+ EXPECT_EQ(absl::Nanoseconds(2), absl::Nanoseconds(2) % absl::Nanoseconds(5)); >+ >+ EXPECT_EQ(absl::Nanoseconds(1), absl::Nanoseconds(10) % absl::Nanoseconds(3)); >+ EXPECT_EQ(absl::Nanoseconds(1), >+ absl::Nanoseconds(10) % absl::Nanoseconds(-3)); >+ EXPECT_EQ(absl::Nanoseconds(-1), >+ absl::Nanoseconds(-10) % absl::Nanoseconds(3)); >+ EXPECT_EQ(absl::Nanoseconds(-1), >+ absl::Nanoseconds(-10) % absl::Nanoseconds(-3)); >+ >+ EXPECT_EQ(absl::Milliseconds(100), >+ absl::Seconds(1) % absl::Milliseconds(300)); >+ EXPECT_EQ( >+ absl::Milliseconds(300), >+ (absl::Seconds(3) + absl::Milliseconds(800)) % absl::Milliseconds(500)); >+ >+ EXPECT_EQ(absl::Nanoseconds(1), absl::Nanoseconds(1) % absl::Seconds(1)); >+ EXPECT_EQ(absl::Nanoseconds(-1), absl::Nanoseconds(-1) % absl::Seconds(1)); >+ EXPECT_EQ(0, absl::Nanoseconds(-1) / absl::Seconds(1)); // Actual -1e-9 >+ >+ // Tests identity a = (a/b)*b + a%b >+#define TEST_MOD_IDENTITY(a, b) \ >+ EXPECT_EQ((a), ((a) / (b))*(b) + ((a)%(b))) >+ >+ TEST_MOD_IDENTITY(absl::Seconds(0), absl::Seconds(2)); >+ TEST_MOD_IDENTITY(absl::Seconds(1), absl::Seconds(1)); >+ TEST_MOD_IDENTITY(absl::Seconds(1), absl::Seconds(2)); >+ TEST_MOD_IDENTITY(absl::Seconds(2), absl::Seconds(1)); >+ >+ TEST_MOD_IDENTITY(absl::Seconds(-2), absl::Seconds(1)); >+ TEST_MOD_IDENTITY(absl::Seconds(2), absl::Seconds(-1)); >+ TEST_MOD_IDENTITY(absl::Seconds(-2), absl::Seconds(-1)); >+ >+ TEST_MOD_IDENTITY(absl::Nanoseconds(0), absl::Nanoseconds(2)); >+ TEST_MOD_IDENTITY(absl::Nanoseconds(1), absl::Nanoseconds(1)); >+ TEST_MOD_IDENTITY(absl::Nanoseconds(1), absl::Nanoseconds(2)); >+ TEST_MOD_IDENTITY(absl::Nanoseconds(2), absl::Nanoseconds(1)); >+ >+ TEST_MOD_IDENTITY(absl::Nanoseconds(-2), absl::Nanoseconds(1)); >+ TEST_MOD_IDENTITY(absl::Nanoseconds(2), absl::Nanoseconds(-1)); >+ TEST_MOD_IDENTITY(absl::Nanoseconds(-2), absl::Nanoseconds(-1)); >+ >+ // Mixed seconds + subseconds >+ absl::Duration mixed_a = absl::Seconds(1) + absl::Nanoseconds(2); >+ absl::Duration mixed_b = absl::Seconds(1) + absl::Nanoseconds(3); >+ >+ TEST_MOD_IDENTITY(absl::Seconds(0), mixed_a); >+ TEST_MOD_IDENTITY(mixed_a, mixed_a); >+ TEST_MOD_IDENTITY(mixed_a, mixed_b); >+ TEST_MOD_IDENTITY(mixed_b, mixed_a); >+ >+ TEST_MOD_IDENTITY(-mixed_a, mixed_b); >+ TEST_MOD_IDENTITY(mixed_a, -mixed_b); >+ TEST_MOD_IDENTITY(-mixed_a, -mixed_b); >+ >+#undef TEST_MOD_IDENTITY >+} >+ >+TEST(Duration, Truncation) { >+ const absl::Duration d = absl::Nanoseconds(1234567890); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ for (int unit_sign : {1, -1}) { // sign shouldn't matter >+ EXPECT_EQ(absl::Nanoseconds(1234567890), >+ Trunc(d, unit_sign * absl::Nanoseconds(1))); >+ EXPECT_EQ(absl::Microseconds(1234567), >+ Trunc(d, unit_sign * absl::Microseconds(1))); >+ EXPECT_EQ(absl::Milliseconds(1234), >+ Trunc(d, unit_sign * absl::Milliseconds(1))); >+ EXPECT_EQ(absl::Seconds(1), Trunc(d, unit_sign * absl::Seconds(1))); >+ EXPECT_EQ(inf, Trunc(inf, unit_sign * absl::Seconds(1))); >+ >+ EXPECT_EQ(absl::Nanoseconds(-1234567890), >+ Trunc(-d, unit_sign * absl::Nanoseconds(1))); >+ EXPECT_EQ(absl::Microseconds(-1234567), >+ Trunc(-d, unit_sign * absl::Microseconds(1))); >+ EXPECT_EQ(absl::Milliseconds(-1234), >+ Trunc(-d, unit_sign * absl::Milliseconds(1))); >+ EXPECT_EQ(absl::Seconds(-1), Trunc(-d, unit_sign * absl::Seconds(1))); >+ EXPECT_EQ(-inf, Trunc(-inf, unit_sign * absl::Seconds(1))); >+ } >+} >+ >+TEST(Duration, Flooring) { >+ const absl::Duration d = absl::Nanoseconds(1234567890); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ for (int unit_sign : {1, -1}) { // sign shouldn't matter >+ EXPECT_EQ(absl::Nanoseconds(1234567890), >+ absl::Floor(d, unit_sign * absl::Nanoseconds(1))); >+ EXPECT_EQ(absl::Microseconds(1234567), >+ absl::Floor(d, unit_sign * absl::Microseconds(1))); >+ EXPECT_EQ(absl::Milliseconds(1234), >+ absl::Floor(d, unit_sign * absl::Milliseconds(1))); >+ EXPECT_EQ(absl::Seconds(1), absl::Floor(d, unit_sign * absl::Seconds(1))); >+ EXPECT_EQ(inf, absl::Floor(inf, unit_sign * absl::Seconds(1))); >+ >+ EXPECT_EQ(absl::Nanoseconds(-1234567890), >+ absl::Floor(-d, unit_sign * absl::Nanoseconds(1))); >+ EXPECT_EQ(absl::Microseconds(-1234568), >+ absl::Floor(-d, unit_sign * absl::Microseconds(1))); >+ EXPECT_EQ(absl::Milliseconds(-1235), >+ absl::Floor(-d, unit_sign * absl::Milliseconds(1))); >+ EXPECT_EQ(absl::Seconds(-2), absl::Floor(-d, unit_sign * absl::Seconds(1))); >+ EXPECT_EQ(-inf, absl::Floor(-inf, unit_sign * absl::Seconds(1))); >+ } >+} >+ >+TEST(Duration, Ceiling) { >+ const absl::Duration d = absl::Nanoseconds(1234567890); >+ const absl::Duration inf = absl::InfiniteDuration(); >+ for (int unit_sign : {1, -1}) { // // sign shouldn't matter >+ EXPECT_EQ(absl::Nanoseconds(1234567890), >+ absl::Ceil(d, unit_sign * absl::Nanoseconds(1))); >+ EXPECT_EQ(absl::Microseconds(1234568), >+ absl::Ceil(d, unit_sign * absl::Microseconds(1))); >+ EXPECT_EQ(absl::Milliseconds(1235), >+ absl::Ceil(d, unit_sign * absl::Milliseconds(1))); >+ EXPECT_EQ(absl::Seconds(2), absl::Ceil(d, unit_sign * absl::Seconds(1))); >+ EXPECT_EQ(inf, absl::Ceil(inf, unit_sign * absl::Seconds(1))); >+ >+ EXPECT_EQ(absl::Nanoseconds(-1234567890), >+ absl::Ceil(-d, unit_sign * absl::Nanoseconds(1))); >+ EXPECT_EQ(absl::Microseconds(-1234567), >+ absl::Ceil(-d, unit_sign * absl::Microseconds(1))); >+ EXPECT_EQ(absl::Milliseconds(-1234), >+ absl::Ceil(-d, unit_sign * absl::Milliseconds(1))); >+ EXPECT_EQ(absl::Seconds(-1), absl::Ceil(-d, unit_sign * absl::Seconds(1))); >+ EXPECT_EQ(-inf, absl::Ceil(-inf, unit_sign * absl::Seconds(1))); >+ } >+} >+ >+TEST(Duration, RoundTripUnits) { >+ const int kRange = 100000; >+ >+#define ROUND_TRIP_UNIT(U, LOW, HIGH) \ >+ do { \ >+ for (int64_t i = LOW; i < HIGH; ++i) { \ >+ absl::Duration d = absl::U(i); \ >+ if (d == absl::InfiniteDuration()) \ >+ EXPECT_EQ(kint64max, d / absl::U(1)); \ >+ else if (d == -absl::InfiniteDuration()) \ >+ EXPECT_EQ(kint64min, d / absl::U(1)); \ >+ else \ >+ EXPECT_EQ(i, absl::U(i) / absl::U(1)); \ >+ } \ >+ } while (0) >+ >+ ROUND_TRIP_UNIT(Nanoseconds, kint64min, kint64min + kRange); >+ ROUND_TRIP_UNIT(Nanoseconds, -kRange, kRange); >+ ROUND_TRIP_UNIT(Nanoseconds, kint64max - kRange, kint64max); >+ >+ ROUND_TRIP_UNIT(Microseconds, kint64min, kint64min + kRange); >+ ROUND_TRIP_UNIT(Microseconds, -kRange, kRange); >+ ROUND_TRIP_UNIT(Microseconds, kint64max - kRange, kint64max); >+ >+ ROUND_TRIP_UNIT(Milliseconds, kint64min, kint64min + kRange); >+ ROUND_TRIP_UNIT(Milliseconds, -kRange, kRange); >+ ROUND_TRIP_UNIT(Milliseconds, kint64max - kRange, kint64max); >+ >+ ROUND_TRIP_UNIT(Seconds, kint64min, kint64min + kRange); >+ ROUND_TRIP_UNIT(Seconds, -kRange, kRange); >+ ROUND_TRIP_UNIT(Seconds, kint64max - kRange, kint64max); >+ >+ ROUND_TRIP_UNIT(Minutes, kint64min / 60, kint64min / 60 + kRange); >+ ROUND_TRIP_UNIT(Minutes, -kRange, kRange); >+ ROUND_TRIP_UNIT(Minutes, kint64max / 60 - kRange, kint64max / 60); >+ >+ ROUND_TRIP_UNIT(Hours, kint64min / 3600, kint64min / 3600 + kRange); >+ ROUND_TRIP_UNIT(Hours, -kRange, kRange); >+ ROUND_TRIP_UNIT(Hours, kint64max / 3600 - kRange, kint64max / 3600); >+ >+#undef ROUND_TRIP_UNIT >+} >+ >+TEST(Duration, TruncConversions) { >+ // Tests ToTimespec()/DurationFromTimespec() >+ const struct { >+ absl::Duration d; >+ timespec ts; >+ } to_ts[] = { >+ {absl::Seconds(1) + absl::Nanoseconds(1), {1, 1}}, >+ {absl::Seconds(1) + absl::Nanoseconds(1) / 2, {1, 0}}, >+ {absl::Seconds(1) + absl::Nanoseconds(0), {1, 0}}, >+ {absl::Seconds(0) + absl::Nanoseconds(0), {0, 0}}, >+ {absl::Seconds(0) - absl::Nanoseconds(1) / 2, {0, 0}}, >+ {absl::Seconds(0) - absl::Nanoseconds(1), {-1, 999999999}}, >+ {absl::Seconds(-1) + absl::Nanoseconds(1), {-1, 1}}, >+ {absl::Seconds(-1) + absl::Nanoseconds(1) / 2, {-1, 1}}, >+ {absl::Seconds(-1) + absl::Nanoseconds(0), {-1, 0}}, >+ {absl::Seconds(-1) - absl::Nanoseconds(1) / 2, {-1, 0}}, >+ }; >+ for (const auto& test : to_ts) { >+ EXPECT_THAT(absl::ToTimespec(test.d), TimespecMatcher(test.ts)); >+ } >+ const struct { >+ timespec ts; >+ absl::Duration d; >+ } from_ts[] = { >+ {{1, 1}, absl::Seconds(1) + absl::Nanoseconds(1)}, >+ {{1, 0}, absl::Seconds(1) + absl::Nanoseconds(0)}, >+ {{0, 0}, absl::Seconds(0) + absl::Nanoseconds(0)}, >+ {{0, -1}, absl::Seconds(0) - absl::Nanoseconds(1)}, >+ {{-1, 999999999}, absl::Seconds(0) - absl::Nanoseconds(1)}, >+ {{-1, 1}, absl::Seconds(-1) + absl::Nanoseconds(1)}, >+ {{-1, 0}, absl::Seconds(-1) + absl::Nanoseconds(0)}, >+ {{-1, -1}, absl::Seconds(-1) - absl::Nanoseconds(1)}, >+ {{-2, 999999999}, absl::Seconds(-1) - absl::Nanoseconds(1)}, >+ }; >+ for (const auto& test : from_ts) { >+ EXPECT_EQ(test.d, absl::DurationFromTimespec(test.ts)); >+ } >+ >+ // Tests ToTimeval()/DurationFromTimeval() (same as timespec above) >+ const struct { >+ absl::Duration d; >+ timeval tv; >+ } to_tv[] = { >+ {absl::Seconds(1) + absl::Microseconds(1), {1, 1}}, >+ {absl::Seconds(1) + absl::Microseconds(1) / 2, {1, 0}}, >+ {absl::Seconds(1) + absl::Microseconds(0), {1, 0}}, >+ {absl::Seconds(0) + absl::Microseconds(0), {0, 0}}, >+ {absl::Seconds(0) - absl::Microseconds(1) / 2, {0, 0}}, >+ {absl::Seconds(0) - absl::Microseconds(1), {-1, 999999}}, >+ {absl::Seconds(-1) + absl::Microseconds(1), {-1, 1}}, >+ {absl::Seconds(-1) + absl::Microseconds(1) / 2, {-1, 1}}, >+ {absl::Seconds(-1) + absl::Microseconds(0), {-1, 0}}, >+ {absl::Seconds(-1) - absl::Microseconds(1) / 2, {-1, 0}}, >+ }; >+ for (const auto& test : to_tv) { >+ EXPECT_THAT(absl::ToTimeval(test.d), TimevalMatcher(test.tv)); >+ } >+ const struct { >+ timeval tv; >+ absl::Duration d; >+ } from_tv[] = { >+ {{1, 1}, absl::Seconds(1) + absl::Microseconds(1)}, >+ {{1, 0}, absl::Seconds(1) + absl::Microseconds(0)}, >+ {{0, 0}, absl::Seconds(0) + absl::Microseconds(0)}, >+ {{0, -1}, absl::Seconds(0) - absl::Microseconds(1)}, >+ {{-1, 999999}, absl::Seconds(0) - absl::Microseconds(1)}, >+ {{-1, 1}, absl::Seconds(-1) + absl::Microseconds(1)}, >+ {{-1, 0}, absl::Seconds(-1) + absl::Microseconds(0)}, >+ {{-1, -1}, absl::Seconds(-1) - absl::Microseconds(1)}, >+ {{-2, 999999}, absl::Seconds(-1) - absl::Microseconds(1)}, >+ }; >+ for (const auto& test : from_tv) { >+ EXPECT_EQ(test.d, absl::DurationFromTimeval(test.tv)); >+ } >+} >+ >+TEST(Duration, SmallConversions) { >+ // Special tests for conversions of small durations. >+ >+ EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(0)); >+ // TODO(bww): Is the next one OK? >+ EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(0.124999999e-9)); >+ EXPECT_EQ(absl::Nanoseconds(1) / 4, absl::Seconds(0.125e-9)); >+ EXPECT_EQ(absl::Nanoseconds(1) / 4, absl::Seconds(0.250e-9)); >+ EXPECT_EQ(absl::Nanoseconds(1) / 2, absl::Seconds(0.375e-9)); >+ EXPECT_EQ(absl::Nanoseconds(1) / 2, absl::Seconds(0.500e-9)); >+ EXPECT_EQ(absl::Nanoseconds(3) / 4, absl::Seconds(0.625e-9)); >+ EXPECT_EQ(absl::Nanoseconds(3) / 4, absl::Seconds(0.750e-9)); >+ EXPECT_EQ(absl::Nanoseconds(1), absl::Seconds(0.875e-9)); >+ EXPECT_EQ(absl::Nanoseconds(1), absl::Seconds(1.000e-9)); >+ >+ EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(-0.124999999e-9)); >+ EXPECT_EQ(-absl::Nanoseconds(1) / 4, absl::Seconds(-0.125e-9)); >+ EXPECT_EQ(-absl::Nanoseconds(1) / 4, absl::Seconds(-0.250e-9)); >+ EXPECT_EQ(-absl::Nanoseconds(1) / 2, absl::Seconds(-0.375e-9)); >+ EXPECT_EQ(-absl::Nanoseconds(1) / 2, absl::Seconds(-0.500e-9)); >+ EXPECT_EQ(-absl::Nanoseconds(3) / 4, absl::Seconds(-0.625e-9)); >+ EXPECT_EQ(-absl::Nanoseconds(3) / 4, absl::Seconds(-0.750e-9)); >+ EXPECT_EQ(-absl::Nanoseconds(1), absl::Seconds(-0.875e-9)); >+ EXPECT_EQ(-absl::Nanoseconds(1), absl::Seconds(-1.000e-9)); >+ >+ timespec ts; >+ ts.tv_sec = 0; >+ ts.tv_nsec = 0; >+ EXPECT_THAT(ToTimespec(absl::Nanoseconds(0)), TimespecMatcher(ts)); >+ // TODO(bww): Are the next three OK? >+ EXPECT_THAT(ToTimespec(absl::Nanoseconds(1) / 4), TimespecMatcher(ts)); >+ EXPECT_THAT(ToTimespec(absl::Nanoseconds(2) / 4), TimespecMatcher(ts)); >+ EXPECT_THAT(ToTimespec(absl::Nanoseconds(3) / 4), TimespecMatcher(ts)); >+ ts.tv_nsec = 1; >+ EXPECT_THAT(ToTimespec(absl::Nanoseconds(4) / 4), TimespecMatcher(ts)); >+ EXPECT_THAT(ToTimespec(absl::Nanoseconds(5) / 4), TimespecMatcher(ts)); >+ EXPECT_THAT(ToTimespec(absl::Nanoseconds(6) / 4), TimespecMatcher(ts)); >+ EXPECT_THAT(ToTimespec(absl::Nanoseconds(7) / 4), TimespecMatcher(ts)); >+ ts.tv_nsec = 2; >+ EXPECT_THAT(ToTimespec(absl::Nanoseconds(8) / 4), TimespecMatcher(ts)); >+ >+ timeval tv; >+ tv.tv_sec = 0; >+ tv.tv_usec = 0; >+ EXPECT_THAT(ToTimeval(absl::Nanoseconds(0)), TimevalMatcher(tv)); >+ // TODO(bww): Is the next one OK? >+ EXPECT_THAT(ToTimeval(absl::Nanoseconds(999)), TimevalMatcher(tv)); >+ tv.tv_usec = 1; >+ EXPECT_THAT(ToTimeval(absl::Nanoseconds(1000)), TimevalMatcher(tv)); >+ EXPECT_THAT(ToTimeval(absl::Nanoseconds(1999)), TimevalMatcher(tv)); >+ tv.tv_usec = 2; >+ EXPECT_THAT(ToTimeval(absl::Nanoseconds(2000)), TimevalMatcher(tv)); >+} >+ >+void VerifySameAsMul(double time_as_seconds, int* const misses) { >+ auto direct_seconds = absl::Seconds(time_as_seconds); >+ auto mul_by_one_second = time_as_seconds * absl::Seconds(1); >+ if (direct_seconds != mul_by_one_second) { >+ if (*misses > 10) return; >+ ASSERT_LE(++(*misses), 10) << "Too many errors, not reporting more."; >+ EXPECT_EQ(direct_seconds, mul_by_one_second) >+ << "given double time_as_seconds = " << std::setprecision(17) >+ << time_as_seconds; >+ } >+} >+ >+// For a variety of interesting durations, we find the exact point >+// where one double converts to that duration, and the very next double >+// converts to the next duration. For both of those points, verify that >+// Seconds(point) returns the same duration as point * Seconds(1.0) >+TEST(Duration, ToDoubleSecondsCheckEdgeCases) { >+ constexpr uint32_t kTicksPerSecond = absl::time_internal::kTicksPerSecond; >+ constexpr auto duration_tick = absl::time_internal::MakeDuration(0, 1u); >+ int misses = 0; >+ for (int64_t seconds = 0; seconds < 99; ++seconds) { >+ uint32_t tick_vals[] = {0, +999, +999999, +999999999, kTicksPerSecond - 1, >+ 0, 1000, 1000000, 1000000000, kTicksPerSecond, >+ 1, 1001, 1000001, 1000000001, kTicksPerSecond + 1, >+ 2, 1002, 1000002, 1000000002, kTicksPerSecond + 2, >+ 3, 1003, 1000003, 1000000003, kTicksPerSecond + 3, >+ 4, 1004, 1000004, 1000000004, kTicksPerSecond + 4, >+ 5, 6, 7, 8, 9}; >+ for (uint32_t ticks : tick_vals) { >+ absl::Duration s_plus_t = absl::Seconds(seconds) + ticks * duration_tick; >+ for (absl::Duration d : {s_plus_t, -s_plus_t}) { >+ absl::Duration after_d = d + duration_tick; >+ EXPECT_NE(d, after_d); >+ EXPECT_EQ(after_d - d, duration_tick); >+ >+ double low_edge = ToDoubleSeconds(d); >+ EXPECT_EQ(d, absl::Seconds(low_edge)); >+ >+ double high_edge = ToDoubleSeconds(after_d); >+ EXPECT_EQ(after_d, absl::Seconds(high_edge)); >+ >+ for (;;) { >+ double midpoint = low_edge + (high_edge - low_edge) / 2; >+ if (midpoint == low_edge || midpoint == high_edge) break; >+ absl::Duration mid_duration = absl::Seconds(midpoint); >+ if (mid_duration == d) { >+ low_edge = midpoint; >+ } else { >+ EXPECT_EQ(mid_duration, after_d); >+ high_edge = midpoint; >+ } >+ } >+ // Now low_edge is the highest double that converts to Duration d, >+ // and high_edge is the lowest double that converts to Duration after_d. >+ VerifySameAsMul(low_edge, &misses); >+ VerifySameAsMul(high_edge, &misses); >+ } >+ } >+ } >+} >+ >+TEST(Duration, ToDoubleSecondsCheckRandom) { >+ std::random_device rd; >+ std::seed_seq seed({rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()}); >+ std::mt19937_64 gen(seed); >+ // We want doubles distributed from 1/8ns up to 2^63, where >+ // as many values are tested from 1ns to 2ns as from 1sec to 2sec, >+ // so even distribute along a log-scale of those values, and >+ // exponentiate before using them. (9.223377e+18 is just slightly >+ // out of bounds for absl::Duration.) >+ std::uniform_real_distribution<double> uniform(std::log(0.125e-9), >+ std::log(9.223377e+18)); >+ int misses = 0; >+ for (int i = 0; i < 1000000; ++i) { >+ double d = std::exp(uniform(gen)); >+ VerifySameAsMul(d, &misses); >+ VerifySameAsMul(-d, &misses); >+ } >+} >+ >+TEST(Duration, ConversionSaturation) { >+ absl::Duration d; >+ >+ const auto max_timeval_sec = >+ std::numeric_limits<decltype(timeval::tv_sec)>::max(); >+ const auto min_timeval_sec = >+ std::numeric_limits<decltype(timeval::tv_sec)>::min(); >+ timeval tv; >+ tv.tv_sec = max_timeval_sec; >+ tv.tv_usec = 999998; >+ d = absl::DurationFromTimeval(tv); >+ tv = ToTimeval(d); >+ EXPECT_EQ(max_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(999998, tv.tv_usec); >+ d += absl::Microseconds(1); >+ tv = ToTimeval(d); >+ EXPECT_EQ(max_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(999999, tv.tv_usec); >+ d += absl::Microseconds(1); // no effect >+ tv = ToTimeval(d); >+ EXPECT_EQ(max_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(999999, tv.tv_usec); >+ >+ tv.tv_sec = min_timeval_sec; >+ tv.tv_usec = 1; >+ d = absl::DurationFromTimeval(tv); >+ tv = ToTimeval(d); >+ EXPECT_EQ(min_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(1, tv.tv_usec); >+ d -= absl::Microseconds(1); >+ tv = ToTimeval(d); >+ EXPECT_EQ(min_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(0, tv.tv_usec); >+ d -= absl::Microseconds(1); // no effect >+ tv = ToTimeval(d); >+ EXPECT_EQ(min_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(0, tv.tv_usec); >+ >+ const auto max_timespec_sec = >+ std::numeric_limits<decltype(timespec::tv_sec)>::max(); >+ const auto min_timespec_sec = >+ std::numeric_limits<decltype(timespec::tv_sec)>::min(); >+ timespec ts; >+ ts.tv_sec = max_timespec_sec; >+ ts.tv_nsec = 999999998; >+ d = absl::DurationFromTimespec(ts); >+ ts = absl::ToTimespec(d); >+ EXPECT_EQ(max_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(999999998, ts.tv_nsec); >+ d += absl::Nanoseconds(1); >+ ts = absl::ToTimespec(d); >+ EXPECT_EQ(max_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(999999999, ts.tv_nsec); >+ d += absl::Nanoseconds(1); // no effect >+ ts = absl::ToTimespec(d); >+ EXPECT_EQ(max_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(999999999, ts.tv_nsec); >+ >+ ts.tv_sec = min_timespec_sec; >+ ts.tv_nsec = 1; >+ d = absl::DurationFromTimespec(ts); >+ ts = absl::ToTimespec(d); >+ EXPECT_EQ(min_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(1, ts.tv_nsec); >+ d -= absl::Nanoseconds(1); >+ ts = absl::ToTimespec(d); >+ EXPECT_EQ(min_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(0, ts.tv_nsec); >+ d -= absl::Nanoseconds(1); // no effect >+ ts = absl::ToTimespec(d); >+ EXPECT_EQ(min_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(0, ts.tv_nsec); >+} >+ >+TEST(Duration, FormatDuration) { >+ // Example from Go's docs. >+ EXPECT_EQ("72h3m0.5s", >+ absl::FormatDuration(absl::Hours(72) + absl::Minutes(3) + >+ absl::Milliseconds(500))); >+ // Go's largest time: 2540400h10m10.000000000s >+ EXPECT_EQ("2540400h10m10s", >+ absl::FormatDuration(absl::Hours(2540400) + absl::Minutes(10) + >+ absl::Seconds(10))); >+ >+ EXPECT_EQ("0", absl::FormatDuration(absl::ZeroDuration())); >+ EXPECT_EQ("0", absl::FormatDuration(absl::Seconds(0))); >+ EXPECT_EQ("0", absl::FormatDuration(absl::Nanoseconds(0))); >+ >+ EXPECT_EQ("1ns", absl::FormatDuration(absl::Nanoseconds(1))); >+ EXPECT_EQ("1us", absl::FormatDuration(absl::Microseconds(1))); >+ EXPECT_EQ("1ms", absl::FormatDuration(absl::Milliseconds(1))); >+ EXPECT_EQ("1s", absl::FormatDuration(absl::Seconds(1))); >+ EXPECT_EQ("1m", absl::FormatDuration(absl::Minutes(1))); >+ EXPECT_EQ("1h", absl::FormatDuration(absl::Hours(1))); >+ >+ EXPECT_EQ("1h1m", absl::FormatDuration(absl::Hours(1) + absl::Minutes(1))); >+ EXPECT_EQ("1h1s", absl::FormatDuration(absl::Hours(1) + absl::Seconds(1))); >+ EXPECT_EQ("1m1s", absl::FormatDuration(absl::Minutes(1) + absl::Seconds(1))); >+ >+ EXPECT_EQ("1h0.25s", >+ absl::FormatDuration(absl::Hours(1) + absl::Milliseconds(250))); >+ EXPECT_EQ("1m0.25s", >+ absl::FormatDuration(absl::Minutes(1) + absl::Milliseconds(250))); >+ EXPECT_EQ("1h1m0.25s", >+ absl::FormatDuration(absl::Hours(1) + absl::Minutes(1) + >+ absl::Milliseconds(250))); >+ EXPECT_EQ("1h0.0005s", >+ absl::FormatDuration(absl::Hours(1) + absl::Microseconds(500))); >+ EXPECT_EQ("1h0.0000005s", >+ absl::FormatDuration(absl::Hours(1) + absl::Nanoseconds(500))); >+ >+ // Subsecond special case. >+ EXPECT_EQ("1.5ns", absl::FormatDuration(absl::Nanoseconds(1) + >+ absl::Nanoseconds(1) / 2)); >+ EXPECT_EQ("1.25ns", absl::FormatDuration(absl::Nanoseconds(1) + >+ absl::Nanoseconds(1) / 4)); >+ EXPECT_EQ("1ns", absl::FormatDuration(absl::Nanoseconds(1) + >+ absl::Nanoseconds(1) / 9)); >+ EXPECT_EQ("1.2us", absl::FormatDuration(absl::Microseconds(1) + >+ absl::Nanoseconds(200))); >+ EXPECT_EQ("1.2ms", absl::FormatDuration(absl::Milliseconds(1) + >+ absl::Microseconds(200))); >+ EXPECT_EQ("1.0002ms", absl::FormatDuration(absl::Milliseconds(1) + >+ absl::Nanoseconds(200))); >+ EXPECT_EQ("1.00001ms", absl::FormatDuration(absl::Milliseconds(1) + >+ absl::Nanoseconds(10))); >+ EXPECT_EQ("1.000001ms", >+ absl::FormatDuration(absl::Milliseconds(1) + absl::Nanoseconds(1))); >+ >+ // Negative durations. >+ EXPECT_EQ("-1ns", absl::FormatDuration(absl::Nanoseconds(-1))); >+ EXPECT_EQ("-1us", absl::FormatDuration(absl::Microseconds(-1))); >+ EXPECT_EQ("-1ms", absl::FormatDuration(absl::Milliseconds(-1))); >+ EXPECT_EQ("-1s", absl::FormatDuration(absl::Seconds(-1))); >+ EXPECT_EQ("-1m", absl::FormatDuration(absl::Minutes(-1))); >+ EXPECT_EQ("-1h", absl::FormatDuration(absl::Hours(-1))); >+ >+ EXPECT_EQ("-1h1m", >+ absl::FormatDuration(-(absl::Hours(1) + absl::Minutes(1)))); >+ EXPECT_EQ("-1h1s", >+ absl::FormatDuration(-(absl::Hours(1) + absl::Seconds(1)))); >+ EXPECT_EQ("-1m1s", >+ absl::FormatDuration(-(absl::Minutes(1) + absl::Seconds(1)))); >+ >+ EXPECT_EQ("-1ns", absl::FormatDuration(absl::Nanoseconds(-1))); >+ EXPECT_EQ("-1.2us", absl::FormatDuration( >+ -(absl::Microseconds(1) + absl::Nanoseconds(200)))); >+ EXPECT_EQ("-1.2ms", absl::FormatDuration( >+ -(absl::Milliseconds(1) + absl::Microseconds(200)))); >+ EXPECT_EQ("-1.0002ms", absl::FormatDuration(-(absl::Milliseconds(1) + >+ absl::Nanoseconds(200)))); >+ EXPECT_EQ("-1.00001ms", absl::FormatDuration(-(absl::Milliseconds(1) + >+ absl::Nanoseconds(10)))); >+ EXPECT_EQ("-1.000001ms", absl::FormatDuration(-(absl::Milliseconds(1) + >+ absl::Nanoseconds(1)))); >+ >+ // >+ // Interesting corner cases. >+ // >+ >+ const absl::Duration qns = absl::Nanoseconds(1) / 4; >+ const absl::Duration max_dur = >+ absl::Seconds(kint64max) + (absl::Seconds(1) - qns); >+ const absl::Duration min_dur = absl::Seconds(kint64min); >+ >+ EXPECT_EQ("0.25ns", absl::FormatDuration(qns)); >+ EXPECT_EQ("-0.25ns", absl::FormatDuration(-qns)); >+ EXPECT_EQ("2562047788015215h30m7.99999999975s", >+ absl::FormatDuration(max_dur)); >+ EXPECT_EQ("-2562047788015215h30m8s", absl::FormatDuration(min_dur)); >+ >+ // Tests printing full precision from units that print using FDivDuration >+ EXPECT_EQ("55.00000000025s", absl::FormatDuration(absl::Seconds(55) + qns)); >+ EXPECT_EQ("55.00000025ms", >+ absl::FormatDuration(absl::Milliseconds(55) + qns)); >+ EXPECT_EQ("55.00025us", absl::FormatDuration(absl::Microseconds(55) + qns)); >+ EXPECT_EQ("55.25ns", absl::FormatDuration(absl::Nanoseconds(55) + qns)); >+ >+ // Formatting infinity >+ EXPECT_EQ("inf", absl::FormatDuration(absl::InfiniteDuration())); >+ EXPECT_EQ("-inf", absl::FormatDuration(-absl::InfiniteDuration())); >+ >+ // Formatting approximately +/- 100 billion years >+ const absl::Duration huge_range = ApproxYears(100000000000); >+ EXPECT_EQ("876000000000000h", absl::FormatDuration(huge_range)); >+ EXPECT_EQ("-876000000000000h", absl::FormatDuration(-huge_range)); >+ >+ EXPECT_EQ("876000000000000h0.999999999s", >+ absl::FormatDuration(huge_range + >+ (absl::Seconds(1) - absl::Nanoseconds(1)))); >+ EXPECT_EQ("876000000000000h0.9999999995s", >+ absl::FormatDuration( >+ huge_range + (absl::Seconds(1) - absl::Nanoseconds(1) / 2))); >+ EXPECT_EQ("876000000000000h0.99999999975s", >+ absl::FormatDuration( >+ huge_range + (absl::Seconds(1) - absl::Nanoseconds(1) / 4))); >+ >+ EXPECT_EQ("-876000000000000h0.999999999s", >+ absl::FormatDuration(-huge_range - >+ (absl::Seconds(1) - absl::Nanoseconds(1)))); >+ EXPECT_EQ("-876000000000000h0.9999999995s", >+ absl::FormatDuration( >+ -huge_range - (absl::Seconds(1) - absl::Nanoseconds(1) / 2))); >+ EXPECT_EQ("-876000000000000h0.99999999975s", >+ absl::FormatDuration( >+ -huge_range - (absl::Seconds(1) - absl::Nanoseconds(1) / 4))); >+} >+ >+TEST(Duration, ParseDuration) { >+ absl::Duration d; >+ >+ // No specified unit. Should only work for zero and infinity. >+ EXPECT_TRUE(absl::ParseDuration("0", &d)); >+ EXPECT_EQ(absl::ZeroDuration(), d); >+ EXPECT_TRUE(absl::ParseDuration("+0", &d)); >+ EXPECT_EQ(absl::ZeroDuration(), d); >+ EXPECT_TRUE(absl::ParseDuration("-0", &d)); >+ EXPECT_EQ(absl::ZeroDuration(), d); >+ >+ EXPECT_TRUE(absl::ParseDuration("inf", &d)); >+ EXPECT_EQ(absl::InfiniteDuration(), d); >+ EXPECT_TRUE(absl::ParseDuration("+inf", &d)); >+ EXPECT_EQ(absl::InfiniteDuration(), d); >+ EXPECT_TRUE(absl::ParseDuration("-inf", &d)); >+ EXPECT_EQ(-absl::InfiniteDuration(), d); >+ EXPECT_FALSE(absl::ParseDuration("infBlah", &d)); >+ >+ // Illegal input forms. >+ EXPECT_FALSE(absl::ParseDuration("", &d)); >+ EXPECT_FALSE(absl::ParseDuration("0.0", &d)); >+ EXPECT_FALSE(absl::ParseDuration(".0", &d)); >+ EXPECT_FALSE(absl::ParseDuration(".", &d)); >+ EXPECT_FALSE(absl::ParseDuration("01", &d)); >+ EXPECT_FALSE(absl::ParseDuration("1", &d)); >+ EXPECT_FALSE(absl::ParseDuration("-1", &d)); >+ EXPECT_FALSE(absl::ParseDuration("2", &d)); >+ EXPECT_FALSE(absl::ParseDuration("2 s", &d)); >+ EXPECT_FALSE(absl::ParseDuration(".s", &d)); >+ EXPECT_FALSE(absl::ParseDuration("-.s", &d)); >+ EXPECT_FALSE(absl::ParseDuration("s", &d)); >+ EXPECT_FALSE(absl::ParseDuration(" 2s", &d)); >+ EXPECT_FALSE(absl::ParseDuration("2s ", &d)); >+ EXPECT_FALSE(absl::ParseDuration(" 2s ", &d)); >+ EXPECT_FALSE(absl::ParseDuration("2mt", &d)); >+ EXPECT_FALSE(absl::ParseDuration("1e3s", &d)); >+ >+ // One unit type. >+ EXPECT_TRUE(absl::ParseDuration("1ns", &d)); >+ EXPECT_EQ(absl::Nanoseconds(1), d); >+ EXPECT_TRUE(absl::ParseDuration("1us", &d)); >+ EXPECT_EQ(absl::Microseconds(1), d); >+ EXPECT_TRUE(absl::ParseDuration("1ms", &d)); >+ EXPECT_EQ(absl::Milliseconds(1), d); >+ EXPECT_TRUE(absl::ParseDuration("1s", &d)); >+ EXPECT_EQ(absl::Seconds(1), d); >+ EXPECT_TRUE(absl::ParseDuration("2m", &d)); >+ EXPECT_EQ(absl::Minutes(2), d); >+ EXPECT_TRUE(absl::ParseDuration("2h", &d)); >+ EXPECT_EQ(absl::Hours(2), d); >+ >+ // Huge counts of a unit. >+ EXPECT_TRUE(absl::ParseDuration("9223372036854775807us", &d)); >+ EXPECT_EQ(absl::Microseconds(9223372036854775807), d); >+ EXPECT_TRUE(absl::ParseDuration("-9223372036854775807us", &d)); >+ EXPECT_EQ(absl::Microseconds(-9223372036854775807), d); >+ >+ // Multiple units. >+ EXPECT_TRUE(absl::ParseDuration("2h3m4s", &d)); >+ EXPECT_EQ(absl::Hours(2) + absl::Minutes(3) + absl::Seconds(4), d); >+ EXPECT_TRUE(absl::ParseDuration("3m4s5us", &d)); >+ EXPECT_EQ(absl::Minutes(3) + absl::Seconds(4) + absl::Microseconds(5), d); >+ EXPECT_TRUE(absl::ParseDuration("2h3m4s5ms6us7ns", &d)); >+ EXPECT_EQ(absl::Hours(2) + absl::Minutes(3) + absl::Seconds(4) + >+ absl::Milliseconds(5) + absl::Microseconds(6) + >+ absl::Nanoseconds(7), >+ d); >+ >+ // Multiple units out of order. >+ EXPECT_TRUE(absl::ParseDuration("2us3m4s5h", &d)); >+ EXPECT_EQ(absl::Hours(5) + absl::Minutes(3) + absl::Seconds(4) + >+ absl::Microseconds(2), >+ d); >+ >+ // Fractional values of units. >+ EXPECT_TRUE(absl::ParseDuration("1.5ns", &d)); >+ EXPECT_EQ(1.5 * absl::Nanoseconds(1), d); >+ EXPECT_TRUE(absl::ParseDuration("1.5us", &d)); >+ EXPECT_EQ(1.5 * absl::Microseconds(1), d); >+ EXPECT_TRUE(absl::ParseDuration("1.5ms", &d)); >+ EXPECT_EQ(1.5 * absl::Milliseconds(1), d); >+ EXPECT_TRUE(absl::ParseDuration("1.5s", &d)); >+ EXPECT_EQ(1.5 * absl::Seconds(1), d); >+ EXPECT_TRUE(absl::ParseDuration("1.5m", &d)); >+ EXPECT_EQ(1.5 * absl::Minutes(1), d); >+ EXPECT_TRUE(absl::ParseDuration("1.5h", &d)); >+ EXPECT_EQ(1.5 * absl::Hours(1), d); >+ >+ // Huge fractional counts of a unit. >+ EXPECT_TRUE(absl::ParseDuration("0.4294967295s", &d)); >+ EXPECT_EQ(absl::Nanoseconds(429496729) + absl::Nanoseconds(1) / 2, d); >+ EXPECT_TRUE(absl::ParseDuration("0.429496729501234567890123456789s", &d)); >+ EXPECT_EQ(absl::Nanoseconds(429496729) + absl::Nanoseconds(1) / 2, d); >+ >+ // Negative durations. >+ EXPECT_TRUE(absl::ParseDuration("-1s", &d)); >+ EXPECT_EQ(absl::Seconds(-1), d); >+ EXPECT_TRUE(absl::ParseDuration("-1m", &d)); >+ EXPECT_EQ(absl::Minutes(-1), d); >+ EXPECT_TRUE(absl::ParseDuration("-1h", &d)); >+ EXPECT_EQ(absl::Hours(-1), d); >+ >+ EXPECT_TRUE(absl::ParseDuration("-1h2s", &d)); >+ EXPECT_EQ(-(absl::Hours(1) + absl::Seconds(2)), d); >+ EXPECT_FALSE(absl::ParseDuration("1h-2s", &d)); >+ EXPECT_FALSE(absl::ParseDuration("-1h-2s", &d)); >+ EXPECT_FALSE(absl::ParseDuration("-1h -2s", &d)); >+} >+ >+TEST(Duration, FormatParseRoundTrip) { >+#define TEST_PARSE_ROUNDTRIP(d) \ >+ do { \ >+ std::string s = absl::FormatDuration(d); \ >+ absl::Duration dur; \ >+ EXPECT_TRUE(absl::ParseDuration(s, &dur)); \ >+ EXPECT_EQ(d, dur); \ >+ } while (0) >+ >+ TEST_PARSE_ROUNDTRIP(absl::Nanoseconds(1)); >+ TEST_PARSE_ROUNDTRIP(absl::Microseconds(1)); >+ TEST_PARSE_ROUNDTRIP(absl::Milliseconds(1)); >+ TEST_PARSE_ROUNDTRIP(absl::Seconds(1)); >+ TEST_PARSE_ROUNDTRIP(absl::Minutes(1)); >+ TEST_PARSE_ROUNDTRIP(absl::Hours(1)); >+ TEST_PARSE_ROUNDTRIP(absl::Hours(1) + absl::Nanoseconds(2)); >+ >+ TEST_PARSE_ROUNDTRIP(absl::Nanoseconds(-1)); >+ TEST_PARSE_ROUNDTRIP(absl::Microseconds(-1)); >+ TEST_PARSE_ROUNDTRIP(absl::Milliseconds(-1)); >+ TEST_PARSE_ROUNDTRIP(absl::Seconds(-1)); >+ TEST_PARSE_ROUNDTRIP(absl::Minutes(-1)); >+ TEST_PARSE_ROUNDTRIP(absl::Hours(-1)); >+ >+ TEST_PARSE_ROUNDTRIP(absl::Hours(-1) + absl::Nanoseconds(2)); >+ TEST_PARSE_ROUNDTRIP(absl::Hours(1) + absl::Nanoseconds(-2)); >+ TEST_PARSE_ROUNDTRIP(absl::Hours(-1) + absl::Nanoseconds(-2)); >+ >+ TEST_PARSE_ROUNDTRIP(absl::Nanoseconds(1) + >+ absl::Nanoseconds(1) / 4); // 1.25ns >+ >+ const absl::Duration huge_range = ApproxYears(100000000000); >+ TEST_PARSE_ROUNDTRIP(huge_range); >+ TEST_PARSE_ROUNDTRIP(huge_range + (absl::Seconds(1) - absl::Nanoseconds(1))); >+ >+#undef TEST_PARSE_ROUNDTRIP >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/format.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/format.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e98e60a372bfc3a4472c8a17ac7a5383782b887a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/format.cc >@@ -0,0 +1,139 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <string.h> >+#include <cctype> >+#include <cstdint> >+ >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+#include "absl/time/time.h" >+ >+namespace cctz = absl::time_internal::cctz; >+ >+namespace absl { >+ >+extern const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez"; >+extern const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; >+ >+extern const char RFC1123_full[] = "%a, %d %b %E4Y %H:%M:%S %z"; >+extern const char RFC1123_no_wday[] = "%d %b %E4Y %H:%M:%S %z"; >+ >+namespace { >+ >+const char kInfiniteFutureStr[] = "infinite-future"; >+const char kInfinitePastStr[] = "infinite-past"; >+ >+struct cctz_parts { >+ cctz::time_point<cctz::seconds> sec; >+ cctz::detail::femtoseconds fem; >+}; >+ >+inline cctz::time_point<cctz::seconds> unix_epoch() { >+ return std::chrono::time_point_cast<cctz::seconds>( >+ std::chrono::system_clock::from_time_t(0)); >+} >+ >+// Splits a Time into seconds and femtoseconds, which can be used with CCTZ. >+// Requires that 't' is finite. See duration.cc for details about rep_hi and >+// rep_lo. >+cctz_parts Split(absl::Time t) { >+ const auto d = time_internal::ToUnixDuration(t); >+ const int64_t rep_hi = time_internal::GetRepHi(d); >+ const int64_t rep_lo = time_internal::GetRepLo(d); >+ const auto sec = unix_epoch() + cctz::seconds(rep_hi); >+ const auto fem = cctz::detail::femtoseconds(rep_lo * (1000 * 1000 / 4)); >+ return {sec, fem}; >+} >+ >+// Joins the given seconds and femtoseconds into a Time. See duration.cc for >+// details about rep_hi and rep_lo. >+absl::Time Join(const cctz_parts& parts) { >+ const int64_t rep_hi = (parts.sec - unix_epoch()).count(); >+ const uint32_t rep_lo = parts.fem.count() / (1000 * 1000 / 4); >+ const auto d = time_internal::MakeDuration(rep_hi, rep_lo); >+ return time_internal::FromUnixDuration(d); >+} >+ >+} // namespace >+ >+std::string FormatTime(const std::string& format, absl::Time t, absl::TimeZone tz) { >+ if (t == absl::InfiniteFuture()) return kInfiniteFutureStr; >+ if (t == absl::InfinitePast()) return kInfinitePastStr; >+ const auto parts = Split(t); >+ return cctz::detail::format(format, parts.sec, parts.fem, >+ cctz::time_zone(tz)); >+} >+ >+std::string FormatTime(absl::Time t, absl::TimeZone tz) { >+ return FormatTime(RFC3339_full, t, tz); >+} >+ >+std::string FormatTime(absl::Time t) { >+ return absl::FormatTime(RFC3339_full, t, absl::LocalTimeZone()); >+} >+ >+bool ParseTime(const std::string& format, const std::string& input, absl::Time* time, >+ std::string* err) { >+ return absl::ParseTime(format, input, absl::UTCTimeZone(), time, err); >+} >+ >+// If the input std::string does not contain an explicit UTC offset, interpret >+// the fields with respect to the given TimeZone. >+bool ParseTime(const std::string& format, const std::string& input, absl::TimeZone tz, >+ absl::Time* time, std::string* err) { >+ const char* data = input.c_str(); >+ while (std::isspace(*data)) ++data; >+ >+ size_t inf_size = strlen(kInfiniteFutureStr); >+ if (strncmp(data, kInfiniteFutureStr, inf_size) == 0) { >+ const char* new_data = data + inf_size; >+ while (std::isspace(*new_data)) ++new_data; >+ if (*new_data == '\0') { >+ *time = InfiniteFuture(); >+ return true; >+ } >+ } >+ >+ inf_size = strlen(kInfinitePastStr); >+ if (strncmp(data, kInfinitePastStr, inf_size) == 0) { >+ const char* new_data = data + inf_size; >+ while (std::isspace(*new_data)) ++new_data; >+ if (*new_data == '\0') { >+ *time = InfinitePast(); >+ return true; >+ } >+ } >+ >+ std::string error; >+ cctz_parts parts; >+ const bool b = cctz::detail::parse(format, input, cctz::time_zone(tz), >+ &parts.sec, &parts.fem, &error); >+ if (b) { >+ *time = Join(parts); >+ } else if (err != nullptr) { >+ *err = error; >+ } >+ return b; >+} >+ >+// Functions required to support absl::Time flags. >+bool ParseFlag(const std::string& text, absl::Time* t, std::string* error) { >+ return absl::ParseTime(RFC3339_full, text, absl::UTCTimeZone(), t, error); >+} >+ >+std::string UnparseFlag(absl::Time t) { >+ return absl::FormatTime(RFC3339_full, t, absl::UTCTimeZone()); >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/format_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/format_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..ee53d71c685484c291b647cf09f5a5c90b9772f3 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/format_benchmark.cc >@@ -0,0 +1,63 @@ >+// Copyright 2018 The Abseil Authors. >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <cstddef> >+#include <string> >+ >+#include "absl/time/internal/test_util.h" >+#include "absl/time/time.h" >+#include "benchmark/benchmark.h" >+ >+namespace { >+ >+namespace { >+const char* const kFormats[] = { >+ absl::RFC1123_full, // 0 >+ absl::RFC1123_no_wday, // 1 >+ absl::RFC3339_full, // 2 >+ absl::RFC3339_sec, // 3 >+ "%Y-%m-%dT%H:%M:%S", // 4 >+ "%Y-%m-%d", // 5 >+}; >+const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]); >+} // namespace >+ >+void BM_Format_FormatTime(benchmark::State& state) { >+ const std::string fmt = kFormats[state.range(0)]; >+ state.SetLabel(fmt); >+ const absl::TimeZone lax = >+ absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ const absl::Time t = >+ absl::FromDateTime(1977, 6, 28, 9, 8, 7, lax) + absl::Nanoseconds(1); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::FormatTime(fmt, t, lax).length()); >+ } >+} >+BENCHMARK(BM_Format_FormatTime)->DenseRange(0, kNumFormats - 1); >+ >+void BM_Format_ParseTime(benchmark::State& state) { >+ const std::string fmt = kFormats[state.range(0)]; >+ state.SetLabel(fmt); >+ const absl::TimeZone lax = >+ absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ absl::Time t = >+ absl::FromDateTime(1977, 6, 28, 9, 8, 7, lax) + absl::Nanoseconds(1); >+ const std::string when = absl::FormatTime(fmt, t, lax); >+ std::string err; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ParseTime(fmt, when, lax, &t, &err)); >+ } >+} >+BENCHMARK(BM_Format_ParseTime)->DenseRange(0, kNumFormats - 1); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/format_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/format_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..7c84c33f1eb55c230eead44613f07db08afef283 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/format_test.cc >@@ -0,0 +1,434 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <cstdint> >+#include <limits> >+#include <string> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/time/internal/test_util.h" >+#include "absl/time/time.h" >+ >+using testing::HasSubstr; >+ >+namespace { >+ >+// A helper that tests the given format specifier by itself, and with leading >+// and trailing characters. For example: TestFormatSpecifier(t, "%a", "Thu"). >+void TestFormatSpecifier(absl::Time t, absl::TimeZone tz, const std::string& fmt, >+ const std::string& ans) { >+ EXPECT_EQ(ans, absl::FormatTime(fmt, t, tz)); >+ EXPECT_EQ("xxx " + ans, absl::FormatTime("xxx " + fmt, t, tz)); >+ EXPECT_EQ(ans + " yyy", absl::FormatTime(fmt + " yyy", t, tz)); >+ EXPECT_EQ("xxx " + ans + " yyy", >+ absl::FormatTime("xxx " + fmt + " yyy", t, tz)); >+} >+ >+// >+// Testing FormatTime() >+// >+ >+TEST(FormatTime, Basics) { >+ absl::TimeZone tz = absl::UTCTimeZone(); >+ absl::Time t = absl::FromTimeT(0); >+ >+ // Starts with a couple basic edge cases. >+ EXPECT_EQ("", absl::FormatTime("", t, tz)); >+ EXPECT_EQ(" ", absl::FormatTime(" ", t, tz)); >+ EXPECT_EQ(" ", absl::FormatTime(" ", t, tz)); >+ EXPECT_EQ("xxx", absl::FormatTime("xxx", t, tz)); >+ std::string big(128, 'x'); >+ EXPECT_EQ(big, absl::FormatTime(big, t, tz)); >+ // Cause the 1024-byte buffer to grow. >+ std::string bigger(100000, 'x'); >+ EXPECT_EQ(bigger, absl::FormatTime(bigger, t, tz)); >+ >+ t += absl::Hours(13) + absl::Minutes(4) + absl::Seconds(5); >+ t += absl::Milliseconds(6) + absl::Microseconds(7) + absl::Nanoseconds(8); >+ EXPECT_EQ("1970-01-01", absl::FormatTime("%Y-%m-%d", t, tz)); >+ EXPECT_EQ("13:04:05", absl::FormatTime("%H:%M:%S", t, tz)); >+ EXPECT_EQ("13:04:05.006", absl::FormatTime("%H:%M:%E3S", t, tz)); >+ EXPECT_EQ("13:04:05.006007", absl::FormatTime("%H:%M:%E6S", t, tz)); >+ EXPECT_EQ("13:04:05.006007008", absl::FormatTime("%H:%M:%E9S", t, tz)); >+} >+ >+TEST(FormatTime, LocaleSpecific) { >+ const absl::TimeZone tz = absl::UTCTimeZone(); >+ absl::Time t = absl::FromTimeT(0); >+ >+ TestFormatSpecifier(t, tz, "%a", "Thu"); >+ TestFormatSpecifier(t, tz, "%A", "Thursday"); >+ TestFormatSpecifier(t, tz, "%b", "Jan"); >+ TestFormatSpecifier(t, tz, "%B", "January"); >+ >+ // %c should at least produce the numeric year and time-of-day. >+ const std::string s = >+ absl::FormatTime("%c", absl::FromTimeT(0), absl::UTCTimeZone()); >+ EXPECT_THAT(s, HasSubstr("1970")); >+ EXPECT_THAT(s, HasSubstr("00:00:00")); >+ >+ TestFormatSpecifier(t, tz, "%p", "AM"); >+ TestFormatSpecifier(t, tz, "%x", "01/01/70"); >+ TestFormatSpecifier(t, tz, "%X", "00:00:00"); >+} >+ >+TEST(FormatTime, ExtendedSeconds) { >+ const absl::TimeZone tz = absl::UTCTimeZone(); >+ >+ // No subseconds. >+ absl::Time t = absl::FromTimeT(0) + absl::Seconds(5); >+ EXPECT_EQ("05", absl::FormatTime("%E*S", t, tz)); >+ EXPECT_EQ("05.000000000000000", absl::FormatTime("%E15S", t, tz)); >+ >+ // With subseconds. >+ t += absl::Milliseconds(6) + absl::Microseconds(7) + absl::Nanoseconds(8); >+ EXPECT_EQ("05.006007008", absl::FormatTime("%E*S", t, tz)); >+ EXPECT_EQ("05", absl::FormatTime("%E0S", t, tz)); >+ EXPECT_EQ("05.006007008000000", absl::FormatTime("%E15S", t, tz)); >+ >+ // Times before the Unix epoch. >+ t = absl::FromUnixMicros(-1); >+ EXPECT_EQ("1969-12-31 23:59:59.999999", >+ absl::FormatTime("%Y-%m-%d %H:%M:%E*S", t, tz)); >+ >+ // Here is a "%E*S" case we got wrong for a while. While the first >+ // instant below is correctly rendered as "...:07.333304", the second >+ // one used to appear as "...:07.33330499999999999". >+ t = absl::FromUnixMicros(1395024427333304); >+ EXPECT_EQ("2014-03-17 02:47:07.333304", >+ absl::FormatTime("%Y-%m-%d %H:%M:%E*S", t, tz)); >+ t += absl::Microseconds(1); >+ EXPECT_EQ("2014-03-17 02:47:07.333305", >+ absl::FormatTime("%Y-%m-%d %H:%M:%E*S", t, tz)); >+} >+ >+TEST(FormatTime, RFC1123FormatPadsYear) { // locale specific >+ absl::TimeZone tz = absl::UTCTimeZone(); >+ >+ // A year of 77 should be padded to 0077. >+ absl::Time t = absl::FromDateTime(77, 6, 28, 9, 8, 7, tz); >+ EXPECT_EQ("Mon, 28 Jun 0077 09:08:07 +0000", >+ absl::FormatTime(absl::RFC1123_full, t, tz)); >+ EXPECT_EQ("28 Jun 0077 09:08:07 +0000", >+ absl::FormatTime(absl::RFC1123_no_wday, t, tz)); >+} >+ >+TEST(FormatTime, InfiniteTime) { >+ absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ >+ // The format and timezone are ignored. >+ EXPECT_EQ("infinite-future", >+ absl::FormatTime("%H:%M blah", absl::InfiniteFuture(), tz)); >+ EXPECT_EQ("infinite-past", >+ absl::FormatTime("%H:%M blah", absl::InfinitePast(), tz)); >+} >+ >+// >+// Testing ParseTime() >+// >+ >+TEST(ParseTime, Basics) { >+ absl::Time t = absl::FromTimeT(1234567890); >+ std::string err; >+ >+ // Simple edge cases. >+ EXPECT_TRUE(absl::ParseTime("", "", &t, &err)) << err; >+ EXPECT_EQ(absl::UnixEpoch(), t); // everything defaulted >+ EXPECT_TRUE(absl::ParseTime(" ", " ", &t, &err)) << err; >+ EXPECT_TRUE(absl::ParseTime(" ", " ", &t, &err)) << err; >+ EXPECT_TRUE(absl::ParseTime("x", "x", &t, &err)) << err; >+ EXPECT_TRUE(absl::ParseTime("xxx", "xxx", &t, &err)) << err; >+ >+ EXPECT_TRUE(absl::ParseTime("%Y-%m-%d %H:%M:%S %z", >+ "2013-06-28 19:08:09 -0800", &t, &err)) >+ << err; >+ absl::Time::Breakdown bd = t.In(absl::FixedTimeZone(-8 * 60 * 60)); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 6, 28, 19, 8, 9, -8 * 60 * 60, false); >+ EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); >+} >+ >+TEST(ParseTime, NullErrorString) { >+ absl::Time t; >+ EXPECT_FALSE(absl::ParseTime("%Q", "invalid format", &t, nullptr)); >+ EXPECT_FALSE(absl::ParseTime("%H", "12 trailing data", &t, nullptr)); >+ EXPECT_FALSE( >+ absl::ParseTime("%H out of range", "42 out of range", &t, nullptr)); >+} >+ >+TEST(ParseTime, WithTimeZone) { >+ const absl::TimeZone tz = >+ absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ absl::Time t; >+ std::string e; >+ >+ // We can parse a std::string without a UTC offset if we supply a timezone. >+ EXPECT_TRUE( >+ absl::ParseTime("%Y-%m-%d %H:%M:%S", "2013-06-28 19:08:09", tz, &t, &e)) >+ << e; >+ absl::Time::Breakdown bd = t.In(tz); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 6, 28, 19, 8, 9, -7 * 60 * 60, true); >+ EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); >+ >+ // But the timezone is ignored when a UTC offset is present. >+ EXPECT_TRUE(absl::ParseTime("%Y-%m-%d %H:%M:%S %z", >+ "2013-06-28 19:08:09 +0800", tz, &t, &e)) >+ << e; >+ bd = t.In(absl::FixedTimeZone(8 * 60 * 60)); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 6, 28, 19, 8, 9, 8 * 60 * 60, false); >+ EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); >+} >+ >+TEST(ParseTime, ErrorCases) { >+ absl::Time t = absl::FromTimeT(0); >+ std::string err; >+ >+ EXPECT_FALSE(absl::ParseTime("%S", "123", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Illegal trailing data")); >+ >+ // Can't parse an illegal format specifier. >+ err.clear(); >+ EXPECT_FALSE(absl::ParseTime("%Q", "x", &t, &err)) << err; >+ // Exact contents of "err" are platform-dependent because of >+ // differences in the strptime implementation between OSX and Linux. >+ EXPECT_FALSE(err.empty()); >+ >+ // Fails because of trailing, unparsed data "blah". >+ EXPECT_FALSE(absl::ParseTime("%m-%d", "2-3 blah", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Illegal trailing data")); >+ >+ // Feb 31 requires normalization. >+ EXPECT_FALSE(absl::ParseTime("%m-%d", "2-31", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Out-of-range")); >+ >+ // Check that we cannot have spaces in UTC offsets. >+ EXPECT_TRUE(absl::ParseTime("%z", "-0203", &t, &err)) << err; >+ EXPECT_FALSE(absl::ParseTime("%z", "- 2 3", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ EXPECT_TRUE(absl::ParseTime("%Ez", "-02:03", &t, &err)) << err; >+ EXPECT_FALSE(absl::ParseTime("%Ez", "- 2: 3", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ >+ // Check that we reject other malformed UTC offsets. >+ EXPECT_FALSE(absl::ParseTime("%Ez", "+-08:00", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ EXPECT_FALSE(absl::ParseTime("%Ez", "-+08:00", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ >+ // Check that we do not accept "-0" in fields that allow zero. >+ EXPECT_FALSE(absl::ParseTime("%Y", "-0", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ EXPECT_FALSE(absl::ParseTime("%E4Y", "-0", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ EXPECT_FALSE(absl::ParseTime("%H", "-0", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ EXPECT_FALSE(absl::ParseTime("%M", "-0", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ EXPECT_FALSE(absl::ParseTime("%S", "-0", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ EXPECT_FALSE(absl::ParseTime("%z", "+-000", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ EXPECT_FALSE(absl::ParseTime("%Ez", "+-0:00", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ EXPECT_FALSE(absl::ParseTime("%z", "-00-0", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Illegal trailing data")); >+ EXPECT_FALSE(absl::ParseTime("%Ez", "-00:-0", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Illegal trailing data")); >+} >+ >+TEST(ParseTime, ExtendedSeconds) { >+ std::string err; >+ absl::Time t; >+ >+ // Here is a "%E*S" case we got wrong for a while. The fractional >+ // part of the first instant is less than 2^31 and was correctly >+ // parsed, while the second (and any subsecond field >=2^31) failed. >+ t = absl::UnixEpoch(); >+ EXPECT_TRUE(absl::ParseTime("%E*S", "0.2147483647", &t, &err)) << err; >+ EXPECT_EQ(absl::UnixEpoch() + absl::Nanoseconds(214748364) + >+ absl::Nanoseconds(1) / 2, >+ t); >+ t = absl::UnixEpoch(); >+ EXPECT_TRUE(absl::ParseTime("%E*S", "0.2147483648", &t, &err)) << err; >+ EXPECT_EQ(absl::UnixEpoch() + absl::Nanoseconds(214748364) + >+ absl::Nanoseconds(3) / 4, >+ t); >+ >+ // We should also be able to specify long strings of digits far >+ // beyond the current resolution and have them convert the same way. >+ t = absl::UnixEpoch(); >+ EXPECT_TRUE(absl::ParseTime( >+ "%E*S", "0.214748364801234567890123456789012345678901234567890123456789", >+ &t, &err)) >+ << err; >+ EXPECT_EQ(absl::UnixEpoch() + absl::Nanoseconds(214748364) + >+ absl::Nanoseconds(3) / 4, >+ t); >+} >+ >+TEST(ParseTime, ExtendedOffsetErrors) { >+ std::string err; >+ absl::Time t; >+ >+ // %z against +-HHMM. >+ EXPECT_FALSE(absl::ParseTime("%z", "-123", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Illegal trailing data")); >+ >+ // %z against +-HH. >+ EXPECT_FALSE(absl::ParseTime("%z", "-1", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+ >+ // %Ez against +-HH:MM. >+ EXPECT_FALSE(absl::ParseTime("%Ez", "-12:3", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Illegal trailing data")); >+ >+ // %Ez against +-HHMM. >+ EXPECT_FALSE(absl::ParseTime("%Ez", "-123", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Illegal trailing data")); >+ >+ // %Ez against +-HH. >+ EXPECT_FALSE(absl::ParseTime("%Ez", "-1", &t, &err)) << err; >+ EXPECT_THAT(err, HasSubstr("Failed to parse")); >+} >+ >+TEST(ParseTime, InfiniteTime) { >+ absl::Time t; >+ std::string err; >+ EXPECT_TRUE(absl::ParseTime("%H:%M blah", "infinite-future", &t, &err)); >+ EXPECT_EQ(absl::InfiniteFuture(), t); >+ >+ // Surrounding whitespace. >+ EXPECT_TRUE(absl::ParseTime("%H:%M blah", " infinite-future", &t, &err)); >+ EXPECT_EQ(absl::InfiniteFuture(), t); >+ EXPECT_TRUE(absl::ParseTime("%H:%M blah", "infinite-future ", &t, &err)); >+ EXPECT_EQ(absl::InfiniteFuture(), t); >+ EXPECT_TRUE(absl::ParseTime("%H:%M blah", " infinite-future ", &t, &err)); >+ EXPECT_EQ(absl::InfiniteFuture(), t); >+ >+ EXPECT_TRUE(absl::ParseTime("%H:%M blah", "infinite-past", &t, &err)); >+ EXPECT_EQ(absl::InfinitePast(), t); >+ >+ // Surrounding whitespace. >+ EXPECT_TRUE(absl::ParseTime("%H:%M blah", " infinite-past", &t, &err)); >+ EXPECT_EQ(absl::InfinitePast(), t); >+ EXPECT_TRUE(absl::ParseTime("%H:%M blah", "infinite-past ", &t, &err)); >+ EXPECT_EQ(absl::InfinitePast(), t); >+ EXPECT_TRUE(absl::ParseTime("%H:%M blah", " infinite-past ", &t, &err)); >+ EXPECT_EQ(absl::InfinitePast(), t); >+ >+ // "infinite-future" as literal std::string >+ absl::TimeZone tz = absl::UTCTimeZone(); >+ EXPECT_TRUE(absl::ParseTime("infinite-future %H:%M", "infinite-future 03:04", >+ &t, &err)); >+ EXPECT_NE(absl::InfiniteFuture(), t); >+ EXPECT_EQ(3, t.In(tz).hour); >+ EXPECT_EQ(4, t.In(tz).minute); >+ >+ // "infinite-past" as literal std::string >+ EXPECT_TRUE( >+ absl::ParseTime("infinite-past %H:%M", "infinite-past 03:04", &t, &err)); >+ EXPECT_NE(absl::InfinitePast(), t); >+ EXPECT_EQ(3, t.In(tz).hour); >+ EXPECT_EQ(4, t.In(tz).minute); >+ >+ // The input doesn't match the format. >+ EXPECT_FALSE(absl::ParseTime("infinite-future %H:%M", "03:04", &t, &err)); >+ EXPECT_FALSE(absl::ParseTime("infinite-past %H:%M", "03:04", &t, &err)); >+} >+ >+TEST(ParseTime, FailsOnUnrepresentableTime) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ absl::Time t; >+ EXPECT_FALSE( >+ absl::ParseTime("%Y-%m-%d", "-292277022657-01-27", utc, &t, nullptr)); >+ EXPECT_TRUE( >+ absl::ParseTime("%Y-%m-%d", "-292277022657-01-28", utc, &t, nullptr)); >+ EXPECT_TRUE( >+ absl::ParseTime("%Y-%m-%d", "292277026596-12-04", utc, &t, nullptr)); >+ EXPECT_FALSE( >+ absl::ParseTime("%Y-%m-%d", "292277026596-12-05", utc, &t, nullptr)); >+} >+ >+// >+// Roundtrip test for FormatTime()/ParseTime(). >+// >+ >+TEST(FormatParse, RoundTrip) { >+ const absl::TimeZone gst = >+ absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ const absl::Time in = absl::FromDateTime(1977, 6, 28, 9, 8, 7, gst); >+ const absl::Duration subseconds = absl::Nanoseconds(654321); >+ std::string err; >+ >+ // RFC3339, which renders subseconds. >+ { >+ absl::Time out; >+ const std::string s = absl::FormatTime(absl::RFC3339_full, in + subseconds, gst); >+ EXPECT_TRUE(absl::ParseTime(absl::RFC3339_full, s, &out, &err)) >+ << s << ": " << err; >+ EXPECT_EQ(in + subseconds, out); // RFC3339_full includes %Ez >+ } >+ >+ // RFC1123, which only does whole seconds. >+ { >+ absl::Time out; >+ const std::string s = absl::FormatTime(absl::RFC1123_full, in, gst); >+ EXPECT_TRUE(absl::ParseTime(absl::RFC1123_full, s, &out, &err)) >+ << s << ": " << err; >+ EXPECT_EQ(in, out); // RFC1123_full includes %z >+ } >+ >+ // `absl::FormatTime()` falls back to strftime() for "%c", which appears to >+ // work. On Windows, `absl::ParseTime()` falls back to std::get_time() which >+ // appears to fail on "%c" (or at least on the "%c" text produced by >+ // `strftime()`). This makes it fail the round-trip test. >+#ifndef _MSC_VER >+ // Even though we don't know what %c will produce, it should roundtrip, >+ // but only in the 0-offset timezone. >+ { >+ absl::Time out; >+ const std::string s = absl::FormatTime("%c", in, absl::UTCTimeZone()); >+ EXPECT_TRUE(absl::ParseTime("%c", s, &out, &err)) << s << ": " << err; >+ EXPECT_EQ(in, out); >+ } >+#endif // _MSC_VER >+} >+ >+TEST(FormatParse, RoundTripDistantFuture) { >+ const absl::TimeZone tz = absl::UTCTimeZone(); >+ const absl::Time in = >+ absl::FromUnixSeconds(std::numeric_limits<int64_t>::max()); >+ std::string err; >+ >+ absl::Time out; >+ const std::string s = absl::FormatTime(absl::RFC3339_full, in, tz); >+ EXPECT_TRUE(absl::ParseTime(absl::RFC3339_full, s, &out, &err)) >+ << s << ": " << err; >+ EXPECT_EQ(in, out); >+} >+ >+TEST(FormatParse, RoundTripDistantPast) { >+ const absl::TimeZone tz = absl::UTCTimeZone(); >+ const absl::Time in = >+ absl::FromUnixSeconds(std::numeric_limits<int64_t>::min()); >+ std::string err; >+ >+ absl::Time out; >+ const std::string s = absl::FormatTime(absl::RFC3339_full, in, tz); >+ EXPECT_TRUE(absl::ParseTime(absl::RFC3339_full, s, &out, &err)) >+ << s << ": " << err; >+ EXPECT_EQ(in, out); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..9f1ba21cf7e21b22f3343f84001a434a83b606b5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel >@@ -0,0 +1,140 @@ >+# Copyright 2016 Google Inc. All Rights Reserved. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+ >+licenses(["notice"]) # Apache License >+ >+### libraries >+ >+cc_library( >+ name = "includes", >+ textual_hdrs = [ >+ "include/cctz/civil_time.h", >+ "include/cctz/civil_time_detail.h", >+ "include/cctz/time_zone.h", >+ ], >+ visibility = ["//absl/time:__pkg__"], >+) >+ >+cc_library( >+ name = "civil_time", >+ srcs = ["src/civil_time_detail.cc"], >+ hdrs = [ >+ "include/cctz/civil_time.h", >+ ], >+ textual_hdrs = ["include/cctz/civil_time_detail.h"], >+ visibility = ["//visibility:public"], >+) >+ >+cc_library( >+ name = "time_zone", >+ srcs = [ >+ "src/time_zone_fixed.cc", >+ "src/time_zone_fixed.h", >+ "src/time_zone_format.cc", >+ "src/time_zone_if.cc", >+ "src/time_zone_if.h", >+ "src/time_zone_impl.cc", >+ "src/time_zone_impl.h", >+ "src/time_zone_info.cc", >+ "src/time_zone_info.h", >+ "src/time_zone_libc.cc", >+ "src/time_zone_libc.h", >+ "src/time_zone_lookup.cc", >+ "src/time_zone_posix.cc", >+ "src/time_zone_posix.h", >+ "src/tzfile.h", >+ "src/zone_info_source.cc", >+ ], >+ hdrs = [ >+ "include/cctz/time_zone.h", >+ "include/cctz/zone_info_source.h", >+ ], >+ visibility = ["//visibility:public"], >+ deps = [":civil_time"], >+) >+ >+### tests >+ >+cc_test( >+ name = "civil_time_test", >+ size = "small", >+ srcs = ["src/civil_time_test.cc"], >+ deps = [ >+ ":civil_time", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "time_zone_format_test", >+ size = "small", >+ srcs = ["src/time_zone_format_test.cc"], >+ data = [":zoneinfo"], >+ tags = [ >+ "no_test_android_arm", >+ "no_test_android_arm64", >+ "no_test_android_x86", >+ ], >+ deps = [ >+ ":civil_time", >+ ":time_zone", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "time_zone_lookup_test", >+ size = "small", >+ srcs = ["src/time_zone_lookup_test.cc"], >+ data = [":zoneinfo"], >+ tags = [ >+ "no_test_android_arm", >+ "no_test_android_arm64", >+ "no_test_android_x86", >+ ], >+ deps = [ >+ ":civil_time", >+ ":time_zone", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+### benchmarks >+ >+cc_test( >+ name = "cctz_benchmark", >+ srcs = [ >+ "src/cctz_benchmark.cc", >+ "src/time_zone_if.h", >+ "src/time_zone_impl.h", >+ "src/time_zone_info.h", >+ "src/tzfile.h", >+ ], >+ linkstatic = 1, >+ tags = ["benchmark"], >+ deps = [ >+ ":civil_time", >+ ":time_zone", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+### examples >+ >+### binaries >+ >+filegroup( >+ name = "zoneinfo", >+ srcs = glob(["testdata/zoneinfo/**"]), >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..86417e7ce3c73563be6972980c38f9a486ace0a3 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.gn >@@ -0,0 +1,72 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("includes") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ "//build/config/compiler:no_chromium_code" ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "include/cctz/civil_time.h", >+ "include/cctz/civil_time_detail.h", >+ "include/cctz/time_zone.h", >+ ] >+ visibility = [] >+ visibility += [ "../time:*" ] >+} >+ >+source_set("civil_time") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ "//build/config/compiler:no_chromium_code" ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "src/civil_time_detail.cc", >+ ] >+ public = [ >+ "include/cctz/civil_time.h", >+ "include/cctz/civil_time_detail.h", >+ ] >+} >+ >+source_set("time_zone") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ "//build/config/compiler:no_chromium_code" ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "src/time_zone_fixed.cc", >+ "src/time_zone_fixed.h", >+ "src/time_zone_format.cc", >+ "src/time_zone_if.cc", >+ "src/time_zone_if.h", >+ "src/time_zone_impl.cc", >+ "src/time_zone_impl.h", >+ "src/time_zone_info.cc", >+ "src/time_zone_info.h", >+ "src/time_zone_libc.cc", >+ "src/time_zone_libc.h", >+ "src/time_zone_lookup.cc", >+ "src/time_zone_posix.cc", >+ "src/time_zone_posix.h", >+ "src/tzfile.h", >+ "src/zone_info_source.cc", >+ ] >+ public = [ >+ "include/cctz/time_zone.h", >+ "include/cctz/zone_info_source.h", >+ ] >+ deps = [ >+ ":civil_time", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h >new file mode 100644 >index 0000000000000000000000000000000000000000..898222b4c7af29830ea20507d9c294f2d0ef969c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h >@@ -0,0 +1,329 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_ >+#define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_ >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time_detail.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// The term "civil time" refers to the legally recognized human-scale time >+// that is represented by the six fields YYYY-MM-DD hh:mm:ss. Modern-day civil >+// time follows the Gregorian Calendar and is a time-zone-independent concept. >+// A "date" is perhaps the most common example of a civil time (represented in >+// this library as cctz::civil_day). This library provides six classes and a >+// handful of functions that help with rounding, iterating, and arithmetic on >+// civil times while avoiding complications like daylight-saving time (DST). >+// >+// The following six classes form the core of this civil-time library: >+// >+// * civil_second >+// * civil_minute >+// * civil_hour >+// * civil_day >+// * civil_month >+// * civil_year >+// >+// Each class is a simple value type with the same interface for construction >+// and the same six accessors for each of the civil fields (year, month, day, >+// hour, minute, and second, aka YMDHMS). These classes differ only in their >+// alignment, which is indicated by the type name and specifies the field on >+// which arithmetic operates. >+// >+// Each class can be constructed by passing up to six optional integer >+// arguments representing the YMDHMS fields (in that order) to the >+// constructor. Omitted fields are assigned their minimum valid value. Hours, >+// minutes, and seconds will be set to 0, month and day will be set to 1, and >+// since there is no minimum valid year, it will be set to 1970. So, a >+// default-constructed civil-time object will have YMDHMS fields representing >+// "1970-01-01 00:00:00". Fields that are out-of-range are normalized (e.g., >+// October 32 -> November 1) so that all civil-time objects represent valid >+// values. >+// >+// Each civil-time class is aligned to the civil-time field indicated in the >+// class's name after normalization. Alignment is performed by setting all the >+// inferior fields to their minimum valid value (as described above). The >+// following are examples of how each of the six types would align the fields >+// representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the >+// std::string format used here is not important; it's just a shorthand way of >+// showing the six YMDHMS fields.) >+// >+// civil_second 2015-11-22 12:34:56 >+// civil_minute 2015-11-22 12:34:00 >+// civil_hour 2015-11-22 12:00:00 >+// civil_day 2015-11-22 00:00:00 >+// civil_month 2015-11-01 00:00:00 >+// civil_year 2015-01-01 00:00:00 >+// >+// Each civil-time type performs arithmetic on the field to which it is >+// aligned. This means that adding 1 to a civil_day increments the day field >+// (normalizing as necessary), and subtracting 7 from a civil_month operates >+// on the month field (normalizing as necessary). All arithmetic produces a >+// valid civil time. Difference requires two similarly aligned civil-time >+// objects and returns the scalar answer in units of the objects' alignment. >+// For example, the difference between two civil_hour objects will give an >+// answer in units of civil hours. >+// >+// In addition to the six civil-time types just described, there are >+// a handful of helper functions and algorithms for performing common >+// calculations. These are described below. >+// >+// Note: In C++14 and later, this library is usable in a constexpr context. >+// >+// CONSTRUCTION: >+// >+// Each of the civil-time types can be constructed in two ways: by directly >+// passing to the constructor up to six (optional) integers representing the >+// YMDHMS fields, or by copying the YMDHMS fields from a differently aligned >+// civil-time type. >+// >+// civil_day default_value; // 1970-01-01 00:00:00 >+// >+// civil_day a(2015, 2, 3); // 2015-02-03 00:00:00 >+// civil_day b(2015, 2, 3, 4, 5, 6); // 2015-02-03 00:00:00 >+// civil_day c(2015); // 2015-01-01 00:00:00 >+// >+// civil_second ss(2015, 2, 3, 4, 5, 6); // 2015-02-03 04:05:06 >+// civil_minute mm(ss); // 2015-02-03 04:05:00 >+// civil_hour hh(mm); // 2015-02-03 04:00:00 >+// civil_day d(hh); // 2015-02-03 00:00:00 >+// civil_month m(d); // 2015-02-01 00:00:00 >+// civil_year y(m); // 2015-01-01 00:00:00 >+// >+// m = civil_month(y); // 2015-01-01 00:00:00 >+// d = civil_day(m); // 2015-01-01 00:00:00 >+// hh = civil_hour(d); // 2015-01-01 00:00:00 >+// mm = civil_minute(hh); // 2015-01-01 00:00:00 >+// ss = civil_second(mm); // 2015-01-01 00:00:00 >+// >+// ALIGNMENT CONVERSION: >+// >+// The alignment of a civil-time object cannot change, but the object may be >+// used to construct a new object with a different alignment. This is referred >+// to as "realigning". When realigning to a type with the same or more >+// precision (e.g., civil_day -> civil_second), the conversion may be >+// performed implicitly since no information is lost. However, if information >+// could be discarded (e.g., civil_second -> civil_day), the conversion must >+// be explicit at the call site. >+// >+// void fun(const civil_day& day); >+// >+// civil_second cs; >+// fun(cs); // Won't compile because data may be discarded >+// fun(civil_day(cs)); // OK: explicit conversion >+// >+// civil_day cd; >+// fun(cd); // OK: no conversion needed >+// >+// civil_month cm; >+// fun(cm); // OK: implicit conversion to civil_day >+// >+// NORMALIZATION: >+// >+// Integer arguments passed to the constructor may be out-of-range, in which >+// case they are normalized to produce a valid civil-time object. This enables >+// natural arithmetic on constructor arguments without worrying about the >+// field's range. Normalization guarantees that there are no invalid >+// civil-time objects. >+// >+// civil_day d(2016, 10, 32); // Out-of-range day; normalized to 2016-11-01 >+// >+// Note: If normalization is undesired, you can signal an error by comparing >+// the constructor arguments to the normalized values returned by the YMDHMS >+// properties. >+// >+// PROPERTIES: >+// >+// All civil-time types have accessors for all six of the civil-time fields: >+// year, month, day, hour, minute, and second. Recall that fields inferior to >+// the type's aligment will be set to their minimum valid value. >+// >+// civil_day d(2015, 6, 28); >+// // d.year() == 2015 >+// // d.month() == 6 >+// // d.day() == 28 >+// // d.hour() == 0 >+// // d.minute() == 0 >+// // d.second() == 0 >+// >+// COMPARISON: >+// >+// Comparison always considers all six YMDHMS fields, regardless of the type's >+// alignment. Comparison between differently aligned civil-time types is >+// allowed. >+// >+// civil_day feb_3(2015, 2, 3); // 2015-02-03 00:00:00 >+// civil_day mar_4(2015, 3, 4); // 2015-03-04 00:00:00 >+// // feb_3 < mar_4 >+// // civil_year(feb_3) == civil_year(mar_4) >+// >+// civil_second feb_3_noon(2015, 2, 3, 12, 0, 0); // 2015-02-03 12:00:00 >+// // feb_3 < feb_3_noon >+// // feb_3 == civil_day(feb_3_noon) >+// >+// // Iterates all the days of February 2015. >+// for (civil_day d(2015, 2, 1); d < civil_month(2015, 3); ++d) { >+// // ... >+// } >+// >+// STREAMING: >+// >+// Each civil-time type may be sent to an output stream using operator<<(). >+// The output format follows the pattern "YYYY-MM-DDThh:mm:ss" where fields >+// inferior to the type's alignment are omitted. >+// >+// civil_second cs(2015, 2, 3, 4, 5, 6); >+// std::cout << cs << "\n"; // Outputs: 2015-02-03T04:05:06 >+// >+// civil_day cd(cs); >+// std::cout << cd << "\n"; // Outputs: 2015-02-03 >+// >+// civil_year cy(cs); >+// std::cout << cy << "\n"; // Outputs: 2015 >+// >+// ARITHMETIC: >+// >+// Civil-time types support natural arithmetic operators such as addition, >+// subtraction, and difference. Arithmetic operates on the civil-time field >+// indicated in the type's name. Difference requires arguments with the same >+// alignment and returns the answer in units of the alignment. >+// >+// civil_day a(2015, 2, 3); >+// ++a; // 2015-02-04 00:00:00 >+// --a; // 2015-02-03 00:00:00 >+// civil_day b = a + 1; // 2015-02-04 00:00:00 >+// civil_day c = 1 + b; // 2015-02-05 00:00:00 >+// int n = c - a; // n = 2 (civil days) >+// int m = c - civil_month(c); // Won't compile: different types. >+// >+// EXAMPLE: Adding a month to January 31. >+// >+// One of the classic questions that arises when considering a civil-time >+// library (or a date library or a date/time library) is this: "What happens >+// when you add a month to January 31?" This is an interesting question >+// because there could be a number of possible answers: >+// >+// 1. March 3 (or 2 if a leap year). This may make sense if the operation >+// wants the equivalent of February 31. >+// 2. February 28 (or 29 if a leap year). This may make sense if the operation >+// wants the last day of January to go to the last day of February. >+// 3. Error. The caller may get some error, an exception, an invalid date >+// object, or maybe false is returned. This may make sense because there is >+// no single unambiguously correct answer to the question. >+// >+// Practically speaking, any answer that is not what the programmer intended >+// is the wrong answer. >+// >+// This civil-time library avoids the problem by making it impossible to ask >+// ambiguous questions. All civil-time objects are aligned to a particular >+// civil-field boundary (such as aligned to a year, month, day, hour, minute, >+// or second), and arithmetic operates on the field to which the object is >+// aligned. This means that in order to "add a month" the object must first be >+// aligned to a month boundary, which is equivalent to the first day of that >+// month. >+// >+// Of course, there are ways to compute an answer the question at hand using >+// this civil-time library, but they require the programmer to be explicit >+// about the answer they expect. To illustrate, let's see how to compute all >+// three of the above possible answers to the question of "Jan 31 plus 1 >+// month": >+// >+// const civil_day d(2015, 1, 31); >+// >+// // Answer 1: >+// // Add 1 to the month field in the constructor, and rely on normalization. >+// const auto ans_normalized = civil_day(d.year(), d.month() + 1, d.day()); >+// // ans_normalized == 2015-03-03 (aka Feb 31) >+// >+// // Answer 2: >+// // Add 1 to month field, capping to the end of next month. >+// const auto next_month = civil_month(d) + 1; >+// const auto last_day_of_next_month = civil_day(next_month + 1) - 1; >+// const auto ans_capped = std::min(ans_normalized, last_day_of_next_month); >+// // ans_capped == 2015-02-28 >+// >+// // Answer 3: >+// // Signal an error if the normalized answer is not in next month. >+// if (civil_month(ans_normalized) != next_month) { >+// // error, month overflow >+// } >+// >+using civil_year = detail::civil_year; >+using civil_month = detail::civil_month; >+using civil_day = detail::civil_day; >+using civil_hour = detail::civil_hour; >+using civil_minute = detail::civil_minute; >+using civil_second = detail::civil_second; >+ >+// An enum class with members monday, tuesday, wednesday, thursday, friday, >+// saturday, and sunday. These enum values may be sent to an output stream >+// using operator<<(). The result is the full weekday name in English with a >+// leading capital letter. >+// >+// weekday wd = weekday::thursday; >+// std::cout << wd << "\n"; // Outputs: Thursday >+// >+using detail::weekday; >+ >+// Returns the weekday for the given civil_day. >+// >+// civil_day a(2015, 8, 13); >+// weekday wd = get_weekday(a); // wd == weekday::thursday >+// >+using detail::get_weekday; >+ >+// Returns the civil_day that strictly follows or precedes the given >+// civil_day, and that falls on the given weekday. >+// >+// For example, given: >+// >+// August 2015 >+// Su Mo Tu We Th Fr Sa >+// 1 >+// 2 3 4 5 6 7 8 >+// 9 10 11 12 13 14 15 >+// 16 17 18 19 20 21 22 >+// 23 24 25 26 27 28 29 >+// 30 31 >+// >+// civil_day a(2015, 8, 13); // get_weekday(a) == weekday::thursday >+// civil_day b = next_weekday(a, weekday::thursday); // b = 2015-08-20 >+// civil_day c = prev_weekday(a, weekday::thursday); // c = 2015-08-06 >+// >+// civil_day d = ... >+// // Gets the following Thursday if d is not already Thursday >+// civil_day thurs1 = prev_weekday(d, weekday::thursday) + 7; >+// // Gets the previous Thursday if d is not already Thursday >+// civil_day thurs2 = next_weekday(d, weekday::thursday) - 7; >+// >+using detail::next_weekday; >+using detail::prev_weekday; >+ >+// Returns the day-of-year for the given civil_day. >+// >+// civil_day a(2015, 1, 1); >+// int yd_jan_1 = get_yearday(a); // yd_jan_1 = 1 >+// civil_day b(2015, 12, 31); >+// int yd_dec_31 = get_yearday(b); // yd_dec_31 = 365 >+// >+using detail::get_yearday; >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+#endif // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h >new file mode 100644 >index 0000000000000000000000000000000000000000..2362a4f4fbc958fa30dcfe7a14187688df462adf >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h >@@ -0,0 +1,560 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_ >+#define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_ >+ >+#include <cstdint> >+#include <limits> >+#include <ostream> >+#include <type_traits> >+ >+// Disable constexpr support unless we are in C++14 mode. >+#if __cpp_constexpr >= 201304 || _MSC_VER >= 1910 >+#define CONSTEXPR_D constexpr // data >+#define CONSTEXPR_F constexpr // function >+#define CONSTEXPR_M constexpr // member >+#else >+#define CONSTEXPR_D const >+#define CONSTEXPR_F inline >+#define CONSTEXPR_M >+#endif >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// Support years that at least span the range of 64-bit time_t values. >+using year_t = std::int_fast64_t; >+ >+// Type alias that indicates an argument is not normalized (e.g., the >+// constructor parameters and operands/results of addition/subtraction). >+using diff_t = std::int_fast64_t; >+ >+namespace detail { >+ >+// Type aliases that indicate normalized argument values. >+using month_t = std::int_fast8_t; // [1:12] >+using day_t = std::int_fast8_t; // [1:31] >+using hour_t = std::int_fast8_t; // [0:23] >+using minute_t = std::int_fast8_t; // [0:59] >+using second_t = std::int_fast8_t; // [0:59] >+ >+// Normalized civil-time fields: Y-M-D HH:MM:SS. >+struct fields { >+ CONSTEXPR_M fields(year_t year, month_t month, day_t day, >+ hour_t hour, minute_t minute, second_t second) >+ : y(year), m(month), d(day), hh(hour), mm(minute), ss(second) {} >+ std::int_least64_t y; >+ std::int_least8_t m; >+ std::int_least8_t d; >+ std::int_least8_t hh; >+ std::int_least8_t mm; >+ std::int_least8_t ss; >+}; >+ >+struct second_tag {}; >+struct minute_tag : second_tag {}; >+struct hour_tag : minute_tag {}; >+struct day_tag : hour_tag {}; >+struct month_tag : day_tag {}; >+struct year_tag : month_tag {}; >+ >+//////////////////////////////////////////////////////////////////////// >+ >+// Field normalization (without avoidable overflow). >+ >+namespace impl { >+ >+CONSTEXPR_F bool is_leap_year(year_t y) noexcept { >+ return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0); >+} >+CONSTEXPR_F int year_index(year_t y, month_t m) noexcept { >+ return (static_cast<int>((y + (m > 2)) % 400) + 400) % 400; >+} >+CONSTEXPR_F int days_per_century(year_t y, month_t m) noexcept { >+ const int yi = year_index(y, m); >+ return 36524 + (yi == 0 || yi > 300); >+} >+CONSTEXPR_F int days_per_4years(year_t y, month_t m) noexcept { >+ const int yi = year_index(y, m); >+ return 1460 + (yi == 0 || yi > 300 || (yi - 1) % 100 < 96); >+} >+CONSTEXPR_F int days_per_year(year_t y, month_t m) noexcept { >+ return is_leap_year(y + (m > 2)) ? 366 : 365; >+} >+CONSTEXPR_F int days_per_month(year_t y, month_t m) noexcept { >+ CONSTEXPR_D int k_days_per_month[1 + 12] = { >+ -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 // non leap year >+ }; >+ return k_days_per_month[m] + (m == 2 && is_leap_year(y)); >+} >+ >+CONSTEXPR_F fields n_day(year_t y, month_t m, diff_t d, diff_t cd, >+ hour_t hh, minute_t mm, second_t ss) noexcept { >+ y += (cd / 146097) * 400; >+ cd %= 146097; >+ if (cd < 0) { >+ y -= 400; >+ cd += 146097; >+ } >+ y += (d / 146097) * 400; >+ d = d % 146097 + cd; >+ if (d > 0) { >+ if (d > 146097) { >+ y += 400; >+ d -= 146097; >+ } >+ } else { >+ if (d > -365) { >+ // We often hit the previous year when stepping a civil time backwards, >+ // so special case it to avoid counting up by 100/4/1-year chunks. >+ y -= 1; >+ d += days_per_year(y, m); >+ } else { >+ y -= 400; >+ d += 146097; >+ } >+ } >+ if (d > 365) { >+ for (int n = days_per_century(y, m); d > n; n = days_per_century(y, m)) { >+ d -= n; >+ y += 100; >+ } >+ for (int n = days_per_4years(y, m); d > n; n = days_per_4years(y, m)) { >+ d -= n; >+ y += 4; >+ } >+ for (int n = days_per_year(y, m); d > n; n = days_per_year(y, m)) { >+ d -= n; >+ ++y; >+ } >+ } >+ if (d > 28) { >+ for (int n = days_per_month(y, m); d > n; n = days_per_month(y, m)) { >+ d -= n; >+ if (++m > 12) { >+ ++y; >+ m = 1; >+ } >+ } >+ } >+ return fields(y, m, static_cast<day_t>(d), hh, mm, ss); >+} >+CONSTEXPR_F fields n_mon(year_t y, diff_t m, diff_t d, diff_t cd, >+ hour_t hh, minute_t mm, second_t ss) noexcept { >+ if (m != 12) { >+ y += m / 12; >+ m %= 12; >+ if (m <= 0) { >+ y -= 1; >+ m += 12; >+ } >+ } >+ return n_day(y, static_cast<month_t>(m), d, cd, hh, mm, ss); >+} >+CONSTEXPR_F fields n_hour(year_t y, diff_t m, diff_t d, diff_t cd, >+ diff_t hh, minute_t mm, second_t ss) noexcept { >+ cd += hh / 24; >+ hh %= 24; >+ if (hh < 0) { >+ cd -= 1; >+ hh += 24; >+ } >+ return n_mon(y, m, d, cd, static_cast<hour_t>(hh), mm, ss); >+} >+CONSTEXPR_F fields n_min(year_t y, diff_t m, diff_t d, diff_t hh, diff_t ch, >+ diff_t mm, second_t ss) noexcept { >+ ch += mm / 60; >+ mm %= 60; >+ if (mm < 0) { >+ ch -= 1; >+ mm += 60; >+ } >+ return n_hour(y, m, d, hh / 24 + ch / 24, hh % 24 + ch % 24, >+ static_cast<minute_t>(mm), ss); >+} >+CONSTEXPR_F fields n_sec(year_t y, diff_t m, diff_t d, diff_t hh, diff_t mm, >+ diff_t ss) noexcept { >+ // Optimization for when (non-constexpr) fields are already normalized. >+ if (0 <= ss && ss < 60) { >+ const second_t nss = static_cast<second_t>(ss); >+ if (0 <= mm && mm < 60) { >+ const minute_t nmm = static_cast<minute_t>(mm); >+ if (0 <= hh && hh < 24) { >+ const hour_t nhh = static_cast<hour_t>(hh); >+ if (1 <= d && d <= 28 && 1 <= m && m <= 12) { >+ const day_t nd = static_cast<day_t>(d); >+ const month_t nm = static_cast<month_t>(m); >+ return fields(y, nm, nd, nhh, nmm, nss); >+ } >+ return n_mon(y, m, d, 0, nhh, nmm, nss); >+ } >+ return n_hour(y, m, d, hh / 24, hh % 24, nmm, nss); >+ } >+ return n_min(y, m, d, hh, mm / 60, mm % 60, nss); >+ } >+ diff_t cm = ss / 60; >+ ss %= 60; >+ if (ss < 0) { >+ cm -= 1; >+ ss += 60; >+ } >+ return n_min(y, m, d, hh, mm / 60 + cm / 60, mm % 60 + cm % 60, >+ static_cast<second_t>(ss)); >+} >+ >+} // namespace impl >+ >+//////////////////////////////////////////////////////////////////////// >+ >+// Increments the indicated (normalized) field by "n". >+CONSTEXPR_F fields step(second_tag, fields f, diff_t n) noexcept { >+ return impl::n_sec(f.y, f.m, f.d, f.hh, f.mm + n / 60, f.ss + n % 60); >+} >+CONSTEXPR_F fields step(minute_tag, fields f, diff_t n) noexcept { >+ return impl::n_min(f.y, f.m, f.d, f.hh + n / 60, 0, f.mm + n % 60, f.ss); >+} >+CONSTEXPR_F fields step(hour_tag, fields f, diff_t n) noexcept { >+ return impl::n_hour(f.y, f.m, f.d + n / 24, 0, f.hh + n % 24, f.mm, f.ss); >+} >+CONSTEXPR_F fields step(day_tag, fields f, diff_t n) noexcept { >+ return impl::n_day(f.y, f.m, f.d, n, f.hh, f.mm, f.ss); >+} >+CONSTEXPR_F fields step(month_tag, fields f, diff_t n) noexcept { >+ return impl::n_mon(f.y + n / 12, f.m + n % 12, f.d, 0, f.hh, f.mm, f.ss); >+} >+CONSTEXPR_F fields step(year_tag, fields f, diff_t n) noexcept { >+ return fields(f.y + n, f.m, f.d, f.hh, f.mm, f.ss); >+} >+ >+//////////////////////////////////////////////////////////////////////// >+ >+namespace impl { >+ >+// Returns (v * f + a) but avoiding intermediate overflow when possible. >+CONSTEXPR_F diff_t scale_add(diff_t v, diff_t f, diff_t a) noexcept { >+ return (v < 0) ? ((v + 1) * f + a) - f : ((v - 1) * f + a) + f; >+} >+ >+// Map a (normalized) Y/M/D to the number of days before/after 1970-01-01. >+// Probably overflows for years outside [-292277022656:292277026595]. >+CONSTEXPR_F diff_t ymd_ord(year_t y, month_t m, day_t d) noexcept { >+ const diff_t eyear = (m <= 2) ? y - 1 : y; >+ const diff_t era = (eyear >= 0 ? eyear : eyear - 399) / 400; >+ const diff_t yoe = eyear - era * 400; >+ const diff_t doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1; >+ const diff_t doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; >+ return era * 146097 + doe - 719468; >+} >+ >+// Returns the difference in days between two normalized Y-M-D tuples. >+// ymd_ord() will encounter integer overflow given extreme year values, >+// yet the difference between two such extreme values may actually be >+// small, so we take a little care to avoid overflow when possible by >+// exploiting the 146097-day cycle. >+CONSTEXPR_F diff_t day_difference(year_t y1, month_t m1, day_t d1, >+ year_t y2, month_t m2, day_t d2) noexcept { >+ const diff_t a_c4_off = y1 % 400; >+ const diff_t b_c4_off = y2 % 400; >+ diff_t c4_diff = (y1 - a_c4_off) - (y2 - b_c4_off); >+ diff_t delta = ymd_ord(a_c4_off, m1, d1) - ymd_ord(b_c4_off, m2, d2); >+ if (c4_diff > 0 && delta < 0) { >+ delta += 2 * 146097; >+ c4_diff -= 2 * 400; >+ } else if (c4_diff < 0 && delta > 0) { >+ delta -= 2 * 146097; >+ c4_diff += 2 * 400; >+ } >+ return (c4_diff / 400 * 146097) + delta; >+} >+ >+} // namespace impl >+ >+// Returns the difference between fields structs using the indicated unit. >+CONSTEXPR_F diff_t difference(year_tag, fields f1, fields f2) noexcept { >+ return f1.y - f2.y; >+} >+CONSTEXPR_F diff_t difference(month_tag, fields f1, fields f2) noexcept { >+ return impl::scale_add(difference(year_tag{}, f1, f2), 12, (f1.m - f2.m)); >+} >+CONSTEXPR_F diff_t difference(day_tag, fields f1, fields f2) noexcept { >+ return impl::day_difference(f1.y, f1.m, f1.d, f2.y, f2.m, f2.d); >+} >+CONSTEXPR_F diff_t difference(hour_tag, fields f1, fields f2) noexcept { >+ return impl::scale_add(difference(day_tag{}, f1, f2), 24, (f1.hh - f2.hh)); >+} >+CONSTEXPR_F diff_t difference(minute_tag, fields f1, fields f2) noexcept { >+ return impl::scale_add(difference(hour_tag{}, f1, f2), 60, (f1.mm - f2.mm)); >+} >+CONSTEXPR_F diff_t difference(second_tag, fields f1, fields f2) noexcept { >+ return impl::scale_add(difference(minute_tag{}, f1, f2), 60, f1.ss - f2.ss); >+} >+ >+//////////////////////////////////////////////////////////////////////// >+ >+// Aligns the (normalized) fields struct to the indicated field. >+CONSTEXPR_F fields align(second_tag, fields f) noexcept { >+ return f; >+} >+CONSTEXPR_F fields align(minute_tag, fields f) noexcept { >+ return fields{f.y, f.m, f.d, f.hh, f.mm, 0}; >+} >+CONSTEXPR_F fields align(hour_tag, fields f) noexcept { >+ return fields{f.y, f.m, f.d, f.hh, 0, 0}; >+} >+CONSTEXPR_F fields align(day_tag, fields f) noexcept { >+ return fields{f.y, f.m, f.d, 0, 0, 0}; >+} >+CONSTEXPR_F fields align(month_tag, fields f) noexcept { >+ return fields{f.y, f.m, 1, 0, 0, 0}; >+} >+CONSTEXPR_F fields align(year_tag, fields f) noexcept { >+ return fields{f.y, 1, 1, 0, 0, 0}; >+} >+ >+//////////////////////////////////////////////////////////////////////// >+ >+template <typename T> >+class civil_time { >+ public: >+ explicit CONSTEXPR_M civil_time(year_t y, diff_t m = 1, diff_t d = 1, >+ diff_t hh = 0, diff_t mm = 0, >+ diff_t ss = 0) noexcept >+ : civil_time(impl::n_sec(y, m, d, hh, mm, ss)) {} >+ >+ CONSTEXPR_M civil_time() noexcept : f_{1970, 1, 1, 0, 0, 0} {} >+ civil_time(const civil_time&) = default; >+ civil_time& operator=(const civil_time&) = default; >+ >+ // Conversion between civil times of different alignment. Conversion to >+ // a more precise alignment is allowed implicitly (e.g., day -> hour), >+ // but conversion where information is discarded must be explicit >+ // (e.g., second -> minute). >+ template <typename U, typename S> >+ using preserves_data = >+ typename std::enable_if<std::is_base_of<U, S>::value>::type; >+ template <typename U> >+ CONSTEXPR_M civil_time(const civil_time<U>& ct, >+ preserves_data<T, U>* = nullptr) noexcept >+ : civil_time(ct.f_) {} >+ template <typename U> >+ explicit CONSTEXPR_M civil_time(const civil_time<U>& ct, >+ preserves_data<U, T>* = nullptr) noexcept >+ : civil_time(ct.f_) {} >+ >+ // Factories for the maximum/minimum representable civil_time. >+ static civil_time max() { >+ const auto max_year = std::numeric_limits<std::int_least64_t>::max(); >+ return civil_time(max_year, 12, 31, 23, 59, 59); >+ } >+ static civil_time min() { >+ const auto min_year = std::numeric_limits<std::int_least64_t>::min(); >+ return civil_time(min_year, 1, 1, 0, 0, 0); >+ } >+ >+ // Field accessors. Note: All but year() return an int. >+ CONSTEXPR_M year_t year() const noexcept { return f_.y; } >+ CONSTEXPR_M int month() const noexcept { return f_.m; } >+ CONSTEXPR_M int day() const noexcept { return f_.d; } >+ CONSTEXPR_M int hour() const noexcept { return f_.hh; } >+ CONSTEXPR_M int minute() const noexcept { return f_.mm; } >+ CONSTEXPR_M int second() const noexcept { return f_.ss; } >+ >+ // Assigning arithmetic. >+ CONSTEXPR_M civil_time& operator+=(diff_t n) noexcept { >+ f_ = step(T{}, f_, n); >+ return *this; >+ } >+ CONSTEXPR_M civil_time& operator-=(diff_t n) noexcept { >+ if (n != std::numeric_limits<diff_t>::min()) { >+ f_ = step(T{}, f_, -n); >+ } else { >+ f_ = step(T{}, step(T{}, f_, -(n + 1)), 1); >+ } >+ return *this; >+ } >+ CONSTEXPR_M civil_time& operator++() noexcept { >+ return *this += 1; >+ } >+ CONSTEXPR_M civil_time operator++(int) noexcept { >+ const civil_time a = *this; >+ ++*this; >+ return a; >+ } >+ CONSTEXPR_M civil_time& operator--() noexcept { >+ return *this -= 1; >+ } >+ CONSTEXPR_M civil_time operator--(int) noexcept { >+ const civil_time a = *this; >+ --*this; >+ return a; >+ } >+ >+ // Binary arithmetic operators. >+ friend CONSTEXPR_F civil_time operator+(civil_time a, diff_t n) noexcept { >+ return a += n; >+ } >+ friend CONSTEXPR_F civil_time operator+(diff_t n, civil_time a) noexcept { >+ return a += n; >+ } >+ friend CONSTEXPR_F civil_time operator-(civil_time a, diff_t n) noexcept { >+ return a -= n; >+ } >+ friend CONSTEXPR_F diff_t operator-(civil_time lhs, civil_time rhs) noexcept { >+ return difference(T{}, lhs.f_, rhs.f_); >+ } >+ >+ private: >+ // All instantiations of this template are allowed to call the following >+ // private constructor and access the private fields member. >+ template <typename U> >+ friend class civil_time; >+ >+ // The designated constructor that all others eventually call. >+ explicit CONSTEXPR_M civil_time(fields f) noexcept : f_(align(T{}, f)) {} >+ >+ fields f_; >+}; >+ >+// Disallows difference between differently aligned types. >+// auto n = civil_day(...) - civil_hour(...); // would be confusing. >+template <typename T, typename U> >+CONSTEXPR_F diff_t operator-(civil_time<T>, civil_time<U>) = delete; >+ >+using civil_year = civil_time<year_tag>; >+using civil_month = civil_time<month_tag>; >+using civil_day = civil_time<day_tag>; >+using civil_hour = civil_time<hour_tag>; >+using civil_minute = civil_time<minute_tag>; >+using civil_second = civil_time<second_tag>; >+ >+//////////////////////////////////////////////////////////////////////// >+ >+// Relational operators that work with differently aligned objects. >+// Always compares all six fields. >+template <typename T1, typename T2> >+CONSTEXPR_F bool operator<(const civil_time<T1>& lhs, >+ const civil_time<T2>& rhs) noexcept { >+ return (lhs.year() < rhs.year() || >+ (lhs.year() == rhs.year() && >+ (lhs.month() < rhs.month() || >+ (lhs.month() == rhs.month() && >+ (lhs.day() < rhs.day() || >+ (lhs.day() == rhs.day() && >+ (lhs.hour() < rhs.hour() || >+ (lhs.hour() == rhs.hour() && >+ (lhs.minute() < rhs.minute() || >+ (lhs.minute() == rhs.minute() && >+ (lhs.second() < rhs.second()))))))))))); >+} >+template <typename T1, typename T2> >+CONSTEXPR_F bool operator<=(const civil_time<T1>& lhs, >+ const civil_time<T2>& rhs) noexcept { >+ return !(rhs < lhs); >+} >+template <typename T1, typename T2> >+CONSTEXPR_F bool operator>=(const civil_time<T1>& lhs, >+ const civil_time<T2>& rhs) noexcept { >+ return !(lhs < rhs); >+} >+template <typename T1, typename T2> >+CONSTEXPR_F bool operator>(const civil_time<T1>& lhs, >+ const civil_time<T2>& rhs) noexcept { >+ return rhs < lhs; >+} >+template <typename T1, typename T2> >+CONSTEXPR_F bool operator==(const civil_time<T1>& lhs, >+ const civil_time<T2>& rhs) noexcept { >+ return lhs.year() == rhs.year() && lhs.month() == rhs.month() && >+ lhs.day() == rhs.day() && lhs.hour() == rhs.hour() && >+ lhs.minute() == rhs.minute() && lhs.second() == rhs.second(); >+} >+template <typename T1, typename T2> >+CONSTEXPR_F bool operator!=(const civil_time<T1>& lhs, >+ const civil_time<T2>& rhs) noexcept { >+ return !(lhs == rhs); >+} >+ >+//////////////////////////////////////////////////////////////////////// >+ >+enum class weekday { >+ monday, >+ tuesday, >+ wednesday, >+ thursday, >+ friday, >+ saturday, >+ sunday, >+}; >+ >+CONSTEXPR_F weekday get_weekday(const civil_day& cd) noexcept { >+ CONSTEXPR_D weekday k_weekday_by_sun_off[7] = { >+ weekday::sunday, weekday::monday, weekday::tuesday, >+ weekday::wednesday, weekday::thursday, weekday::friday, >+ weekday::saturday, >+ }; >+ CONSTEXPR_D int k_weekday_offsets[1 + 12] = { >+ -1, 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4, >+ }; >+ year_t wd = cd.year() - (cd.month() < 3); >+ if (wd >= 0) { >+ wd += wd / 4 - wd / 100 + wd / 400; >+ } else { >+ wd += (wd - 3) / 4 - (wd - 99) / 100 + (wd - 399) / 400; >+ } >+ wd += k_weekday_offsets[cd.month()] + cd.day(); >+ return k_weekday_by_sun_off[(wd % 7 + 7) % 7]; >+} >+ >+//////////////////////////////////////////////////////////////////////// >+ >+CONSTEXPR_F civil_day next_weekday(civil_day cd, weekday wd) noexcept { >+ do { cd += 1; } while (get_weekday(cd) != wd); >+ return cd; >+} >+ >+CONSTEXPR_F civil_day prev_weekday(civil_day cd, weekday wd) noexcept { >+ do { cd -= 1; } while (get_weekday(cd) != wd); >+ return cd; >+} >+ >+CONSTEXPR_F int get_yearday(const civil_day& cd) noexcept { >+ CONSTEXPR_D int k_month_offsets[1 + 12] = { >+ -1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, >+ }; >+ const int feb29 = (cd.month() > 2 && impl::is_leap_year(cd.year())); >+ return k_month_offsets[cd.month()] + feb29 + cd.day(); >+} >+ >+//////////////////////////////////////////////////////////////////////// >+ >+std::ostream& operator<<(std::ostream& os, const civil_year& y); >+std::ostream& operator<<(std::ostream& os, const civil_month& m); >+std::ostream& operator<<(std::ostream& os, const civil_day& d); >+std::ostream& operator<<(std::ostream& os, const civil_hour& h); >+std::ostream& operator<<(std::ostream& os, const civil_minute& m); >+std::ostream& operator<<(std::ostream& os, const civil_second& s); >+std::ostream& operator<<(std::ostream& os, weekday wd); >+ >+} // namespace detail >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+#undef CONSTEXPR_M >+#undef CONSTEXPR_F >+#undef CONSTEXPR_D >+ >+#endif // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h >new file mode 100644 >index 0000000000000000000000000000000000000000..0b9764ea72a9caa3e5f2f7fee0427357aed28808 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h >@@ -0,0 +1,380 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// A library for translating between absolute times (represented by >+// std::chrono::time_points of the std::chrono::system_clock) and civil >+// times (represented by cctz::civil_second) using the rules defined by >+// a time zone (cctz::time_zone). >+ >+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_ >+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_ >+ >+#include <chrono> >+#include <cstdint> >+#include <string> >+#include <utility> >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// Convenience aliases. Not intended as public API points. >+template <typename D> >+using time_point = std::chrono::time_point<std::chrono::system_clock, D>; >+using seconds = std::chrono::duration<std::int_fast64_t>; >+using sys_seconds = seconds; // Deprecated. Use cctz::seconds instead. >+ >+namespace detail { >+template <typename D> >+inline std::pair<time_point<seconds>, D> >+split_seconds(const time_point<D>& tp) { >+ auto sec = std::chrono::time_point_cast<seconds>(tp); >+ auto sub = tp - sec; >+ if (sub.count() < 0) { >+ sec -= seconds(1); >+ sub += seconds(1); >+ } >+ return {sec, std::chrono::duration_cast<D>(sub)}; >+} >+inline std::pair<time_point<seconds>, seconds> >+split_seconds(const time_point<seconds>& tp) { >+ return {tp, seconds::zero()}; >+} >+} // namespace detail >+ >+// cctz::time_zone is an opaque, small, value-type class representing a >+// geo-political region within which particular rules are used for mapping >+// between absolute and civil times. Time zones are named using the TZ >+// identifiers from the IANA Time Zone Database, such as "America/Los_Angeles" >+// or "Australia/Sydney". Time zones are created from factory functions such >+// as load_time_zone(). Note: strings like "PST" and "EDT" are not valid TZ >+// identifiers. >+// >+// Example: >+// cctz::time_zone utc = cctz::utc_time_zone(); >+// cctz::time_zone pst = cctz::fixed_time_zone(std::chrono::hours(-8)); >+// cctz::time_zone loc = cctz::local_time_zone(); >+// cctz::time_zone lax; >+// if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... } >+// >+// See also: >+// - http://www.iana.org/time-zones >+// - http://en.wikipedia.org/wiki/Zoneinfo >+class time_zone { >+ public: >+ time_zone() : time_zone(nullptr) {} // Equivalent to UTC >+ time_zone(const time_zone&) = default; >+ time_zone& operator=(const time_zone&) = default; >+ >+ std::string name() const; >+ >+ // An absolute_lookup represents the civil time (cctz::civil_second) within >+ // this time_zone at the given absolute time (time_point). There are >+ // additionally a few other fields that may be useful when working with >+ // older APIs, such as std::tm. >+ // >+ // Example: >+ // const cctz::time_zone tz = ... >+ // const auto tp = std::chrono::system_clock::now(); >+ // const cctz::time_zone::absolute_lookup al = tz.lookup(tp); >+ struct absolute_lookup { >+ civil_second cs; >+ // Note: The following fields exist for backward compatibility with older >+ // APIs. Accessing these fields directly is a sign of imprudent logic in >+ // the calling code. Modern time-related code should only access this data >+ // indirectly by way of cctz::format(). >+ int offset; // civil seconds east of UTC >+ bool is_dst; // is offset non-standard? >+ const char* abbr; // time-zone abbreviation (e.g., "PST") >+ }; >+ absolute_lookup lookup(const time_point<seconds>& tp) const; >+ template <typename D> >+ absolute_lookup lookup(const time_point<D>& tp) const { >+ return lookup(detail::split_seconds(tp).first); >+ } >+ >+ // A civil_lookup represents the absolute time(s) (time_point) that >+ // correspond to the given civil time (cctz::civil_second) within this >+ // time_zone. Usually the given civil time represents a unique instant >+ // in time, in which case the conversion is unambiguous. However, >+ // within this time zone, the given civil time may be skipped (e.g., >+ // during a positive UTC offset shift), or repeated (e.g., during a >+ // negative UTC offset shift). To account for these possibilities, >+ // civil_lookup is richer than just a single time_point. >+ // >+ // In all cases the civil_lookup::kind enum will indicate the nature >+ // of the given civil-time argument, and the pre, trans, and post >+ // members will give the absolute time answers using the pre-transition >+ // offset, the transition point itself, and the post-transition offset, >+ // respectively (all three times are equal if kind == UNIQUE). If any >+ // of these three absolute times is outside the representable range of a >+ // time_point<seconds> the field is set to its maximum/minimum value. >+ // >+ // Example: >+ // cctz::time_zone lax; >+ // if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... } >+ // >+ // // A unique civil time. >+ // auto jan01 = lax.lookup(cctz::civil_second(2011, 1, 1, 0, 0, 0)); >+ // // jan01.kind == cctz::time_zone::civil_lookup::UNIQUE >+ // // jan01.pre is 2011/01/01 00:00:00 -0800 >+ // // jan01.trans is 2011/01/01 00:00:00 -0800 >+ // // jan01.post is 2011/01/01 00:00:00 -0800 >+ // >+ // // A Spring DST transition, when there is a gap in civil time. >+ // auto mar13 = lax.lookup(cctz::civil_second(2011, 3, 13, 2, 15, 0)); >+ // // mar13.kind == cctz::time_zone::civil_lookup::SKIPPED >+ // // mar13.pre is 2011/03/13 03:15:00 -0700 >+ // // mar13.trans is 2011/03/13 03:00:00 -0700 >+ // // mar13.post is 2011/03/13 01:15:00 -0800 >+ // >+ // // A Fall DST transition, when civil times are repeated. >+ // auto nov06 = lax.lookup(cctz::civil_second(2011, 11, 6, 1, 15, 0)); >+ // // nov06.kind == cctz::time_zone::civil_lookup::REPEATED >+ // // nov06.pre is 2011/11/06 01:15:00 -0700 >+ // // nov06.trans is 2011/11/06 01:00:00 -0800 >+ // // nov06.post is 2011/11/06 01:15:00 -0800 >+ struct civil_lookup { >+ enum civil_kind { >+ UNIQUE, // the civil time was singular (pre == trans == post) >+ SKIPPED, // the civil time did not exist (pre >= trans > post) >+ REPEATED, // the civil time was ambiguous (pre < trans <= post) >+ } kind; >+ time_point<seconds> pre; // uses the pre-transition offset >+ time_point<seconds> trans; // instant of civil-offset change >+ time_point<seconds> post; // uses the post-transition offset >+ }; >+ civil_lookup lookup(const civil_second& cs) const; >+ >+ // Finds the time of the next/previous offset change in this time zone. >+ // >+ // By definition, next_transition(tp, &trans) returns false when tp has >+ // its maximum value, and prev_transition(tp, &trans) returns false >+ // when tp has its minimum value. If the zone has no transitions, the >+ // result will also be false no matter what the argument. >+ // >+ // Otherwise, when tp has its minimum value, next_transition(tp, &trans) >+ // returns true and sets trans to the first recorded transition. Chains >+ // of calls to next_transition()/prev_transition() will eventually return >+ // false, but it is unspecified exactly when next_transition(tp, &trans) >+ // jumps to false, or what time is set by prev_transition(tp, &trans) for >+ // a very distant tp. >+ // >+ // Note: Enumeration of time-zone transitions is for informational purposes >+ // only. Modern time-related code should not care about when offset changes >+ // occur. >+ // >+ // Example: >+ // cctz::time_zone nyc; >+ // if (!cctz::load_time_zone("America/New_York", &nyc)) { ... } >+ // const auto now = std::chrono::system_clock::now(); >+ // auto tp = cctz::time_point<cctz::seconds>::min(); >+ // cctz::time_zone::civil_transition trans; >+ // while (tp <= now && nyc.next_transition(tp, &trans)) { >+ // // transition: trans.from -> trans.to >+ // tp = nyc.lookup(trans.to).trans; >+ // } >+ struct civil_transition { >+ civil_second from; // the civil time we jump from >+ civil_second to; // the civil time we jump to >+ }; >+ bool next_transition(const time_point<seconds>& tp, >+ civil_transition* trans) const; >+ template <typename D> >+ bool next_transition(const time_point<D>& tp, >+ civil_transition* trans) const { >+ return next_transition(detail::split_seconds(tp).first, trans); >+ } >+ bool prev_transition(const time_point<seconds>& tp, >+ civil_transition* trans) const; >+ template <typename D> >+ bool prev_transition(const time_point<D>& tp, >+ civil_transition* trans) const { >+ return prev_transition(detail::split_seconds(tp).first, trans); >+ } >+ >+ // version() and description() provide additional information about the >+ // time zone. The content of each of the returned strings is unspecified, >+ // however, when the IANA Time Zone Database is the underlying data source >+ // the version() std::string will be in the familar form (e.g, "2018e") or >+ // empty when unavailable. >+ // >+ // Note: These functions are for informational or testing purposes only. >+ std::string version() const; // empty when unknown >+ std::string description() const; >+ >+ // Relational operators. >+ friend bool operator==(time_zone lhs, time_zone rhs) { >+ return &lhs.effective_impl() == &rhs.effective_impl(); >+ } >+ friend bool operator!=(time_zone lhs, time_zone rhs) { >+ return !(lhs == rhs); >+ } >+ >+ class Impl; >+ >+ private: >+ explicit time_zone(const Impl* impl) : impl_(impl) {} >+ const Impl& effective_impl() const; // handles implicit UTC >+ const Impl* impl_; >+}; >+ >+// Loads the named time zone. May perform I/O on the initial load. >+// If the name is invalid, or some other kind of error occurs, returns >+// false and "*tz" is set to the UTC time zone. >+bool load_time_zone(const std::string& name, time_zone* tz); >+ >+// Returns a time_zone representing UTC. Cannot fail. >+time_zone utc_time_zone(); >+ >+// Returns a time zone that is a fixed offset (seconds east) from UTC. >+// Note: If the absolute value of the offset is greater than 24 hours >+// you'll get UTC (i.e., zero offset) instead. >+time_zone fixed_time_zone(const seconds& offset); >+ >+// Returns a time zone representing the local time zone. Falls back to UTC. >+// Note: local_time_zone.name() may only be something like "localtime". >+time_zone local_time_zone(); >+ >+// Returns the civil time (cctz::civil_second) within the given time zone at >+// the given absolute time (time_point). Since the additional fields provided >+// by the time_zone::absolute_lookup struct should rarely be needed in modern >+// code, this convert() function is simpler and should be preferred. >+template <typename D> >+inline civil_second convert(const time_point<D>& tp, const time_zone& tz) { >+ return tz.lookup(tp).cs; >+} >+ >+// Returns the absolute time (time_point) that corresponds to the given civil >+// time within the given time zone. If the civil time is not unique (i.e., if >+// it was either repeated or non-existent), then the returned time_point is >+// the best estimate that preserves relative order. That is, this function >+// guarantees that if cs1 < cs2, then convert(cs1, tz) <= convert(cs2, tz). >+inline time_point<seconds> convert(const civil_second& cs, >+ const time_zone& tz) { >+ const time_zone::civil_lookup cl = tz.lookup(cs); >+ if (cl.kind == time_zone::civil_lookup::SKIPPED) return cl.trans; >+ return cl.pre; >+} >+ >+namespace detail { >+using femtoseconds = std::chrono::duration<std::int_fast64_t, std::femto>; >+std::string format(const std::string&, const time_point<seconds>&, >+ const femtoseconds&, const time_zone&); >+bool parse(const std::string&, const std::string&, const time_zone&, >+ time_point<seconds>*, femtoseconds*, std::string* err = nullptr); >+} // namespace detail >+ >+// Formats the given time_point in the given cctz::time_zone according to >+// the provided format std::string. Uses strftime()-like formatting options, >+// with the following extensions: >+// >+// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) >+// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss) >+// - %E#S - Seconds with # digits of fractional precision >+// - %E*S - Seconds with full fractional precision (a literal '*') >+// - %E#f - Fractional seconds with # digits of precision >+// - %E*f - Fractional seconds with full precision (a literal '*') >+// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) >+// >+// Note that %E0S behaves like %S, and %E0f produces no characters. In >+// contrast %E*f always produces at least one digit, which may be '0'. >+// >+// Note that %Y produces as many characters as it takes to fully render the >+// year. A year outside of [-999:9999] when formatted with %E4Y will produce >+// more than four characters, just like %Y. >+// >+// Tip: Format strings should include the UTC offset (e.g., %z, %Ez, or %E*z) >+// so that the resulting std::string uniquely identifies an absolute time. >+// >+// Example: >+// cctz::time_zone lax; >+// if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... } >+// auto tp = cctz::convert(cctz::civil_second(2013, 1, 2, 3, 4, 5), lax); >+// std::string f = cctz::format("%H:%M:%S", tp, lax); // "03:04:05" >+// f = cctz::format("%H:%M:%E3S", tp, lax); // "03:04:05.000" >+template <typename D> >+inline std::string format(const std::string& fmt, const time_point<D>& tp, >+ const time_zone& tz) { >+ const auto p = detail::split_seconds(tp); >+ const auto n = std::chrono::duration_cast<detail::femtoseconds>(p.second); >+ return detail::format(fmt, p.first, n, tz); >+} >+ >+// Parses an input std::string according to the provided format std::string and >+// returns the corresponding time_point. Uses strftime()-like formatting >+// options, with the same extensions as cctz::format(), but with the >+// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez >+// and %E*z also accept the same inputs. >+// >+// %Y consumes as many numeric characters as it can, so the matching data >+// should always be terminated with a non-numeric. %E4Y always consumes >+// exactly four characters, including any sign. >+// >+// Unspecified fields are taken from the default date and time of ... >+// >+// "1970-01-01 00:00:00.0 +0000" >+// >+// For example, parsing a std::string of "15:45" (%H:%M) will return a time_point >+// that represents "1970-01-01 15:45:00.0 +0000". >+// >+// Note that parse() returns time instants, so it makes most sense to parse >+// fully-specified date/time strings that include a UTC offset (%z, %Ez, or >+// %E*z). >+// >+// Note also that parse() only heeds the fields year, month, day, hour, >+// minute, (fractional) second, and UTC offset. Other fields, like weekday (%a >+// or %A), while parsed for syntactic validity, are ignored in the conversion. >+// >+// Date and time fields that are out-of-range will be treated as errors rather >+// than normalizing them like cctz::civil_second() would do. For example, it >+// is an error to parse the date "Oct 32, 2013" because 32 is out of range. >+// >+// A second of ":60" is normalized to ":00" of the following minute with >+// fractional seconds discarded. The following table shows how the given >+// seconds and subseconds will be parsed: >+// >+// "59.x" -> 59.x // exact >+// "60.x" -> 00.0 // normalized >+// "00.x" -> 00.x // exact >+// >+// Errors are indicated by returning false. >+// >+// Example: >+// const cctz::time_zone tz = ... >+// std::chrono::system_clock::time_point tp; >+// if (cctz::parse("%Y-%m-%d", "2015-10-09", tz, &tp)) { >+// ... >+// } >+template <typename D> >+inline bool parse(const std::string& fmt, const std::string& input, >+ const time_zone& tz, time_point<D>* tpp) { >+ time_point<seconds> sec; >+ detail::femtoseconds fs; >+ const bool b = detail::parse(fmt, input, tz, &sec, &fs); >+ if (b) { >+ // TODO: Return false if unrepresentable as a time_point<D>. >+ *tpp = std::chrono::time_point_cast<D>(sec); >+ *tpp += std::chrono::duration_cast<D>(fs); >+ } >+ return b; >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/zone_info_source.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/zone_info_source.h >new file mode 100644 >index 0000000000000000000000000000000000000000..20a76979370fc06cceee9c9c7c78a51bb0f8c9fe >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/zone_info_source.h >@@ -0,0 +1,96 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_ >+#define ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_ >+ >+#include <cstddef> >+#include <functional> >+#include <memory> >+#include <string> >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// A stdio-like interface for providing zoneinfo data for a particular zone. >+class ZoneInfoSource { >+ public: >+ virtual ~ZoneInfoSource(); >+ >+ virtual std::size_t Read(void* ptr, std::size_t size) = 0; // like fread() >+ virtual int Skip(std::size_t offset) = 0; // like fseek() >+ >+ // Until the zoneinfo data supports versioning information, we provide >+ // a way for a ZoneInfoSource to indicate it out-of-band. The default >+ // implementation returns an empty std::string. >+ virtual std::string Version() const; >+}; >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+namespace absl { >+namespace time_internal { >+namespace cctz_extension { >+ >+// A function-pointer type for a factory that returns a ZoneInfoSource >+// given the name of a time zone and a fallback factory. Returns null >+// when the data for the named zone cannot be found. >+using ZoneInfoSourceFactory = >+ std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource> (*)( >+ const std::string&, >+ const std::function<std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource>( >+ const std::string&)>&); >+ >+// The user can control the mapping of zone names to zoneinfo data by >+// providing a definition for cctz_extension::zone_info_source_factory. >+// For example, given functions my_factory() and my_other_factory() that >+// can return a ZoneInfoSource for a named zone, we could inject them into >+// cctz::load_time_zone() with: >+// >+// namespace cctz_extension { >+// namespace { >+// std::unique_ptr<cctz::ZoneInfoSource> CustomFactory( >+// const std::string& name, >+// const std::function<std::unique_ptr<cctz::ZoneInfoSource>( >+// const std::string& name)>& fallback_factory) { >+// if (auto zip = my_factory(name)) return zip; >+// if (auto zip = fallback_factory(name)) return zip; >+// if (auto zip = my_other_factory(name)) return zip; >+// return nullptr; >+// } >+// } // namespace >+// ZoneInfoSourceFactory zone_info_source_factory = CustomFactory; >+// } // namespace cctz_extension >+// >+// This might be used, say, to use zoneinfo data embedded in the program, >+// or read from a (possibly compressed) file archive, or both. >+// >+// cctz_extension::zone_info_source_factory() will be called: >+// (1) from the same thread as the cctz::load_time_zone() call, >+// (2) only once for any zone name, and >+// (3) serially (i.e., no concurrent execution). >+// >+// The fallback factory obtains zoneinfo data by reading files in ${TZDIR}, >+// and it is used automatically when no zone_info_source_factory definition >+// is linked into the program. >+extern ZoneInfoSourceFactory zone_info_source_factory; >+ >+} // namespace cctz_extension >+} // namespace time_internal >+} // namespace absl >+ >+#endif // ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..c97df78c09c83945e68f5511b7b92e4af31770c4 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc >@@ -0,0 +1,980 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include <algorithm> >+#include <cassert> >+#include <chrono> >+#include <ctime> >+#include <random> >+#include <string> >+#include <vector> >+ >+#include "benchmark/benchmark.h" >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+#include "time_zone_impl.h" >+ >+namespace { >+ >+namespace cctz = absl::time_internal::cctz; >+ >+void BM_Difference_Days(benchmark::State& state) { >+ const cctz::civil_day c(2014, 8, 22); >+ const cctz::civil_day epoch(1970, 1, 1); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(c - epoch); >+ } >+} >+BENCHMARK(BM_Difference_Days); >+ >+void BM_Step_Days(benchmark::State& state) { >+ const cctz::civil_day kStart(2014, 8, 22); >+ cctz::civil_day c = kStart; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(++c); >+ } >+} >+BENCHMARK(BM_Step_Days); >+ >+const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez"; >+const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; >+ >+const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z"; >+const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z"; >+ >+// A list of known time-zone names. >+// TODO: Refactor with src/time_zone_lookup_test.cc. >+const char* const kTimeZoneNames[] = { >+ "Africa/Abidjan", >+ "Africa/Accra", >+ "Africa/Addis_Ababa", >+ "Africa/Algiers", >+ "Africa/Asmara", >+ "Africa/Asmera", >+ "Africa/Bamako", >+ "Africa/Bangui", >+ "Africa/Banjul", >+ "Africa/Bissau", >+ "Africa/Blantyre", >+ "Africa/Brazzaville", >+ "Africa/Bujumbura", >+ "Africa/Cairo", >+ "Africa/Casablanca", >+ "Africa/Ceuta", >+ "Africa/Conakry", >+ "Africa/Dakar", >+ "Africa/Dar_es_Salaam", >+ "Africa/Djibouti", >+ "Africa/Douala", >+ "Africa/El_Aaiun", >+ "Africa/Freetown", >+ "Africa/Gaborone", >+ "Africa/Harare", >+ "Africa/Johannesburg", >+ "Africa/Juba", >+ "Africa/Kampala", >+ "Africa/Khartoum", >+ "Africa/Kigali", >+ "Africa/Kinshasa", >+ "Africa/Lagos", >+ "Africa/Libreville", >+ "Africa/Lome", >+ "Africa/Luanda", >+ "Africa/Lubumbashi", >+ "Africa/Lusaka", >+ "Africa/Malabo", >+ "Africa/Maputo", >+ "Africa/Maseru", >+ "Africa/Mbabane", >+ "Africa/Mogadishu", >+ "Africa/Monrovia", >+ "Africa/Nairobi", >+ "Africa/Ndjamena", >+ "Africa/Niamey", >+ "Africa/Nouakchott", >+ "Africa/Ouagadougou", >+ "Africa/Porto-Novo", >+ "Africa/Sao_Tome", >+ "Africa/Timbuktu", >+ "Africa/Tripoli", >+ "Africa/Tunis", >+ "Africa/Windhoek", >+ "America/Adak", >+ "America/Anchorage", >+ "America/Anguilla", >+ "America/Antigua", >+ "America/Araguaina", >+ "America/Argentina/Buenos_Aires", >+ "America/Argentina/Catamarca", >+ "America/Argentina/ComodRivadavia", >+ "America/Argentina/Cordoba", >+ "America/Argentina/Jujuy", >+ "America/Argentina/La_Rioja", >+ "America/Argentina/Mendoza", >+ "America/Argentina/Rio_Gallegos", >+ "America/Argentina/Salta", >+ "America/Argentina/San_Juan", >+ "America/Argentina/San_Luis", >+ "America/Argentina/Tucuman", >+ "America/Argentina/Ushuaia", >+ "America/Aruba", >+ "America/Asuncion", >+ "America/Atikokan", >+ "America/Atka", >+ "America/Bahia", >+ "America/Bahia_Banderas", >+ "America/Barbados", >+ "America/Belem", >+ "America/Belize", >+ "America/Blanc-Sablon", >+ "America/Boa_Vista", >+ "America/Bogota", >+ "America/Boise", >+ "America/Buenos_Aires", >+ "America/Cambridge_Bay", >+ "America/Campo_Grande", >+ "America/Cancun", >+ "America/Caracas", >+ "America/Catamarca", >+ "America/Cayenne", >+ "America/Cayman", >+ "America/Chicago", >+ "America/Chihuahua", >+ "America/Coral_Harbour", >+ "America/Cordoba", >+ "America/Costa_Rica", >+ "America/Creston", >+ "America/Cuiaba", >+ "America/Curacao", >+ "America/Danmarkshavn", >+ "America/Dawson", >+ "America/Dawson_Creek", >+ "America/Denver", >+ "America/Detroit", >+ "America/Dominica", >+ "America/Edmonton", >+ "America/Eirunepe", >+ "America/El_Salvador", >+ "America/Ensenada", >+ "America/Fort_Nelson", >+ "America/Fort_Wayne", >+ "America/Fortaleza", >+ "America/Glace_Bay", >+ "America/Godthab", >+ "America/Goose_Bay", >+ "America/Grand_Turk", >+ "America/Grenada", >+ "America/Guadeloupe", >+ "America/Guatemala", >+ "America/Guayaquil", >+ "America/Guyana", >+ "America/Halifax", >+ "America/Havana", >+ "America/Hermosillo", >+ "America/Indiana/Indianapolis", >+ "America/Indiana/Knox", >+ "America/Indiana/Marengo", >+ "America/Indiana/Petersburg", >+ "America/Indiana/Tell_City", >+ "America/Indiana/Vevay", >+ "America/Indiana/Vincennes", >+ "America/Indiana/Winamac", >+ "America/Indianapolis", >+ "America/Inuvik", >+ "America/Iqaluit", >+ "America/Jamaica", >+ "America/Jujuy", >+ "America/Juneau", >+ "America/Kentucky/Louisville", >+ "America/Kentucky/Monticello", >+ "America/Knox_IN", >+ "America/Kralendijk", >+ "America/La_Paz", >+ "America/Lima", >+ "America/Los_Angeles", >+ "America/Louisville", >+ "America/Lower_Princes", >+ "America/Maceio", >+ "America/Managua", >+ "America/Manaus", >+ "America/Marigot", >+ "America/Martinique", >+ "America/Matamoros", >+ "America/Mazatlan", >+ "America/Mendoza", >+ "America/Menominee", >+ "America/Merida", >+ "America/Metlakatla", >+ "America/Mexico_City", >+ "America/Miquelon", >+ "America/Moncton", >+ "America/Monterrey", >+ "America/Montevideo", >+ "America/Montreal", >+ "America/Montserrat", >+ "America/Nassau", >+ "America/New_York", >+ "America/Nipigon", >+ "America/Nome", >+ "America/Noronha", >+ "America/North_Dakota/Beulah", >+ "America/North_Dakota/Center", >+ "America/North_Dakota/New_Salem", >+ "America/Ojinaga", >+ "America/Panama", >+ "America/Pangnirtung", >+ "America/Paramaribo", >+ "America/Phoenix", >+ "America/Port-au-Prince", >+ "America/Port_of_Spain", >+ "America/Porto_Acre", >+ "America/Porto_Velho", >+ "America/Puerto_Rico", >+ "America/Punta_Arenas", >+ "America/Rainy_River", >+ "America/Rankin_Inlet", >+ "America/Recife", >+ "America/Regina", >+ "America/Resolute", >+ "America/Rio_Branco", >+ "America/Rosario", >+ "America/Santa_Isabel", >+ "America/Santarem", >+ "America/Santiago", >+ "America/Santo_Domingo", >+ "America/Sao_Paulo", >+ "America/Scoresbysund", >+ "America/Shiprock", >+ "America/Sitka", >+ "America/St_Barthelemy", >+ "America/St_Johns", >+ "America/St_Kitts", >+ "America/St_Lucia", >+ "America/St_Thomas", >+ "America/St_Vincent", >+ "America/Swift_Current", >+ "America/Tegucigalpa", >+ "America/Thule", >+ "America/Thunder_Bay", >+ "America/Tijuana", >+ "America/Toronto", >+ "America/Tortola", >+ "America/Vancouver", >+ "America/Virgin", >+ "America/Whitehorse", >+ "America/Winnipeg", >+ "America/Yakutat", >+ "America/Yellowknife", >+ "Antarctica/Casey", >+ "Antarctica/Davis", >+ "Antarctica/DumontDUrville", >+ "Antarctica/Macquarie", >+ "Antarctica/Mawson", >+ "Antarctica/McMurdo", >+ "Antarctica/Palmer", >+ "Antarctica/Rothera", >+ "Antarctica/South_Pole", >+ "Antarctica/Syowa", >+ "Antarctica/Troll", >+ "Antarctica/Vostok", >+ "Arctic/Longyearbyen", >+ "Asia/Aden", >+ "Asia/Almaty", >+ "Asia/Amman", >+ "Asia/Anadyr", >+ "Asia/Aqtau", >+ "Asia/Aqtobe", >+ "Asia/Ashgabat", >+ "Asia/Ashkhabad", >+ "Asia/Atyrau", >+ "Asia/Baghdad", >+ "Asia/Bahrain", >+ "Asia/Baku", >+ "Asia/Bangkok", >+ "Asia/Barnaul", >+ "Asia/Beirut", >+ "Asia/Bishkek", >+ "Asia/Brunei", >+ "Asia/Calcutta", >+ "Asia/Chita", >+ "Asia/Choibalsan", >+ "Asia/Chongqing", >+ "Asia/Chungking", >+ "Asia/Colombo", >+ "Asia/Dacca", >+ "Asia/Damascus", >+ "Asia/Dhaka", >+ "Asia/Dili", >+ "Asia/Dubai", >+ "Asia/Dushanbe", >+ "Asia/Famagusta", >+ "Asia/Gaza", >+ "Asia/Harbin", >+ "Asia/Hebron", >+ "Asia/Ho_Chi_Minh", >+ "Asia/Hong_Kong", >+ "Asia/Hovd", >+ "Asia/Irkutsk", >+ "Asia/Istanbul", >+ "Asia/Jakarta", >+ "Asia/Jayapura", >+ "Asia/Jerusalem", >+ "Asia/Kabul", >+ "Asia/Kamchatka", >+ "Asia/Karachi", >+ "Asia/Kashgar", >+ "Asia/Kathmandu", >+ "Asia/Katmandu", >+ "Asia/Khandyga", >+ "Asia/Kolkata", >+ "Asia/Krasnoyarsk", >+ "Asia/Kuala_Lumpur", >+ "Asia/Kuching", >+ "Asia/Kuwait", >+ "Asia/Macao", >+ "Asia/Macau", >+ "Asia/Magadan", >+ "Asia/Makassar", >+ "Asia/Manila", >+ "Asia/Muscat", >+ "Asia/Nicosia", >+ "Asia/Novokuznetsk", >+ "Asia/Novosibirsk", >+ "Asia/Omsk", >+ "Asia/Oral", >+ "Asia/Phnom_Penh", >+ "Asia/Pontianak", >+ "Asia/Pyongyang", >+ "Asia/Qatar", >+ "Asia/Qyzylorda", >+ "Asia/Rangoon", >+ "Asia/Riyadh", >+ "Asia/Saigon", >+ "Asia/Sakhalin", >+ "Asia/Samarkand", >+ "Asia/Seoul", >+ "Asia/Shanghai", >+ "Asia/Singapore", >+ "Asia/Srednekolymsk", >+ "Asia/Taipei", >+ "Asia/Tashkent", >+ "Asia/Tbilisi", >+ "Asia/Tehran", >+ "Asia/Tel_Aviv", >+ "Asia/Thimbu", >+ "Asia/Thimphu", >+ "Asia/Tokyo", >+ "Asia/Tomsk", >+ "Asia/Ujung_Pandang", >+ "Asia/Ulaanbaatar", >+ "Asia/Ulan_Bator", >+ "Asia/Urumqi", >+ "Asia/Ust-Nera", >+ "Asia/Vientiane", >+ "Asia/Vladivostok", >+ "Asia/Yakutsk", >+ "Asia/Yangon", >+ "Asia/Yekaterinburg", >+ "Asia/Yerevan", >+ "Atlantic/Azores", >+ "Atlantic/Bermuda", >+ "Atlantic/Canary", >+ "Atlantic/Cape_Verde", >+ "Atlantic/Faeroe", >+ "Atlantic/Faroe", >+ "Atlantic/Jan_Mayen", >+ "Atlantic/Madeira", >+ "Atlantic/Reykjavik", >+ "Atlantic/South_Georgia", >+ "Atlantic/St_Helena", >+ "Atlantic/Stanley", >+ "Australia/ACT", >+ "Australia/Adelaide", >+ "Australia/Brisbane", >+ "Australia/Broken_Hill", >+ "Australia/Canberra", >+ "Australia/Currie", >+ "Australia/Darwin", >+ "Australia/Eucla", >+ "Australia/Hobart", >+ "Australia/LHI", >+ "Australia/Lindeman", >+ "Australia/Lord_Howe", >+ "Australia/Melbourne", >+ "Australia/NSW", >+ "Australia/North", >+ "Australia/Perth", >+ "Australia/Queensland", >+ "Australia/South", >+ "Australia/Sydney", >+ "Australia/Tasmania", >+ "Australia/Victoria", >+ "Australia/West", >+ "Australia/Yancowinna", >+ "Brazil/Acre", >+ "Brazil/DeNoronha", >+ "Brazil/East", >+ "Brazil/West", >+ "CET", >+ "CST6CDT", >+ "Canada/Atlantic", >+ "Canada/Central", >+ "Canada/Eastern", >+ "Canada/Mountain", >+ "Canada/Newfoundland", >+ "Canada/Pacific", >+ "Canada/Saskatchewan", >+ "Canada/Yukon", >+ "Chile/Continental", >+ "Chile/EasterIsland", >+ "Cuba", >+ "EET", >+ "EST", >+ "EST5EDT", >+ "Egypt", >+ "Eire", >+ "Etc/GMT", >+ "Etc/GMT+0", >+ "Etc/GMT+1", >+ "Etc/GMT+10", >+ "Etc/GMT+11", >+ "Etc/GMT+12", >+ "Etc/GMT+2", >+ "Etc/GMT+3", >+ "Etc/GMT+4", >+ "Etc/GMT+5", >+ "Etc/GMT+6", >+ "Etc/GMT+7", >+ "Etc/GMT+8", >+ "Etc/GMT+9", >+ "Etc/GMT-0", >+ "Etc/GMT-1", >+ "Etc/GMT-10", >+ "Etc/GMT-11", >+ "Etc/GMT-12", >+ "Etc/GMT-13", >+ "Etc/GMT-14", >+ "Etc/GMT-2", >+ "Etc/GMT-3", >+ "Etc/GMT-4", >+ "Etc/GMT-5", >+ "Etc/GMT-6", >+ "Etc/GMT-7", >+ "Etc/GMT-8", >+ "Etc/GMT-9", >+ "Etc/GMT0", >+ "Etc/Greenwich", >+ "Etc/UCT", >+ "Etc/UTC", >+ "Etc/Universal", >+ "Etc/Zulu", >+ "Europe/Amsterdam", >+ "Europe/Andorra", >+ "Europe/Astrakhan", >+ "Europe/Athens", >+ "Europe/Belfast", >+ "Europe/Belgrade", >+ "Europe/Berlin", >+ "Europe/Bratislava", >+ "Europe/Brussels", >+ "Europe/Bucharest", >+ "Europe/Budapest", >+ "Europe/Busingen", >+ "Europe/Chisinau", >+ "Europe/Copenhagen", >+ "Europe/Dublin", >+ "Europe/Gibraltar", >+ "Europe/Guernsey", >+ "Europe/Helsinki", >+ "Europe/Isle_of_Man", >+ "Europe/Istanbul", >+ "Europe/Jersey", >+ "Europe/Kaliningrad", >+ "Europe/Kiev", >+ "Europe/Kirov", >+ "Europe/Lisbon", >+ "Europe/Ljubljana", >+ "Europe/London", >+ "Europe/Luxembourg", >+ "Europe/Madrid", >+ "Europe/Malta", >+ "Europe/Mariehamn", >+ "Europe/Minsk", >+ "Europe/Monaco", >+ "Europe/Moscow", >+ "Europe/Nicosia", >+ "Europe/Oslo", >+ "Europe/Paris", >+ "Europe/Podgorica", >+ "Europe/Prague", >+ "Europe/Riga", >+ "Europe/Rome", >+ "Europe/Samara", >+ "Europe/San_Marino", >+ "Europe/Sarajevo", >+ "Europe/Saratov", >+ "Europe/Simferopol", >+ "Europe/Skopje", >+ "Europe/Sofia", >+ "Europe/Stockholm", >+ "Europe/Tallinn", >+ "Europe/Tirane", >+ "Europe/Tiraspol", >+ "Europe/Ulyanovsk", >+ "Europe/Uzhgorod", >+ "Europe/Vaduz", >+ "Europe/Vatican", >+ "Europe/Vienna", >+ "Europe/Vilnius", >+ "Europe/Volgograd", >+ "Europe/Warsaw", >+ "Europe/Zagreb", >+ "Europe/Zaporozhye", >+ "Europe/Zurich", >+ "GB", >+ "GB-Eire", >+ "GMT", >+ "GMT+0", >+ "GMT-0", >+ "GMT0", >+ "Greenwich", >+ "HST", >+ "Hongkong", >+ "Iceland", >+ "Indian/Antananarivo", >+ "Indian/Chagos", >+ "Indian/Christmas", >+ "Indian/Cocos", >+ "Indian/Comoro", >+ "Indian/Kerguelen", >+ "Indian/Mahe", >+ "Indian/Maldives", >+ "Indian/Mauritius", >+ "Indian/Mayotte", >+ "Indian/Reunion", >+ "Iran", >+ "Israel", >+ "Jamaica", >+ "Japan", >+ "Kwajalein", >+ "Libya", >+ "MET", >+ "MST", >+ "MST7MDT", >+ "Mexico/BajaNorte", >+ "Mexico/BajaSur", >+ "Mexico/General", >+ "NZ", >+ "NZ-CHAT", >+ "Navajo", >+ "PRC", >+ "PST8PDT", >+ "Pacific/Apia", >+ "Pacific/Auckland", >+ "Pacific/Bougainville", >+ "Pacific/Chatham", >+ "Pacific/Chuuk", >+ "Pacific/Easter", >+ "Pacific/Efate", >+ "Pacific/Enderbury", >+ "Pacific/Fakaofo", >+ "Pacific/Fiji", >+ "Pacific/Funafuti", >+ "Pacific/Galapagos", >+ "Pacific/Gambier", >+ "Pacific/Guadalcanal", >+ "Pacific/Guam", >+ "Pacific/Honolulu", >+ "Pacific/Johnston", >+ "Pacific/Kiritimati", >+ "Pacific/Kosrae", >+ "Pacific/Kwajalein", >+ "Pacific/Majuro", >+ "Pacific/Marquesas", >+ "Pacific/Midway", >+ "Pacific/Nauru", >+ "Pacific/Niue", >+ "Pacific/Norfolk", >+ "Pacific/Noumea", >+ "Pacific/Pago_Pago", >+ "Pacific/Palau", >+ "Pacific/Pitcairn", >+ "Pacific/Pohnpei", >+ "Pacific/Ponape", >+ "Pacific/Port_Moresby", >+ "Pacific/Rarotonga", >+ "Pacific/Saipan", >+ "Pacific/Samoa", >+ "Pacific/Tahiti", >+ "Pacific/Tarawa", >+ "Pacific/Tongatapu", >+ "Pacific/Truk", >+ "Pacific/Wake", >+ "Pacific/Wallis", >+ "Pacific/Yap", >+ "Poland", >+ "Portugal", >+ "ROC", >+ "ROK", >+ "Singapore", >+ "Turkey", >+ "UCT", >+ "US/Alaska", >+ "US/Aleutian", >+ "US/Arizona", >+ "US/Central", >+ "US/East-Indiana", >+ "US/Eastern", >+ "US/Hawaii", >+ "US/Indiana-Starke", >+ "US/Michigan", >+ "US/Mountain", >+ "US/Pacific", >+ "US/Samoa", >+ "UTC", >+ "Universal", >+ "W-SU", >+ "WET", >+ "Zulu", >+ nullptr >+}; >+ >+std::vector<std::string> AllTimeZoneNames() { >+ std::vector<std::string> names; >+ for (const char* const* namep = kTimeZoneNames; *namep != nullptr; ++namep) { >+ names.push_back(std::string("file:") + *namep); >+ } >+ assert(!names.empty()); >+ >+ std::mt19937 urbg(42); // a UniformRandomBitGenerator with fixed seed >+ std::shuffle(names.begin(), names.end(), urbg); >+ return names; >+} >+ >+cctz::time_zone TestTimeZone() { >+ cctz::time_zone tz; >+ cctz::load_time_zone("America/Los_Angeles", &tz); >+ return tz; >+} >+ >+void BM_Zone_LoadUTCTimeZoneFirst(benchmark::State& state) { >+ cctz::time_zone tz; >+ cctz::load_time_zone("UTC", &tz); // in case we're first >+ cctz::time_zone::Impl::ClearTimeZoneMapTestOnly(); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz)); >+ } >+} >+BENCHMARK(BM_Zone_LoadUTCTimeZoneFirst); >+ >+void BM_Zone_LoadUTCTimeZoneLast(benchmark::State& state) { >+ cctz::time_zone tz; >+ for (const auto& name : AllTimeZoneNames()) { >+ cctz::load_time_zone(name, &tz); // prime cache >+ } >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz)); >+ } >+} >+BENCHMARK(BM_Zone_LoadUTCTimeZoneLast); >+ >+void BM_Zone_LoadTimeZoneFirst(benchmark::State& state) { >+ cctz::time_zone tz = cctz::utc_time_zone(); // in case we're first >+ const std::string name = "file:America/Los_Angeles"; >+ while (state.KeepRunning()) { >+ state.PauseTiming(); >+ cctz::time_zone::Impl::ClearTimeZoneMapTestOnly(); >+ state.ResumeTiming(); >+ benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz)); >+ } >+} >+BENCHMARK(BM_Zone_LoadTimeZoneFirst); >+ >+void BM_Zone_LoadTimeZoneCached(benchmark::State& state) { >+ cctz::time_zone tz = cctz::utc_time_zone(); // in case we're first >+ cctz::time_zone::Impl::ClearTimeZoneMapTestOnly(); >+ const std::string name = "file:America/Los_Angeles"; >+ cctz::load_time_zone(name, &tz); // prime cache >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz)); >+ } >+} >+BENCHMARK(BM_Zone_LoadTimeZoneCached); >+ >+void BM_Zone_LoadLocalTimeZoneCached(benchmark::State& state) { >+ cctz::utc_time_zone(); // in case we're first >+ cctz::time_zone::Impl::ClearTimeZoneMapTestOnly(); >+ cctz::local_time_zone(); // prime cache >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(cctz::local_time_zone()); >+ } >+} >+BENCHMARK(BM_Zone_LoadLocalTimeZoneCached); >+ >+void BM_Zone_LoadAllTimeZonesFirst(benchmark::State& state) { >+ cctz::time_zone tz; >+ const std::vector<std::string> names = AllTimeZoneNames(); >+ for (auto index = names.size(); state.KeepRunning(); ++index) { >+ if (index == names.size()) { >+ index = 0; >+ } >+ if (index == 0) { >+ state.PauseTiming(); >+ cctz::time_zone::Impl::ClearTimeZoneMapTestOnly(); >+ state.ResumeTiming(); >+ } >+ benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz)); >+ } >+} >+BENCHMARK(BM_Zone_LoadAllTimeZonesFirst); >+ >+void BM_Zone_LoadAllTimeZonesCached(benchmark::State& state) { >+ cctz::time_zone tz; >+ const std::vector<std::string> names = AllTimeZoneNames(); >+ for (const auto& name : names) { >+ cctz::load_time_zone(name, &tz); // prime cache >+ } >+ for (auto index = names.size(); state.KeepRunning(); ++index) { >+ if (index == names.size()) { >+ index = 0; >+ } >+ benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz)); >+ } >+} >+BENCHMARK(BM_Zone_LoadAllTimeZonesCached); >+ >+void BM_Zone_TimeZoneEqualityImplicit(benchmark::State& state) { >+ cctz::time_zone tz; // implicit UTC >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(tz == tz); >+ } >+} >+BENCHMARK(BM_Zone_TimeZoneEqualityImplicit); >+ >+void BM_Zone_TimeZoneEqualityExplicit(benchmark::State& state) { >+ cctz::time_zone tz = cctz::utc_time_zone(); // explicit UTC >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(tz == tz); >+ } >+} >+BENCHMARK(BM_Zone_TimeZoneEqualityExplicit); >+ >+void BM_Zone_UTCTimeZone(benchmark::State& state) { >+ cctz::time_zone tz; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(cctz::utc_time_zone()); >+ } >+} >+BENCHMARK(BM_Zone_UTCTimeZone); >+ >+// In each "ToDateTime" benchmark we switch between two instants >+// separated by at least one transition in order to defeat any >+// internal caching of previous results (e.g., see local_time_hint_). >+// >+// The "UTC" variants use UTC instead of the Google/local time zone. >+ >+void BM_Time_ToDateTime_CCTZ(benchmark::State& state) { >+ const cctz::time_zone tz = TestTimeZone(); >+ std::chrono::system_clock::time_point tp = >+ std::chrono::system_clock::from_time_t(1384569027); >+ std::chrono::system_clock::time_point tp2 = >+ std::chrono::system_clock::from_time_t(1418962578); >+ while (state.KeepRunning()) { >+ std::swap(tp, tp2); >+ tp += std::chrono::seconds(1); >+ benchmark::DoNotOptimize(cctz::convert(tp, tz)); >+ } >+} >+BENCHMARK(BM_Time_ToDateTime_CCTZ); >+ >+void BM_Time_ToDateTime_Libc(benchmark::State& state) { >+ // No timezone support, so just use localtime. >+ time_t t = 1384569027; >+ time_t t2 = 1418962578; >+ struct tm tm; >+ while (state.KeepRunning()) { >+ std::swap(t, t2); >+ t += 1; >+#if defined(_WIN32) || defined(_WIN64) >+ benchmark::DoNotOptimize(localtime_s(&tm, &t)); >+#else >+ benchmark::DoNotOptimize(localtime_r(&t, &tm)); >+#endif >+ } >+} >+BENCHMARK(BM_Time_ToDateTime_Libc); >+ >+void BM_Time_ToDateTimeUTC_CCTZ(benchmark::State& state) { >+ const cctz::time_zone tz = cctz::utc_time_zone(); >+ std::chrono::system_clock::time_point tp = >+ std::chrono::system_clock::from_time_t(1384569027); >+ while (state.KeepRunning()) { >+ tp += std::chrono::seconds(1); >+ benchmark::DoNotOptimize(cctz::convert(tp, tz)); >+ } >+} >+BENCHMARK(BM_Time_ToDateTimeUTC_CCTZ); >+ >+void BM_Time_ToDateTimeUTC_Libc(benchmark::State& state) { >+ time_t t = 1384569027; >+ struct tm tm; >+ while (state.KeepRunning()) { >+ t += 1; >+#if defined(_WIN32) || defined(_WIN64) >+ benchmark::DoNotOptimize(gmtime_s(&tm, &t)); >+#else >+ benchmark::DoNotOptimize(gmtime_r(&t, &tm)); >+#endif >+ } >+} >+BENCHMARK(BM_Time_ToDateTimeUTC_Libc); >+ >+// In each "FromDateTime" benchmark we switch between two YMDhms >+// values separated by at least one transition in order to defeat any >+// internal caching of previous results (e.g., see time_local_hint_). >+// >+// The "UTC" variants use UTC instead of the Google/local time zone. >+// The "Day0" variants require normalization of the day of month. >+ >+void BM_Time_FromDateTime_CCTZ(benchmark::State& state) { >+ const cctz::time_zone tz = TestTimeZone(); >+ int i = 0; >+ while (state.KeepRunning()) { >+ if ((i++ & 1) == 0) { >+ benchmark::DoNotOptimize( >+ cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz)); >+ } else { >+ benchmark::DoNotOptimize( >+ cctz::convert(cctz::civil_second(2013, 11, 15, 18, 30, 27), tz)); >+ } >+ } >+} >+BENCHMARK(BM_Time_FromDateTime_CCTZ); >+ >+void BM_Time_FromDateTime_Libc(benchmark::State& state) { >+ // No timezone support, so just use localtime. >+ int i = 0; >+ while (state.KeepRunning()) { >+ struct tm tm; >+ if ((i++ & 1) == 0) { >+ tm.tm_year = 2014 - 1900; >+ tm.tm_mon = 12 - 1; >+ tm.tm_mday = 18; >+ tm.tm_hour = 20; >+ tm.tm_min = 16; >+ tm.tm_sec = 18; >+ } else { >+ tm.tm_year = 2013 - 1900; >+ tm.tm_mon = 11 - 1; >+ tm.tm_mday = 15; >+ tm.tm_hour = 18; >+ tm.tm_min = 30; >+ tm.tm_sec = 27; >+ } >+ tm.tm_isdst = -1; >+ benchmark::DoNotOptimize(mktime(&tm)); >+ } >+} >+BENCHMARK(BM_Time_FromDateTime_Libc); >+ >+void BM_Time_FromDateTimeUTC_CCTZ(benchmark::State& state) { >+ const cctz::time_zone tz = cctz::utc_time_zone(); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize( >+ cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz)); >+ } >+} >+BENCHMARK(BM_Time_FromDateTimeUTC_CCTZ); >+ >+// There is no BM_Time_FromDateTimeUTC_Libc. >+ >+void BM_Time_FromDateTimeDay0_CCTZ(benchmark::State& state) { >+ const cctz::time_zone tz = TestTimeZone(); >+ int i = 0; >+ while (state.KeepRunning()) { >+ if ((i++ & 1) == 0) { >+ benchmark::DoNotOptimize( >+ cctz::convert(cctz::civil_second(2014, 12, 0, 20, 16, 18), tz)); >+ } else { >+ benchmark::DoNotOptimize( >+ cctz::convert(cctz::civil_second(2013, 11, 0, 18, 30, 27), tz)); >+ } >+ } >+} >+BENCHMARK(BM_Time_FromDateTimeDay0_CCTZ); >+ >+void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) { >+ // No timezone support, so just use localtime. >+ int i = 0; >+ while (state.KeepRunning()) { >+ struct tm tm; >+ if ((i++ & 1) == 0) { >+ tm.tm_year = 2014 - 1900; >+ tm.tm_mon = 12 - 1; >+ tm.tm_mday = 0; >+ tm.tm_hour = 20; >+ tm.tm_min = 16; >+ tm.tm_sec = 18; >+ } else { >+ tm.tm_year = 2013 - 1900; >+ tm.tm_mon = 11 - 1; >+ tm.tm_mday = 0; >+ tm.tm_hour = 18; >+ tm.tm_min = 30; >+ tm.tm_sec = 27; >+ } >+ tm.tm_isdst = -1; >+ benchmark::DoNotOptimize(mktime(&tm)); >+ } >+} >+BENCHMARK(BM_Time_FromDateTimeDay0_Libc); >+ >+const char* const kFormats[] = { >+ RFC1123_full, // 0 >+ RFC1123_no_wday, // 1 >+ RFC3339_full, // 2 >+ RFC3339_sec, // 3 >+ "%Y-%m-%dT%H:%M:%S", // 4 >+ "%Y-%m-%d", // 5 >+}; >+const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]); >+ >+void BM_Format_FormatTime(benchmark::State& state) { >+ const std::string fmt = kFormats[state.range(0)]; >+ state.SetLabel(fmt); >+ const cctz::time_zone tz = TestTimeZone(); >+ const std::chrono::system_clock::time_point tp = >+ cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) + >+ std::chrono::microseconds(1); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(cctz::format(fmt, tp, tz)); >+ } >+} >+BENCHMARK(BM_Format_FormatTime)->DenseRange(0, kNumFormats - 1); >+ >+void BM_Format_ParseTime(benchmark::State& state) { >+ const std::string fmt = kFormats[state.range(0)]; >+ state.SetLabel(fmt); >+ const cctz::time_zone tz = TestTimeZone(); >+ std::chrono::system_clock::time_point tp = >+ cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) + >+ std::chrono::microseconds(1); >+ const std::string when = cctz::format(fmt, tp, tz); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(cctz::parse(fmt, when, tz, &tp)); >+ } >+} >+BENCHMARK(BM_Format_ParseTime)->DenseRange(0, kNumFormats - 1); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_detail.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_detail.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..780d5c96e8bfe3df0fa8f20ceb5424bb5fef7ab5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_detail.cc >@@ -0,0 +1,90 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time_detail.h" >+ >+#include <iomanip> >+#include <ostream> >+#include <sstream> >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+namespace detail { >+ >+// Output stream operators output a format matching YYYY-MM-DDThh:mm:ss, >+// while omitting fields inferior to the type's alignment. For example, >+// civil_day is formatted only as YYYY-MM-DD. >+std::ostream& operator<<(std::ostream& os, const civil_year& y) { >+ std::stringstream ss; >+ ss << y.year(); // No padding. >+ return os << ss.str(); >+} >+std::ostream& operator<<(std::ostream& os, const civil_month& m) { >+ std::stringstream ss; >+ ss << civil_year(m) << '-'; >+ ss << std::setfill('0') << std::setw(2) << m.month(); >+ return os << ss.str(); >+} >+std::ostream& operator<<(std::ostream& os, const civil_day& d) { >+ std::stringstream ss; >+ ss << civil_month(d) << '-'; >+ ss << std::setfill('0') << std::setw(2) << d.day(); >+ return os << ss.str(); >+} >+std::ostream& operator<<(std::ostream& os, const civil_hour& h) { >+ std::stringstream ss; >+ ss << civil_day(h) << 'T'; >+ ss << std::setfill('0') << std::setw(2) << h.hour(); >+ return os << ss.str(); >+} >+std::ostream& operator<<(std::ostream& os, const civil_minute& m) { >+ std::stringstream ss; >+ ss << civil_hour(m) << ':'; >+ ss << std::setfill('0') << std::setw(2) << m.minute(); >+ return os << ss.str(); >+} >+std::ostream& operator<<(std::ostream& os, const civil_second& s) { >+ std::stringstream ss; >+ ss << civil_minute(s) << ':'; >+ ss << std::setfill('0') << std::setw(2) << s.second(); >+ return os << ss.str(); >+} >+ >+//////////////////////////////////////////////////////////////////////// >+ >+std::ostream& operator<<(std::ostream& os, weekday wd) { >+ switch (wd) { >+ case weekday::monday: >+ return os << "Monday"; >+ case weekday::tuesday: >+ return os << "Tuesday"; >+ case weekday::wednesday: >+ return os << "Wednesday"; >+ case weekday::thursday: >+ return os << "Thursday"; >+ case weekday::friday: >+ return os << "Friday"; >+ case weekday::saturday: >+ return os << "Saturday"; >+ case weekday::sunday: >+ return os << "Sunday"; >+ } >+ return os; // Should never get here, but -Wreturn-type may warn without this. >+} >+ >+} // namespace detail >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..f6648c8f1f21f3207aba1b5e4bb066061b064b65 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_test.cc >@@ -0,0 +1,1049 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+ >+#include <iomanip> >+#include <limits> >+#include <sstream> >+#include <string> >+#include <type_traits> >+ >+#include "gtest/gtest.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+namespace { >+ >+template <typename T> >+std::string Format(const T& t) { >+ std::stringstream ss; >+ ss << t; >+ return ss.str(); >+} >+ >+} // namespace >+ >+#if __cpp_constexpr >= 201304 || _MSC_VER >= 1910 >+// Construction constexpr tests >+ >+TEST(CivilTime, Normal) { >+ constexpr civil_second css(2016, 1, 28, 17, 14, 12); >+ static_assert(css.second() == 12, "Normal.second"); >+ constexpr civil_minute cmm(2016, 1, 28, 17, 14); >+ static_assert(cmm.minute() == 14, "Normal.minute"); >+ constexpr civil_hour chh(2016, 1, 28, 17); >+ static_assert(chh.hour() == 17, "Normal.hour"); >+ constexpr civil_day cd(2016, 1, 28); >+ static_assert(cd.day() == 28, "Normal.day"); >+ constexpr civil_month cm(2016, 1); >+ static_assert(cm.month() == 1, "Normal.month"); >+ constexpr civil_year cy(2016); >+ static_assert(cy.year() == 2016, "Normal.year"); >+} >+ >+TEST(CivilTime, Conversion) { >+ constexpr civil_year cy(2016); >+ static_assert(cy.year() == 2016, "Conversion.year"); >+ constexpr civil_month cm(cy); >+ static_assert(cm.month() == 1, "Conversion.month"); >+ constexpr civil_day cd(cm); >+ static_assert(cd.day() == 1, "Conversion.day"); >+ constexpr civil_hour chh(cd); >+ static_assert(chh.hour() == 0, "Conversion.hour"); >+ constexpr civil_minute cmm(chh); >+ static_assert(cmm.minute() == 0, "Conversion.minute"); >+ constexpr civil_second css(cmm); >+ static_assert(css.second() == 0, "Conversion.second"); >+} >+ >+// Normalization constexpr tests >+ >+TEST(CivilTime, Normalized) { >+ constexpr civil_second cs(2016, 1, 28, 17, 14, 12); >+ static_assert(cs.year() == 2016, "Normalized.year"); >+ static_assert(cs.month() == 1, "Normalized.month"); >+ static_assert(cs.day() == 28, "Normalized.day"); >+ static_assert(cs.hour() == 17, "Normalized.hour"); >+ static_assert(cs.minute() == 14, "Normalized.minute"); >+ static_assert(cs.second() == 12, "Normalized.second"); >+} >+ >+TEST(CivilTime, SecondOverflow) { >+ constexpr civil_second cs(2016, 1, 28, 17, 14, 121); >+ static_assert(cs.year() == 2016, "SecondOverflow.year"); >+ static_assert(cs.month() == 1, "SecondOverflow.month"); >+ static_assert(cs.day() == 28, "SecondOverflow.day"); >+ static_assert(cs.hour() == 17, "SecondOverflow.hour"); >+ static_assert(cs.minute() == 16, "SecondOverflow.minute"); >+ static_assert(cs.second() == 1, "SecondOverflow.second"); >+} >+ >+TEST(CivilTime, SecondUnderflow) { >+ constexpr civil_second cs(2016, 1, 28, 17, 14, -121); >+ static_assert(cs.year() == 2016, "SecondUnderflow.year"); >+ static_assert(cs.month() == 1, "SecondUnderflow.month"); >+ static_assert(cs.day() == 28, "SecondUnderflow.day"); >+ static_assert(cs.hour() == 17, "SecondUnderflow.hour"); >+ static_assert(cs.minute() == 11, "SecondUnderflow.minute"); >+ static_assert(cs.second() == 59, "SecondUnderflow.second"); >+} >+ >+TEST(CivilTime, MinuteOverflow) { >+ constexpr civil_second cs(2016, 1, 28, 17, 121, 12); >+ static_assert(cs.year() == 2016, "MinuteOverflow.year"); >+ static_assert(cs.month() == 1, "MinuteOverflow.month"); >+ static_assert(cs.day() == 28, "MinuteOverflow.day"); >+ static_assert(cs.hour() == 19, "MinuteOverflow.hour"); >+ static_assert(cs.minute() == 1, "MinuteOverflow.minute"); >+ static_assert(cs.second() == 12, "MinuteOverflow.second"); >+} >+ >+TEST(CivilTime, MinuteUnderflow) { >+ constexpr civil_second cs(2016, 1, 28, 17, -121, 12); >+ static_assert(cs.year() == 2016, "MinuteUnderflow.year"); >+ static_assert(cs.month() == 1, "MinuteUnderflow.month"); >+ static_assert(cs.day() == 28, "MinuteUnderflow.day"); >+ static_assert(cs.hour() == 14, "MinuteUnderflow.hour"); >+ static_assert(cs.minute() == 59, "MinuteUnderflow.minute"); >+ static_assert(cs.second() == 12, "MinuteUnderflow.second"); >+} >+ >+TEST(CivilTime, HourOverflow) { >+ constexpr civil_second cs(2016, 1, 28, 49, 14, 12); >+ static_assert(cs.year() == 2016, "HourOverflow.year"); >+ static_assert(cs.month() == 1, "HourOverflow.month"); >+ static_assert(cs.day() == 30, "HourOverflow.day"); >+ static_assert(cs.hour() == 1, "HourOverflow.hour"); >+ static_assert(cs.minute() == 14, "HourOverflow.minute"); >+ static_assert(cs.second() == 12, "HourOverflow.second"); >+} >+ >+TEST(CivilTime, HourUnderflow) { >+ constexpr civil_second cs(2016, 1, 28, -49, 14, 12); >+ static_assert(cs.year() == 2016, "HourUnderflow.year"); >+ static_assert(cs.month() == 1, "HourUnderflow.month"); >+ static_assert(cs.day() == 25, "HourUnderflow.day"); >+ static_assert(cs.hour() == 23, "HourUnderflow.hour"); >+ static_assert(cs.minute() == 14, "HourUnderflow.minute"); >+ static_assert(cs.second() == 12, "HourUnderflow.second"); >+} >+ >+TEST(CivilTime, MonthOverflow) { >+ constexpr civil_second cs(2016, 25, 28, 17, 14, 12); >+ static_assert(cs.year() == 2018, "MonthOverflow.year"); >+ static_assert(cs.month() == 1, "MonthOverflow.month"); >+ static_assert(cs.day() == 28, "MonthOverflow.day"); >+ static_assert(cs.hour() == 17, "MonthOverflow.hour"); >+ static_assert(cs.minute() == 14, "MonthOverflow.minute"); >+ static_assert(cs.second() == 12, "MonthOverflow.second"); >+} >+ >+TEST(CivilTime, MonthUnderflow) { >+ constexpr civil_second cs(2016, -25, 28, 17, 14, 12); >+ static_assert(cs.year() == 2013, "MonthUnderflow.year"); >+ static_assert(cs.month() == 11, "MonthUnderflow.month"); >+ static_assert(cs.day() == 28, "MonthUnderflow.day"); >+ static_assert(cs.hour() == 17, "MonthUnderflow.hour"); >+ static_assert(cs.minute() == 14, "MonthUnderflow.minute"); >+ static_assert(cs.second() == 12, "MonthUnderflow.second"); >+} >+ >+TEST(CivilTime, C4Overflow) { >+ constexpr civil_second cs(2016, 1, 292195, 17, 14, 12); >+ static_assert(cs.year() == 2816, "C4Overflow.year"); >+ static_assert(cs.month() == 1, "C4Overflow.month"); >+ static_assert(cs.day() == 1, "C4Overflow.day"); >+ static_assert(cs.hour() == 17, "C4Overflow.hour"); >+ static_assert(cs.minute() == 14, "C4Overflow.minute"); >+ static_assert(cs.second() == 12, "C4Overflow.second"); >+} >+ >+TEST(CivilTime, C4Underflow) { >+ constexpr civil_second cs(2016, 1, -292195, 17, 14, 12); >+ static_assert(cs.year() == 1215, "C4Underflow.year"); >+ static_assert(cs.month() == 12, "C4Underflow.month"); >+ static_assert(cs.day() == 30, "C4Underflow.day"); >+ static_assert(cs.hour() == 17, "C4Underflow.hour"); >+ static_assert(cs.minute() == 14, "C4Underflow.minute"); >+ static_assert(cs.second() == 12, "C4Underflow.second"); >+} >+ >+TEST(CivilTime, MixedNormalization) { >+ constexpr civil_second cs(2016, -42, 122, 99, -147, 4949); >+ static_assert(cs.year() == 2012, "MixedNormalization.year"); >+ static_assert(cs.month() == 10, "MixedNormalization.month"); >+ static_assert(cs.day() == 4, "MixedNormalization.day"); >+ static_assert(cs.hour() == 1, "MixedNormalization.hour"); >+ static_assert(cs.minute() == 55, "MixedNormalization.minute"); >+ static_assert(cs.second() == 29, "MixedNormalization.second"); >+} >+ >+// Relational constexpr tests >+ >+TEST(CivilTime, Less) { >+ constexpr civil_second cs1(2016, 1, 28, 17, 14, 12); >+ constexpr civil_second cs2(2016, 1, 28, 17, 14, 13); >+ constexpr bool less = cs1 < cs2; >+ static_assert(less, "Less"); >+} >+ >+// Arithmetic constexpr tests >+ >+TEST(CivilTime, Addition) { >+ constexpr civil_second cs1(2016, 1, 28, 17, 14, 12); >+ constexpr civil_second cs2 = cs1 + 50; >+ static_assert(cs2.year() == 2016, "Addition.year"); >+ static_assert(cs2.month() == 1, "Addition.month"); >+ static_assert(cs2.day() == 28, "Addition.day"); >+ static_assert(cs2.hour() == 17, "Addition.hour"); >+ static_assert(cs2.minute() == 15, "Addition.minute"); >+ static_assert(cs2.second() == 2, "Addition.second"); >+} >+ >+TEST(CivilTime, Subtraction) { >+ constexpr civil_second cs1(2016, 1, 28, 17, 14, 12); >+ constexpr civil_second cs2 = cs1 - 50; >+ static_assert(cs2.year() == 2016, "Subtraction.year"); >+ static_assert(cs2.month() == 1, "Subtraction.month"); >+ static_assert(cs2.day() == 28, "Subtraction.day"); >+ static_assert(cs2.hour() == 17, "Subtraction.hour"); >+ static_assert(cs2.minute() == 13, "Subtraction.minute"); >+ static_assert(cs2.second() == 22, "Subtraction.second"); >+} >+ >+TEST(CivilTime, Difference) { >+ constexpr civil_day cd1(2016, 1, 28); >+ constexpr civil_day cd2(2015, 1, 28); >+ constexpr int diff = cd1 - cd2; >+ static_assert(diff == 365, "Difference"); >+} >+ >+// NOTE: Run this with --copt=-ftrapv to detect overflow problems. >+TEST(CivilTime, DifferenceWithHugeYear) { >+ { >+ constexpr civil_day d1(9223372036854775807, 1, 1); >+ constexpr civil_day d2(9223372036854775807, 12, 31); >+ static_assert(d2 - d1 == 364, "DifferenceWithHugeYear"); >+ } >+ { >+ constexpr civil_day d1(-9223372036854775807 - 1, 1, 1); >+ constexpr civil_day d2(-9223372036854775807 - 1, 12, 31); >+ static_assert(d2 - d1 == 365, "DifferenceWithHugeYear"); >+ } >+ { >+ // Check the limits of the return value at the end of the year range. >+ constexpr civil_day d1(9223372036854775807, 1, 1); >+ constexpr civil_day d2(9198119301927009252, 6, 6); >+ static_assert(d1 - d2 == 9223372036854775807, "DifferenceWithHugeYear"); >+ static_assert((d2 - 1) - d1 == -9223372036854775807 - 1, >+ "DifferenceWithHugeYear"); >+ } >+ { >+ // Check the limits of the return value at the start of the year range. >+ constexpr civil_day d1(-9223372036854775807 - 1, 1, 1); >+ constexpr civil_day d2(-9198119301927009254, 7, 28); >+ static_assert(d2 - d1 == 9223372036854775807, "DifferenceWithHugeYear"); >+ static_assert(d1 - (d2 + 1) == -9223372036854775807 - 1, >+ "DifferenceWithHugeYear"); >+ } >+ { >+ // Check the limits of the return value from either side of year 0. >+ constexpr civil_day d1(-12626367463883278, 9, 3); >+ constexpr civil_day d2(12626367463883277, 3, 28); >+ static_assert(d2 - d1 == 9223372036854775807, "DifferenceWithHugeYear"); >+ static_assert(d1 - (d2 + 1) == -9223372036854775807 - 1, >+ "DifferenceWithHugeYear"); >+ } >+} >+ >+// NOTE: Run this with --copt=-ftrapv to detect overflow problems. >+TEST(CivilTime, DifferenceNoIntermediateOverflow) { >+ { >+ // The difference up to the minute field would be below the minimum >+ // diff_t, but the 52 extra seconds brings us back to the minimum. >+ constexpr civil_second s1(-292277022657, 1, 27, 8, 29 - 1, 52); >+ constexpr civil_second s2(1970, 1, 1, 0, 0 - 1, 0); >+ static_assert(s1 - s2 == -9223372036854775807 - 1, >+ "DifferenceNoIntermediateOverflow"); >+ } >+ { >+ // The difference up to the minute field would be above the maximum >+ // diff_t, but the -53 extra seconds brings us back to the maximum. >+ constexpr civil_second s1(292277026596, 12, 4, 15, 30, 7 - 7); >+ constexpr civil_second s2(1970, 1, 1, 0, 0, 0 - 7); >+ static_assert(s1 - s2 == 9223372036854775807, >+ "DifferenceNoIntermediateOverflow"); >+ } >+} >+ >+// Helper constexpr tests >+ >+TEST(CivilTime, WeekDay) { >+ constexpr civil_day cd(2016, 1, 28); >+ constexpr weekday wd = get_weekday(cd); >+ static_assert(wd == weekday::thursday, "Weekday"); >+} >+ >+TEST(CivilTime, NextWeekDay) { >+ constexpr civil_day cd(2016, 1, 28); >+ constexpr civil_day next = next_weekday(cd, weekday::thursday); >+ static_assert(next.year() == 2016, "NextWeekDay.year"); >+ static_assert(next.month() == 2, "NextWeekDay.month"); >+ static_assert(next.day() == 4, "NextWeekDay.day"); >+} >+ >+TEST(CivilTime, PrevWeekDay) { >+ constexpr civil_day cd(2016, 1, 28); >+ constexpr civil_day prev = prev_weekday(cd, weekday::thursday); >+ static_assert(prev.year() == 2016, "PrevWeekDay.year"); >+ static_assert(prev.month() == 1, "PrevWeekDay.month"); >+ static_assert(prev.day() == 21, "PrevWeekDay.day"); >+} >+ >+TEST(CivilTime, YearDay) { >+ constexpr civil_day cd(2016, 1, 28); >+ constexpr int yd = get_yearday(cd); >+ static_assert(yd == 28, "YearDay"); >+} >+#endif // __cpp_constexpr >= 201304 || _MSC_VER >= 1910 >+ >+// The remaining tests do not use constexpr. >+ >+TEST(CivilTime, DefaultConstruction) { >+ civil_second ss; >+ EXPECT_EQ("1970-01-01T00:00:00", Format(ss)); >+ >+ civil_minute mm; >+ EXPECT_EQ("1970-01-01T00:00", Format(mm)); >+ >+ civil_hour hh; >+ EXPECT_EQ("1970-01-01T00", Format(hh)); >+ >+ civil_day d; >+ EXPECT_EQ("1970-01-01", Format(d)); >+ >+ civil_month m; >+ EXPECT_EQ("1970-01", Format(m)); >+ >+ civil_year y; >+ EXPECT_EQ("1970", Format(y)); >+} >+ >+TEST(CivilTime, StructMember) { >+ struct S { >+ civil_day day; >+ }; >+ S s = {}; >+ EXPECT_EQ(civil_day{}, s.day); >+} >+ >+TEST(CivilTime, FieldsConstruction) { >+ EXPECT_EQ("2015-01-02T03:04:05", Format(civil_second(2015, 1, 2, 3, 4, 5))); >+ EXPECT_EQ("2015-01-02T03:04:00", Format(civil_second(2015, 1, 2, 3, 4))); >+ EXPECT_EQ("2015-01-02T03:00:00", Format(civil_second(2015, 1, 2, 3))); >+ EXPECT_EQ("2015-01-02T00:00:00", Format(civil_second(2015, 1, 2))); >+ EXPECT_EQ("2015-01-01T00:00:00", Format(civil_second(2015, 1))); >+ EXPECT_EQ("2015-01-01T00:00:00", Format(civil_second(2015))); >+ >+ EXPECT_EQ("2015-01-02T03:04", Format(civil_minute(2015, 1, 2, 3, 4, 5))); >+ EXPECT_EQ("2015-01-02T03:04", Format(civil_minute(2015, 1, 2, 3, 4))); >+ EXPECT_EQ("2015-01-02T03:00", Format(civil_minute(2015, 1, 2, 3))); >+ EXPECT_EQ("2015-01-02T00:00", Format(civil_minute(2015, 1, 2))); >+ EXPECT_EQ("2015-01-01T00:00", Format(civil_minute(2015, 1))); >+ EXPECT_EQ("2015-01-01T00:00", Format(civil_minute(2015))); >+ >+ EXPECT_EQ("2015-01-02T03", Format(civil_hour(2015, 1, 2, 3, 4, 5))); >+ EXPECT_EQ("2015-01-02T03", Format(civil_hour(2015, 1, 2, 3, 4))); >+ EXPECT_EQ("2015-01-02T03", Format(civil_hour(2015, 1, 2, 3))); >+ EXPECT_EQ("2015-01-02T00", Format(civil_hour(2015, 1, 2))); >+ EXPECT_EQ("2015-01-01T00", Format(civil_hour(2015, 1))); >+ EXPECT_EQ("2015-01-01T00", Format(civil_hour(2015))); >+ >+ EXPECT_EQ("2015-01-02", Format(civil_day(2015, 1, 2, 3, 4, 5))); >+ EXPECT_EQ("2015-01-02", Format(civil_day(2015, 1, 2, 3, 4))); >+ EXPECT_EQ("2015-01-02", Format(civil_day(2015, 1, 2, 3))); >+ EXPECT_EQ("2015-01-02", Format(civil_day(2015, 1, 2))); >+ EXPECT_EQ("2015-01-01", Format(civil_day(2015, 1))); >+ EXPECT_EQ("2015-01-01", Format(civil_day(2015))); >+ >+ EXPECT_EQ("2015-01", Format(civil_month(2015, 1, 2, 3, 4, 5))); >+ EXPECT_EQ("2015-01", Format(civil_month(2015, 1, 2, 3, 4))); >+ EXPECT_EQ("2015-01", Format(civil_month(2015, 1, 2, 3))); >+ EXPECT_EQ("2015-01", Format(civil_month(2015, 1, 2))); >+ EXPECT_EQ("2015-01", Format(civil_month(2015, 1))); >+ EXPECT_EQ("2015-01", Format(civil_month(2015))); >+ >+ EXPECT_EQ("2015", Format(civil_year(2015, 1, 2, 3, 4, 5))); >+ EXPECT_EQ("2015", Format(civil_year(2015, 1, 2, 3, 4))); >+ EXPECT_EQ("2015", Format(civil_year(2015, 1, 2, 3))); >+ EXPECT_EQ("2015", Format(civil_year(2015, 1, 2))); >+ EXPECT_EQ("2015", Format(civil_year(2015, 1))); >+ EXPECT_EQ("2015", Format(civil_year(2015))); >+} >+ >+TEST(CivilTime, FieldsConstructionLimits) { >+ const int kIntMax = std::numeric_limits<int>::max(); >+ EXPECT_EQ("2038-01-19T03:14:07", >+ Format(civil_second(1970, 1, 1, 0, 0, kIntMax))); >+ EXPECT_EQ("6121-02-11T05:21:07", >+ Format(civil_second(1970, 1, 1, 0, kIntMax, kIntMax))); >+ EXPECT_EQ("251104-11-20T12:21:07", >+ Format(civil_second(1970, 1, 1, kIntMax, kIntMax, kIntMax))); >+ EXPECT_EQ("6130715-05-30T12:21:07", >+ Format(civil_second(1970, 1, kIntMax, kIntMax, kIntMax, kIntMax))); >+ EXPECT_EQ( >+ "185087685-11-26T12:21:07", >+ Format(civil_second(1970, kIntMax, kIntMax, kIntMax, kIntMax, kIntMax))); >+ >+ const int kIntMin = std::numeric_limits<int>::min(); >+ EXPECT_EQ("1901-12-13T20:45:52", >+ Format(civil_second(1970, 1, 1, 0, 0, kIntMin))); >+ EXPECT_EQ("-2182-11-20T18:37:52", >+ Format(civil_second(1970, 1, 1, 0, kIntMin, kIntMin))); >+ EXPECT_EQ("-247165-02-11T10:37:52", >+ Format(civil_second(1970, 1, 1, kIntMin, kIntMin, kIntMin))); >+ EXPECT_EQ("-6126776-08-01T10:37:52", >+ Format(civil_second(1970, 1, kIntMin, kIntMin, kIntMin, kIntMin))); >+ EXPECT_EQ( >+ "-185083747-10-31T10:37:52", >+ Format(civil_second(1970, kIntMin, kIntMin, kIntMin, kIntMin, kIntMin))); >+} >+ >+TEST(CivilTime, ImplicitCrossAlignment) { >+ civil_year year(2015); >+ civil_month month = year; >+ civil_day day = month; >+ civil_hour hour = day; >+ civil_minute minute = hour; >+ civil_second second = minute; >+ >+ second = year; >+ EXPECT_EQ(second, year); >+ second = month; >+ EXPECT_EQ(second, month); >+ second = day; >+ EXPECT_EQ(second, day); >+ second = hour; >+ EXPECT_EQ(second, hour); >+ second = minute; >+ EXPECT_EQ(second, minute); >+ >+ minute = year; >+ EXPECT_EQ(minute, year); >+ minute = month; >+ EXPECT_EQ(minute, month); >+ minute = day; >+ EXPECT_EQ(minute, day); >+ minute = hour; >+ EXPECT_EQ(minute, hour); >+ >+ hour = year; >+ EXPECT_EQ(hour, year); >+ hour = month; >+ EXPECT_EQ(hour, month); >+ hour = day; >+ EXPECT_EQ(hour, day); >+ >+ day = year; >+ EXPECT_EQ(day, year); >+ day = month; >+ EXPECT_EQ(day, month); >+ >+ month = year; >+ EXPECT_EQ(month, year); >+ >+ // Ensures unsafe conversions are not allowed. >+ EXPECT_FALSE((std::is_convertible<civil_second, civil_minute>::value)); >+ EXPECT_FALSE((std::is_convertible<civil_second, civil_hour>::value)); >+ EXPECT_FALSE((std::is_convertible<civil_second, civil_day>::value)); >+ EXPECT_FALSE((std::is_convertible<civil_second, civil_month>::value)); >+ EXPECT_FALSE((std::is_convertible<civil_second, civil_year>::value)); >+ >+ EXPECT_FALSE((std::is_convertible<civil_minute, civil_hour>::value)); >+ EXPECT_FALSE((std::is_convertible<civil_minute, civil_day>::value)); >+ EXPECT_FALSE((std::is_convertible<civil_minute, civil_month>::value)); >+ EXPECT_FALSE((std::is_convertible<civil_minute, civil_year>::value)); >+ >+ EXPECT_FALSE((std::is_convertible<civil_hour, civil_day>::value)); >+ EXPECT_FALSE((std::is_convertible<civil_hour, civil_month>::value)); >+ EXPECT_FALSE((std::is_convertible<civil_hour, civil_year>::value)); >+ >+ EXPECT_FALSE((std::is_convertible<civil_day, civil_month>::value)); >+ EXPECT_FALSE((std::is_convertible<civil_day, civil_year>::value)); >+ >+ EXPECT_FALSE((std::is_convertible<civil_month, civil_year>::value)); >+} >+ >+TEST(CivilTime, ExplicitCrossAlignment) { >+ // >+ // Assign from smaller units -> larger units >+ // >+ >+ civil_second second(2015, 1, 2, 3, 4, 5); >+ EXPECT_EQ("2015-01-02T03:04:05", Format(second)); >+ >+ civil_minute minute(second); >+ EXPECT_EQ("2015-01-02T03:04", Format(minute)); >+ >+ civil_hour hour(minute); >+ EXPECT_EQ("2015-01-02T03", Format(hour)); >+ >+ civil_day day(hour); >+ EXPECT_EQ("2015-01-02", Format(day)); >+ >+ civil_month month(day); >+ EXPECT_EQ("2015-01", Format(month)); >+ >+ civil_year year(month); >+ EXPECT_EQ("2015", Format(year)); >+ >+ // >+ // Now assign from larger units -> smaller units >+ // >+ >+ month = civil_month(year); >+ EXPECT_EQ("2015-01", Format(month)); >+ >+ day = civil_day(month); >+ EXPECT_EQ("2015-01-01", Format(day)); >+ >+ hour = civil_hour(day); >+ EXPECT_EQ("2015-01-01T00", Format(hour)); >+ >+ minute = civil_minute(hour); >+ EXPECT_EQ("2015-01-01T00:00", Format(minute)); >+ >+ second = civil_second(minute); >+ EXPECT_EQ("2015-01-01T00:00:00", Format(second)); >+} >+ >+// Metafunction to test whether difference is allowed between two types. >+template <typename T1, typename T2> >+struct HasDifference { >+ template <typename U1, typename U2> >+ static std::false_type test(...); >+ template <typename U1, typename U2> >+ static std::true_type test(decltype(std::declval<U1>() - std::declval<U2>())); >+ static constexpr bool value = decltype(test<T1, T2>(0))::value; >+}; >+ >+TEST(CivilTime, DisallowCrossAlignedDifference) { >+ // Difference is allowed between types with the same alignment. >+ static_assert(HasDifference<civil_second, civil_second>::value, ""); >+ static_assert(HasDifference<civil_minute, civil_minute>::value, ""); >+ static_assert(HasDifference<civil_hour, civil_hour>::value, ""); >+ static_assert(HasDifference<civil_day, civil_day>::value, ""); >+ static_assert(HasDifference<civil_month, civil_month>::value, ""); >+ static_assert(HasDifference<civil_year, civil_year>::value, ""); >+ >+ // Difference is disallowed between types with different alignments. >+ static_assert(!HasDifference<civil_second, civil_minute>::value, ""); >+ static_assert(!HasDifference<civil_second, civil_hour>::value, ""); >+ static_assert(!HasDifference<civil_second, civil_day>::value, ""); >+ static_assert(!HasDifference<civil_second, civil_month>::value, ""); >+ static_assert(!HasDifference<civil_second, civil_year>::value, ""); >+ >+ static_assert(!HasDifference<civil_minute, civil_hour>::value, ""); >+ static_assert(!HasDifference<civil_minute, civil_day>::value, ""); >+ static_assert(!HasDifference<civil_minute, civil_month>::value, ""); >+ static_assert(!HasDifference<civil_minute, civil_year>::value, ""); >+ >+ static_assert(!HasDifference<civil_hour, civil_day>::value, ""); >+ static_assert(!HasDifference<civil_hour, civil_month>::value, ""); >+ static_assert(!HasDifference<civil_hour, civil_year>::value, ""); >+ >+ static_assert(!HasDifference<civil_day, civil_month>::value, ""); >+ static_assert(!HasDifference<civil_day, civil_year>::value, ""); >+ >+ static_assert(!HasDifference<civil_month, civil_year>::value, ""); >+} >+ >+TEST(CivilTime, ValueSemantics) { >+ const civil_hour a(2015, 1, 2, 3); >+ const civil_hour b = a; >+ const civil_hour c(b); >+ civil_hour d; >+ d = c; >+ EXPECT_EQ("2015-01-02T03", Format(d)); >+} >+ >+TEST(CivilTime, Relational) { >+ // Tests that the alignment unit is ignored in comparison. >+ const civil_year year(2014); >+ const civil_month month(year); >+ EXPECT_EQ(year, month); >+ >+#define TEST_RELATIONAL(OLDER, YOUNGER) \ >+ do { \ >+ EXPECT_FALSE(OLDER < OLDER); \ >+ EXPECT_FALSE(OLDER > OLDER); \ >+ EXPECT_TRUE(OLDER >= OLDER); \ >+ EXPECT_TRUE(OLDER <= OLDER); \ >+ EXPECT_FALSE(YOUNGER < YOUNGER); \ >+ EXPECT_FALSE(YOUNGER > YOUNGER); \ >+ EXPECT_TRUE(YOUNGER >= YOUNGER); \ >+ EXPECT_TRUE(YOUNGER <= YOUNGER); \ >+ EXPECT_EQ(OLDER, OLDER); \ >+ EXPECT_NE(OLDER, YOUNGER); \ >+ EXPECT_LT(OLDER, YOUNGER); \ >+ EXPECT_LE(OLDER, YOUNGER); \ >+ EXPECT_GT(YOUNGER, OLDER); \ >+ EXPECT_GE(YOUNGER, OLDER); \ >+ } while (0) >+ >+ // Alignment is ignored in comparison (verified above), so kSecond is used >+ // to test comparison in all field positions. >+ TEST_RELATIONAL(civil_second(2014, 1, 1, 0, 0, 0), >+ civil_second(2015, 1, 1, 0, 0, 0)); >+ TEST_RELATIONAL(civil_second(2014, 1, 1, 0, 0, 0), >+ civil_second(2014, 2, 1, 0, 0, 0)); >+ TEST_RELATIONAL(civil_second(2014, 1, 1, 0, 0, 0), >+ civil_second(2014, 1, 2, 0, 0, 0)); >+ TEST_RELATIONAL(civil_second(2014, 1, 1, 0, 0, 0), >+ civil_second(2014, 1, 1, 1, 0, 0)); >+ TEST_RELATIONAL(civil_second(2014, 1, 1, 1, 0, 0), >+ civil_second(2014, 1, 1, 1, 1, 0)); >+ TEST_RELATIONAL(civil_second(2014, 1, 1, 1, 1, 0), >+ civil_second(2014, 1, 1, 1, 1, 1)); >+ >+ // Tests the relational operators of two different CivilTime types. >+ TEST_RELATIONAL(civil_day(2014, 1, 1), civil_minute(2014, 1, 1, 1, 1)); >+ TEST_RELATIONAL(civil_day(2014, 1, 1), civil_month(2014, 2)); >+ >+#undef TEST_RELATIONAL >+} >+ >+TEST(CivilTime, Arithmetic) { >+ civil_second second(2015, 1, 2, 3, 4, 5); >+ EXPECT_EQ("2015-01-02T03:04:06", Format(second += 1)); >+ EXPECT_EQ("2015-01-02T03:04:07", Format(second + 1)); >+ EXPECT_EQ("2015-01-02T03:04:08", Format(2 + second)); >+ EXPECT_EQ("2015-01-02T03:04:05", Format(second - 1)); >+ EXPECT_EQ("2015-01-02T03:04:05", Format(second -= 1)); >+ EXPECT_EQ("2015-01-02T03:04:05", Format(second++)); >+ EXPECT_EQ("2015-01-02T03:04:07", Format(++second)); >+ EXPECT_EQ("2015-01-02T03:04:07", Format(second--)); >+ EXPECT_EQ("2015-01-02T03:04:05", Format(--second)); >+ >+ civil_minute minute(2015, 1, 2, 3, 4); >+ EXPECT_EQ("2015-01-02T03:05", Format(minute += 1)); >+ EXPECT_EQ("2015-01-02T03:06", Format(minute + 1)); >+ EXPECT_EQ("2015-01-02T03:07", Format(2 + minute)); >+ EXPECT_EQ("2015-01-02T03:04", Format(minute - 1)); >+ EXPECT_EQ("2015-01-02T03:04", Format(minute -= 1)); >+ EXPECT_EQ("2015-01-02T03:04", Format(minute++)); >+ EXPECT_EQ("2015-01-02T03:06", Format(++minute)); >+ EXPECT_EQ("2015-01-02T03:06", Format(minute--)); >+ EXPECT_EQ("2015-01-02T03:04", Format(--minute)); >+ >+ civil_hour hour(2015, 1, 2, 3); >+ EXPECT_EQ("2015-01-02T04", Format(hour += 1)); >+ EXPECT_EQ("2015-01-02T05", Format(hour + 1)); >+ EXPECT_EQ("2015-01-02T06", Format(2 + hour)); >+ EXPECT_EQ("2015-01-02T03", Format(hour - 1)); >+ EXPECT_EQ("2015-01-02T03", Format(hour -= 1)); >+ EXPECT_EQ("2015-01-02T03", Format(hour++)); >+ EXPECT_EQ("2015-01-02T05", Format(++hour)); >+ EXPECT_EQ("2015-01-02T05", Format(hour--)); >+ EXPECT_EQ("2015-01-02T03", Format(--hour)); >+ >+ civil_day day(2015, 1, 2); >+ EXPECT_EQ("2015-01-03", Format(day += 1)); >+ EXPECT_EQ("2015-01-04", Format(day + 1)); >+ EXPECT_EQ("2015-01-05", Format(2 + day)); >+ EXPECT_EQ("2015-01-02", Format(day - 1)); >+ EXPECT_EQ("2015-01-02", Format(day -= 1)); >+ EXPECT_EQ("2015-01-02", Format(day++)); >+ EXPECT_EQ("2015-01-04", Format(++day)); >+ EXPECT_EQ("2015-01-04", Format(day--)); >+ EXPECT_EQ("2015-01-02", Format(--day)); >+ >+ civil_month month(2015, 1); >+ EXPECT_EQ("2015-02", Format(month += 1)); >+ EXPECT_EQ("2015-03", Format(month + 1)); >+ EXPECT_EQ("2015-04", Format(2 + month)); >+ EXPECT_EQ("2015-01", Format(month - 1)); >+ EXPECT_EQ("2015-01", Format(month -= 1)); >+ EXPECT_EQ("2015-01", Format(month++)); >+ EXPECT_EQ("2015-03", Format(++month)); >+ EXPECT_EQ("2015-03", Format(month--)); >+ EXPECT_EQ("2015-01", Format(--month)); >+ >+ civil_year year(2015); >+ EXPECT_EQ("2016", Format(year += 1)); >+ EXPECT_EQ("2017", Format(year + 1)); >+ EXPECT_EQ("2018", Format(2 + year)); >+ EXPECT_EQ("2015", Format(year - 1)); >+ EXPECT_EQ("2015", Format(year -= 1)); >+ EXPECT_EQ("2015", Format(year++)); >+ EXPECT_EQ("2017", Format(++year)); >+ EXPECT_EQ("2017", Format(year--)); >+ EXPECT_EQ("2015", Format(--year)); >+} >+ >+TEST(CivilTime, ArithmeticLimits) { >+ const int kIntMax = std::numeric_limits<int>::max(); >+ const int kIntMin = std::numeric_limits<int>::min(); >+ >+ civil_second second(1970, 1, 1, 0, 0, 0); >+ second += kIntMax; >+ EXPECT_EQ("2038-01-19T03:14:07", Format(second)); >+ second -= kIntMax; >+ EXPECT_EQ("1970-01-01T00:00:00", Format(second)); >+ second += kIntMin; >+ EXPECT_EQ("1901-12-13T20:45:52", Format(second)); >+ second -= kIntMin; >+ EXPECT_EQ("1970-01-01T00:00:00", Format(second)); >+ >+ civil_minute minute(1970, 1, 1, 0, 0); >+ minute += kIntMax; >+ EXPECT_EQ("6053-01-23T02:07", Format(minute)); >+ minute -= kIntMax; >+ EXPECT_EQ("1970-01-01T00:00", Format(minute)); >+ minute += kIntMin; >+ EXPECT_EQ("-2114-12-08T21:52", Format(minute)); >+ minute -= kIntMin; >+ EXPECT_EQ("1970-01-01T00:00", Format(minute)); >+ >+ civil_hour hour(1970, 1, 1, 0); >+ hour += kIntMax; >+ EXPECT_EQ("246953-10-09T07", Format(hour)); >+ hour -= kIntMax; >+ EXPECT_EQ("1970-01-01T00", Format(hour)); >+ hour += kIntMin; >+ EXPECT_EQ("-243014-03-24T16", Format(hour)); >+ hour -= kIntMin; >+ EXPECT_EQ("1970-01-01T00", Format(hour)); >+ >+ civil_day day(1970, 1, 1); >+ day += kIntMax; >+ EXPECT_EQ("5881580-07-11", Format(day)); >+ day -= kIntMax; >+ EXPECT_EQ("1970-01-01", Format(day)); >+ day += kIntMin; >+ EXPECT_EQ("-5877641-06-23", Format(day)); >+ day -= kIntMin; >+ EXPECT_EQ("1970-01-01", Format(day)); >+ >+ civil_month month(1970, 1); >+ month += kIntMax; >+ EXPECT_EQ("178958940-08", Format(month)); >+ month -= kIntMax; >+ EXPECT_EQ("1970-01", Format(month)); >+ month += kIntMin; >+ EXPECT_EQ("-178955001-05", Format(month)); >+ month -= kIntMin; >+ EXPECT_EQ("1970-01", Format(month)); >+ >+ civil_year year(0); >+ year += kIntMax; >+ EXPECT_EQ("2147483647", Format(year)); >+ year -= kIntMax; >+ EXPECT_EQ("0", Format(year)); >+ year += kIntMin; >+ EXPECT_EQ("-2147483648", Format(year)); >+ year -= kIntMin; >+ EXPECT_EQ("0", Format(year)); >+} >+ >+TEST(CivilTime, ArithmeticDifference) { >+ civil_second second(2015, 1, 2, 3, 4, 5); >+ EXPECT_EQ(0, second - second); >+ EXPECT_EQ(10, (second + 10) - second); >+ EXPECT_EQ(-10, (second - 10) - second); >+ >+ civil_minute minute(2015, 1, 2, 3, 4); >+ EXPECT_EQ(0, minute - minute); >+ EXPECT_EQ(10, (minute + 10) - minute); >+ EXPECT_EQ(-10, (minute - 10) - minute); >+ >+ civil_hour hour(2015, 1, 2, 3); >+ EXPECT_EQ(0, hour - hour); >+ EXPECT_EQ(10, (hour + 10) - hour); >+ EXPECT_EQ(-10, (hour - 10) - hour); >+ >+ civil_day day(2015, 1, 2); >+ EXPECT_EQ(0, day - day); >+ EXPECT_EQ(10, (day + 10) - day); >+ EXPECT_EQ(-10, (day - 10) - day); >+ >+ civil_month month(2015, 1); >+ EXPECT_EQ(0, month - month); >+ EXPECT_EQ(10, (month + 10) - month); >+ EXPECT_EQ(-10, (month - 10) - month); >+ >+ civil_year year(2015); >+ EXPECT_EQ(0, year - year); >+ EXPECT_EQ(10, (year + 10) - year); >+ EXPECT_EQ(-10, (year - 10) - year); >+} >+ >+TEST(CivilTime, DifferenceLimits) { >+ const int kIntMax = std::numeric_limits<int>::max(); >+ const int kIntMin = std::numeric_limits<int>::min(); >+ >+ // Check day arithmetic at the end of the year range. >+ const civil_day max_day(kIntMax, 12, 31); >+ EXPECT_EQ(1, max_day - (max_day - 1)); >+ EXPECT_EQ(-1, (max_day - 1) - max_day); >+ >+ // Check day arithmetic at the end of the year range. >+ const civil_day min_day(kIntMin, 1, 1); >+ EXPECT_EQ(1, (min_day + 1) - min_day); >+ EXPECT_EQ(-1, min_day - (min_day + 1)); >+ >+ // Check the limits of the return value. >+ const civil_day d1(1970, 1, 1); >+ const civil_day d2(5881580, 7, 11); >+ EXPECT_EQ(kIntMax, d2 - d1); >+ EXPECT_EQ(kIntMin, d1 - (d2 + 1)); >+} >+ >+TEST(CivilTime, Properties) { >+ civil_second ss(2015, 2, 3, 4, 5, 6); >+ EXPECT_EQ(2015, ss.year()); >+ EXPECT_EQ(2, ss.month()); >+ EXPECT_EQ(3, ss.day()); >+ EXPECT_EQ(4, ss.hour()); >+ EXPECT_EQ(5, ss.minute()); >+ EXPECT_EQ(6, ss.second()); >+ >+ civil_minute mm(2015, 2, 3, 4, 5, 6); >+ EXPECT_EQ(2015, mm.year()); >+ EXPECT_EQ(2, mm.month()); >+ EXPECT_EQ(3, mm.day()); >+ EXPECT_EQ(4, mm.hour()); >+ EXPECT_EQ(5, mm.minute()); >+ EXPECT_EQ(0, mm.second()); >+ >+ civil_hour hh(2015, 2, 3, 4, 5, 6); >+ EXPECT_EQ(2015, hh.year()); >+ EXPECT_EQ(2, hh.month()); >+ EXPECT_EQ(3, hh.day()); >+ EXPECT_EQ(4, hh.hour()); >+ EXPECT_EQ(0, hh.minute()); >+ EXPECT_EQ(0, hh.second()); >+ >+ civil_day d(2015, 2, 3, 4, 5, 6); >+ EXPECT_EQ(2015, d.year()); >+ EXPECT_EQ(2, d.month()); >+ EXPECT_EQ(3, d.day()); >+ EXPECT_EQ(0, d.hour()); >+ EXPECT_EQ(0, d.minute()); >+ EXPECT_EQ(0, d.second()); >+ EXPECT_EQ(weekday::tuesday, get_weekday(d)); >+ EXPECT_EQ(34, get_yearday(d)); >+ >+ civil_month m(2015, 2, 3, 4, 5, 6); >+ EXPECT_EQ(2015, m.year()); >+ EXPECT_EQ(2, m.month()); >+ EXPECT_EQ(1, m.day()); >+ EXPECT_EQ(0, m.hour()); >+ EXPECT_EQ(0, m.minute()); >+ EXPECT_EQ(0, m.second()); >+ >+ civil_year y(2015, 2, 3, 4, 5, 6); >+ EXPECT_EQ(2015, y.year()); >+ EXPECT_EQ(1, y.month()); >+ EXPECT_EQ(1, y.day()); >+ EXPECT_EQ(0, y.hour()); >+ EXPECT_EQ(0, y.minute()); >+ EXPECT_EQ(0, y.second()); >+} >+ >+TEST(CivilTime, OutputStream) { >+ // Tests formatting of civil_year, which does not pad. >+ EXPECT_EQ("2016", Format(civil_year(2016))); >+ EXPECT_EQ("123", Format(civil_year(123))); >+ EXPECT_EQ("0", Format(civil_year(0))); >+ EXPECT_EQ("-1", Format(civil_year(-1))); >+ >+ // Tests formatting of sub-year types, which pad to 2 digits >+ EXPECT_EQ("2016-02", Format(civil_month(2016, 2))); >+ EXPECT_EQ("2016-02-03", Format(civil_day(2016, 2, 3))); >+ EXPECT_EQ("2016-02-03T04", Format(civil_hour(2016, 2, 3, 4))); >+ EXPECT_EQ("2016-02-03T04:05", Format(civil_minute(2016, 2, 3, 4, 5))); >+ EXPECT_EQ("2016-02-03T04:05:06", Format(civil_second(2016, 2, 3, 4, 5, 6))); >+ >+ // Tests formatting of weekday. >+ EXPECT_EQ("Monday", Format(weekday::monday)); >+ EXPECT_EQ("Tuesday", Format(weekday::tuesday)); >+ EXPECT_EQ("Wednesday", Format(weekday::wednesday)); >+ EXPECT_EQ("Thursday", Format(weekday::thursday)); >+ EXPECT_EQ("Friday", Format(weekday::friday)); >+ EXPECT_EQ("Saturday", Format(weekday::saturday)); >+ EXPECT_EQ("Sunday", Format(weekday::sunday)); >+} >+ >+TEST(CivilTime, OutputStreamLeftFillWidth) { >+ civil_second cs(2016, 2, 3, 4, 5, 6); >+ { >+ std::stringstream ss; >+ ss << std::left << std::setfill('.'); >+ ss << std::setw(3) << 'X'; >+ ss << std::setw(21) << civil_year(cs); >+ ss << std::setw(3) << 'X'; >+ EXPECT_EQ("X..2016.................X..", ss.str()); >+ } >+ { >+ std::stringstream ss; >+ ss << std::left << std::setfill('.'); >+ ss << std::setw(3) << 'X'; >+ ss << std::setw(21) << civil_month(cs); >+ ss << std::setw(3) << 'X'; >+ EXPECT_EQ("X..2016-02..............X..", ss.str()); >+ } >+ { >+ std::stringstream ss; >+ ss << std::left << std::setfill('.'); >+ ss << std::setw(3) << 'X'; >+ ss << std::setw(21) << civil_day(cs); >+ ss << std::setw(3) << 'X'; >+ EXPECT_EQ("X..2016-02-03...........X..", ss.str()); >+ } >+ { >+ std::stringstream ss; >+ ss << std::left << std::setfill('.'); >+ ss << std::setw(3) << 'X'; >+ ss << std::setw(21) << civil_hour(cs); >+ ss << std::setw(3) << 'X'; >+ EXPECT_EQ("X..2016-02-03T04........X..", ss.str()); >+ } >+ { >+ std::stringstream ss; >+ ss << std::left << std::setfill('.'); >+ ss << std::setw(3) << 'X'; >+ ss << std::setw(21) << civil_minute(cs); >+ ss << std::setw(3) << 'X'; >+ EXPECT_EQ("X..2016-02-03T04:05.....X..", ss.str()); >+ } >+ { >+ std::stringstream ss; >+ ss << std::left << std::setfill('.'); >+ ss << std::setw(3) << 'X'; >+ ss << std::setw(21) << civil_second(cs); >+ ss << std::setw(3) << 'X'; >+ EXPECT_EQ("X..2016-02-03T04:05:06..X..", ss.str()); >+ } >+} >+ >+TEST(CivilTime, NextPrevWeekday) { >+ // Jan 1, 1970 was a Thursday. >+ const civil_day thursday(1970, 1, 1); >+ EXPECT_EQ(weekday::thursday, get_weekday(thursday)); >+ >+ // Thursday -> Thursday >+ civil_day d = next_weekday(thursday, weekday::thursday); >+ EXPECT_EQ(7, d - thursday) << Format(d); >+ EXPECT_EQ(d - 14, prev_weekday(thursday, weekday::thursday)); >+ >+ // Thursday -> Friday >+ d = next_weekday(thursday, weekday::friday); >+ EXPECT_EQ(1, d - thursday) << Format(d); >+ EXPECT_EQ(d - 7, prev_weekday(thursday, weekday::friday)); >+ >+ // Thursday -> Saturday >+ d = next_weekday(thursday, weekday::saturday); >+ EXPECT_EQ(2, d - thursday) << Format(d); >+ EXPECT_EQ(d - 7, prev_weekday(thursday, weekday::saturday)); >+ >+ // Thursday -> Sunday >+ d = next_weekday(thursday, weekday::sunday); >+ EXPECT_EQ(3, d - thursday) << Format(d); >+ EXPECT_EQ(d - 7, prev_weekday(thursday, weekday::sunday)); >+ >+ // Thursday -> Monday >+ d = next_weekday(thursday, weekday::monday); >+ EXPECT_EQ(4, d - thursday) << Format(d); >+ EXPECT_EQ(d - 7, prev_weekday(thursday, weekday::monday)); >+ >+ // Thursday -> Tuesday >+ d = next_weekday(thursday, weekday::tuesday); >+ EXPECT_EQ(5, d - thursday) << Format(d); >+ EXPECT_EQ(d - 7, prev_weekday(thursday, weekday::tuesday)); >+ >+ // Thursday -> Wednesday >+ d = next_weekday(thursday, weekday::wednesday); >+ EXPECT_EQ(6, d - thursday) << Format(d); >+ EXPECT_EQ(d - 7, prev_weekday(thursday, weekday::wednesday)); >+} >+ >+TEST(CivilTime, NormalizeWithHugeYear) { >+ civil_month c(9223372036854775807, 1); >+ EXPECT_EQ("9223372036854775807-01", Format(c)); >+ c = c - 1; // Causes normalization >+ EXPECT_EQ("9223372036854775806-12", Format(c)); >+ >+ c = civil_month(-9223372036854775807 - 1, 1); >+ EXPECT_EQ("-9223372036854775808-01", Format(c)); >+ c = c + 12; // Causes normalization >+ EXPECT_EQ("-9223372036854775807-01", Format(c)); >+} >+ >+TEST(CivilTime, LeapYears) { >+ // Test data for leap years. >+ const struct { >+ int year; >+ int days; >+ struct { >+ int month; >+ int day; >+ } leap_day; // The date of the day after Feb 28. >+ } kLeapYearTable[]{ >+ {1900, 365, {3, 1}}, >+ {1999, 365, {3, 1}}, >+ {2000, 366, {2, 29}}, // leap year >+ {2001, 365, {3, 1}}, >+ {2002, 365, {3, 1}}, >+ {2003, 365, {3, 1}}, >+ {2004, 366, {2, 29}}, // leap year >+ {2005, 365, {3, 1}}, >+ {2006, 365, {3, 1}}, >+ {2007, 365, {3, 1}}, >+ {2008, 366, {2, 29}}, // leap year >+ {2009, 365, {3, 1}}, >+ {2100, 365, {3, 1}}, >+ }; >+ >+ for (const auto& e : kLeapYearTable) { >+ // Tests incrementing through the leap day. >+ const civil_day feb28(e.year, 2, 28); >+ const civil_day next_day = feb28 + 1; >+ EXPECT_EQ(e.leap_day.month, next_day.month()); >+ EXPECT_EQ(e.leap_day.day, next_day.day()); >+ >+ // Tests difference in days of leap years. >+ const civil_year year(feb28); >+ const civil_year next_year = year + 1; >+ EXPECT_EQ(e.days, civil_day(next_year) - civil_day(year)); >+ } >+} >+ >+TEST(CivilTime, FirstThursdayInMonth) { >+ const civil_day nov1(2014, 11, 1); >+ const civil_day thursday = prev_weekday(nov1, weekday::thursday) + 7; >+ EXPECT_EQ("2014-11-06", Format(thursday)); >+ >+ // Bonus: Date of Thanksgiving in the United States >+ // Rule: Fourth Thursday of November >+ const civil_day thanksgiving = thursday + 7 * 3; >+ EXPECT_EQ("2014-11-27", Format(thanksgiving)); >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..598b08fde42236cf137e0e82d09d9f2c1f1b22f0 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc >@@ -0,0 +1,123 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "time_zone_fixed.h" >+ >+#include <algorithm> >+#include <chrono> >+#include <cstdio> >+#include <cstring> >+#include <string> >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+namespace { >+ >+// The prefix used for the internal names of fixed-offset zones. >+const char kFixedOffsetPrefix[] = "Fixed/UTC"; >+ >+int Parse02d(const char* p) { >+ static const char kDigits[] = "0123456789"; >+ if (const char* ap = std::strchr(kDigits, *p)) { >+ int v = static_cast<int>(ap - kDigits); >+ if (const char* bp = std::strchr(kDigits, *++p)) { >+ return (v * 10) + static_cast<int>(bp - kDigits); >+ } >+ } >+ return -1; >+} >+ >+} // namespace >+ >+bool FixedOffsetFromName(const std::string& name, seconds* offset) { >+ if (name.compare(0, std::string::npos, "UTC", 3) == 0) { >+ *offset = seconds::zero(); >+ return true; >+ } >+ >+ const std::size_t prefix_len = sizeof(kFixedOffsetPrefix) - 1; >+ const char* const ep = kFixedOffsetPrefix + prefix_len; >+ if (name.size() != prefix_len + 9) // <prefix>+99:99:99 >+ return false; >+ if (!std::equal(kFixedOffsetPrefix, ep, name.begin())) >+ return false; >+ const char* np = name.data() + prefix_len; >+ if (np[0] != '+' && np[0] != '-') >+ return false; >+ if (np[3] != ':' || np[6] != ':') // see note below about large offsets >+ return false; >+ >+ int hours = Parse02d(np + 1); >+ if (hours == -1) return false; >+ int mins = Parse02d(np + 4); >+ if (mins == -1) return false; >+ int secs = Parse02d(np + 7); >+ if (secs == -1) return false; >+ >+ secs += ((hours * 60) + mins) * 60; >+ if (secs > 24 * 60 * 60) return false; // outside supported offset range >+ *offset = seconds(secs * (np[0] == '-' ? -1 : 1)); // "-" means west >+ return true; >+} >+ >+std::string FixedOffsetToName(const seconds& offset) { >+ if (offset == seconds::zero()) return "UTC"; >+ if (offset < std::chrono::hours(-24) || offset > std::chrono::hours(24)) { >+ // We don't support fixed-offset zones more than 24 hours >+ // away from UTC to avoid complications in rendering such >+ // offsets and to (somewhat) limit the total number of zones. >+ return "UTC"; >+ } >+ int seconds = static_cast<int>(offset.count()); >+ const char sign = (seconds < 0 ? '-' : '+'); >+ int minutes = seconds / 60; >+ seconds %= 60; >+ if (sign == '-') { >+ if (seconds > 0) { >+ seconds -= 60; >+ minutes += 1; >+ } >+ seconds = -seconds; >+ minutes = -minutes; >+ } >+ int hours = minutes / 60; >+ minutes %= 60; >+ char buf[sizeof(kFixedOffsetPrefix) + sizeof("-24:00:00")]; >+ snprintf(buf, sizeof(buf), "%s%c%02d:%02d:%02d", >+ kFixedOffsetPrefix, sign, hours, minutes, seconds); >+ return buf; >+} >+ >+std::string FixedOffsetToAbbr(const seconds& offset) { >+ std::string abbr = FixedOffsetToName(offset); >+ const std::size_t prefix_len = sizeof(kFixedOffsetPrefix) - 1; >+ if (abbr.size() == prefix_len + 9) { // <prefix>+99:99:99 >+ abbr.erase(0, prefix_len); // +99:99:99 >+ abbr.erase(6, 1); // +99:9999 >+ abbr.erase(3, 1); // +999999 >+ if (abbr[5] == '0' && abbr[6] == '0') { // +999900 >+ abbr.erase(5, 2); // +9999 >+ if (abbr[3] == '0' && abbr[4] == '0') { // +9900 >+ abbr.erase(3, 2); // +99 >+ } >+ } >+ } >+ return abbr; >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.h >new file mode 100644 >index 0000000000000000000000000000000000000000..489b857d5df31f11c1693c107c102d7abe965f7a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.h >@@ -0,0 +1,49 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_ >+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_ >+ >+#include <string> >+ >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// Helper functions for dealing with the names and abbreviations >+// of time zones that are a fixed offset (seconds east) from UTC. >+// FixedOffsetFromName() extracts the offset from a valid fixed-offset >+// name, while FixedOffsetToName() and FixedOffsetToAbbr() generate >+// the canonical zone name and abbreviation respectively for the given >+// offset. >+// >+// A fixed-offset name looks like "Fixed/UTC<+-><hours>:<mins>:<secs>". >+// Its abbreviation is of the form "UTC(<+->H?H(MM(SS)?)?)?" where the >+// optional pieces are omitted when their values are zero. (Note that >+// the sign is the opposite of that used in a POSIX TZ specification.) >+// >+// Note: FixedOffsetFromName() fails on syntax errors or when the parsed >+// offset exceeds 24 hours. FixedOffsetToName() and FixedOffsetToAbbr() >+// both produce "UTC" when the argument offset exceeds 24 hours. >+bool FixedOffsetFromName(const std::string& name, seconds* offset); >+std::string FixedOffsetToName(const seconds& offset); >+std::string FixedOffsetToAbbr(const seconds& offset); >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..1b023848efa18e81562d57b3955ac120df855474 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc >@@ -0,0 +1,851 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#if !defined(HAS_STRPTIME) >+# if !defined(_MSC_VER) >+# define HAS_STRPTIME 1 // assume everyone has strptime() except windows >+# endif >+#endif >+ >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+ >+#include <cctype> >+#include <chrono> >+#include <cstddef> >+#include <cstdint> >+#include <cstring> >+#include <ctime> >+#include <limits> >+#include <string> >+#include <vector> >+#if !HAS_STRPTIME >+#include <iomanip> >+#include <sstream> >+#endif >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+#include "time_zone_if.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+namespace detail { >+ >+namespace { >+ >+#if !HAS_STRPTIME >+// Build a strptime() using C++11's std::get_time(). >+char* strptime(const char* s, const char* fmt, std::tm* tm) { >+ std::istringstream input(s); >+ input >> std::get_time(tm, fmt); >+ if (input.fail()) return nullptr; >+ return const_cast<char*>(s) + >+ (input.eof() ? strlen(s) : static_cast<std::size_t>(input.tellg())); >+} >+#endif >+ >+std::tm ToTM(const time_zone::absolute_lookup& al) { >+ std::tm tm{}; >+ tm.tm_sec = al.cs.second(); >+ tm.tm_min = al.cs.minute(); >+ tm.tm_hour = al.cs.hour(); >+ tm.tm_mday = al.cs.day(); >+ tm.tm_mon = al.cs.month() - 1; >+ >+ // Saturate tm.tm_year is cases of over/underflow. >+ if (al.cs.year() < std::numeric_limits<int>::min() + 1900) { >+ tm.tm_year = std::numeric_limits<int>::min(); >+ } else if (al.cs.year() - 1900 > std::numeric_limits<int>::max()) { >+ tm.tm_year = std::numeric_limits<int>::max(); >+ } else { >+ tm.tm_year = static_cast<int>(al.cs.year() - 1900); >+ } >+ >+ switch (get_weekday(civil_day(al.cs))) { >+ case weekday::sunday: >+ tm.tm_wday = 0; >+ break; >+ case weekday::monday: >+ tm.tm_wday = 1; >+ break; >+ case weekday::tuesday: >+ tm.tm_wday = 2; >+ break; >+ case weekday::wednesday: >+ tm.tm_wday = 3; >+ break; >+ case weekday::thursday: >+ tm.tm_wday = 4; >+ break; >+ case weekday::friday: >+ tm.tm_wday = 5; >+ break; >+ case weekday::saturday: >+ tm.tm_wday = 6; >+ break; >+ } >+ tm.tm_yday = get_yearday(civil_day(al.cs)) - 1; >+ tm.tm_isdst = al.is_dst ? 1 : 0; >+ return tm; >+} >+ >+const char kDigits[] = "0123456789"; >+ >+// Formats a 64-bit integer in the given field width. Note that it is up >+// to the caller of Format64() [and Format02d()/FormatOffset()] to ensure >+// that there is sufficient space before ep to hold the conversion. >+char* Format64(char* ep, int width, std::int_fast64_t v) { >+ bool neg = false; >+ if (v < 0) { >+ --width; >+ neg = true; >+ if (v == std::numeric_limits<std::int_fast64_t>::min()) { >+ // Avoid negating minimum value. >+ std::int_fast64_t last_digit = -(v % 10); >+ v /= 10; >+ if (last_digit < 0) { >+ ++v; >+ last_digit += 10; >+ } >+ --width; >+ *--ep = kDigits[last_digit]; >+ } >+ v = -v; >+ } >+ do { >+ --width; >+ *--ep = kDigits[v % 10]; >+ } while (v /= 10); >+ while (--width >= 0) *--ep = '0'; // zero pad >+ if (neg) *--ep = '-'; >+ return ep; >+} >+ >+// Formats [0 .. 99] as %02d. >+char* Format02d(char* ep, int v) { >+ *--ep = kDigits[v % 10]; >+ *--ep = kDigits[(v / 10) % 10]; >+ return ep; >+} >+ >+// Formats a UTC offset, like +00:00. >+char* FormatOffset(char* ep, int offset, const char* mode) { >+ // TODO: Follow the RFC3339 "Unknown Local Offset Convention" and >+ // generate a "negative zero" when we're formatting a zero offset >+ // as the result of a failed load_time_zone(). >+ char sign = '+'; >+ if (offset < 0) { >+ offset = -offset; // bounded by 24h so no overflow >+ sign = '-'; >+ } >+ char sep = mode[0]; >+ if (sep != '\0' && mode[1] == '*') { >+ ep = Format02d(ep, offset % 60); >+ *--ep = sep; >+ } >+ int minutes = offset / 60; >+ ep = Format02d(ep, minutes % 60); >+ if (sep != '\0') *--ep = sep; >+ ep = Format02d(ep, minutes / 60); >+ *--ep = sign; >+ return ep; >+} >+ >+// Formats a std::tm using strftime(3). >+void FormatTM(std::string* out, const std::string& fmt, const std::tm& tm) { >+ // strftime(3) returns the number of characters placed in the output >+ // array (which may be 0 characters). It also returns 0 to indicate >+ // an error, like the array wasn't large enough. To accommodate this, >+ // the following code grows the buffer size from 2x the format std::string >+ // length up to 32x. >+ for (std::size_t i = 2; i != 32; i *= 2) { >+ std::size_t buf_size = fmt.size() * i; >+ std::vector<char> buf(buf_size); >+ if (std::size_t len = strftime(&buf[0], buf_size, fmt.c_str(), &tm)) { >+ out->append(&buf[0], len); >+ return; >+ } >+ } >+} >+ >+// Used for %E#S/%E#f specifiers and for data values in parse(). >+template <typename T> >+const char* ParseInt(const char* dp, int width, T min, T max, T* vp) { >+ if (dp != nullptr) { >+ const T kmin = std::numeric_limits<T>::min(); >+ bool erange = false; >+ bool neg = false; >+ T value = 0; >+ if (*dp == '-') { >+ neg = true; >+ if (width <= 0 || --width != 0) { >+ ++dp; >+ } else { >+ dp = nullptr; // width was 1 >+ } >+ } >+ if (const char* const bp = dp) { >+ while (const char* cp = strchr(kDigits, *dp)) { >+ int d = static_cast<int>(cp - kDigits); >+ if (d >= 10) break; >+ if (value < kmin / 10) { >+ erange = true; >+ break; >+ } >+ value *= 10; >+ if (value < kmin + d) { >+ erange = true; >+ break; >+ } >+ value -= d; >+ dp += 1; >+ if (width > 0 && --width == 0) break; >+ } >+ if (dp != bp && !erange && (neg || value != kmin)) { >+ if (!neg || value != 0) { >+ if (!neg) value = -value; // make positive >+ if (min <= value && value <= max) { >+ *vp = value; >+ } else { >+ dp = nullptr; >+ } >+ } else { >+ dp = nullptr; >+ } >+ } else { >+ dp = nullptr; >+ } >+ } >+ } >+ return dp; >+} >+ >+// The number of base-10 digits that can be represented by a signed 64-bit >+// integer. That is, 10^kDigits10_64 <= 2^63 - 1 < 10^(kDigits10_64 + 1). >+const int kDigits10_64 = 18; >+ >+// 10^n for everything that can be represented by a signed 64-bit integer. >+const std::int_fast64_t kExp10[kDigits10_64 + 1] = { >+ 1, >+ 10, >+ 100, >+ 1000, >+ 10000, >+ 100000, >+ 1000000, >+ 10000000, >+ 100000000, >+ 1000000000, >+ 10000000000, >+ 100000000000, >+ 1000000000000, >+ 10000000000000, >+ 100000000000000, >+ 1000000000000000, >+ 10000000000000000, >+ 100000000000000000, >+ 1000000000000000000, >+}; >+ >+} // namespace >+ >+// Uses strftime(3) to format the given Time. The following extended format >+// specifiers are also supported: >+// >+// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) >+// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss) >+// - %E#S - Seconds with # digits of fractional precision >+// - %E*S - Seconds with full fractional precision (a literal '*') >+// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) >+// >+// The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are >+// handled internally for performance reasons. strftime(3) is slow due to >+// a POSIX requirement to respect changes to ${TZ}. >+// >+// The TZ/GNU %s extension is handled internally because strftime() has >+// to use mktime() to generate it, and that assumes the local time zone. >+// >+// We also handle the %z and %Z specifiers to accommodate platforms that do >+// not support the tm_gmtoff and tm_zone extensions to std::tm. >+// >+// Requires that zero() <= fs < seconds(1). >+std::string format(const std::string& format, const time_point<seconds>& tp, >+ const detail::femtoseconds& fs, const time_zone& tz) { >+ std::string result; >+ result.reserve(format.size()); // A reasonable guess for the result size. >+ const time_zone::absolute_lookup al = tz.lookup(tp); >+ const std::tm tm = ToTM(al); >+ >+ // Scratch buffer for internal conversions. >+ char buf[3 + kDigits10_64]; // enough for longest conversion >+ char* const ep = buf + sizeof(buf); >+ char* bp; // works back from ep >+ >+ // Maintain three, disjoint subsequences that span format. >+ // [format.begin() ... pending) : already formatted into result >+ // [pending ... cur) : formatting pending, but no special cases >+ // [cur ... format.end()) : unexamined >+ // Initially, everything is in the unexamined part. >+ const char* pending = format.c_str(); // NUL terminated >+ const char* cur = pending; >+ const char* end = pending + format.length(); >+ >+ while (cur != end) { // while something is unexamined >+ // Moves cur to the next percent sign. >+ const char* start = cur; >+ while (cur != end && *cur != '%') ++cur; >+ >+ // If the new pending text is all ordinary, copy it out. >+ if (cur != start && pending == start) { >+ result.append(pending, static_cast<std::size_t>(cur - pending)); >+ pending = start = cur; >+ } >+ >+ // Span the sequential percent signs. >+ const char* percent = cur; >+ while (cur != end && *cur == '%') ++cur; >+ >+ // If the new pending text is all percents, copy out one >+ // percent for every matched pair, then skip those pairs. >+ if (cur != start && pending == start) { >+ std::size_t escaped = static_cast<std::size_t>(cur - pending) / 2; >+ result.append(pending, escaped); >+ pending += escaped * 2; >+ // Also copy out a single trailing percent. >+ if (pending != cur && cur == end) { >+ result.push_back(*pending++); >+ } >+ } >+ >+ // Loop unless we have an unescaped percent. >+ if (cur == end || (cur - percent) % 2 == 0) continue; >+ >+ // Simple specifiers that we handle ourselves. >+ if (strchr("YmdeHMSzZs%", *cur)) { >+ if (cur - 1 != pending) { >+ FormatTM(&result, std::string(pending, cur - 1), tm); >+ } >+ switch (*cur) { >+ case 'Y': >+ // This avoids the tm.tm_year overflow problem for %Y, however >+ // tm.tm_year will still be used by other specifiers like %D. >+ bp = Format64(ep, 0, al.cs.year()); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ break; >+ case 'm': >+ bp = Format02d(ep, al.cs.month()); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ break; >+ case 'd': >+ case 'e': >+ bp = Format02d(ep, al.cs.day()); >+ if (*cur == 'e' && *bp == '0') *bp = ' '; // for Windows >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ break; >+ case 'H': >+ bp = Format02d(ep, al.cs.hour()); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ break; >+ case 'M': >+ bp = Format02d(ep, al.cs.minute()); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ break; >+ case 'S': >+ bp = Format02d(ep, al.cs.second()); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ break; >+ case 'z': >+ bp = FormatOffset(ep, al.offset, ""); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ break; >+ case 'Z': >+ result.append(al.abbr); >+ break; >+ case 's': >+ bp = Format64(ep, 0, ToUnixSeconds(tp)); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ break; >+ case '%': >+ result.push_back('%'); >+ break; >+ } >+ pending = ++cur; >+ continue; >+ } >+ >+ // Loop if there is no E modifier. >+ if (*cur != 'E' || ++cur == end) continue; >+ >+ // Format our extensions. >+ if (*cur == 'z') { >+ // Formats %Ez. >+ if (cur - 2 != pending) { >+ FormatTM(&result, std::string(pending, cur - 2), tm); >+ } >+ bp = FormatOffset(ep, al.offset, ":"); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ pending = ++cur; >+ } else if (*cur == '*' && cur + 1 != end && *(cur + 1) == 'z') { >+ // Formats %E*z. >+ if (cur - 2 != pending) { >+ FormatTM(&result, std::string(pending, cur - 2), tm); >+ } >+ bp = FormatOffset(ep, al.offset, ":*"); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ pending = cur += 2; >+ } else if (*cur == '*' && cur + 1 != end && >+ (*(cur + 1) == 'S' || *(cur + 1) == 'f')) { >+ // Formats %E*S or %E*F. >+ if (cur - 2 != pending) { >+ FormatTM(&result, std::string(pending, cur - 2), tm); >+ } >+ char* cp = ep; >+ bp = Format64(cp, 15, fs.count()); >+ while (cp != bp && cp[-1] == '0') --cp; >+ switch (*(cur + 1)) { >+ case 'S': >+ if (cp != bp) *--bp = '.'; >+ bp = Format02d(bp, al.cs.second()); >+ break; >+ case 'f': >+ if (cp == bp) *--bp = '0'; >+ break; >+ } >+ result.append(bp, static_cast<std::size_t>(cp - bp)); >+ pending = cur += 2; >+ } else if (*cur == '4' && cur + 1 != end && *(cur + 1) == 'Y') { >+ // Formats %E4Y. >+ if (cur - 2 != pending) { >+ FormatTM(&result, std::string(pending, cur - 2), tm); >+ } >+ bp = Format64(ep, 4, al.cs.year()); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ pending = cur += 2; >+ } else if (std::isdigit(*cur)) { >+ // Possibly found %E#S or %E#f. >+ int n = 0; >+ if (const char* np = ParseInt(cur, 0, 0, 1024, &n)) { >+ if (*np == 'S' || *np == 'f') { >+ // Formats %E#S or %E#f. >+ if (cur - 2 != pending) { >+ FormatTM(&result, std::string(pending, cur - 2), tm); >+ } >+ bp = ep; >+ if (n > 0) { >+ if (n > kDigits10_64) n = kDigits10_64; >+ bp = Format64(bp, n, (n > 15) ? fs.count() * kExp10[n - 15] >+ : fs.count() / kExp10[15 - n]); >+ if (*np == 'S') *--bp = '.'; >+ } >+ if (*np == 'S') bp = Format02d(bp, al.cs.second()); >+ result.append(bp, static_cast<std::size_t>(ep - bp)); >+ pending = cur = ++np; >+ } >+ } >+ } >+ } >+ >+ // Formats any remaining data. >+ if (end != pending) { >+ FormatTM(&result, std::string(pending, end), tm); >+ } >+ >+ return result; >+} >+ >+namespace { >+ >+const char* ParseOffset(const char* dp, const char* mode, int* offset) { >+ if (dp != nullptr) { >+ const char first = *dp++; >+ if (first == '+' || first == '-') { >+ char sep = mode[0]; >+ int hours = 0; >+ int minutes = 0; >+ int seconds = 0; >+ const char* ap = ParseInt(dp, 2, 0, 23, &hours); >+ if (ap != nullptr && ap - dp == 2) { >+ dp = ap; >+ if (sep != '\0' && *ap == sep) ++ap; >+ const char* bp = ParseInt(ap, 2, 0, 59, &minutes); >+ if (bp != nullptr && bp - ap == 2) { >+ dp = bp; >+ if (sep != '\0' && *bp == sep) ++bp; >+ const char* cp = ParseInt(bp, 2, 0, 59, &seconds); >+ if (cp != nullptr && cp - bp == 2) dp = cp; >+ } >+ *offset = ((hours * 60 + minutes) * 60) + seconds; >+ if (first == '-') *offset = -*offset; >+ } else { >+ dp = nullptr; >+ } >+ } else if (first == 'Z') { // Zulu >+ *offset = 0; >+ } else { >+ dp = nullptr; >+ } >+ } >+ return dp; >+} >+ >+const char* ParseZone(const char* dp, std::string* zone) { >+ zone->clear(); >+ if (dp != nullptr) { >+ while (*dp != '\0' && !std::isspace(*dp)) zone->push_back(*dp++); >+ if (zone->empty()) dp = nullptr; >+ } >+ return dp; >+} >+ >+const char* ParseSubSeconds(const char* dp, detail::femtoseconds* subseconds) { >+ if (dp != nullptr) { >+ std::int_fast64_t v = 0; >+ std::int_fast64_t exp = 0; >+ const char* const bp = dp; >+ while (const char* cp = strchr(kDigits, *dp)) { >+ int d = static_cast<int>(cp - kDigits); >+ if (d >= 10) break; >+ if (exp < 15) { >+ exp += 1; >+ v *= 10; >+ v += d; >+ } >+ ++dp; >+ } >+ if (dp != bp) { >+ v *= kExp10[15 - exp]; >+ *subseconds = detail::femtoseconds(v); >+ } else { >+ dp = nullptr; >+ } >+ } >+ return dp; >+} >+ >+// Parses a std::string into a std::tm using strptime(3). >+const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) { >+ if (dp != nullptr) { >+ dp = strptime(dp, fmt, tm); >+ } >+ return dp; >+} >+ >+} // namespace >+ >+// Uses strptime(3) to parse the given input. Supports the same extended >+// format specifiers as format(), although %E#S and %E*S are treated >+// identically (and similarly for %E#f and %E*f). %Ez and %E*z also accept >+// the same inputs. >+// >+// The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are >+// handled internally so that we can normally avoid strptime() altogether >+// (which is particularly helpful when the native implementation is broken). >+// >+// The TZ/GNU %s extension is handled internally because strptime() has to >+// use localtime_r() to generate it, and that assumes the local time zone. >+// >+// We also handle the %z specifier to accommodate platforms that do not >+// support the tm_gmtoff extension to std::tm. %Z is parsed but ignored. >+bool parse(const std::string& format, const std::string& input, >+ const time_zone& tz, time_point<seconds>* sec, >+ detail::femtoseconds* fs, std::string* err) { >+ // The unparsed input. >+ const char* data = input.c_str(); // NUL terminated >+ >+ // Skips leading whitespace. >+ while (std::isspace(*data)) ++data; >+ >+ const year_t kyearmax = std::numeric_limits<year_t>::max(); >+ const year_t kyearmin = std::numeric_limits<year_t>::min(); >+ >+ // Sets default values for unspecified fields. >+ bool saw_year = false; >+ year_t year = 1970; >+ std::tm tm{}; >+ tm.tm_year = 1970 - 1900; >+ tm.tm_mon = 1 - 1; // Jan >+ tm.tm_mday = 1; >+ tm.tm_hour = 0; >+ tm.tm_min = 0; >+ tm.tm_sec = 0; >+ tm.tm_wday = 4; // Thu >+ tm.tm_yday = 0; >+ tm.tm_isdst = 0; >+ auto subseconds = detail::femtoseconds::zero(); >+ bool saw_offset = false; >+ int offset = 0; // No offset from passed tz. >+ std::string zone = "UTC"; >+ >+ const char* fmt = format.c_str(); // NUL terminated >+ bool twelve_hour = false; >+ bool afternoon = false; >+ >+ bool saw_percent_s = false; >+ std::int_fast64_t percent_s = 0; >+ >+ // Steps through format, one specifier at a time. >+ while (data != nullptr && *fmt != '\0') { >+ if (std::isspace(*fmt)) { >+ while (std::isspace(*data)) ++data; >+ while (std::isspace(*++fmt)) continue; >+ continue; >+ } >+ >+ if (*fmt != '%') { >+ if (*data == *fmt) { >+ ++data; >+ ++fmt; >+ } else { >+ data = nullptr; >+ } >+ continue; >+ } >+ >+ const char* percent = fmt; >+ if (*++fmt == '\0') { >+ data = nullptr; >+ continue; >+ } >+ switch (*fmt++) { >+ case 'Y': >+ // Symmetrically with FormatTime(), directly handing %Y avoids the >+ // tm.tm_year overflow problem. However, tm.tm_year will still be >+ // used by other specifiers like %D. >+ data = ParseInt(data, 0, kyearmin, kyearmax, &year); >+ if (data != nullptr) saw_year = true; >+ continue; >+ case 'm': >+ data = ParseInt(data, 2, 1, 12, &tm.tm_mon); >+ if (data != nullptr) tm.tm_mon -= 1; >+ continue; >+ case 'd': >+ case 'e': >+ data = ParseInt(data, 2, 1, 31, &tm.tm_mday); >+ continue; >+ case 'H': >+ data = ParseInt(data, 2, 0, 23, &tm.tm_hour); >+ twelve_hour = false; >+ continue; >+ case 'M': >+ data = ParseInt(data, 2, 0, 59, &tm.tm_min); >+ continue; >+ case 'S': >+ data = ParseInt(data, 2, 0, 60, &tm.tm_sec); >+ continue; >+ case 'I': >+ case 'l': >+ case 'r': // probably uses %I >+ twelve_hour = true; >+ break; >+ case 'R': // uses %H >+ case 'T': // uses %H >+ case 'c': // probably uses %H >+ case 'X': // probably uses %H >+ twelve_hour = false; >+ break; >+ case 'z': >+ data = ParseOffset(data, "", &offset); >+ if (data != nullptr) saw_offset = true; >+ continue; >+ case 'Z': // ignored; zone abbreviations are ambiguous >+ data = ParseZone(data, &zone); >+ continue; >+ case 's': >+ data = ParseInt(data, 0, >+ std::numeric_limits<std::int_fast64_t>::min(), >+ std::numeric_limits<std::int_fast64_t>::max(), >+ &percent_s); >+ if (data != nullptr) saw_percent_s = true; >+ continue; >+ case '%': >+ data = (*data == '%' ? data + 1 : nullptr); >+ continue; >+ case 'E': >+ if (*fmt == 'z' || (*fmt == '*' && *(fmt + 1) == 'z')) { >+ data = ParseOffset(data, ":", &offset); >+ if (data != nullptr) saw_offset = true; >+ fmt += (*fmt == 'z') ? 1 : 2; >+ continue; >+ } >+ if (*fmt == '*' && *(fmt + 1) == 'S') { >+ data = ParseInt(data, 2, 0, 60, &tm.tm_sec); >+ if (data != nullptr && *data == '.') { >+ data = ParseSubSeconds(data + 1, &subseconds); >+ } >+ fmt += 2; >+ continue; >+ } >+ if (*fmt == '*' && *(fmt + 1) == 'f') { >+ if (data != nullptr && std::isdigit(*data)) { >+ data = ParseSubSeconds(data, &subseconds); >+ } >+ fmt += 2; >+ continue; >+ } >+ if (*fmt == '4' && *(fmt + 1) == 'Y') { >+ const char* bp = data; >+ data = ParseInt(data, 4, year_t{-999}, year_t{9999}, &year); >+ if (data != nullptr) { >+ if (data - bp == 4) { >+ saw_year = true; >+ } else { >+ data = nullptr; // stopped too soon >+ } >+ } >+ fmt += 2; >+ continue; >+ } >+ if (std::isdigit(*fmt)) { >+ int n = 0; // value ignored >+ if (const char* np = ParseInt(fmt, 0, 0, 1024, &n)) { >+ if (*np == 'S') { >+ data = ParseInt(data, 2, 0, 60, &tm.tm_sec); >+ if (data != nullptr && *data == '.') { >+ data = ParseSubSeconds(data + 1, &subseconds); >+ } >+ fmt = ++np; >+ continue; >+ } >+ if (*np == 'f') { >+ if (data != nullptr && std::isdigit(*data)) { >+ data = ParseSubSeconds(data, &subseconds); >+ } >+ fmt = ++np; >+ continue; >+ } >+ } >+ } >+ if (*fmt == 'c') twelve_hour = false; // probably uses %H >+ if (*fmt == 'X') twelve_hour = false; // probably uses %H >+ if (*fmt != '\0') ++fmt; >+ break; >+ case 'O': >+ if (*fmt == 'H') twelve_hour = false; >+ if (*fmt == 'I') twelve_hour = true; >+ if (*fmt != '\0') ++fmt; >+ break; >+ } >+ >+ // Parses the current specifier. >+ const char* orig_data = data; >+ std::string spec(percent, static_cast<std::size_t>(fmt - percent)); >+ data = ParseTM(data, spec.c_str(), &tm); >+ >+ // If we successfully parsed %p we need to remember whether the result >+ // was AM or PM so that we can adjust tm_hour before ConvertDateTime(). >+ // So reparse the input with a known AM hour, and check if it is shifted >+ // to a PM hour. >+ if (spec == "%p" && data != nullptr) { >+ std::string test_input = "1"; >+ test_input.append(orig_data, static_cast<std::size_t>(data - orig_data)); >+ const char* test_data = test_input.c_str(); >+ std::tm tmp{}; >+ ParseTM(test_data, "%I%p", &tmp); >+ afternoon = (tmp.tm_hour == 13); >+ } >+ } >+ >+ // Adjust a 12-hour tm_hour value if it should be in the afternoon. >+ if (twelve_hour && afternoon && tm.tm_hour < 12) { >+ tm.tm_hour += 12; >+ } >+ >+ if (data == nullptr) { >+ if (err != nullptr) *err = "Failed to parse input"; >+ return false; >+ } >+ >+ // Skip any remaining whitespace. >+ while (std::isspace(*data)) ++data; >+ >+ // parse() must consume the entire input std::string. >+ if (*data != '\0') { >+ if (err != nullptr) *err = "Illegal trailing data in input string"; >+ return false; >+ } >+ >+ // If we saw %s then we ignore anything else and return that time. >+ if (saw_percent_s) { >+ *sec = FromUnixSeconds(percent_s); >+ *fs = detail::femtoseconds::zero(); >+ return true; >+ } >+ >+ // If we saw %z, %Ez, or %E*z then we want to interpret the parsed fields >+ // in UTC and then shift by that offset. Otherwise we want to interpret >+ // the fields directly in the passed time_zone. >+ time_zone ptz = saw_offset ? utc_time_zone() : tz; >+ >+ // Allows a leap second of 60 to normalize forward to the following ":00". >+ if (tm.tm_sec == 60) { >+ tm.tm_sec -= 1; >+ offset -= 1; >+ subseconds = detail::femtoseconds::zero(); >+ } >+ >+ if (!saw_year) { >+ year = year_t{tm.tm_year}; >+ if (year > kyearmax - 1900) { >+ // Platform-dependent, maybe unreachable. >+ if (err != nullptr) *err = "Out-of-range year"; >+ return false; >+ } >+ year += 1900; >+ } >+ >+ const int month = tm.tm_mon + 1; >+ civil_second cs(year, month, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); >+ >+ // parse() should not allow normalization. Due to the restricted field >+ // ranges above (see ParseInt()), the only possibility is for days to roll >+ // into months. That is, parsing "Sep 31" should not produce "Oct 1". >+ if (cs.month() != month || cs.day() != tm.tm_mday) { >+ if (err != nullptr) *err = "Out-of-range field"; >+ return false; >+ } >+ >+ // Accounts for the offset adjustment before converting to absolute time. >+ if ((offset < 0 && cs > civil_second::max() + offset) || >+ (offset > 0 && cs < civil_second::min() + offset)) { >+ if (err != nullptr) *err = "Out-of-range field"; >+ return false; >+ } >+ cs -= offset; >+ >+ const auto tp = ptz.lookup(cs).pre; >+ // Checks for overflow/underflow and returns an error as necessary. >+ if (tp == time_point<seconds>::max()) { >+ const auto al = ptz.lookup(time_point<seconds>::max()); >+ if (cs > al.cs) { >+ if (err != nullptr) *err = "Out-of-range field"; >+ return false; >+ } >+ } >+ if (tp == time_point<seconds>::min()) { >+ const auto al = ptz.lookup(time_point<seconds>::min()); >+ if (cs < al.cs) { >+ if (err != nullptr) *err = "Out-of-range field"; >+ return false; >+ } >+ } >+ >+ *sec = tp; >+ *fs = subseconds; >+ return true; >+} >+ >+} // namespace detail >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..a90dda7603a8a10e37b3b58d9665968b583962be >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc >@@ -0,0 +1,1426 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+ >+#include <chrono> >+#include <iomanip> >+#include <sstream> >+#include <string> >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+ >+namespace chrono = std::chrono; >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+namespace { >+ >+// This helper is a macro so that failed expectations show up with the >+// correct line numbers. >+#define ExpectTime(tp, tz, y, m, d, hh, mm, ss, off, isdst, zone) \ >+ do { \ >+ time_zone::absolute_lookup al = tz.lookup(tp); \ >+ EXPECT_EQ(y, al.cs.year()); \ >+ EXPECT_EQ(m, al.cs.month()); \ >+ EXPECT_EQ(d, al.cs.day()); \ >+ EXPECT_EQ(hh, al.cs.hour()); \ >+ EXPECT_EQ(mm, al.cs.minute()); \ >+ EXPECT_EQ(ss, al.cs.second()); \ >+ EXPECT_EQ(off, al.offset); \ >+ EXPECT_TRUE(isdst == al.is_dst); \ >+ EXPECT_STREQ(zone, al.abbr); \ >+ } while (0) >+ >+const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez"; >+const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; >+ >+const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z"; >+const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z"; >+ >+// A helper that tests the given format specifier by itself, and with leading >+// and trailing characters. For example: TestFormatSpecifier(tp, "%a", "Thu"). >+template <typename D> >+void TestFormatSpecifier(time_point<D> tp, time_zone tz, const std::string& fmt, >+ const std::string& ans) { >+ EXPECT_EQ(ans, format(fmt, tp, tz)) << fmt; >+ EXPECT_EQ("xxx " + ans, format("xxx " + fmt, tp, tz)); >+ EXPECT_EQ(ans + " yyy", format(fmt + " yyy", tp, tz)); >+ EXPECT_EQ("xxx " + ans + " yyy", format("xxx " + fmt + " yyy", tp, tz)); >+} >+ >+// These tests sometimes run on platforms that have zoneinfo data so old >+// that the transition we are attempting to check does not exist, most >+// notably Android emulators. Fortunately, AndroidZoneInfoSource supports >+// time_zone::version() so, in cases where we've learned that it matters, >+// we can make the check conditionally. >+int VersionCmp(time_zone tz, const std::string& target) { >+ std::string version = tz.version(); >+ if (version.empty() && !target.empty()) return 1; // unknown > known >+ return version.compare(target); >+} >+ >+} // namespace >+ >+// >+// Testing format() >+// >+ >+TEST(Format, TimePointResolution) { >+ const char kFmt[] = "%H:%M:%E*S"; >+ const time_zone utc = utc_time_zone(); >+ const time_point<chrono::nanoseconds> t0 = >+ chrono::system_clock::from_time_t(1420167845) + >+ chrono::milliseconds(123) + chrono::microseconds(456) + >+ chrono::nanoseconds(789); >+ EXPECT_EQ( >+ "03:04:05.123456789", >+ format(kFmt, chrono::time_point_cast<chrono::nanoseconds>(t0), utc)); >+ EXPECT_EQ( >+ "03:04:05.123456", >+ format(kFmt, chrono::time_point_cast<chrono::microseconds>(t0), utc)); >+ EXPECT_EQ( >+ "03:04:05.123", >+ format(kFmt, chrono::time_point_cast<chrono::milliseconds>(t0), utc)); >+ EXPECT_EQ("03:04:05", >+ format(kFmt, chrono::time_point_cast<chrono::seconds>(t0), utc)); >+ EXPECT_EQ("03:04:05", >+ format(kFmt, chrono::time_point_cast<absl::time_internal::cctz::seconds>(t0), utc)); >+ EXPECT_EQ("03:04:00", >+ format(kFmt, chrono::time_point_cast<chrono::minutes>(t0), utc)); >+ EXPECT_EQ("03:00:00", >+ format(kFmt, chrono::time_point_cast<chrono::hours>(t0), utc)); >+} >+ >+TEST(Format, TimePointExtendedResolution) { >+ const char kFmt[] = "%H:%M:%E*S"; >+ const time_zone utc = utc_time_zone(); >+ const time_point<absl::time_internal::cctz::seconds> tp = >+ chrono::time_point_cast<absl::time_internal::cctz::seconds>( >+ chrono::system_clock::from_time_t(0)) + >+ chrono::hours(12) + chrono::minutes(34) + chrono::seconds(56); >+ >+ EXPECT_EQ( >+ "12:34:56.123456789012345", >+ detail::format(kFmt, tp, detail::femtoseconds(123456789012345), utc)); >+ EXPECT_EQ( >+ "12:34:56.012345678901234", >+ detail::format(kFmt, tp, detail::femtoseconds(12345678901234), utc)); >+ EXPECT_EQ( >+ "12:34:56.001234567890123", >+ detail::format(kFmt, tp, detail::femtoseconds(1234567890123), utc)); >+ EXPECT_EQ( >+ "12:34:56.000123456789012", >+ detail::format(kFmt, tp, detail::femtoseconds(123456789012), utc)); >+ >+ EXPECT_EQ("12:34:56.000000000000123", >+ detail::format(kFmt, tp, detail::femtoseconds(123), utc)); >+ EXPECT_EQ("12:34:56.000000000000012", >+ detail::format(kFmt, tp, detail::femtoseconds(12), utc)); >+ EXPECT_EQ("12:34:56.000000000000001", >+ detail::format(kFmt, tp, detail::femtoseconds(1), utc)); >+} >+ >+TEST(Format, Basics) { >+ time_zone tz = utc_time_zone(); >+ time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); >+ >+ // Starts with a couple basic edge cases. >+ EXPECT_EQ("", format("", tp, tz)); >+ EXPECT_EQ(" ", format(" ", tp, tz)); >+ EXPECT_EQ(" ", format(" ", tp, tz)); >+ EXPECT_EQ("xxx", format("xxx", tp, tz)); >+ std::string big(128, 'x'); >+ EXPECT_EQ(big, format(big, tp, tz)); >+ // Cause the 1024-byte buffer to grow. >+ std::string bigger(100000, 'x'); >+ EXPECT_EQ(bigger, format(bigger, tp, tz)); >+ >+ tp += chrono::hours(13) + chrono::minutes(4) + chrono::seconds(5); >+ tp += chrono::milliseconds(6) + chrono::microseconds(7) + >+ chrono::nanoseconds(8); >+ EXPECT_EQ("1970-01-01", format("%Y-%m-%d", tp, tz)); >+ EXPECT_EQ("13:04:05", format("%H:%M:%S", tp, tz)); >+ EXPECT_EQ("13:04:05.006", format("%H:%M:%E3S", tp, tz)); >+ EXPECT_EQ("13:04:05.006007", format("%H:%M:%E6S", tp, tz)); >+ EXPECT_EQ("13:04:05.006007008", format("%H:%M:%E9S", tp, tz)); >+} >+ >+TEST(Format, PosixConversions) { >+ const time_zone tz = utc_time_zone(); >+ auto tp = chrono::system_clock::from_time_t(0); >+ >+ TestFormatSpecifier(tp, tz, "%d", "01"); >+ TestFormatSpecifier(tp, tz, "%e", " 1"); // extension but internal support >+ TestFormatSpecifier(tp, tz, "%H", "00"); >+ TestFormatSpecifier(tp, tz, "%I", "12"); >+ TestFormatSpecifier(tp, tz, "%j", "001"); >+ TestFormatSpecifier(tp, tz, "%m", "01"); >+ TestFormatSpecifier(tp, tz, "%M", "00"); >+ TestFormatSpecifier(tp, tz, "%S", "00"); >+ TestFormatSpecifier(tp, tz, "%U", "00"); >+ TestFormatSpecifier(tp, tz, "%w", "4"); // 4=Thursday >+ TestFormatSpecifier(tp, tz, "%W", "00"); >+ TestFormatSpecifier(tp, tz, "%y", "70"); >+ TestFormatSpecifier(tp, tz, "%Y", "1970"); >+ TestFormatSpecifier(tp, tz, "%z", "+0000"); >+ TestFormatSpecifier(tp, tz, "%Z", "UTC"); >+ TestFormatSpecifier(tp, tz, "%%", "%"); >+ >+#if defined(__linux__) >+ // SU/C99/TZ extensions >+ TestFormatSpecifier(tp, tz, "%C", "19"); >+ TestFormatSpecifier(tp, tz, "%D", "01/01/70"); >+ TestFormatSpecifier(tp, tz, "%F", "1970-01-01"); >+ TestFormatSpecifier(tp, tz, "%g", "70"); >+ TestFormatSpecifier(tp, tz, "%G", "1970"); >+ TestFormatSpecifier(tp, tz, "%k", " 0"); >+ TestFormatSpecifier(tp, tz, "%l", "12"); >+ TestFormatSpecifier(tp, tz, "%n", "\n"); >+ TestFormatSpecifier(tp, tz, "%R", "00:00"); >+ TestFormatSpecifier(tp, tz, "%t", "\t"); >+ TestFormatSpecifier(tp, tz, "%T", "00:00:00"); >+ TestFormatSpecifier(tp, tz, "%u", "4"); // 4=Thursday >+ TestFormatSpecifier(tp, tz, "%V", "01"); >+ TestFormatSpecifier(tp, tz, "%s", "0"); >+#endif >+} >+ >+TEST(Format, LocaleSpecific) { >+ const time_zone tz = utc_time_zone(); >+ auto tp = chrono::system_clock::from_time_t(0); >+ >+ TestFormatSpecifier(tp, tz, "%a", "Thu"); >+ TestFormatSpecifier(tp, tz, "%A", "Thursday"); >+ TestFormatSpecifier(tp, tz, "%b", "Jan"); >+ TestFormatSpecifier(tp, tz, "%B", "January"); >+ >+ // %c should at least produce the numeric year and time-of-day. >+ const std::string s = format("%c", tp, utc_time_zone()); >+ EXPECT_THAT(s, testing::HasSubstr("1970")); >+ EXPECT_THAT(s, testing::HasSubstr("00:00:00")); >+ >+ TestFormatSpecifier(tp, tz, "%p", "AM"); >+ TestFormatSpecifier(tp, tz, "%x", "01/01/70"); >+ TestFormatSpecifier(tp, tz, "%X", "00:00:00"); >+ >+#if defined(__linux__) >+ // SU/C99/TZ extensions >+ TestFormatSpecifier(tp, tz, "%h", "Jan"); // Same as %b >+ TestFormatSpecifier(tp, tz, "%P", "am"); >+ TestFormatSpecifier(tp, tz, "%r", "12:00:00 AM"); >+ >+ // Modified conversion specifiers %E_ >+ TestFormatSpecifier(tp, tz, "%Ec", "Thu Jan 1 00:00:00 1970"); >+ TestFormatSpecifier(tp, tz, "%EC", "19"); >+ TestFormatSpecifier(tp, tz, "%Ex", "01/01/70"); >+ TestFormatSpecifier(tp, tz, "%EX", "00:00:00"); >+ TestFormatSpecifier(tp, tz, "%Ey", "70"); >+ TestFormatSpecifier(tp, tz, "%EY", "1970"); >+ >+ // Modified conversion specifiers %O_ >+ TestFormatSpecifier(tp, tz, "%Od", "01"); >+ TestFormatSpecifier(tp, tz, "%Oe", " 1"); >+ TestFormatSpecifier(tp, tz, "%OH", "00"); >+ TestFormatSpecifier(tp, tz, "%OI", "12"); >+ TestFormatSpecifier(tp, tz, "%Om", "01"); >+ TestFormatSpecifier(tp, tz, "%OM", "00"); >+ TestFormatSpecifier(tp, tz, "%OS", "00"); >+ TestFormatSpecifier(tp, tz, "%Ou", "4"); // 4=Thursday >+ TestFormatSpecifier(tp, tz, "%OU", "00"); >+ TestFormatSpecifier(tp, tz, "%OV", "01"); >+ TestFormatSpecifier(tp, tz, "%Ow", "4"); // 4=Thursday >+ TestFormatSpecifier(tp, tz, "%OW", "00"); >+ TestFormatSpecifier(tp, tz, "%Oy", "70"); >+#endif >+} >+ >+TEST(Format, Escaping) { >+ const time_zone tz = utc_time_zone(); >+ auto tp = chrono::system_clock::from_time_t(0); >+ >+ TestFormatSpecifier(tp, tz, "%%", "%"); >+ TestFormatSpecifier(tp, tz, "%%a", "%a"); >+ TestFormatSpecifier(tp, tz, "%%b", "%b"); >+ TestFormatSpecifier(tp, tz, "%%Ea", "%Ea"); >+ TestFormatSpecifier(tp, tz, "%%Es", "%Es"); >+ TestFormatSpecifier(tp, tz, "%%E3S", "%E3S"); >+ TestFormatSpecifier(tp, tz, "%%OS", "%OS"); >+ TestFormatSpecifier(tp, tz, "%%O3S", "%O3S"); >+ >+ // Multiple levels of escaping. >+ TestFormatSpecifier(tp, tz, "%%%Y", "%1970"); >+ TestFormatSpecifier(tp, tz, "%%%E3S", "%00.000"); >+ TestFormatSpecifier(tp, tz, "%%%%E3S", "%%E3S"); >+} >+ >+TEST(Format, ExtendedSeconds) { >+ const time_zone tz = utc_time_zone(); >+ >+ // No subseconds. >+ time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); >+ tp += chrono::seconds(5); >+ EXPECT_EQ("05", format("%E*S", tp, tz)); >+ EXPECT_EQ("05", format("%E0S", tp, tz)); >+ EXPECT_EQ("05.0", format("%E1S", tp, tz)); >+ EXPECT_EQ("05.00", format("%E2S", tp, tz)); >+ EXPECT_EQ("05.000", format("%E3S", tp, tz)); >+ EXPECT_EQ("05.0000", format("%E4S", tp, tz)); >+ EXPECT_EQ("05.00000", format("%E5S", tp, tz)); >+ EXPECT_EQ("05.000000", format("%E6S", tp, tz)); >+ EXPECT_EQ("05.0000000", format("%E7S", tp, tz)); >+ EXPECT_EQ("05.00000000", format("%E8S", tp, tz)); >+ EXPECT_EQ("05.000000000", format("%E9S", tp, tz)); >+ EXPECT_EQ("05.0000000000", format("%E10S", tp, tz)); >+ EXPECT_EQ("05.00000000000", format("%E11S", tp, tz)); >+ EXPECT_EQ("05.000000000000", format("%E12S", tp, tz)); >+ EXPECT_EQ("05.0000000000000", format("%E13S", tp, tz)); >+ EXPECT_EQ("05.00000000000000", format("%E14S", tp, tz)); >+ EXPECT_EQ("05.000000000000000", format("%E15S", tp, tz)); >+ >+ // With subseconds. >+ tp += chrono::milliseconds(6) + chrono::microseconds(7) + >+ chrono::nanoseconds(8); >+ EXPECT_EQ("05.006007008", format("%E*S", tp, tz)); >+ EXPECT_EQ("05", format("%E0S", tp, tz)); >+ EXPECT_EQ("05.0", format("%E1S", tp, tz)); >+ EXPECT_EQ("05.00", format("%E2S", tp, tz)); >+ EXPECT_EQ("05.006", format("%E3S", tp, tz)); >+ EXPECT_EQ("05.0060", format("%E4S", tp, tz)); >+ EXPECT_EQ("05.00600", format("%E5S", tp, tz)); >+ EXPECT_EQ("05.006007", format("%E6S", tp, tz)); >+ EXPECT_EQ("05.0060070", format("%E7S", tp, tz)); >+ EXPECT_EQ("05.00600700", format("%E8S", tp, tz)); >+ EXPECT_EQ("05.006007008", format("%E9S", tp, tz)); >+ EXPECT_EQ("05.0060070080", format("%E10S", tp, tz)); >+ EXPECT_EQ("05.00600700800", format("%E11S", tp, tz)); >+ EXPECT_EQ("05.006007008000", format("%E12S", tp, tz)); >+ EXPECT_EQ("05.0060070080000", format("%E13S", tp, tz)); >+ EXPECT_EQ("05.00600700800000", format("%E14S", tp, tz)); >+ EXPECT_EQ("05.006007008000000", format("%E15S", tp, tz)); >+ >+ // Times before the Unix epoch. >+ tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(-1); >+ EXPECT_EQ("1969-12-31 23:59:59.999999", >+ format("%Y-%m-%d %H:%M:%E*S", tp, tz)); >+ >+ // Here is a "%E*S" case we got wrong for a while. While the first >+ // instant below is correctly rendered as "...:07.333304", the second >+ // one used to appear as "...:07.33330499999999999". >+ tp = chrono::system_clock::from_time_t(0) + >+ chrono::microseconds(1395024427333304); >+ EXPECT_EQ("2014-03-17 02:47:07.333304", >+ format("%Y-%m-%d %H:%M:%E*S", tp, tz)); >+ tp += chrono::microseconds(1); >+ EXPECT_EQ("2014-03-17 02:47:07.333305", >+ format("%Y-%m-%d %H:%M:%E*S", tp, tz)); >+} >+ >+TEST(Format, ExtendedSubeconds) { >+ const time_zone tz = utc_time_zone(); >+ >+ // No subseconds. >+ time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); >+ tp += chrono::seconds(5); >+ EXPECT_EQ("0", format("%E*f", tp, tz)); >+ EXPECT_EQ("", format("%E0f", tp, tz)); >+ EXPECT_EQ("0", format("%E1f", tp, tz)); >+ EXPECT_EQ("00", format("%E2f", tp, tz)); >+ EXPECT_EQ("000", format("%E3f", tp, tz)); >+ EXPECT_EQ("0000", format("%E4f", tp, tz)); >+ EXPECT_EQ("00000", format("%E5f", tp, tz)); >+ EXPECT_EQ("000000", format("%E6f", tp, tz)); >+ EXPECT_EQ("0000000", format("%E7f", tp, tz)); >+ EXPECT_EQ("00000000", format("%E8f", tp, tz)); >+ EXPECT_EQ("000000000", format("%E9f", tp, tz)); >+ EXPECT_EQ("0000000000", format("%E10f", tp, tz)); >+ EXPECT_EQ("00000000000", format("%E11f", tp, tz)); >+ EXPECT_EQ("000000000000", format("%E12f", tp, tz)); >+ EXPECT_EQ("0000000000000", format("%E13f", tp, tz)); >+ EXPECT_EQ("00000000000000", format("%E14f", tp, tz)); >+ EXPECT_EQ("000000000000000", format("%E15f", tp, tz)); >+ >+ // With subseconds. >+ tp += chrono::milliseconds(6) + chrono::microseconds(7) + >+ chrono::nanoseconds(8); >+ EXPECT_EQ("006007008", format("%E*f", tp, tz)); >+ EXPECT_EQ("", format("%E0f", tp, tz)); >+ EXPECT_EQ("0", format("%E1f", tp, tz)); >+ EXPECT_EQ("00", format("%E2f", tp, tz)); >+ EXPECT_EQ("006", format("%E3f", tp, tz)); >+ EXPECT_EQ("0060", format("%E4f", tp, tz)); >+ EXPECT_EQ("00600", format("%E5f", tp, tz)); >+ EXPECT_EQ("006007", format("%E6f", tp, tz)); >+ EXPECT_EQ("0060070", format("%E7f", tp, tz)); >+ EXPECT_EQ("00600700", format("%E8f", tp, tz)); >+ EXPECT_EQ("006007008", format("%E9f", tp, tz)); >+ EXPECT_EQ("0060070080", format("%E10f", tp, tz)); >+ EXPECT_EQ("00600700800", format("%E11f", tp, tz)); >+ EXPECT_EQ("006007008000", format("%E12f", tp, tz)); >+ EXPECT_EQ("0060070080000", format("%E13f", tp, tz)); >+ EXPECT_EQ("00600700800000", format("%E14f", tp, tz)); >+ EXPECT_EQ("006007008000000", format("%E15f", tp, tz)); >+ >+ // Times before the Unix epoch. >+ tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(-1); >+ EXPECT_EQ("1969-12-31 23:59:59.999999", >+ format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); >+ >+ // Here is a "%E*S" case we got wrong for a while. While the first >+ // instant below is correctly rendered as "...:07.333304", the second >+ // one used to appear as "...:07.33330499999999999". >+ tp = chrono::system_clock::from_time_t(0) + >+ chrono::microseconds(1395024427333304); >+ EXPECT_EQ("2014-03-17 02:47:07.333304", >+ format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); >+ tp += chrono::microseconds(1); >+ EXPECT_EQ("2014-03-17 02:47:07.333305", >+ format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); >+} >+ >+TEST(Format, CompareExtendSecondsVsSubseconds) { >+ const time_zone tz = utc_time_zone(); >+ >+ // This test case illustrates the differences/similarities between: >+ // fmt_A: %E<prec>S >+ // fmt_B: %S.%E<prec>f >+ auto fmt_A = [](const std::string& prec) { return "%E" + prec + "S"; }; >+ auto fmt_B = [](const std::string& prec) { return "%S.%E" + prec + "f"; }; >+ >+ // No subseconds: >+ time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); >+ tp += chrono::seconds(5); >+ // ... %E*S and %S.%E*f are different. >+ EXPECT_EQ("05", format(fmt_A("*"), tp, tz)); >+ EXPECT_EQ("05.0", format(fmt_B("*"), tp, tz)); >+ // ... %E0S and %S.%E0f are different. >+ EXPECT_EQ("05", format(fmt_A("0"), tp, tz)); >+ EXPECT_EQ("05.", format(fmt_B("0"), tp, tz)); >+ // ... %E<prec>S and %S.%E<prec>f are the same for prec in [1:15]. >+ for (int prec = 1; prec <= 15; ++prec) { >+ const std::string a = format(fmt_A(std::to_string(prec)), tp, tz); >+ const std::string b = format(fmt_B(std::to_string(prec)), tp, tz); >+ EXPECT_EQ(a, b) << "prec=" << prec; >+ } >+ >+ // With subseconds: >+ // ... %E*S and %S.%E*f are the same. >+ tp += chrono::milliseconds(6) + chrono::microseconds(7) + >+ chrono::nanoseconds(8); >+ EXPECT_EQ("05.006007008", format(fmt_A("*"), tp, tz)); >+ EXPECT_EQ("05.006007008", format(fmt_B("*"), tp, tz)); >+ // ... %E0S and %S.%E0f are different. >+ EXPECT_EQ("05", format(fmt_A("0"), tp, tz)); >+ EXPECT_EQ("05.", format(fmt_B("0"), tp, tz)); >+ // ... %E<prec>S and %S.%E<prec>f are the same for prec in [1:15]. >+ for (int prec = 1; prec <= 15; ++prec) { >+ const std::string a = format(fmt_A(std::to_string(prec)), tp, tz); >+ const std::string b = format(fmt_B(std::to_string(prec)), tp, tz); >+ EXPECT_EQ(a, b) << "prec=" << prec; >+ } >+} >+ >+TEST(Format, ExtendedOffset) { >+ auto tp = chrono::system_clock::from_time_t(0); >+ >+ time_zone tz = utc_time_zone(); >+ TestFormatSpecifier(tp, tz, "%Ez", "+00:00"); >+ >+ EXPECT_TRUE(load_time_zone("America/New_York", &tz)); >+ TestFormatSpecifier(tp, tz, "%Ez", "-05:00"); >+ >+ EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz)); >+ TestFormatSpecifier(tp, tz, "%Ez", "-08:00"); >+ >+ EXPECT_TRUE(load_time_zone("Australia/Sydney", &tz)); >+ TestFormatSpecifier(tp, tz, "%Ez", "+10:00"); >+ >+ EXPECT_TRUE(load_time_zone("Africa/Monrovia", &tz)); >+ // The true offset is -00:44:30 but %z only gives (truncated) minutes. >+ TestFormatSpecifier(tp, tz, "%z", "-0044"); >+ TestFormatSpecifier(tp, tz, "%Ez", "-00:44"); >+} >+ >+TEST(Format, ExtendedSecondOffset) { >+ const time_zone utc = utc_time_zone(); >+ time_point<chrono::seconds> tp; >+ time_zone tz; >+ >+ EXPECT_TRUE(load_time_zone("America/New_York", &tz)); >+ tp = convert(civil_second(1883, 11, 18, 16, 59, 59), utc); >+ if (tz.lookup(tp).offset == -5 * 60 * 60) { >+ // It looks like the tzdata is only 32 bit (probably macOS), >+ // which bottoms out at 1901-12-13T20:45:52+00:00. >+ } else { >+ TestFormatSpecifier(tp, tz, "%E*z", "-04:56:02"); >+ TestFormatSpecifier(tp, tz, "%Ez", "-04:56"); >+ } >+ tp += chrono::seconds(1); >+ TestFormatSpecifier(tp, tz, "%E*z", "-05:00:00"); >+ >+ EXPECT_TRUE(load_time_zone("Europe/Moscow", &tz)); >+ tp = convert(civil_second(1919, 6, 30, 23, 59, 59), utc); >+ if (VersionCmp(tz, "2016g") >= 0) { >+ TestFormatSpecifier(tp, tz, "%E*z", "+04:31:19"); >+ TestFormatSpecifier(tp, tz, "%Ez", "+04:31"); >+ } >+ tp += chrono::seconds(1); >+ TestFormatSpecifier(tp, tz, "%E*z", "+04:00:00"); >+} >+ >+TEST(Format, ExtendedYears) { >+ const time_zone utc = utc_time_zone(); >+ const char e4y_fmt[] = "%E4Y%m%d"; // no separators >+ >+ // %E4Y zero-pads the year to produce at least 4 chars, including the sign. >+ auto tp = convert(civil_second(-999, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("-9991127", format(e4y_fmt, tp, utc)); >+ tp = convert(civil_second(-99, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("-0991127", format(e4y_fmt, tp, utc)); >+ tp = convert(civil_second(-9, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("-0091127", format(e4y_fmt, tp, utc)); >+ tp = convert(civil_second(-1, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("-0011127", format(e4y_fmt, tp, utc)); >+ tp = convert(civil_second(0, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("00001127", format(e4y_fmt, tp, utc)); >+ tp = convert(civil_second(1, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("00011127", format(e4y_fmt, tp, utc)); >+ tp = convert(civil_second(9, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("00091127", format(e4y_fmt, tp, utc)); >+ tp = convert(civil_second(99, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("00991127", format(e4y_fmt, tp, utc)); >+ tp = convert(civil_second(999, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("09991127", format(e4y_fmt, tp, utc)); >+ tp = convert(civil_second(9999, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("99991127", format(e4y_fmt, tp, utc)); >+ >+ // When the year is outside [-999:9999], more than 4 chars are produced. >+ tp = convert(civil_second(-1000, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("-10001127", format(e4y_fmt, tp, utc)); >+ tp = convert(civil_second(10000, 11, 27, 0, 0, 0), utc); >+ EXPECT_EQ("100001127", format(e4y_fmt, tp, utc)); >+} >+ >+TEST(Format, RFC3339Format) { >+ time_zone tz; >+ EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz)); >+ >+ time_point<chrono::nanoseconds> tp = >+ convert(civil_second(1977, 6, 28, 9, 8, 7), tz); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_full, tp, tz)); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); >+ >+ tp += chrono::milliseconds(100); >+ EXPECT_EQ("1977-06-28T09:08:07.1-07:00", format(RFC3339_full, tp, tz)); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); >+ >+ tp += chrono::milliseconds(20); >+ EXPECT_EQ("1977-06-28T09:08:07.12-07:00", format(RFC3339_full, tp, tz)); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); >+ >+ tp += chrono::milliseconds(3); >+ EXPECT_EQ("1977-06-28T09:08:07.123-07:00", format(RFC3339_full, tp, tz)); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); >+ >+ tp += chrono::microseconds(400); >+ EXPECT_EQ("1977-06-28T09:08:07.1234-07:00", format(RFC3339_full, tp, tz)); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); >+ >+ tp += chrono::microseconds(50); >+ EXPECT_EQ("1977-06-28T09:08:07.12345-07:00", format(RFC3339_full, tp, tz)); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); >+ >+ tp += chrono::microseconds(6); >+ EXPECT_EQ("1977-06-28T09:08:07.123456-07:00", format(RFC3339_full, tp, tz)); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); >+ >+ tp += chrono::nanoseconds(700); >+ EXPECT_EQ("1977-06-28T09:08:07.1234567-07:00", format(RFC3339_full, tp, tz)); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); >+ >+ tp += chrono::nanoseconds(80); >+ EXPECT_EQ("1977-06-28T09:08:07.12345678-07:00", format(RFC3339_full, tp, tz)); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); >+ >+ tp += chrono::nanoseconds(9); >+ EXPECT_EQ("1977-06-28T09:08:07.123456789-07:00", >+ format(RFC3339_full, tp, tz)); >+ EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); >+} >+ >+TEST(Format, RFC1123Format) { // locale specific >+ time_zone tz; >+ EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz)); >+ >+ auto tp = convert(civil_second(1977, 6, 28, 9, 8, 7), tz); >+ EXPECT_EQ("Tue, 28 Jun 1977 09:08:07 -0700", format(RFC1123_full, tp, tz)); >+ EXPECT_EQ("28 Jun 1977 09:08:07 -0700", format(RFC1123_no_wday, tp, tz)); >+} >+ >+// >+// Testing parse() >+// >+ >+TEST(Parse, TimePointResolution) { >+ const char kFmt[] = "%H:%M:%E*S"; >+ const time_zone utc = utc_time_zone(); >+ >+ time_point<chrono::nanoseconds> tp_ns; >+ EXPECT_TRUE(parse(kFmt, "03:04:05.123456789", utc, &tp_ns)); >+ EXPECT_EQ("03:04:05.123456789", format(kFmt, tp_ns, utc)); >+ EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_ns)); >+ EXPECT_EQ("03:04:05.123456", format(kFmt, tp_ns, utc)); >+ >+ time_point<chrono::microseconds> tp_us; >+ EXPECT_TRUE(parse(kFmt, "03:04:05.123456789", utc, &tp_us)); >+ EXPECT_EQ("03:04:05.123456", format(kFmt, tp_us, utc)); >+ EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_us)); >+ EXPECT_EQ("03:04:05.123456", format(kFmt, tp_us, utc)); >+ EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_us)); >+ EXPECT_EQ("03:04:05.123", format(kFmt, tp_us, utc)); >+ >+ time_point<chrono::milliseconds> tp_ms; >+ EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_ms)); >+ EXPECT_EQ("03:04:05.123", format(kFmt, tp_ms, utc)); >+ EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_ms)); >+ EXPECT_EQ("03:04:05.123", format(kFmt, tp_ms, utc)); >+ EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_ms)); >+ EXPECT_EQ("03:04:05", format(kFmt, tp_ms, utc)); >+ >+ time_point<chrono::seconds> tp_s; >+ EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_s)); >+ EXPECT_EQ("03:04:05", format(kFmt, tp_s, utc)); >+ EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_s)); >+ EXPECT_EQ("03:04:05", format(kFmt, tp_s, utc)); >+ >+ time_point<chrono::minutes> tp_m; >+ EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_m)); >+ EXPECT_EQ("03:04:00", format(kFmt, tp_m, utc)); >+ >+ time_point<chrono::hours> tp_h; >+ EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_h)); >+ EXPECT_EQ("03:00:00", format(kFmt, tp_h, utc)); >+} >+ >+TEST(Parse, TimePointExtendedResolution) { >+ const char kFmt[] = "%H:%M:%E*S"; >+ const time_zone utc = utc_time_zone(); >+ >+ time_point<absl::time_internal::cctz::seconds> tp; >+ detail::femtoseconds fs; >+ EXPECT_TRUE(detail::parse(kFmt, "12:34:56.123456789012345", utc, &tp, &fs)); >+ EXPECT_EQ("12:34:56.123456789012345", detail::format(kFmt, tp, fs, utc)); >+ EXPECT_TRUE(detail::parse(kFmt, "12:34:56.012345678901234", utc, &tp, &fs)); >+ EXPECT_EQ("12:34:56.012345678901234", detail::format(kFmt, tp, fs, utc)); >+ EXPECT_TRUE(detail::parse(kFmt, "12:34:56.001234567890123", utc, &tp, &fs)); >+ EXPECT_EQ("12:34:56.001234567890123", detail::format(kFmt, tp, fs, utc)); >+ EXPECT_TRUE(detail::parse(kFmt, "12:34:56.000000000000123", utc, &tp, &fs)); >+ EXPECT_EQ("12:34:56.000000000000123", detail::format(kFmt, tp, fs, utc)); >+ EXPECT_TRUE(detail::parse(kFmt, "12:34:56.000000000000012", utc, &tp, &fs)); >+ EXPECT_EQ("12:34:56.000000000000012", detail::format(kFmt, tp, fs, utc)); >+ EXPECT_TRUE(detail::parse(kFmt, "12:34:56.000000000000001", utc, &tp, &fs)); >+ EXPECT_EQ("12:34:56.000000000000001", detail::format(kFmt, tp, fs, utc)); >+} >+ >+TEST(Parse, Basics) { >+ time_zone tz = utc_time_zone(); >+ time_point<chrono::nanoseconds> tp = >+ chrono::system_clock::from_time_t(1234567890); >+ >+ // Simple edge cases. >+ EXPECT_TRUE(parse("", "", tz, &tp)); >+ EXPECT_EQ(chrono::system_clock::from_time_t(0), tp); // everything defaulted >+ EXPECT_TRUE(parse(" ", " ", tz, &tp)); >+ EXPECT_TRUE(parse(" ", " ", tz, &tp)); >+ EXPECT_TRUE(parse("x", "x", tz, &tp)); >+ EXPECT_TRUE(parse("xxx", "xxx", tz, &tp)); >+ >+ EXPECT_TRUE( >+ parse("%Y-%m-%d %H:%M:%S %z", "2013-06-28 19:08:09 -0800", tz, &tp)); >+ ExpectTime(tp, tz, 2013, 6, 29, 3, 8, 9, 0, false, "UTC"); >+} >+ >+TEST(Parse, WithTimeZone) { >+ time_zone tz; >+ EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz)); >+ time_point<chrono::nanoseconds> tp; >+ >+ // We can parse a std::string without a UTC offset if we supply a timezone. >+ EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S", "2013-06-28 19:08:09", tz, &tp)); >+ ExpectTime(tp, tz, 2013, 6, 28, 19, 8, 9, -7 * 60 * 60, true, "PDT"); >+ >+ // But the timezone is ignored when a UTC offset is present. >+ EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S %z", "2013-06-28 19:08:09 +0800", >+ utc_time_zone(), &tp)); >+ ExpectTime(tp, tz, 2013, 6, 28, 19 - 8 - 7, 8, 9, -7 * 60 * 60, true, "PDT"); >+ >+ // Check a skipped time (a Spring DST transition). parse() returns >+ // the preferred-offset result, as defined for ConvertDateTime(). >+ EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S", "2011-03-13 02:15:00", tz, &tp)); >+ ExpectTime(tp, tz, 2011, 3, 13, 3, 15, 0, -7 * 60 * 60, true, "PDT"); >+ >+ // Check a repeated time (a Fall DST transition). parse() returns >+ // the preferred-offset result, as defined for ConvertDateTime(). >+ EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S", "2011-11-06 01:15:00", tz, &tp)); >+ ExpectTime(tp, tz, 2011, 11, 6, 1, 15, 0, -7 * 60 * 60, true, "PDT"); >+} >+ >+TEST(Parse, LeapSecond) { >+ time_zone tz; >+ EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz)); >+ time_point<chrono::nanoseconds> tp; >+ >+ // ":59" -> ":59" >+ EXPECT_TRUE(parse(RFC3339_full, "2013-06-28T07:08:59-08:00", tz, &tp)); >+ ExpectTime(tp, tz, 2013, 6, 28, 8, 8, 59, -7 * 60 * 60, true, "PDT"); >+ >+ // ":59.5" -> ":59.5" >+ EXPECT_TRUE(parse(RFC3339_full, "2013-06-28T07:08:59.5-08:00", tz, &tp)); >+ ExpectTime(tp, tz, 2013, 6, 28, 8, 8, 59, -7 * 60 * 60, true, "PDT"); >+ >+ // ":60" -> ":00" >+ EXPECT_TRUE(parse(RFC3339_full, "2013-06-28T07:08:60-08:00", tz, &tp)); >+ ExpectTime(tp, tz, 2013, 6, 28, 8, 9, 0, -7 * 60 * 60, true, "PDT"); >+ >+ // ":60.5" -> ":00.0" >+ EXPECT_TRUE(parse(RFC3339_full, "2013-06-28T07:08:60.5-08:00", tz, &tp)); >+ ExpectTime(tp, tz, 2013, 6, 28, 8, 9, 0, -7 * 60 * 60, true, "PDT"); >+ >+ // ":61" -> error >+ EXPECT_FALSE(parse(RFC3339_full, "2013-06-28T07:08:61-08:00", tz, &tp)); >+} >+ >+TEST(Parse, ErrorCases) { >+ const time_zone tz = utc_time_zone(); >+ auto tp = chrono::system_clock::from_time_t(0); >+ >+ // Illegal trailing data. >+ EXPECT_FALSE(parse("%S", "123", tz, &tp)); >+ >+ // Can't parse an illegal format specifier. >+ EXPECT_FALSE(parse("%Q", "x", tz, &tp)); >+ >+ // Fails because of trailing, unparsed data "blah". >+ EXPECT_FALSE(parse("%m-%d", "2-3 blah", tz, &tp)); >+ >+ // Trailing whitespace is allowed. >+ EXPECT_TRUE(parse("%m-%d", "2-3 ", tz, &tp)); >+ EXPECT_EQ(2, convert(tp, utc_time_zone()).month()); >+ EXPECT_EQ(3, convert(tp, utc_time_zone()).day()); >+ >+ // Feb 31 requires normalization. >+ EXPECT_FALSE(parse("%m-%d", "2-31", tz, &tp)); >+ >+ // Check that we cannot have spaces in UTC offsets. >+ EXPECT_TRUE(parse("%z", "-0203", tz, &tp)); >+ EXPECT_FALSE(parse("%z", "- 2 3", tz, &tp)); >+ EXPECT_TRUE(parse("%Ez", "-02:03", tz, &tp)); >+ EXPECT_FALSE(parse("%Ez", "- 2: 3", tz, &tp)); >+ >+ // Check that we reject other malformed UTC offsets. >+ EXPECT_FALSE(parse("%Ez", "+-08:00", tz, &tp)); >+ EXPECT_FALSE(parse("%Ez", "-+08:00", tz, &tp)); >+ >+ // Check that we do not accept "-0" in fields that allow zero. >+ EXPECT_FALSE(parse("%Y", "-0", tz, &tp)); >+ EXPECT_FALSE(parse("%E4Y", "-0", tz, &tp)); >+ EXPECT_FALSE(parse("%H", "-0", tz, &tp)); >+ EXPECT_FALSE(parse("%M", "-0", tz, &tp)); >+ EXPECT_FALSE(parse("%S", "-0", tz, &tp)); >+ EXPECT_FALSE(parse("%z", "+-000", tz, &tp)); >+ EXPECT_FALSE(parse("%Ez", "+-0:00", tz, &tp)); >+ EXPECT_FALSE(parse("%z", "-00-0", tz, &tp)); >+ EXPECT_FALSE(parse("%Ez", "-00:-0", tz, &tp)); >+} >+ >+TEST(Parse, PosixConversions) { >+ time_zone tz = utc_time_zone(); >+ auto tp = chrono::system_clock::from_time_t(0); >+ const auto reset = convert(civil_second(1977, 6, 28, 9, 8, 7), tz); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%d", "15", tz, &tp)); >+ EXPECT_EQ(15, convert(tp, tz).day()); >+ >+ // %e is an extension, but is supported internally. >+ tp = reset; >+ EXPECT_TRUE(parse("%e", "15", tz, &tp)); >+ EXPECT_EQ(15, convert(tp, tz).day()); // Equivalent to %d >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%H", "17", tz, &tp)); >+ EXPECT_EQ(17, convert(tp, tz).hour()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%I", "5", tz, &tp)); >+ EXPECT_EQ(5, convert(tp, tz).hour()); >+ >+ // %j is parsed but ignored. >+ EXPECT_TRUE(parse("%j", "32", tz, &tp)); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%m", "11", tz, &tp)); >+ EXPECT_EQ(11, convert(tp, tz).month()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%M", "33", tz, &tp)); >+ EXPECT_EQ(33, convert(tp, tz).minute()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%S", "55", tz, &tp)); >+ EXPECT_EQ(55, convert(tp, tz).second()); >+ >+ // %U is parsed but ignored. >+ EXPECT_TRUE(parse("%U", "15", tz, &tp)); >+ >+ // %w is parsed but ignored. >+ EXPECT_TRUE(parse("%w", "2", tz, &tp)); >+ >+ // %W is parsed but ignored. >+ EXPECT_TRUE(parse("%W", "22", tz, &tp)); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%y", "04", tz, &tp)); >+ EXPECT_EQ(2004, convert(tp, tz).year()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%Y", "2004", tz, &tp)); >+ EXPECT_EQ(2004, convert(tp, tz).year()); >+ >+ EXPECT_TRUE(parse("%%", "%", tz, &tp)); >+ >+#if defined(__linux__) >+ // SU/C99/TZ extensions >+ >+ // Because we handle each (non-internal) specifier in a separate call >+ // to strptime(), there is no way to group %C and %y together. So we >+ // just skip the %C/%y case. >+#if 0 >+ tp = reset; >+ EXPECT_TRUE(parse("%C %y", "20 04", tz, &tp)); >+ EXPECT_EQ(2004, convert(tp, tz).year()); >+#endif >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%D", "02/03/04", tz, &tp)); >+ EXPECT_EQ(2, convert(tp, tz).month()); >+ EXPECT_EQ(3, convert(tp, tz).day()); >+ EXPECT_EQ(2004, convert(tp, tz).year()); >+ >+ EXPECT_TRUE(parse("%n", "\n", tz, &tp)); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%R", "03:44", tz, &tp)); >+ EXPECT_EQ(3, convert(tp, tz).hour()); >+ EXPECT_EQ(44, convert(tp, tz).minute()); >+ >+ EXPECT_TRUE(parse("%t", "\t\v\f\n\r ", tz, &tp)); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%T", "03:44:55", tz, &tp)); >+ EXPECT_EQ(3, convert(tp, tz).hour()); >+ EXPECT_EQ(44, convert(tp, tz).minute()); >+ EXPECT_EQ(55, convert(tp, tz).second()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%s", "1234567890", tz, &tp)); >+ EXPECT_EQ(chrono::system_clock::from_time_t(1234567890), tp); >+ >+ // %s conversion, like %z/%Ez, pays no heed to the optional zone. >+ time_zone lax; >+ EXPECT_TRUE(load_time_zone("America/Los_Angeles", &lax)); >+ tp = reset; >+ EXPECT_TRUE(parse("%s", "1234567890", lax, &tp)); >+ EXPECT_EQ(chrono::system_clock::from_time_t(1234567890), tp); >+ >+ // This is most important when the time has the same YMDhms >+ // breakdown in the zone as some other time. For example, ... >+ // 1414917000 in US/Pacific -> Sun Nov 2 01:30:00 2014 (PDT) >+ // 1414920600 in US/Pacific -> Sun Nov 2 01:30:00 2014 (PST) >+ tp = reset; >+ EXPECT_TRUE(parse("%s", "1414917000", lax, &tp)); >+ EXPECT_EQ(chrono::system_clock::from_time_t(1414917000), tp); >+ tp = reset; >+ EXPECT_TRUE(parse("%s", "1414920600", lax, &tp)); >+ EXPECT_EQ(chrono::system_clock::from_time_t(1414920600), tp); >+#endif >+} >+ >+TEST(Parse, LocaleSpecific) { >+ time_zone tz = utc_time_zone(); >+ auto tp = chrono::system_clock::from_time_t(0); >+ const auto reset = convert(civil_second(1977, 6, 28, 9, 8, 7), tz); >+ >+ // %a is parsed but ignored. >+ EXPECT_TRUE(parse("%a", "Mon", tz, &tp)); >+ >+ // %A is parsed but ignored. >+ EXPECT_TRUE(parse("%A", "Monday", tz, &tp)); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%b", "Feb", tz, &tp)); >+ EXPECT_EQ(2, convert(tp, tz).month()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%B", "February", tz, &tp)); >+ EXPECT_EQ(2, convert(tp, tz).month()); >+ >+ // %p is parsed but ignored if it's alone. But it's used with %I. >+ EXPECT_TRUE(parse("%p", "AM", tz, &tp)); >+ tp = reset; >+ EXPECT_TRUE(parse("%I %p", "5 PM", tz, &tp)); >+ EXPECT_EQ(17, convert(tp, tz).hour()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%x", "02/03/04", tz, &tp)); >+ if (convert(tp, tz).month() == 2) { >+ EXPECT_EQ(3, convert(tp, tz).day()); >+ } else { >+ EXPECT_EQ(2, convert(tp, tz).day()); >+ EXPECT_EQ(3, convert(tp, tz).month()); >+ } >+ EXPECT_EQ(2004, convert(tp, tz).year()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%X", "15:44:55", tz, &tp)); >+ EXPECT_EQ(15, convert(tp, tz).hour()); >+ EXPECT_EQ(44, convert(tp, tz).minute()); >+ EXPECT_EQ(55, convert(tp, tz).second()); >+ >+#if defined(__linux__) >+ // SU/C99/TZ extensions >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%h", "Feb", tz, &tp)); >+ EXPECT_EQ(2, convert(tp, tz).month()); // Equivalent to %b >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%l %p", "5 PM", tz, &tp)); >+ EXPECT_EQ(17, convert(tp, tz).hour()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%r", "03:44:55 PM", tz, &tp)); >+ EXPECT_EQ(15, convert(tp, tz).hour()); >+ EXPECT_EQ(44, convert(tp, tz).minute()); >+ EXPECT_EQ(55, convert(tp, tz).second()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%Ec", "Tue Nov 19 05:06:07 2013", tz, &tp)); >+ EXPECT_EQ(convert(civil_second(2013, 11, 19, 5, 6, 7), tz), tp); >+ >+ // Modified conversion specifiers %E_ >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%Ex", "02/03/04", tz, &tp)); >+ EXPECT_EQ(2, convert(tp, tz).month()); >+ EXPECT_EQ(3, convert(tp, tz).day()); >+ EXPECT_EQ(2004, convert(tp, tz).year()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%EX", "15:44:55", tz, &tp)); >+ EXPECT_EQ(15, convert(tp, tz).hour()); >+ EXPECT_EQ(44, convert(tp, tz).minute()); >+ EXPECT_EQ(55, convert(tp, tz).second()); >+ >+ // %Ey, the year offset from %EC, doesn't really make sense alone as there >+ // is no way to represent it in tm_year (%EC is not simply the century). >+ // Yet, because we handle each (non-internal) specifier in a separate call >+ // to strptime(), there is no way to group %EC and %Ey either. So we just >+ // skip the %EC and %Ey cases. >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%EY", "2004", tz, &tp)); >+ EXPECT_EQ(2004, convert(tp, tz).year()); >+ >+ // Modified conversion specifiers %O_ >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%Od", "15", tz, &tp)); >+ EXPECT_EQ(15, convert(tp, tz).day()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%Oe", "15", tz, &tp)); >+ EXPECT_EQ(15, convert(tp, tz).day()); // Equivalent to %d >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%OH", "17", tz, &tp)); >+ EXPECT_EQ(17, convert(tp, tz).hour()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%OI", "5", tz, &tp)); >+ EXPECT_EQ(5, convert(tp, tz).hour()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%Om", "11", tz, &tp)); >+ EXPECT_EQ(11, convert(tp, tz).month()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%OM", "33", tz, &tp)); >+ EXPECT_EQ(33, convert(tp, tz).minute()); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%OS", "55", tz, &tp)); >+ EXPECT_EQ(55, convert(tp, tz).second()); >+ >+ // %OU is parsed but ignored. >+ EXPECT_TRUE(parse("%OU", "15", tz, &tp)); >+ >+ // %Ow is parsed but ignored. >+ EXPECT_TRUE(parse("%Ow", "2", tz, &tp)); >+ >+ // %OW is parsed but ignored. >+ EXPECT_TRUE(parse("%OW", "22", tz, &tp)); >+ >+ tp = reset; >+ EXPECT_TRUE(parse("%Oy", "04", tz, &tp)); >+ EXPECT_EQ(2004, convert(tp, tz).year()); >+#endif >+} >+ >+TEST(Parse, ExtendedSeconds) { >+ const time_zone tz = utc_time_zone(); >+ const time_point<chrono::nanoseconds> unix_epoch = >+ chrono::system_clock::from_time_t(0); >+ >+ // All %E<prec>S cases are treated the same as %E*S on input. >+ auto precisions = {"*", "0", "1", "2", "3", "4", "5", "6", "7", >+ "8", "9", "10", "11", "12", "13", "14", "15"}; >+ for (const std::string& prec : precisions) { >+ const std::string fmt = "%E" + prec + "S"; >+ SCOPED_TRACE(fmt); >+ time_point<chrono::nanoseconds> tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "5", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::seconds(5), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "05", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::seconds(5), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "05.0", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::seconds(5), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "05.00", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::seconds(5), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "05.6", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(600), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "05.60", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(600), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "05.600", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(600), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "05.67", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(670), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "05.670", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(670), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "05.678", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(678), tp); >+ } >+ >+ // Here is a "%E*S" case we got wrong for a while. The fractional >+ // part of the first instant is less than 2^31 and was correctly >+ // parsed, while the second (and any subsecond field >=2^31) failed. >+ time_point<chrono::nanoseconds> tp = unix_epoch; >+ EXPECT_TRUE(parse("%E*S", "0.2147483647", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse("%E*S", "0.2147483648", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); >+ >+ // We should also be able to specify long strings of digits far >+ // beyond the current resolution and have them convert the same way. >+ tp = unix_epoch; >+ EXPECT_TRUE(parse( >+ "%E*S", "0.214748364801234567890123456789012345678901234567890123456789", >+ tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); >+} >+ >+TEST(Parse, ExtendedSecondsScan) { >+ const time_zone tz = utc_time_zone(); >+ time_point<chrono::nanoseconds> tp; >+ for (int ms = 0; ms < 1000; ms += 111) { >+ for (int us = 0; us < 1000; us += 27) { >+ const int micros = ms * 1000 + us; >+ for (int ns = 0; ns < 1000; ns += 9) { >+ const auto expected = chrono::system_clock::from_time_t(0) + >+ chrono::nanoseconds(micros * 1000 + ns); >+ std::ostringstream oss; >+ oss << "0." << std::setfill('0') << std::setw(3); >+ oss << ms << std::setw(3) << us << std::setw(3) << ns; >+ const std::string input = oss.str(); >+ EXPECT_TRUE(parse("%E*S", input, tz, &tp)); >+ EXPECT_EQ(expected, tp) << input; >+ } >+ } >+ } >+} >+ >+TEST(Parse, ExtendedSubeconds) { >+ const time_zone tz = utc_time_zone(); >+ const time_point<chrono::nanoseconds> unix_epoch = >+ chrono::system_clock::from_time_t(0); >+ >+ // All %E<prec>f cases are treated the same as %E*f on input. >+ auto precisions = {"*", "0", "1", "2", "3", "4", "5", "6", "7", >+ "8", "9", "10", "11", "12", "13", "14", "15"}; >+ for (const std::string& prec : precisions) { >+ const std::string fmt = "%E" + prec + "f"; >+ SCOPED_TRACE(fmt); >+ time_point<chrono::nanoseconds> tp = unix_epoch - chrono::seconds(1); >+ EXPECT_TRUE(parse(fmt, "", tz, &tp)); >+ EXPECT_EQ(unix_epoch, tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "6", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::milliseconds(600), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "60", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::milliseconds(600), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "600", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::milliseconds(600), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "67", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::milliseconds(670), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "670", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::milliseconds(670), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "678", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::milliseconds(678), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse(fmt, "6789", tz, &tp)); >+ EXPECT_EQ( >+ unix_epoch + chrono::milliseconds(678) + chrono::microseconds(900), tp); >+ } >+ >+ // Here is a "%E*f" case we got wrong for a while. The fractional >+ // part of the first instant is less than 2^31 and was correctly >+ // parsed, while the second (and any subsecond field >=2^31) failed. >+ time_point<chrono::nanoseconds> tp = unix_epoch; >+ EXPECT_TRUE(parse("%E*f", "2147483647", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); >+ tp = unix_epoch; >+ EXPECT_TRUE(parse("%E*f", "2147483648", tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); >+ >+ // We should also be able to specify long strings of digits far >+ // beyond the current resolution and have them convert the same way. >+ tp = unix_epoch; >+ EXPECT_TRUE(parse( >+ "%E*f", "214748364801234567890123456789012345678901234567890123456789", >+ tz, &tp)); >+ EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); >+} >+ >+TEST(Parse, ExtendedSubecondsScan) { >+ time_point<chrono::nanoseconds> tp; >+ const time_zone tz = utc_time_zone(); >+ for (int ms = 0; ms < 1000; ms += 111) { >+ for (int us = 0; us < 1000; us += 27) { >+ const int micros = ms * 1000 + us; >+ for (int ns = 0; ns < 1000; ns += 9) { >+ std::ostringstream oss; >+ oss << std::setfill('0') << std::setw(3) << ms; >+ oss << std::setw(3) << us << std::setw(3) << ns; >+ const std::string nanos = oss.str(); >+ const auto expected = chrono::system_clock::from_time_t(0) + >+ chrono::nanoseconds(micros * 1000 + ns); >+ for (int ps = 0; ps < 1000; ps += 250) { >+ std::ostringstream oss; >+ oss << std::setfill('0') << std::setw(3) << ps; >+ const std::string input = nanos + oss.str() + "999"; >+ EXPECT_TRUE(parse("%E*f", input, tz, &tp)); >+ EXPECT_EQ(expected + chrono::nanoseconds(ps) / 1000, tp) << input; >+ } >+ } >+ } >+ } >+} >+ >+TEST(Parse, ExtendedOffset) { >+ const time_zone utc = utc_time_zone(); >+ time_point<absl::time_internal::cctz::seconds> tp; >+ >+ // %z against +-HHMM. >+ EXPECT_TRUE(parse("%z", "+0000", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%z", "-1234", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 0), utc), tp); >+ EXPECT_TRUE(parse("%z", "+1234", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 26, 0), utc), tp); >+ EXPECT_FALSE(parse("%z", "-123", utc, &tp)); >+ >+ // %z against +-HH. >+ EXPECT_TRUE(parse("%z", "+00", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%z", "-12", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%z", "+12", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 12, 0, 0), utc), tp); >+ EXPECT_FALSE(parse("%z", "-1", utc, &tp)); >+ >+ // %Ez against +-HH:MM. >+ EXPECT_TRUE(parse("%Ez", "+00:00", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%Ez", "-12:34", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 0), utc), tp); >+ EXPECT_TRUE(parse("%Ez", "+12:34", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 26, 0), utc), tp); >+ EXPECT_FALSE(parse("%Ez", "-12:3", utc, &tp)); >+ >+ // %Ez against +-HHMM. >+ EXPECT_TRUE(parse("%Ez", "+0000", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%Ez", "-1234", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 0), utc), tp); >+ EXPECT_TRUE(parse("%Ez", "+1234", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 26, 0), utc), tp); >+ EXPECT_FALSE(parse("%Ez", "-123", utc, &tp)); >+ >+ // %Ez against +-HH. >+ EXPECT_TRUE(parse("%Ez", "+00", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%Ez", "-12", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%Ez", "+12", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 12, 0, 0), utc), tp); >+ EXPECT_FALSE(parse("%Ez", "-1", utc, &tp)); >+} >+ >+TEST(Parse, ExtendedSecondOffset) { >+ const time_zone utc = utc_time_zone(); >+ time_point<absl::time_internal::cctz::seconds> tp; >+ >+ // %Ez against +-HH:MM:SS. >+ EXPECT_TRUE(parse("%Ez", "+00:00:00", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%Ez", "-12:34:56", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 56), utc), tp); >+ EXPECT_TRUE(parse("%Ez", "+12:34:56", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 25, 4), utc), tp); >+ EXPECT_FALSE(parse("%Ez", "-12:34:5", utc, &tp)); >+ >+ // %Ez against +-HHMMSS. >+ EXPECT_TRUE(parse("%Ez", "+000000", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%Ez", "-123456", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 56), utc), tp); >+ EXPECT_TRUE(parse("%Ez", "+123456", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 25, 4), utc), tp); >+ EXPECT_FALSE(parse("%Ez", "-12345", utc, &tp)); >+ >+ // %E*z against +-HH:MM:SS. >+ EXPECT_TRUE(parse("%E*z", "+00:00:00", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%E*z", "-12:34:56", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 56), utc), tp); >+ EXPECT_TRUE(parse("%E*z", "+12:34:56", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 25, 4), utc), tp); >+ EXPECT_FALSE(parse("%E*z", "-12:34:5", utc, &tp)); >+ >+ // %E*z against +-HHMMSS. >+ EXPECT_TRUE(parse("%E*z", "+000000", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%E*z", "-123456", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 56), utc), tp); >+ EXPECT_TRUE(parse("%E*z", "+123456", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 25, 4), utc), tp); >+ EXPECT_FALSE(parse("%E*z", "-12345", utc, &tp)); >+ >+ // %E*z against +-HH:MM. >+ EXPECT_TRUE(parse("%E*z", "+00:00", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%E*z", "-12:34", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 0), utc), tp); >+ EXPECT_TRUE(parse("%E*z", "+12:34", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 26, 0), utc), tp); >+ EXPECT_FALSE(parse("%E*z", "-12:3", utc, &tp)); >+ >+ // %E*z against +-HHMM. >+ EXPECT_TRUE(parse("%E*z", "+0000", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%E*z", "-1234", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 0), utc), tp); >+ EXPECT_TRUE(parse("%E*z", "+1234", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 26, 0), utc), tp); >+ EXPECT_FALSE(parse("%E*z", "-123", utc, &tp)); >+ >+ // %E*z against +-HH. >+ EXPECT_TRUE(parse("%E*z", "+00", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%E*z", "-12", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 0, 0), utc), tp); >+ EXPECT_TRUE(parse("%E*z", "+12", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1969, 12, 31, 12, 0, 0), utc), tp); >+ EXPECT_FALSE(parse("%E*z", "-1", utc, &tp)); >+} >+ >+TEST(Parse, ExtendedYears) { >+ const time_zone utc = utc_time_zone(); >+ const char e4y_fmt[] = "%E4Y%m%d"; // no separators >+ time_point<absl::time_internal::cctz::seconds> tp; >+ >+ // %E4Y consumes exactly four chars, including any sign. >+ EXPECT_TRUE(parse(e4y_fmt, "-9991127", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(-999, 11, 27, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse(e4y_fmt, "-0991127", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(-99, 11, 27, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse(e4y_fmt, "-0091127", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(-9, 11, 27, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse(e4y_fmt, "-0011127", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(-1, 11, 27, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse(e4y_fmt, "00001127", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(0, 11, 27, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse(e4y_fmt, "00011127", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(1, 11, 27, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse(e4y_fmt, "00091127", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(9, 11, 27, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse(e4y_fmt, "00991127", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(99, 11, 27, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse(e4y_fmt, "09991127", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(999, 11, 27, 0, 0, 0), utc), tp); >+ EXPECT_TRUE(parse(e4y_fmt, "99991127", utc, &tp)); >+ EXPECT_EQ(convert(civil_second(9999, 11, 27, 0, 0, 0), utc), tp); >+ >+ // When the year is outside [-999:9999], the parse fails. >+ EXPECT_FALSE(parse(e4y_fmt, "-10001127", utc, &tp)); >+ EXPECT_FALSE(parse(e4y_fmt, "100001127", utc, &tp)); >+} >+ >+TEST(Parse, RFC3339Format) { >+ const time_zone tz = utc_time_zone(); >+ time_point<chrono::nanoseconds> tp; >+ EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00+00:00", tz, &tp)); >+ ExpectTime(tp, tz, 2014, 2, 12, 20, 21, 0, 0, false, "UTC"); >+ >+ // Check that %Ez also accepts "Z" as a synonym for "+00:00". >+ time_point<chrono::nanoseconds> tp2; >+ EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp2)); >+ EXPECT_EQ(tp, tp2); >+} >+ >+TEST(Parse, MaxRange) { >+ const time_zone utc = utc_time_zone(); >+ time_point<absl::time_internal::cctz::seconds> tp; >+ >+ // tests the upper limit using +00:00 offset >+ EXPECT_TRUE( >+ parse(RFC3339_sec, "292277026596-12-04T15:30:07+00:00", utc, &tp)); >+ EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::max()); >+ EXPECT_FALSE( >+ parse(RFC3339_sec, "292277026596-12-04T15:30:08+00:00", utc, &tp)); >+ >+ // tests the upper limit using -01:00 offset >+ EXPECT_TRUE( >+ parse(RFC3339_sec, "292277026596-12-04T14:30:07-01:00", utc, &tp)); >+ EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::max()); >+ EXPECT_FALSE( >+ parse(RFC3339_sec, "292277026596-12-04T15:30:07-01:00", utc, &tp)); >+ >+ // tests the lower limit using +00:00 offset >+ EXPECT_TRUE( >+ parse(RFC3339_sec, "-292277022657-01-27T08:29:52+00:00", utc, &tp)); >+ EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::min()); >+ EXPECT_FALSE( >+ parse(RFC3339_sec, "-292277022657-01-27T08:29:51+00:00", utc, &tp)); >+ >+ // tests the lower limit using +01:00 offset >+ EXPECT_TRUE( >+ parse(RFC3339_sec, "-292277022657-01-27T09:29:52+01:00", utc, &tp)); >+ EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::min()); >+ EXPECT_FALSE( >+ parse(RFC3339_sec, "-292277022657-01-27T08:29:51+01:00", utc, &tp)); >+ >+ // tests max/min civil-second overflow >+ EXPECT_FALSE(parse(RFC3339_sec, "9223372036854775807-12-31T23:59:59-00:01", >+ utc, &tp)); >+ EXPECT_FALSE(parse(RFC3339_sec, "-9223372036854775808-01-01T00:00:00+00:01", >+ utc, &tp)); >+ >+ // TODO: Add tests that parsing times with fractional seconds overflow >+ // appropriately. This can't be done until cctz::parse() properly detects >+ // overflow when combining the chrono seconds and femto. >+} >+ >+// >+// Roundtrip test for format()/parse(). >+// >+ >+TEST(FormatParse, RoundTrip) { >+ time_zone lax; >+ EXPECT_TRUE(load_time_zone("America/Los_Angeles", &lax)); >+ const auto in = convert(civil_second(1977, 6, 28, 9, 8, 7), lax); >+ const auto subseconds = chrono::nanoseconds(654321); >+ >+ // RFC3339, which renders subseconds. >+ { >+ time_point<chrono::nanoseconds> out; >+ const std::string s = format(RFC3339_full, in + subseconds, lax); >+ EXPECT_TRUE(parse(RFC3339_full, s, lax, &out)) << s; >+ EXPECT_EQ(in + subseconds, out); // RFC3339_full includes %Ez >+ } >+ >+ // RFC1123, which only does whole seconds. >+ { >+ time_point<chrono::nanoseconds> out; >+ const std::string s = format(RFC1123_full, in, lax); >+ EXPECT_TRUE(parse(RFC1123_full, s, lax, &out)) << s; >+ EXPECT_EQ(in, out); // RFC1123_full includes %z >+ } >+ >+#if defined(_WIN32) || defined(_WIN64) >+ // Initial investigations indicate the %c does not roundtrip on Windows. >+ // TODO: Figure out what is going on here (perhaps a locale problem). >+#else >+ // Even though we don't know what %c will produce, it should roundtrip, >+ // but only in the 0-offset timezone. >+ { >+ time_point<chrono::nanoseconds> out; >+ time_zone utc = utc_time_zone(); >+ const std::string s = format("%c", in, utc); >+ EXPECT_TRUE(parse("%c", s, utc, &out)) << s; >+ EXPECT_EQ(in, out); >+ } >+#endif >+} >+ >+TEST(FormatParse, RoundTripDistantFuture) { >+ const time_zone utc = utc_time_zone(); >+ const time_point<absl::time_internal::cctz::seconds> in = time_point<absl::time_internal::cctz::seconds>::max(); >+ const std::string s = format(RFC3339_full, in, utc); >+ time_point<absl::time_internal::cctz::seconds> out; >+ EXPECT_TRUE(parse(RFC3339_full, s, utc, &out)) << s; >+ EXPECT_EQ(in, out); >+} >+ >+TEST(FormatParse, RoundTripDistantPast) { >+ const time_zone utc = utc_time_zone(); >+ const time_point<absl::time_internal::cctz::seconds> in = time_point<absl::time_internal::cctz::seconds>::min(); >+ const std::string s = format(RFC3339_full, in, utc); >+ time_point<absl::time_internal::cctz::seconds> out; >+ EXPECT_TRUE(parse(RFC3339_full, s, utc, &out)) << s; >+ EXPECT_EQ(in, out); >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..380834a172a8173b8a6a8a3260bff231da5a21da >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc >@@ -0,0 +1,41 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "time_zone_if.h" >+#include "time_zone_info.h" >+#include "time_zone_libc.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+std::unique_ptr<TimeZoneIf> TimeZoneIf::Load(const std::string& name) { >+ // Support "libc:localtime" and "libc:*" to access the legacy >+ // localtime and UTC support respectively from the C library. >+ if (name.compare(0, 5, "libc:") == 0) { >+ return std::unique_ptr<TimeZoneIf>(new TimeZoneLibC(name.substr(5))); >+ } >+ >+ // Otherwise use the "zoneinfo" implementation by default. >+ std::unique_ptr<TimeZoneInfo> tz(new TimeZoneInfo); >+ if (!tz->Load(name)) tz.reset(); >+ return std::unique_ptr<TimeZoneIf>(tz.release()); >+} >+ >+// Defined out-of-line to avoid emitting a weak vtable in all TUs. >+TimeZoneIf::~TimeZoneIf() {} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h >new file mode 100644 >index 0000000000000000000000000000000000000000..e4bd3866a87b8dd4da6566864db56d7fb7d6f90a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h >@@ -0,0 +1,72 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_ >+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_ >+ >+#include <chrono> >+#include <cstdint> >+#include <memory> >+#include <string> >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// A simple interface used to hide time-zone complexities from time_zone::Impl. >+// Subclasses implement the functions for civil-time conversions in the zone. >+class TimeZoneIf { >+ public: >+ // A factory function for TimeZoneIf implementations. >+ static std::unique_ptr<TimeZoneIf> Load(const std::string& name); >+ >+ virtual ~TimeZoneIf(); >+ >+ virtual time_zone::absolute_lookup BreakTime( >+ const time_point<seconds>& tp) const = 0; >+ virtual time_zone::civil_lookup MakeTime( >+ const civil_second& cs) const = 0; >+ >+ virtual bool NextTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const = 0; >+ virtual bool PrevTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const = 0; >+ >+ virtual std::string Version() const = 0; >+ virtual std::string Description() const = 0; >+ >+ protected: >+ TimeZoneIf() {} >+}; >+ >+// Convert between time_point<seconds> and a count of seconds since the >+// Unix epoch. We assume that the std::chrono::system_clock and the >+// Unix clock are second aligned, but not that they share an epoch. >+inline std::int_fast64_t ToUnixSeconds(const time_point<seconds>& tp) { >+ return (tp - std::chrono::time_point_cast<seconds>( >+ std::chrono::system_clock::from_time_t(0))).count(); >+} >+inline time_point<seconds> FromUnixSeconds(std::int_fast64_t t) { >+ return std::chrono::time_point_cast<seconds>( >+ std::chrono::system_clock::from_time_t(0)) + seconds(t); >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..3062ccd3ceb06afaf0b7762bd3e0dbf9b2f4f908 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc >@@ -0,0 +1,108 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "time_zone_impl.h" >+ >+#include <mutex> >+#include <string> >+#include <unordered_map> >+#include <utility> >+ >+#include "time_zone_fixed.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+namespace { >+ >+// time_zone::Impls are linked into a map to support fast lookup by name. >+using TimeZoneImplByName = >+ std::unordered_map<std::string, const time_zone::Impl*>; >+TimeZoneImplByName* time_zone_map = nullptr; >+ >+// Mutual exclusion for time_zone_map. >+std::mutex time_zone_mutex; >+ >+} // namespace >+ >+time_zone time_zone::Impl::UTC() { >+ return time_zone(UTCImpl()); >+} >+ >+bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { >+ const time_zone::Impl* const utc_impl = UTCImpl(); >+ >+ // First check for UTC (which is never a key in time_zone_map). >+ auto offset = seconds::zero(); >+ if (FixedOffsetFromName(name, &offset) && offset == seconds::zero()) { >+ *tz = time_zone(utc_impl); >+ return true; >+ } >+ >+ // Then check, under a shared lock, whether the time zone has already >+ // been loaded. This is the common path. TODO: Move to shared_mutex. >+ { >+ std::lock_guard<std::mutex> lock(time_zone_mutex); >+ if (time_zone_map != nullptr) { >+ TimeZoneImplByName::const_iterator itr = time_zone_map->find(name); >+ if (itr != time_zone_map->end()) { >+ *tz = time_zone(itr->second); >+ return itr->second != utc_impl; >+ } >+ } >+ } >+ >+ // Now check again, under an exclusive lock. >+ std::lock_guard<std::mutex> lock(time_zone_mutex); >+ if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName; >+ const Impl*& impl = (*time_zone_map)[name]; >+ if (impl == nullptr) { >+ // The first thread in loads the new time zone. >+ Impl* new_impl = new Impl(name); >+ new_impl->zone_ = TimeZoneIf::Load(new_impl->name_); >+ if (new_impl->zone_ == nullptr) { >+ delete new_impl; // free the nascent Impl >+ impl = utc_impl; // and fallback to UTC >+ } else { >+ impl = new_impl; // install new time zone >+ } >+ } >+ *tz = time_zone(impl); >+ return impl != utc_impl; >+} >+ >+void time_zone::Impl::ClearTimeZoneMapTestOnly() { >+ std::lock_guard<std::mutex> lock(time_zone_mutex); >+ if (time_zone_map != nullptr) { >+ // Existing time_zone::Impl* entries are in the wild, so we simply >+ // leak them. Future requests will result in reloading the data. >+ time_zone_map->clear(); >+ } >+} >+ >+time_zone::Impl::Impl(const std::string& name) : name_(name) {} >+ >+const time_zone::Impl* time_zone::Impl::UTCImpl() { >+ static Impl* utc_impl = [] { >+ Impl* impl = new Impl("UTC"); >+ impl->zone_ = TimeZoneIf::Load(impl->name_); // never fails >+ return impl; >+ }(); >+ return utc_impl; >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h >new file mode 100644 >index 0000000000000000000000000000000000000000..14965ef54bfb211b23b1341bcb06eb8ce2ce13e0 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h >@@ -0,0 +1,90 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_ >+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_ >+ >+#include <memory> >+#include <string> >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+#include "time_zone_if.h" >+#include "time_zone_info.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// time_zone::Impl is the internal object referenced by a cctz::time_zone. >+class time_zone::Impl { >+ public: >+ // The UTC time zone. Also used for other time zones that fail to load. >+ static time_zone UTC(); >+ >+ // Load a named time zone. Returns false if the name is invalid, or if >+ // some other kind of error occurs. Note that loading "UTC" never fails. >+ static bool LoadTimeZone(const std::string& name, time_zone* tz); >+ >+ // Clears the map of cached time zones. Primarily for use in benchmarks >+ // that gauge the performance of loading/parsing the time-zone data. >+ static void ClearTimeZoneMapTestOnly(); >+ >+ // The primary key is the time-zone ID (e.g., "America/New_York"). >+ const std::string& Name() const { >+ // TODO: It would nice if the zoneinfo data included the zone name. >+ return name_; >+ } >+ >+ // Breaks a time_point down to civil-time components in this time zone. >+ time_zone::absolute_lookup BreakTime(const time_point<seconds>& tp) const { >+ return zone_->BreakTime(tp); >+ } >+ >+ // Converts the civil-time components in this time zone into a time_point. >+ // That is, the opposite of BreakTime(). The requested civil time may be >+ // ambiguous or illegal due to a change of UTC offset. >+ time_zone::civil_lookup MakeTime(const civil_second& cs) const { >+ return zone_->MakeTime(cs); >+ } >+ >+ // Finds the time of the next/previous offset change in this time zone. >+ bool NextTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const { >+ return zone_->NextTransition(tp, trans); >+ } >+ bool PrevTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const { >+ return zone_->PrevTransition(tp, trans); >+ } >+ >+ // Returns an implementation-defined version std::string for this time zone. >+ std::string Version() const { return zone_->Version(); } >+ >+ // Returns an implementation-defined description of this time zone. >+ std::string Description() const { return zone_->Description(); } >+ >+ private: >+ explicit Impl(const std::string& name); >+ static const Impl* UTCImpl(); >+ >+ const std::string name_; >+ std::unique_ptr<TimeZoneIf> zone_; >+}; >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..bf73635d4c6a8c033b6e487925c41a2eab805184 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc >@@ -0,0 +1,976 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// This file implements the TimeZoneIf interface using the "zoneinfo" >+// data provided by the IANA Time Zone Database (i.e., the only real game >+// in town). >+// >+// TimeZoneInfo represents the history of UTC-offset changes within a time >+// zone. Most changes are due to daylight-saving rules, but occasionally >+// shifts are made to the time-zone's base offset. The database only attempts >+// to be definitive for times since 1970, so be wary of local-time conversions >+// before that. Also, rule and zone-boundary changes are made at the whim >+// of governments, so the conversion of future times needs to be taken with >+// a grain of salt. >+// >+// For more information see tzfile(5), http://www.iana.org/time-zones, or >+// http://en.wikipedia.org/wiki/Zoneinfo. >+// >+// Note that we assume the proleptic Gregorian calendar and 60-second >+// minutes throughout. >+ >+#include "time_zone_info.h" >+ >+#include <algorithm> >+#include <cassert> >+#include <chrono> >+#include <cstdint> >+#include <cstdio> >+#include <cstdlib> >+#include <cstring> >+#include <functional> >+#include <iostream> >+#include <memory> >+#include <sstream> >+#include <string> >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+#include "time_zone_fixed.h" >+#include "time_zone_posix.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+namespace { >+ >+inline bool IsLeap(year_t year) { >+ return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0); >+} >+ >+// The number of days in non-leap and leap years respectively. >+const std::int_least32_t kDaysPerYear[2] = {365, 366}; >+ >+// The day offsets of the beginning of each (1-based) month in non-leap and >+// leap years respectively (e.g., 335 days before December in a leap year). >+const std::int_least16_t kMonthOffsets[2][1 + 12 + 1] = { >+ {-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, >+ {-1, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}, >+}; >+ >+// We reject leap-second encoded zoneinfo and so assume 60-second minutes. >+const std::int_least32_t kSecsPerDay = 24 * 60 * 60; >+ >+// 400-year chunks always have 146097 days (20871 weeks). >+const std::int_least64_t kSecsPer400Years = 146097LL * kSecsPerDay; >+ >+// Like kDaysPerYear[] but scaled up by a factor of kSecsPerDay. >+const std::int_least32_t kSecsPerYear[2] = { >+ 365 * kSecsPerDay, >+ 366 * kSecsPerDay, >+}; >+ >+// Single-byte, unsigned numeric values are encoded directly. >+inline std::uint_fast8_t Decode8(const char* cp) { >+ return static_cast<std::uint_fast8_t>(*cp) & 0xff; >+} >+ >+// Multi-byte, numeric values are encoded using a MSB first, >+// twos-complement representation. These helpers decode, from >+// the given address, 4-byte and 8-byte values respectively. >+// Note: If int_fastXX_t == intXX_t and this machine is not >+// twos complement, then there will be at least one input value >+// we cannot represent. >+std::int_fast32_t Decode32(const char* cp) { >+ std::uint_fast32_t v = 0; >+ for (int i = 0; i != (32 / 8); ++i) v = (v << 8) | Decode8(cp++); >+ const std::int_fast32_t s32max = 0x7fffffff; >+ const auto s32maxU = static_cast<std::uint_fast32_t>(s32max); >+ if (v <= s32maxU) return static_cast<std::int_fast32_t>(v); >+ return static_cast<std::int_fast32_t>(v - s32maxU - 1) - s32max - 1; >+} >+ >+std::int_fast64_t Decode64(const char* cp) { >+ std::uint_fast64_t v = 0; >+ for (int i = 0; i != (64 / 8); ++i) v = (v << 8) | Decode8(cp++); >+ const std::int_fast64_t s64max = 0x7fffffffffffffff; >+ const auto s64maxU = static_cast<std::uint_fast64_t>(s64max); >+ if (v <= s64maxU) return static_cast<std::int_fast64_t>(v); >+ return static_cast<std::int_fast64_t>(v - s64maxU - 1) - s64max - 1; >+} >+ >+// Generate a year-relative offset for a PosixTransition. >+std::int_fast64_t TransOffset(bool leap_year, int jan1_weekday, >+ const PosixTransition& pt) { >+ std::int_fast64_t days = 0; >+ switch (pt.date.fmt) { >+ case PosixTransition::J: { >+ days = pt.date.j.day; >+ if (!leap_year || days < kMonthOffsets[1][3]) days -= 1; >+ break; >+ } >+ case PosixTransition::N: { >+ days = pt.date.n.day; >+ break; >+ } >+ case PosixTransition::M: { >+ const bool last_week = (pt.date.m.week == 5); >+ days = kMonthOffsets[leap_year][pt.date.m.month + last_week]; >+ const std::int_fast64_t weekday = (jan1_weekday + days) % 7; >+ if (last_week) { >+ days -= (weekday + 7 - 1 - pt.date.m.weekday) % 7 + 1; >+ } else { >+ days += (pt.date.m.weekday + 7 - weekday) % 7; >+ days += (pt.date.m.week - 1) * 7; >+ } >+ break; >+ } >+ } >+ return (days * kSecsPerDay) + pt.time.offset; >+} >+ >+inline time_zone::civil_lookup MakeUnique(const time_point<seconds>& tp) { >+ time_zone::civil_lookup cl; >+ cl.kind = time_zone::civil_lookup::UNIQUE; >+ cl.pre = cl.trans = cl.post = tp; >+ return cl; >+} >+ >+inline time_zone::civil_lookup MakeUnique(std::int_fast64_t unix_time) { >+ return MakeUnique(FromUnixSeconds(unix_time)); >+} >+ >+inline time_zone::civil_lookup MakeSkipped(const Transition& tr, >+ const civil_second& cs) { >+ time_zone::civil_lookup cl; >+ cl.kind = time_zone::civil_lookup::SKIPPED; >+ cl.pre = FromUnixSeconds(tr.unix_time - 1 + (cs - tr.prev_civil_sec)); >+ cl.trans = FromUnixSeconds(tr.unix_time); >+ cl.post = FromUnixSeconds(tr.unix_time - (tr.civil_sec - cs)); >+ return cl; >+} >+ >+inline time_zone::civil_lookup MakeRepeated(const Transition& tr, >+ const civil_second& cs) { >+ time_zone::civil_lookup cl; >+ cl.kind = time_zone::civil_lookup::REPEATED; >+ cl.pre = FromUnixSeconds(tr.unix_time - 1 - (tr.prev_civil_sec - cs)); >+ cl.trans = FromUnixSeconds(tr.unix_time); >+ cl.post = FromUnixSeconds(tr.unix_time + (cs - tr.civil_sec)); >+ return cl; >+} >+ >+inline civil_second YearShift(const civil_second& cs, year_t shift) { >+ return civil_second(cs.year() + shift, cs.month(), cs.day(), >+ cs.hour(), cs.minute(), cs.second()); >+} >+ >+} // namespace >+ >+// What (no leap-seconds) UTC+seconds zoneinfo would look like. >+bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) { >+ transition_types_.resize(1); >+ TransitionType& tt(transition_types_.back()); >+ tt.utc_offset = static_cast<std::int_least32_t>(offset.count()); >+ tt.is_dst = false; >+ tt.abbr_index = 0; >+ >+ // We temporarily add some redundant, contemporary (2013 through 2023) >+ // transitions for performance reasons. See TimeZoneInfo::LocalTime(). >+ // TODO: Fix the performance issue and remove the extra transitions. >+ transitions_.clear(); >+ transitions_.reserve(12); >+ for (const std::int_fast64_t unix_time : { >+ -(1LL << 59), // BIG_BANG >+ 1356998400LL, // 2013-01-01T00:00:00+00:00 >+ 1388534400LL, // 2014-01-01T00:00:00+00:00 >+ 1420070400LL, // 2015-01-01T00:00:00+00:00 >+ 1451606400LL, // 2016-01-01T00:00:00+00:00 >+ 1483228800LL, // 2017-01-01T00:00:00+00:00 >+ 1514764800LL, // 2018-01-01T00:00:00+00:00 >+ 1546300800LL, // 2019-01-01T00:00:00+00:00 >+ 1577836800LL, // 2020-01-01T00:00:00+00:00 >+ 1609459200LL, // 2021-01-01T00:00:00+00:00 >+ 1640995200LL, // 2022-01-01T00:00:00+00:00 >+ 1672531200LL, // 2023-01-01T00:00:00+00:00 >+ 2147483647LL, // 2^31 - 1 >+ }) { >+ Transition& tr(*transitions_.emplace(transitions_.end())); >+ tr.unix_time = unix_time; >+ tr.type_index = 0; >+ tr.civil_sec = LocalTime(tr.unix_time, tt).cs; >+ tr.prev_civil_sec = tr.civil_sec - 1; >+ } >+ >+ default_transition_type_ = 0; >+ abbreviations_ = FixedOffsetToAbbr(offset); >+ abbreviations_.append(1, '\0'); // add NUL >+ future_spec_.clear(); // never needed for a fixed-offset zone >+ extended_ = false; >+ >+ tt.civil_max = LocalTime(seconds::max().count(), tt).cs; >+ tt.civil_min = LocalTime(seconds::min().count(), tt).cs; >+ >+ transitions_.shrink_to_fit(); >+ return true; >+} >+ >+// Builds the in-memory header using the raw bytes from the file. >+bool TimeZoneInfo::Header::Build(const tzhead& tzh) { >+ std::int_fast32_t v; >+ if ((v = Decode32(tzh.tzh_timecnt)) < 0) return false; >+ timecnt = static_cast<std::size_t>(v); >+ if ((v = Decode32(tzh.tzh_typecnt)) < 0) return false; >+ typecnt = static_cast<std::size_t>(v); >+ if ((v = Decode32(tzh.tzh_charcnt)) < 0) return false; >+ charcnt = static_cast<std::size_t>(v); >+ if ((v = Decode32(tzh.tzh_leapcnt)) < 0) return false; >+ leapcnt = static_cast<std::size_t>(v); >+ if ((v = Decode32(tzh.tzh_ttisstdcnt)) < 0) return false; >+ ttisstdcnt = static_cast<std::size_t>(v); >+ if ((v = Decode32(tzh.tzh_ttisgmtcnt)) < 0) return false; >+ ttisgmtcnt = static_cast<std::size_t>(v); >+ return true; >+} >+ >+// How many bytes of data are associated with this header. The result >+// depends upon whether this is a section with 4-byte or 8-byte times. >+std::size_t TimeZoneInfo::Header::DataLength(std::size_t time_len) const { >+ std::size_t len = 0; >+ len += (time_len + 1) * timecnt; // unix_time + type_index >+ len += (4 + 1 + 1) * typecnt; // utc_offset + is_dst + abbr_index >+ len += 1 * charcnt; // abbreviations >+ len += (time_len + 4) * leapcnt; // leap-time + TAI-UTC >+ len += 1 * ttisstdcnt; // UTC/local indicators >+ len += 1 * ttisgmtcnt; // standard/wall indicators >+ return len; >+} >+ >+// Check that the TransitionType has the expected offset/is_dst/abbreviation. >+void TimeZoneInfo::CheckTransition(const std::string& name, >+ const TransitionType& tt, >+ std::int_fast32_t offset, bool is_dst, >+ const std::string& abbr) const { >+ if (tt.utc_offset != offset || tt.is_dst != is_dst || >+ &abbreviations_[tt.abbr_index] != abbr) { >+ std::clog << name << ": Transition" >+ << " offset=" << tt.utc_offset << "/" >+ << (tt.is_dst ? "DST" : "STD") >+ << "/abbr=" << &abbreviations_[tt.abbr_index] >+ << " does not match POSIX spec '" << future_spec_ << "'\n"; >+ } >+} >+ >+// zic(8) can generate no-op transitions when a zone changes rules at an >+// instant when there is actually no discontinuity. So we check whether >+// two transitions have equivalent types (same offset/is_dst/abbr). >+bool TimeZoneInfo::EquivTransitions(std::uint_fast8_t tt1_index, >+ std::uint_fast8_t tt2_index) const { >+ if (tt1_index == tt2_index) return true; >+ const TransitionType& tt1(transition_types_[tt1_index]); >+ const TransitionType& tt2(transition_types_[tt2_index]); >+ if (tt1.is_dst != tt2.is_dst) return false; >+ if (tt1.utc_offset != tt2.utc_offset) return false; >+ if (tt1.abbr_index != tt2.abbr_index) return false; >+ return true; >+} >+ >+// Use the POSIX-TZ-environment-variable-style std::string to handle times >+// in years after the last transition stored in the zoneinfo data. >+void TimeZoneInfo::ExtendTransitions(const std::string& name, >+ const Header& hdr) { >+ extended_ = false; >+ bool extending = !future_spec_.empty(); >+ >+ PosixTimeZone posix; >+ if (extending && !ParsePosixSpec(future_spec_, &posix)) { >+ std::clog << name << ": Failed to parse '" << future_spec_ << "'\n"; >+ extending = false; >+ } >+ >+ if (extending && posix.dst_abbr.empty()) { // std only >+ // The future specification should match the last/default transition, >+ // and that means that handling the future will fall out naturally. >+ std::uint_fast8_t index = default_transition_type_; >+ if (hdr.timecnt != 0) index = transitions_[hdr.timecnt - 1].type_index; >+ const TransitionType& tt(transition_types_[index]); >+ CheckTransition(name, tt, posix.std_offset, false, posix.std_abbr); >+ extending = false; >+ } >+ >+ if (extending && hdr.timecnt < 2) { >+ std::clog << name << ": Too few transitions for POSIX spec\n"; >+ extending = false; >+ } >+ >+ if (!extending) { >+ // Ensure that there is always a transition in the second half of the >+ // time line (the BIG_BANG transition is in the first half) so that the >+ // signed difference between a civil_second and the civil_second of its >+ // previous transition is always representable, without overflow. >+ const Transition& last(transitions_.back()); >+ if (last.unix_time < 0) { >+ const std::uint_fast8_t type_index = last.type_index; >+ Transition& tr(*transitions_.emplace(transitions_.end())); >+ tr.unix_time = 2147483647; // 2038-01-19T03:14:07+00:00 >+ tr.type_index = type_index; >+ } >+ return; // last transition wins >+ } >+ >+ // Extend the transitions for an additional 400 years using the >+ // future specification. Years beyond those can be handled by >+ // mapping back to a cycle-equivalent year within that range. >+ // zic(8) should probably do this so that we don't have to. >+ // TODO: Reduce the extension by the number of compatible >+ // transitions already in place. >+ transitions_.reserve(hdr.timecnt + 400 * 2 + 1); >+ transitions_.resize(hdr.timecnt + 400 * 2); >+ extended_ = true; >+ >+ // The future specification should match the last two transitions, >+ // and those transitions should have different is_dst flags. Note >+ // that nothing says the UTC offset used by the is_dst transition >+ // must be greater than that used by the !is_dst transition. (See >+ // Europe/Dublin, for example.) >+ const Transition* tr0 = &transitions_[hdr.timecnt - 1]; >+ const Transition* tr1 = &transitions_[hdr.timecnt - 2]; >+ const TransitionType* tt0 = &transition_types_[tr0->type_index]; >+ const TransitionType* tt1 = &transition_types_[tr1->type_index]; >+ const TransitionType& dst(tt0->is_dst ? *tt0 : *tt1); >+ const TransitionType& std(tt0->is_dst ? *tt1 : *tt0); >+ CheckTransition(name, dst, posix.dst_offset, true, posix.dst_abbr); >+ CheckTransition(name, std, posix.std_offset, false, posix.std_abbr); >+ >+ // Add the transitions to tr1 and back to tr0 for each extra year. >+ last_year_ = LocalTime(tr0->unix_time, *tt0).cs.year(); >+ bool leap_year = IsLeap(last_year_); >+ const civil_day jan1(last_year_, 1, 1); >+ std::int_fast64_t jan1_time = civil_second(jan1) - civil_second(); >+ int jan1_weekday = (static_cast<int>(get_weekday(jan1)) + 1) % 7; >+ Transition* tr = &transitions_[hdr.timecnt]; // next trans to fill >+ if (LocalTime(tr1->unix_time, *tt1).cs.year() != last_year_) { >+ // Add a single extra transition to align to a calendar year. >+ transitions_.resize(transitions_.size() + 1); >+ assert(tr == &transitions_[hdr.timecnt]); // no reallocation >+ const PosixTransition& pt1(tt0->is_dst ? posix.dst_end : posix.dst_start); >+ std::int_fast64_t tr1_offset = TransOffset(leap_year, jan1_weekday, pt1); >+ tr->unix_time = jan1_time + tr1_offset - tt0->utc_offset; >+ tr++->type_index = tr1->type_index; >+ tr0 = &transitions_[hdr.timecnt]; >+ tr1 = &transitions_[hdr.timecnt - 1]; >+ tt0 = &transition_types_[tr0->type_index]; >+ tt1 = &transition_types_[tr1->type_index]; >+ } >+ const PosixTransition& pt1(tt0->is_dst ? posix.dst_end : posix.dst_start); >+ const PosixTransition& pt0(tt0->is_dst ? posix.dst_start : posix.dst_end); >+ for (const year_t limit = last_year_ + 400; last_year_ < limit;) { >+ last_year_ += 1; // an additional year of generated transitions >+ jan1_time += kSecsPerYear[leap_year]; >+ jan1_weekday = (jan1_weekday + kDaysPerYear[leap_year]) % 7; >+ leap_year = !leap_year && IsLeap(last_year_); >+ std::int_fast64_t tr1_offset = TransOffset(leap_year, jan1_weekday, pt1); >+ tr->unix_time = jan1_time + tr1_offset - tt0->utc_offset; >+ tr++->type_index = tr1->type_index; >+ std::int_fast64_t tr0_offset = TransOffset(leap_year, jan1_weekday, pt0); >+ tr->unix_time = jan1_time + tr0_offset - tt1->utc_offset; >+ tr++->type_index = tr0->type_index; >+ } >+ assert(tr == &transitions_[0] + transitions_.size()); >+} >+ >+bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) { >+ // Read and validate the header. >+ tzhead tzh; >+ if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) >+ return false; >+ if (strncmp(tzh.tzh_magic, TZ_MAGIC, sizeof(tzh.tzh_magic)) != 0) >+ return false; >+ Header hdr; >+ if (!hdr.Build(tzh)) >+ return false; >+ std::size_t time_len = 4; >+ if (tzh.tzh_version[0] != '\0') { >+ // Skip the 4-byte data. >+ if (zip->Skip(hdr.DataLength(time_len)) != 0) >+ return false; >+ // Read and validate the header for the 8-byte data. >+ if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) >+ return false; >+ if (strncmp(tzh.tzh_magic, TZ_MAGIC, sizeof(tzh.tzh_magic)) != 0) >+ return false; >+ if (tzh.tzh_version[0] == '\0') >+ return false; >+ if (!hdr.Build(tzh)) >+ return false; >+ time_len = 8; >+ } >+ if (hdr.typecnt == 0) >+ return false; >+ if (hdr.leapcnt != 0) { >+ // This code assumes 60-second minutes so we do not want >+ // the leap-second encoded zoneinfo. We could reverse the >+ // compensation, but the "right" encoding is rarely used >+ // so currently we simply reject such data. >+ return false; >+ } >+ if (hdr.ttisstdcnt != 0 && hdr.ttisstdcnt != hdr.typecnt) >+ return false; >+ if (hdr.ttisgmtcnt != 0 && hdr.ttisgmtcnt != hdr.typecnt) >+ return false; >+ >+ // Read the data into a local buffer. >+ std::size_t len = hdr.DataLength(time_len); >+ std::vector<char> tbuf(len); >+ if (zip->Read(tbuf.data(), len) != len) >+ return false; >+ const char* bp = tbuf.data(); >+ >+ // Decode and validate the transitions. >+ transitions_.reserve(hdr.timecnt + 2); // We might add a couple. >+ transitions_.resize(hdr.timecnt); >+ for (std::size_t i = 0; i != hdr.timecnt; ++i) { >+ transitions_[i].unix_time = (time_len == 4) ? Decode32(bp) : Decode64(bp); >+ bp += time_len; >+ if (i != 0) { >+ // Check that the transitions are ordered by time (as zic guarantees). >+ if (!Transition::ByUnixTime()(transitions_[i - 1], transitions_[i])) >+ return false; // out of order >+ } >+ } >+ bool seen_type_0 = false; >+ for (std::size_t i = 0; i != hdr.timecnt; ++i) { >+ transitions_[i].type_index = Decode8(bp++); >+ if (transitions_[i].type_index >= hdr.typecnt) >+ return false; >+ if (transitions_[i].type_index == 0) >+ seen_type_0 = true; >+ } >+ >+ // Decode and validate the transition types. >+ transition_types_.resize(hdr.typecnt); >+ for (std::size_t i = 0; i != hdr.typecnt; ++i) { >+ transition_types_[i].utc_offset = >+ static_cast<std::int_least32_t>(Decode32(bp)); >+ if (transition_types_[i].utc_offset >= kSecsPerDay || >+ transition_types_[i].utc_offset <= -kSecsPerDay) >+ return false; >+ bp += 4; >+ transition_types_[i].is_dst = (Decode8(bp++) != 0); >+ transition_types_[i].abbr_index = Decode8(bp++); >+ if (transition_types_[i].abbr_index >= hdr.charcnt) >+ return false; >+ } >+ >+ // Determine the before-first-transition type. >+ default_transition_type_ = 0; >+ if (seen_type_0 && hdr.timecnt != 0) { >+ std::uint_fast8_t index = 0; >+ if (transition_types_[0].is_dst) { >+ index = transitions_[0].type_index; >+ while (index != 0 && transition_types_[index].is_dst) >+ --index; >+ } >+ while (index != hdr.typecnt && transition_types_[index].is_dst) >+ ++index; >+ if (index != hdr.typecnt) >+ default_transition_type_ = index; >+ } >+ >+ // Copy all the abbreviations. >+ abbreviations_.assign(bp, hdr.charcnt); >+ bp += hdr.charcnt; >+ >+ // Skip the unused portions. We've already dispensed with leap-second >+ // encoded zoneinfo. The ttisstd/ttisgmt indicators only apply when >+ // interpreting a POSIX spec that does not include start/end rules, and >+ // that isn't the case here (see "zic -p"). >+ bp += (8 + 4) * hdr.leapcnt; // leap-time + TAI-UTC >+ bp += 1 * hdr.ttisstdcnt; // UTC/local indicators >+ bp += 1 * hdr.ttisgmtcnt; // standard/wall indicators >+ assert(bp == tbuf.data() + tbuf.size()); >+ >+ future_spec_.clear(); >+ if (tzh.tzh_version[0] != '\0') { >+ // Snarf up the NL-enclosed future POSIX spec. Note >+ // that version '3' files utilize an extended format. >+ auto get_char = [](ZoneInfoSource* zip) -> int { >+ unsigned char ch; // all non-EOF results are positive >+ return (zip->Read(&ch, 1) == 1) ? ch : EOF; >+ }; >+ if (get_char(zip) != '\n') >+ return false; >+ for (int c = get_char(zip); c != '\n'; c = get_char(zip)) { >+ if (c == EOF) >+ return false; >+ future_spec_.push_back(static_cast<char>(c)); >+ } >+ } >+ >+ // We don't check for EOF so that we're forwards compatible. >+ >+ // If we did not find version information during the standard loading >+ // process (as of tzh_version '3' that is unsupported), then ask the >+ // ZoneInfoSource for any out-of-bound version std::string it may be privy to. >+ if (version_.empty()) { >+ version_ = zip->Version(); >+ } >+ >+ // Trim redundant transitions. zic may have added these to work around >+ // differences between the glibc and reference implementations (see >+ // zic.c:dontmerge) and the Qt library (see zic.c:WORK_AROUND_QTBUG_53071). >+ // For us, they just get in the way when we do future_spec_ extension. >+ while (hdr.timecnt > 1) { >+ if (!EquivTransitions(transitions_[hdr.timecnt - 1].type_index, >+ transitions_[hdr.timecnt - 2].type_index)) { >+ break; >+ } >+ hdr.timecnt -= 1; >+ } >+ transitions_.resize(hdr.timecnt); >+ >+ // Ensure that there is always a transition in the first half of the >+ // time line (the second half is handled in ExtendTransitions()) so that >+ // the signed difference between a civil_second and the civil_second of >+ // its previous transition is always representable, without overflow. >+ // A contemporary zic will usually have already done this for us. >+ if (transitions_.empty() || transitions_.front().unix_time >= 0) { >+ Transition& tr(*transitions_.emplace(transitions_.begin())); >+ tr.unix_time = -(1LL << 59); // see tz/zic.c "BIG_BANG" >+ tr.type_index = default_transition_type_; >+ hdr.timecnt += 1; >+ } >+ >+ // Extend the transitions using the future specification. >+ ExtendTransitions(name, hdr); >+ >+ // Compute the local civil time for each transition and the preceding >+ // second. These will be used for reverse conversions in MakeTime(). >+ const TransitionType* ttp = &transition_types_[default_transition_type_]; >+ for (std::size_t i = 0; i != transitions_.size(); ++i) { >+ Transition& tr(transitions_[i]); >+ tr.prev_civil_sec = LocalTime(tr.unix_time, *ttp).cs - 1; >+ ttp = &transition_types_[tr.type_index]; >+ tr.civil_sec = LocalTime(tr.unix_time, *ttp).cs; >+ if (i != 0) { >+ // Check that the transitions are ordered by civil time. Essentially >+ // this means that an offset change cannot cross another such change. >+ // No one does this in practice, and we depend on it in MakeTime(). >+ if (!Transition::ByCivilTime()(transitions_[i - 1], tr)) >+ return false; // out of order >+ } >+ } >+ >+ // Compute the maximum/minimum civil times that can be converted to a >+ // time_point<seconds> for each of the zone's transition types. >+ for (auto& tt : transition_types_) { >+ tt.civil_max = LocalTime(seconds::max().count(), tt).cs; >+ tt.civil_min = LocalTime(seconds::min().count(), tt).cs; >+ } >+ >+ transitions_.shrink_to_fit(); >+ return true; >+} >+ >+namespace { >+ >+// fopen(3) adaptor. >+inline FILE* FOpen(const char* path, const char* mode) { >+#if defined(_MSC_VER) >+ FILE* fp; >+ if (fopen_s(&fp, path, mode) != 0) fp = nullptr; >+ return fp; >+#else >+ return fopen(path, mode); // TODO: Enable the close-on-exec flag. >+#endif >+} >+ >+// A stdio(3)-backed implementation of ZoneInfoSource. >+class FileZoneInfoSource : public ZoneInfoSource { >+ public: >+ static std::unique_ptr<ZoneInfoSource> Open(const std::string& name); >+ >+ std::size_t Read(void* ptr, std::size_t size) override { >+ size = std::min(size, len_); >+ std::size_t nread = fread(ptr, 1, size, fp_.get()); >+ len_ -= nread; >+ return nread; >+ } >+ int Skip(std::size_t offset) override { >+ offset = std::min(offset, len_); >+ int rc = fseek(fp_.get(), static_cast<long>(offset), SEEK_CUR); >+ if (rc == 0) len_ -= offset; >+ return rc; >+ } >+ std::string Version() const override { >+ // TODO: It would nice if the zoneinfo data included the tzdb version. >+ return std::string(); >+ } >+ >+ protected: >+ explicit FileZoneInfoSource( >+ FILE* fp, std::size_t len = std::numeric_limits<std::size_t>::max()) >+ : fp_(fp, fclose), len_(len) {} >+ >+ private: >+ std::unique_ptr<FILE, int(*)(FILE*)> fp_; >+ std::size_t len_; >+}; >+ >+std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open( >+ const std::string& name) { >+ // Use of the "file:" prefix is intended for testing purposes only. >+ if (name.compare(0, 5, "file:") == 0) return Open(name.substr(5)); >+ >+ // Map the time-zone name to a path name. >+ std::string path; >+ if (name.empty() || name[0] != '/') { >+ const char* tzdir = "/usr/share/zoneinfo"; >+ char* tzdir_env = nullptr; >+#if defined(_MSC_VER) >+ _dupenv_s(&tzdir_env, nullptr, "TZDIR"); >+#else >+ tzdir_env = std::getenv("TZDIR"); >+#endif >+ if (tzdir_env && *tzdir_env) tzdir = tzdir_env; >+ path += tzdir; >+ path += '/'; >+#if defined(_MSC_VER) >+ free(tzdir_env); >+#endif >+ } >+ path += name; >+ >+ // Open the zoneinfo file. >+ FILE* fp = FOpen(path.c_str(), "rb"); >+ if (fp == nullptr) return nullptr; >+ std::size_t length = 0; >+ if (fseek(fp, 0, SEEK_END) == 0) { >+ long pos = ftell(fp); >+ if (pos >= 0) { >+ length = static_cast<std::size_t>(pos); >+ } >+ rewind(fp); >+ } >+ return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(fp, length)); >+} >+ >+class AndroidZoneInfoSource : public FileZoneInfoSource { >+ public: >+ static std::unique_ptr<ZoneInfoSource> Open(const std::string& name); >+ std::string Version() const override { return version_; } >+ >+ private: >+ explicit AndroidZoneInfoSource(FILE* fp, std::size_t len, const char* vers) >+ : FileZoneInfoSource(fp, len), version_(vers) {} >+ std::string version_; >+}; >+ >+std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( >+ const std::string& name) { >+ // Use of the "file:" prefix is intended for testing purposes only. >+ if (name.compare(0, 5, "file:") == 0) return Open(name.substr(5)); >+ >+#if defined(__ANDROID__) >+ // See Android's libc/tzcode/bionic.cpp for additional information. >+ for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata", >+ "/system/usr/share/zoneinfo/tzdata"}) { >+ std::unique_ptr<FILE, int (*)(FILE*)> fp(FOpen(tzdata, "rb"), fclose); >+ if (fp.get() == nullptr) continue; >+ >+ char hbuf[24]; // covers header.zonetab_offset too >+ if (fread(hbuf, 1, sizeof(hbuf), fp.get()) != sizeof(hbuf)) continue; >+ if (strncmp(hbuf, "tzdata", 6) != 0) continue; >+ const char* vers = (hbuf[11] == '\0') ? hbuf + 6 : ""; >+ const std::int_fast32_t index_offset = Decode32(hbuf + 12); >+ const std::int_fast32_t data_offset = Decode32(hbuf + 16); >+ if (index_offset < 0 || data_offset < index_offset) continue; >+ if (fseek(fp.get(), static_cast<long>(index_offset), SEEK_SET) != 0) >+ continue; >+ >+ char ebuf[52]; // covers entry.unused too >+ const std::size_t index_size = >+ static_cast<std::size_t>(data_offset - index_offset); >+ const std::size_t zonecnt = index_size / sizeof(ebuf); >+ if (zonecnt * sizeof(ebuf) != index_size) continue; >+ for (std::size_t i = 0; i != zonecnt; ++i) { >+ if (fread(ebuf, 1, sizeof(ebuf), fp.get()) != sizeof(ebuf)) break; >+ const std::int_fast32_t start = data_offset + Decode32(ebuf + 40); >+ const std::int_fast32_t length = Decode32(ebuf + 44); >+ if (start < 0 || length < 0) break; >+ ebuf[40] = '\0'; // ensure zone name is NUL terminated >+ if (strcmp(name.c_str(), ebuf) == 0) { >+ if (fseek(fp.get(), static_cast<long>(start), SEEK_SET) != 0) break; >+ return std::unique_ptr<ZoneInfoSource>(new AndroidZoneInfoSource( >+ fp.release(), static_cast<std::size_t>(length), vers)); >+ } >+ } >+ } >+#endif // __ANDROID__ >+ return nullptr; >+} >+ >+} // namespace >+ >+bool TimeZoneInfo::Load(const std::string& name) { >+ // We can ensure that the loading of UTC or any other fixed-offset >+ // zone never fails because the simple, fixed-offset state can be >+ // internally generated. Note that this depends on our choice to not >+ // accept leap-second encoded ("right") zoneinfo. >+ auto offset = seconds::zero(); >+ if (FixedOffsetFromName(name, &offset)) { >+ return ResetToBuiltinUTC(offset); >+ } >+ >+ // Find and use a ZoneInfoSource to load the named zone. >+ auto zip = cctz_extension::zone_info_source_factory( >+ name, [](const std::string& name) -> std::unique_ptr<ZoneInfoSource> { >+ if (auto zip = FileZoneInfoSource::Open(name)) return zip; >+ if (auto zip = AndroidZoneInfoSource::Open(name)) return zip; >+ return nullptr; >+ }); >+ return zip != nullptr && Load(name, zip.get()); >+} >+ >+// BreakTime() translation for a particular transition type. >+time_zone::absolute_lookup TimeZoneInfo::LocalTime( >+ std::int_fast64_t unix_time, const TransitionType& tt) const { >+ // A civil time in "+offset" looks like (time+offset) in UTC. >+ // Note: We perform two additions in the civil_second domain to >+ // sidestep the chance of overflow in (unix_time + tt.utc_offset). >+ return {(civil_second() + unix_time) + tt.utc_offset, >+ tt.utc_offset, tt.is_dst, &abbreviations_[tt.abbr_index]}; >+} >+ >+// BreakTime() translation for a particular transition. >+time_zone::absolute_lookup TimeZoneInfo::LocalTime( >+ std::int_fast64_t unix_time, const Transition& tr) const { >+ const TransitionType& tt = transition_types_[tr.type_index]; >+ // Note: (unix_time - tr.unix_time) will never overflow as we >+ // have ensured that there is always a "nearby" transition. >+ return {tr.civil_sec + (unix_time - tr.unix_time), // TODO: Optimize. >+ tt.utc_offset, tt.is_dst, &abbreviations_[tt.abbr_index]}; >+} >+ >+// MakeTime() translation with a conversion-preserving +N * 400-year shift. >+time_zone::civil_lookup TimeZoneInfo::TimeLocal(const civil_second& cs, >+ year_t c4_shift) const { >+ assert(last_year_ - 400 < cs.year() && cs.year() <= last_year_); >+ time_zone::civil_lookup cl = MakeTime(cs); >+ if (c4_shift > seconds::max().count() / kSecsPer400Years) { >+ cl.pre = cl.trans = cl.post = time_point<seconds>::max(); >+ } else { >+ const auto offset = seconds(c4_shift * kSecsPer400Years); >+ const auto limit = time_point<seconds>::max() - offset; >+ for (auto* tp : {&cl.pre, &cl.trans, &cl.post}) { >+ if (*tp > limit) { >+ *tp = time_point<seconds>::max(); >+ } else { >+ *tp += offset; >+ } >+ } >+ } >+ return cl; >+} >+ >+time_zone::absolute_lookup TimeZoneInfo::BreakTime( >+ const time_point<seconds>& tp) const { >+ std::int_fast64_t unix_time = ToUnixSeconds(tp); >+ const std::size_t timecnt = transitions_.size(); >+ assert(timecnt != 0); // We always add a transition. >+ >+ if (unix_time < transitions_[0].unix_time) { >+ return LocalTime(unix_time, transition_types_[default_transition_type_]); >+ } >+ if (unix_time >= transitions_[timecnt - 1].unix_time) { >+ // After the last transition. If we extended the transitions using >+ // future_spec_, shift back to a supported year using the 400-year >+ // cycle of calendaric equivalence and then compensate accordingly. >+ if (extended_) { >+ const std::int_fast64_t diff = >+ unix_time - transitions_[timecnt - 1].unix_time; >+ const year_t shift = diff / kSecsPer400Years + 1; >+ const auto d = seconds(shift * kSecsPer400Years); >+ time_zone::absolute_lookup al = BreakTime(tp - d); >+ al.cs = YearShift(al.cs, shift * 400); >+ return al; >+ } >+ return LocalTime(unix_time, transitions_[timecnt - 1]); >+ } >+ >+ const std::size_t hint = local_time_hint_.load(std::memory_order_relaxed); >+ if (0 < hint && hint < timecnt) { >+ if (transitions_[hint - 1].unix_time <= unix_time) { >+ if (unix_time < transitions_[hint].unix_time) { >+ return LocalTime(unix_time, transitions_[hint - 1]); >+ } >+ } >+ } >+ >+ const Transition target = {unix_time, 0, civil_second(), civil_second()}; >+ const Transition* begin = &transitions_[0]; >+ const Transition* tr = std::upper_bound(begin, begin + timecnt, target, >+ Transition::ByUnixTime()); >+ local_time_hint_.store(static_cast<std::size_t>(tr - begin), >+ std::memory_order_relaxed); >+ return LocalTime(unix_time, *--tr); >+} >+ >+time_zone::civil_lookup TimeZoneInfo::MakeTime(const civil_second& cs) const { >+ const std::size_t timecnt = transitions_.size(); >+ assert(timecnt != 0); // We always add a transition. >+ >+ // Find the first transition after our target civil time. >+ const Transition* tr = nullptr; >+ const Transition* begin = &transitions_[0]; >+ const Transition* end = begin + timecnt; >+ if (cs < begin->civil_sec) { >+ tr = begin; >+ } else if (cs >= transitions_[timecnt - 1].civil_sec) { >+ tr = end; >+ } else { >+ const std::size_t hint = time_local_hint_.load(std::memory_order_relaxed); >+ if (0 < hint && hint < timecnt) { >+ if (transitions_[hint - 1].civil_sec <= cs) { >+ if (cs < transitions_[hint].civil_sec) { >+ tr = begin + hint; >+ } >+ } >+ } >+ if (tr == nullptr) { >+ const Transition target = {0, 0, cs, civil_second()}; >+ tr = std::upper_bound(begin, end, target, Transition::ByCivilTime()); >+ time_local_hint_.store(static_cast<std::size_t>(tr - begin), >+ std::memory_order_relaxed); >+ } >+ } >+ >+ if (tr == begin) { >+ if (tr->prev_civil_sec >= cs) { >+ // Before first transition, so use the default offset. >+ const TransitionType& tt(transition_types_[default_transition_type_]); >+ if (cs < tt.civil_min) return MakeUnique(time_point<seconds>::min()); >+ return MakeUnique(cs - (civil_second() + tt.utc_offset)); >+ } >+ // tr->prev_civil_sec < cs < tr->civil_sec >+ return MakeSkipped(*tr, cs); >+ } >+ >+ if (tr == end) { >+ if (cs > (--tr)->prev_civil_sec) { >+ // After the last transition. If we extended the transitions using >+ // future_spec_, shift back to a supported year using the 400-year >+ // cycle of calendaric equivalence and then compensate accordingly. >+ if (extended_ && cs.year() > last_year_) { >+ const year_t shift = (cs.year() - last_year_ - 1) / 400 + 1; >+ return TimeLocal(YearShift(cs, shift * -400), shift); >+ } >+ const TransitionType& tt(transition_types_[tr->type_index]); >+ if (cs > tt.civil_max) return MakeUnique(time_point<seconds>::max()); >+ return MakeUnique(tr->unix_time + (cs - tr->civil_sec)); >+ } >+ // tr->civil_sec <= cs <= tr->prev_civil_sec >+ return MakeRepeated(*tr, cs); >+ } >+ >+ if (tr->prev_civil_sec < cs) { >+ // tr->prev_civil_sec < cs < tr->civil_sec >+ return MakeSkipped(*tr, cs); >+ } >+ >+ if (cs <= (--tr)->prev_civil_sec) { >+ // tr->civil_sec <= cs <= tr->prev_civil_sec >+ return MakeRepeated(*tr, cs); >+ } >+ >+ // In between transitions. >+ return MakeUnique(tr->unix_time + (cs - tr->civil_sec)); >+} >+ >+std::string TimeZoneInfo::Version() const { >+ return version_; >+} >+ >+std::string TimeZoneInfo::Description() const { >+ std::ostringstream oss; >+ oss << "#trans=" << transitions_.size(); >+ oss << " #types=" << transition_types_.size(); >+ oss << " spec='" << future_spec_ << "'"; >+ return oss.str(); >+} >+ >+bool TimeZoneInfo::NextTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const { >+ if (transitions_.empty()) return false; >+ const Transition* begin = &transitions_[0]; >+ const Transition* end = begin + transitions_.size(); >+ if (begin->unix_time <= -(1LL << 59)) { >+ // Do not report the BIG_BANG found in recent zoneinfo data as it is >+ // really a sentinel, not a transition. See tz/zic.c. >+ ++begin; >+ } >+ std::int_fast64_t unix_time = ToUnixSeconds(tp); >+ const Transition target = { unix_time }; >+ const Transition* tr = std::upper_bound(begin, end, target, >+ Transition::ByUnixTime()); >+ for (; tr != end; ++tr) { // skip no-op transitions >+ std::uint_fast8_t prev_type_index = >+ (tr == begin) ? default_transition_type_ : tr[-1].type_index; >+ if (!EquivTransitions(prev_type_index, tr[0].type_index)) break; >+ } >+ // When tr == end we return false, ignoring future_spec_. >+ if (tr == end) return false; >+ trans->from = tr->prev_civil_sec + 1; >+ trans->to = tr->civil_sec; >+ return true; >+} >+ >+bool TimeZoneInfo::PrevTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const { >+ if (transitions_.empty()) return false; >+ const Transition* begin = &transitions_[0]; >+ const Transition* end = begin + transitions_.size(); >+ if (begin->unix_time <= -(1LL << 59)) { >+ // Do not report the BIG_BANG found in recent zoneinfo data as it is >+ // really a sentinel, not a transition. See tz/zic.c. >+ ++begin; >+ } >+ std::int_fast64_t unix_time = ToUnixSeconds(tp); >+ if (FromUnixSeconds(unix_time) != tp) { >+ if (unix_time == std::numeric_limits<std::int_fast64_t>::max()) { >+ if (end == begin) return false; // Ignore future_spec_. >+ trans->from = (--end)->prev_civil_sec + 1; >+ trans->to = end->civil_sec; >+ return true; >+ } >+ unix_time += 1; // ceils >+ } >+ const Transition target = { unix_time }; >+ const Transition* tr = std::lower_bound(begin, end, target, >+ Transition::ByUnixTime()); >+ for (; tr != begin; --tr) { // skip no-op transitions >+ std::uint_fast8_t prev_type_index = >+ (tr - 1 == begin) ? default_transition_type_ : tr[-2].type_index; >+ if (!EquivTransitions(prev_type_index, tr[-1].type_index)) break; >+ } >+ // When tr == end we return the "last" transition, ignoring future_spec_. >+ if (tr == begin) return false; >+ trans->from = (--tr)->prev_civil_sec + 1; >+ trans->to = tr->civil_sec; >+ return true; >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h >new file mode 100644 >index 0000000000000000000000000000000000000000..958e9b6bd744d18c1d2ad8bbfcec99a0028de0b4 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h >@@ -0,0 +1,136 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_ >+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_ >+ >+#include <atomic> >+#include <cstddef> >+#include <cstdint> >+#include <string> >+#include <vector> >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+#include "absl/time/internal/cctz/include/cctz/zone_info_source.h" >+#include "time_zone_if.h" >+#include "tzfile.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// A transition to a new UTC offset. >+struct Transition { >+ std::int_least64_t unix_time; // the instant of this transition >+ std::uint_least8_t type_index; // index of the transition type >+ civil_second civil_sec; // local civil time of transition >+ civil_second prev_civil_sec; // local civil time one second earlier >+ >+ struct ByUnixTime { >+ inline bool operator()(const Transition& lhs, const Transition& rhs) const { >+ return lhs.unix_time < rhs.unix_time; >+ } >+ }; >+ struct ByCivilTime { >+ inline bool operator()(const Transition& lhs, const Transition& rhs) const { >+ return lhs.civil_sec < rhs.civil_sec; >+ } >+ }; >+}; >+ >+// The characteristics of a particular transition. >+struct TransitionType { >+ std::int_least32_t utc_offset; // the new prevailing UTC offset >+ civil_second civil_max; // max convertible civil time for offset >+ civil_second civil_min; // min convertible civil time for offset >+ bool is_dst; // did we move into daylight-saving time >+ std::uint_least8_t abbr_index; // index of the new abbreviation >+}; >+ >+// A time zone backed by the IANA Time Zone Database (zoneinfo). >+class TimeZoneInfo : public TimeZoneIf { >+ public: >+ TimeZoneInfo() = default; >+ TimeZoneInfo(const TimeZoneInfo&) = delete; >+ TimeZoneInfo& operator=(const TimeZoneInfo&) = delete; >+ >+ // Loads the zoneinfo for the given name, returning true if successful. >+ bool Load(const std::string& name); >+ >+ // TimeZoneIf implementations. >+ time_zone::absolute_lookup BreakTime( >+ const time_point<seconds>& tp) const override; >+ time_zone::civil_lookup MakeTime( >+ const civil_second& cs) const override; >+ bool NextTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const override; >+ bool PrevTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const override; >+ std::string Version() const override; >+ std::string Description() const override; >+ >+ private: >+ struct Header { // counts of: >+ std::size_t timecnt; // transition times >+ std::size_t typecnt; // transition types >+ std::size_t charcnt; // zone abbreviation characters >+ std::size_t leapcnt; // leap seconds (we expect none) >+ std::size_t ttisstdcnt; // UTC/local indicators (unused) >+ std::size_t ttisgmtcnt; // standard/wall indicators (unused) >+ >+ bool Build(const tzhead& tzh); >+ std::size_t DataLength(std::size_t time_len) const; >+ }; >+ >+ void CheckTransition(const std::string& name, const TransitionType& tt, >+ std::int_fast32_t offset, bool is_dst, >+ const std::string& abbr) const; >+ bool EquivTransitions(std::uint_fast8_t tt1_index, >+ std::uint_fast8_t tt2_index) const; >+ void ExtendTransitions(const std::string& name, const Header& hdr); >+ >+ bool ResetToBuiltinUTC(const seconds& offset); >+ bool Load(const std::string& name, ZoneInfoSource* zip); >+ >+ // Helpers for BreakTime() and MakeTime(). >+ time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, >+ const TransitionType& tt) const; >+ time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, >+ const Transition& tr) const; >+ time_zone::civil_lookup TimeLocal(const civil_second& cs, >+ year_t c4_shift) const; >+ >+ std::vector<Transition> transitions_; // ordered by unix_time and civil_sec >+ std::vector<TransitionType> transition_types_; // distinct transition types >+ std::uint_fast8_t default_transition_type_; // for before first transition >+ std::string abbreviations_; // all the NUL-terminated abbreviations >+ >+ std::string version_; // the tzdata version if available >+ std::string future_spec_; // for after the last zic transition >+ bool extended_; // future_spec_ was used to generate transitions >+ year_t last_year_; // the final year of the generated transitions >+ >+ // We remember the transitions found during the last BreakTime() and >+ // MakeTime() calls. If the next request is for the same transition we >+ // will avoid re-searching. >+ mutable std::atomic<std::size_t> local_time_hint_ = {}; // BreakTime() hint >+ mutable std::atomic<std::size_t> time_local_hint_ = {}; // MakeTime() hint >+}; >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..074c8d0a4a40e13982ab8a4e2b80bf63e13f9ae5 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc >@@ -0,0 +1,162 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#if defined(_WIN32) || defined(_WIN64) >+#define _CRT_SECURE_NO_WARNINGS 1 >+#endif >+ >+#include "time_zone_libc.h" >+ >+#include <chrono> >+#include <ctime> >+#include <tuple> >+#include <utility> >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+namespace { >+ >+// .first is seconds east of UTC; .second is the time-zone abbreviation. >+using OffsetAbbr = std::pair<int, const char*>; >+ >+// Defines a function that can be called as follows: >+// >+// std::tm tm = ...; >+// OffsetAbbr off_abbr = get_offset_abbr(tm); >+// >+#if defined(_WIN32) || defined(_WIN64) >+// Uses the globals: '_timezone', '_dstbias' and '_tzname'. >+OffsetAbbr get_offset_abbr(const std::tm& tm) { >+ const bool is_dst = tm.tm_isdst > 0; >+ const int off = _timezone + (is_dst ? _dstbias : 0); >+ const char* abbr = _tzname[is_dst]; >+ return {off, abbr}; >+} >+#elif defined(__sun) >+// Uses the globals: 'timezone', 'altzone' and 'tzname'. >+OffsetAbbr get_offset_abbr(const std::tm& tm) { >+ const bool is_dst = tm.tm_isdst > 0; >+ const int off = is_dst ? altzone : timezone; >+ const char* abbr = tzname[is_dst]; >+ return {off, abbr}; >+} >+#elif defined(__native_client__) || defined(__myriad2__) || \ >+ defined(__EMSCRIPTEN__) >+// Uses the globals: 'timezone' and 'tzname'. >+OffsetAbbr get_offset_abbr(const std::tm& tm) { >+ const bool is_dst = tm.tm_isdst > 0; >+ const int off = _timezone + (is_dst ? 60 * 60 : 0); >+ const char* abbr = tzname[is_dst]; >+ return {off, abbr}; >+} >+#else >+// >+// Returns an OffsetAbbr using std::tm fields with various spellings. >+// >+#if !defined(tm_gmtoff) && !defined(tm_zone) >+template <typename T> >+OffsetAbbr get_offset_abbr(const T& tm, decltype(&T::tm_gmtoff) = nullptr, >+ decltype(&T::tm_zone) = nullptr) { >+ return {tm.tm_gmtoff, tm.tm_zone}; >+} >+#endif // !defined(tm_gmtoff) && !defined(tm_zone) >+#if !defined(__tm_gmtoff) && !defined(__tm_zone) >+template <typename T> >+OffsetAbbr get_offset_abbr(const T& tm, decltype(&T::__tm_gmtoff) = nullptr, >+ decltype(&T::__tm_zone) = nullptr) { >+ return {tm.__tm_gmtoff, tm.__tm_zone}; >+} >+#endif // !defined(__tm_gmtoff) && !defined(__tm_zone) >+#endif >+ >+} // namespace >+ >+TimeZoneLibC::TimeZoneLibC(const std::string& name) >+ : local_(name == "localtime") {} >+ >+time_zone::absolute_lookup TimeZoneLibC::BreakTime( >+ const time_point<seconds>& tp) const { >+ time_zone::absolute_lookup al; >+ std::time_t t = ToUnixSeconds(tp); >+ std::tm tm; >+ if (local_) { >+#if defined(_WIN32) || defined(_WIN64) >+ localtime_s(&tm, &t); >+#else >+ localtime_r(&t, &tm); >+#endif >+ std::tie(al.offset, al.abbr) = get_offset_abbr(tm); >+ } else { >+#if defined(_WIN32) || defined(_WIN64) >+ gmtime_s(&tm, &t); >+#else >+ gmtime_r(&t, &tm); >+#endif >+ al.offset = 0; >+ al.abbr = "UTC"; >+ } >+ al.cs = civil_second(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, >+ tm.tm_hour, tm.tm_min, tm.tm_sec); >+ al.is_dst = tm.tm_isdst > 0; >+ return al; >+} >+ >+time_zone::civil_lookup TimeZoneLibC::MakeTime(const civil_second& cs) const { >+ time_zone::civil_lookup cl; >+ std::time_t t; >+ if (local_) { >+ // Does not handle SKIPPED/AMBIGUOUS or huge years. >+ std::tm tm; >+ tm.tm_year = static_cast<int>(cs.year() - 1900); >+ tm.tm_mon = cs.month() - 1; >+ tm.tm_mday = cs.day(); >+ tm.tm_hour = cs.hour(); >+ tm.tm_min = cs.minute(); >+ tm.tm_sec = cs.second(); >+ tm.tm_isdst = -1; >+ t = std::mktime(&tm); >+ } else { >+ t = cs - civil_second(); >+ } >+ cl.kind = time_zone::civil_lookup::UNIQUE; >+ cl.pre = cl.trans = cl.post = FromUnixSeconds(t); >+ return cl; >+} >+ >+bool TimeZoneLibC::NextTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const { >+ return false; >+} >+ >+bool TimeZoneLibC::PrevTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const { >+ return false; >+} >+ >+std::string TimeZoneLibC::Version() const { >+ return std::string(); // unknown >+} >+ >+std::string TimeZoneLibC::Description() const { >+ return local_ ? "localtime" : "UTC"; >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h >new file mode 100644 >index 0000000000000000000000000000000000000000..4e40c61ab243d2e3c77c62f71f4107f996e1d8e6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h >@@ -0,0 +1,53 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_ >+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_ >+ >+#include <string> >+ >+#include "time_zone_if.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// A time zone backed by gmtime_r(3), localtime_r(3), and mktime(3), >+// and which therefore only supports UTC and the local time zone. >+// TODO: Add support for fixed offsets from UTC. >+class TimeZoneLibC : public TimeZoneIf { >+ public: >+ explicit TimeZoneLibC(const std::string& name); >+ >+ // TimeZoneIf implementations. >+ time_zone::absolute_lookup BreakTime( >+ const time_point<seconds>& tp) const override; >+ time_zone::civil_lookup MakeTime( >+ const civil_second& cs) const override; >+ bool NextTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const override; >+ bool PrevTransition(const time_point<seconds>& tp, >+ time_zone::civil_transition* trans) const override; >+ std::string Version() const override; >+ std::string Description() const override; >+ >+ private: >+ const bool local_; // localtime or UTC >+}; >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..f2d151e4d5e562a00cd73da1ec0d9799e17f7277 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc >@@ -0,0 +1,168 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+ >+#if defined(__ANDROID__) >+#include <sys/system_properties.h> >+#if __ANDROID_API__ >= 21 >+#include <dlfcn.h> >+#endif >+#endif >+#include <cstdlib> >+#include <cstring> >+#include <string> >+ >+#include "time_zone_fixed.h" >+#include "time_zone_impl.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+#if defined(__ANDROID__) && __ANDROID_API__ >= 21 >+namespace { >+// Android 'L' removes __system_property_get() from the NDK, however >+// it is still a hidden symbol in libc so we use dlsym() to access it. >+// See Chromium's base/sys_info_android.cc for a similar example. >+ >+using property_get_func = int (*)(const char*, char*); >+ >+property_get_func LoadSystemPropertyGet() { >+ int flag = RTLD_LAZY | RTLD_GLOBAL; >+#if defined(RTLD_NOLOAD) >+ flag |= RTLD_NOLOAD; // libc.so should already be resident >+#endif >+ if (void* handle = dlopen("libc.so", flag)) { >+ void* sym = dlsym(handle, "__system_property_get"); >+ dlclose(handle); >+ return reinterpret_cast<property_get_func>(sym); >+ } >+ return nullptr; >+} >+ >+int __system_property_get(const char* name, char* value) { >+ static property_get_func system_property_get = LoadSystemPropertyGet(); >+ return system_property_get ? system_property_get(name, value) : -1; >+} >+ >+} // namespace >+#endif >+ >+std::string time_zone::name() const { >+ return effective_impl().Name(); >+} >+ >+time_zone::absolute_lookup time_zone::lookup( >+ const time_point<seconds>& tp) const { >+ return effective_impl().BreakTime(tp); >+} >+ >+time_zone::civil_lookup time_zone::lookup(const civil_second& cs) const { >+ return effective_impl().MakeTime(cs); >+} >+ >+bool time_zone::next_transition(const time_point<seconds>& tp, >+ civil_transition* trans) const { >+ return effective_impl().NextTransition(tp, trans); >+} >+ >+bool time_zone::prev_transition(const time_point<seconds>& tp, >+ civil_transition* trans) const { >+ return effective_impl().PrevTransition(tp, trans); >+} >+ >+std::string time_zone::version() const { >+ return effective_impl().Version(); >+} >+ >+std::string time_zone::description() const { >+ return effective_impl().Description(); >+} >+ >+const time_zone::Impl& time_zone::effective_impl() const { >+ if (impl_ == nullptr) { >+ // Dereferencing an implicit-UTC time_zone is expected to be >+ // rare, so we don't mind paying a small synchronization cost. >+ return *time_zone::Impl::UTC().impl_; >+ } >+ return *impl_; >+} >+ >+bool load_time_zone(const std::string& name, time_zone* tz) { >+ return time_zone::Impl::LoadTimeZone(name, tz); >+} >+ >+time_zone utc_time_zone() { >+ return time_zone::Impl::UTC(); // avoid name lookup >+} >+ >+time_zone fixed_time_zone(const seconds& offset) { >+ time_zone tz; >+ load_time_zone(FixedOffsetToName(offset), &tz); >+ return tz; >+} >+ >+time_zone local_time_zone() { >+ const char* zone = ":localtime"; >+ >+ // Allow ${TZ} to override to default zone. >+ char* tz_env = nullptr; >+#if defined(_MSC_VER) >+ _dupenv_s(&tz_env, nullptr, "TZ"); >+#else >+ tz_env = std::getenv("TZ"); >+#endif >+#if defined(__ANDROID__) >+ char sysprop[PROP_VALUE_MAX]; >+ if (tz_env == nullptr) >+ if (__system_property_get("persist.sys.timezone", sysprop) > 0) >+ tz_env = sysprop; >+#endif >+ if (tz_env) zone = tz_env; >+ >+ // We only support the "[:]<zone-name>" form. >+ if (*zone == ':') ++zone; >+ >+ // Map "localtime" to a system-specific name, but >+ // allow ${LOCALTIME} to override the default name. >+ char* localtime_env = nullptr; >+ if (strcmp(zone, "localtime") == 0) { >+#if defined(_MSC_VER) >+ // System-specific default is just "localtime". >+ _dupenv_s(&localtime_env, nullptr, "LOCALTIME"); >+#else >+ zone = "/etc/localtime"; // System-specific default. >+ localtime_env = std::getenv("LOCALTIME"); >+#endif >+ if (localtime_env) zone = localtime_env; >+ } >+ >+ const std::string name = zone; >+#if defined(_MSC_VER) >+ free(localtime_env); >+ free(tz_env); >+#endif >+ >+ time_zone tz; >+ load_time_zone(name, &tz); // Falls back to UTC. >+ // TODO: Follow the RFC3339 "Unknown Local Offset Convention" and >+ // arrange for %z to generate "-0000" when we don't know the local >+ // offset because the load_time_zone() failed and we're using UTC. >+ return tz; >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..551292fb55e0882d2bbeb1178289540f2e99841c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc >@@ -0,0 +1,1331 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+ >+#include <chrono> >+#include <cstddef> >+#include <future> >+#include <string> >+#include <thread> >+#include <vector> >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+#include "gtest/gtest.h" >+ >+namespace chrono = std::chrono; >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+namespace { >+ >+// A list of known time-zone names. >+const char* const kTimeZoneNames[] = { >+ "Africa/Abidjan", >+ "Africa/Accra", >+ "Africa/Addis_Ababa", >+ "Africa/Algiers", >+ "Africa/Asmara", >+ "Africa/Asmera", >+ "Africa/Bamako", >+ "Africa/Bangui", >+ "Africa/Banjul", >+ "Africa/Bissau", >+ "Africa/Blantyre", >+ "Africa/Brazzaville", >+ "Africa/Bujumbura", >+ "Africa/Cairo", >+ "Africa/Casablanca", >+ "Africa/Ceuta", >+ "Africa/Conakry", >+ "Africa/Dakar", >+ "Africa/Dar_es_Salaam", >+ "Africa/Djibouti", >+ "Africa/Douala", >+ "Africa/El_Aaiun", >+ "Africa/Freetown", >+ "Africa/Gaborone", >+ "Africa/Harare", >+ "Africa/Johannesburg", >+ "Africa/Juba", >+ "Africa/Kampala", >+ "Africa/Khartoum", >+ "Africa/Kigali", >+ "Africa/Kinshasa", >+ "Africa/Lagos", >+ "Africa/Libreville", >+ "Africa/Lome", >+ "Africa/Luanda", >+ "Africa/Lubumbashi", >+ "Africa/Lusaka", >+ "Africa/Malabo", >+ "Africa/Maputo", >+ "Africa/Maseru", >+ "Africa/Mbabane", >+ "Africa/Mogadishu", >+ "Africa/Monrovia", >+ "Africa/Nairobi", >+ "Africa/Ndjamena", >+ "Africa/Niamey", >+ "Africa/Nouakchott", >+ "Africa/Ouagadougou", >+ "Africa/Porto-Novo", >+ "Africa/Sao_Tome", >+ "Africa/Timbuktu", >+ "Africa/Tripoli", >+ "Africa/Tunis", >+ "Africa/Windhoek", >+ "America/Adak", >+ "America/Anchorage", >+ "America/Anguilla", >+ "America/Antigua", >+ "America/Araguaina", >+ "America/Argentina/Buenos_Aires", >+ "America/Argentina/Catamarca", >+ "America/Argentina/ComodRivadavia", >+ "America/Argentina/Cordoba", >+ "America/Argentina/Jujuy", >+ "America/Argentina/La_Rioja", >+ "America/Argentina/Mendoza", >+ "America/Argentina/Rio_Gallegos", >+ "America/Argentina/Salta", >+ "America/Argentina/San_Juan", >+ "America/Argentina/San_Luis", >+ "America/Argentina/Tucuman", >+ "America/Argentina/Ushuaia", >+ "America/Aruba", >+ "America/Asuncion", >+ "America/Atikokan", >+ "America/Atka", >+ "America/Bahia", >+ "America/Bahia_Banderas", >+ "America/Barbados", >+ "America/Belem", >+ "America/Belize", >+ "America/Blanc-Sablon", >+ "America/Boa_Vista", >+ "America/Bogota", >+ "America/Boise", >+ "America/Buenos_Aires", >+ "America/Cambridge_Bay", >+ "America/Campo_Grande", >+ "America/Cancun", >+ "America/Caracas", >+ "America/Catamarca", >+ "America/Cayenne", >+ "America/Cayman", >+ "America/Chicago", >+ "America/Chihuahua", >+ "America/Coral_Harbour", >+ "America/Cordoba", >+ "America/Costa_Rica", >+ "America/Creston", >+ "America/Cuiaba", >+ "America/Curacao", >+ "America/Danmarkshavn", >+ "America/Dawson", >+ "America/Dawson_Creek", >+ "America/Denver", >+ "America/Detroit", >+ "America/Dominica", >+ "America/Edmonton", >+ "America/Eirunepe", >+ "America/El_Salvador", >+ "America/Ensenada", >+ "America/Fort_Nelson", >+ "America/Fort_Wayne", >+ "America/Fortaleza", >+ "America/Glace_Bay", >+ "America/Godthab", >+ "America/Goose_Bay", >+ "America/Grand_Turk", >+ "America/Grenada", >+ "America/Guadeloupe", >+ "America/Guatemala", >+ "America/Guayaquil", >+ "America/Guyana", >+ "America/Halifax", >+ "America/Havana", >+ "America/Hermosillo", >+ "America/Indiana/Indianapolis", >+ "America/Indiana/Knox", >+ "America/Indiana/Marengo", >+ "America/Indiana/Petersburg", >+ "America/Indiana/Tell_City", >+ "America/Indiana/Vevay", >+ "America/Indiana/Vincennes", >+ "America/Indiana/Winamac", >+ "America/Indianapolis", >+ "America/Inuvik", >+ "America/Iqaluit", >+ "America/Jamaica", >+ "America/Jujuy", >+ "America/Juneau", >+ "America/Kentucky/Louisville", >+ "America/Kentucky/Monticello", >+ "America/Knox_IN", >+ "America/Kralendijk", >+ "America/La_Paz", >+ "America/Lima", >+ "America/Los_Angeles", >+ "America/Louisville", >+ "America/Lower_Princes", >+ "America/Maceio", >+ "America/Managua", >+ "America/Manaus", >+ "America/Marigot", >+ "America/Martinique", >+ "America/Matamoros", >+ "America/Mazatlan", >+ "America/Mendoza", >+ "America/Menominee", >+ "America/Merida", >+ "America/Metlakatla", >+ "America/Mexico_City", >+ "America/Miquelon", >+ "America/Moncton", >+ "America/Monterrey", >+ "America/Montevideo", >+ "America/Montreal", >+ "America/Montserrat", >+ "America/Nassau", >+ "America/New_York", >+ "America/Nipigon", >+ "America/Nome", >+ "America/Noronha", >+ "America/North_Dakota/Beulah", >+ "America/North_Dakota/Center", >+ "America/North_Dakota/New_Salem", >+ "America/Ojinaga", >+ "America/Panama", >+ "America/Pangnirtung", >+ "America/Paramaribo", >+ "America/Phoenix", >+ "America/Port-au-Prince", >+ "America/Port_of_Spain", >+ "America/Porto_Acre", >+ "America/Porto_Velho", >+ "America/Puerto_Rico", >+ "America/Punta_Arenas", >+ "America/Rainy_River", >+ "America/Rankin_Inlet", >+ "America/Recife", >+ "America/Regina", >+ "America/Resolute", >+ "America/Rio_Branco", >+ "America/Rosario", >+ "America/Santa_Isabel", >+ "America/Santarem", >+ "America/Santiago", >+ "America/Santo_Domingo", >+ "America/Sao_Paulo", >+ "America/Scoresbysund", >+ "America/Shiprock", >+ "America/Sitka", >+ "America/St_Barthelemy", >+ "America/St_Johns", >+ "America/St_Kitts", >+ "America/St_Lucia", >+ "America/St_Thomas", >+ "America/St_Vincent", >+ "America/Swift_Current", >+ "America/Tegucigalpa", >+ "America/Thule", >+ "America/Thunder_Bay", >+ "America/Tijuana", >+ "America/Toronto", >+ "America/Tortola", >+ "America/Vancouver", >+ "America/Virgin", >+ "America/Whitehorse", >+ "America/Winnipeg", >+ "America/Yakutat", >+ "America/Yellowknife", >+ "Antarctica/Casey", >+ "Antarctica/Davis", >+ "Antarctica/DumontDUrville", >+ "Antarctica/Macquarie", >+ "Antarctica/Mawson", >+ "Antarctica/McMurdo", >+ "Antarctica/Palmer", >+ "Antarctica/Rothera", >+ "Antarctica/South_Pole", >+ "Antarctica/Syowa", >+ "Antarctica/Troll", >+ "Antarctica/Vostok", >+ "Arctic/Longyearbyen", >+ "Asia/Aden", >+ "Asia/Almaty", >+ "Asia/Amman", >+ "Asia/Anadyr", >+ "Asia/Aqtau", >+ "Asia/Aqtobe", >+ "Asia/Ashgabat", >+ "Asia/Ashkhabad", >+ "Asia/Atyrau", >+ "Asia/Baghdad", >+ "Asia/Bahrain", >+ "Asia/Baku", >+ "Asia/Bangkok", >+ "Asia/Barnaul", >+ "Asia/Beirut", >+ "Asia/Bishkek", >+ "Asia/Brunei", >+ "Asia/Calcutta", >+ "Asia/Chita", >+ "Asia/Choibalsan", >+ "Asia/Chongqing", >+ "Asia/Chungking", >+ "Asia/Colombo", >+ "Asia/Dacca", >+ "Asia/Damascus", >+ "Asia/Dhaka", >+ "Asia/Dili", >+ "Asia/Dubai", >+ "Asia/Dushanbe", >+ "Asia/Famagusta", >+ "Asia/Gaza", >+ "Asia/Harbin", >+ "Asia/Hebron", >+ "Asia/Ho_Chi_Minh", >+ "Asia/Hong_Kong", >+ "Asia/Hovd", >+ "Asia/Irkutsk", >+ "Asia/Istanbul", >+ "Asia/Jakarta", >+ "Asia/Jayapura", >+ "Asia/Jerusalem", >+ "Asia/Kabul", >+ "Asia/Kamchatka", >+ "Asia/Karachi", >+ "Asia/Kashgar", >+ "Asia/Kathmandu", >+ "Asia/Katmandu", >+ "Asia/Khandyga", >+ "Asia/Kolkata", >+ "Asia/Krasnoyarsk", >+ "Asia/Kuala_Lumpur", >+ "Asia/Kuching", >+ "Asia/Kuwait", >+ "Asia/Macao", >+ "Asia/Macau", >+ "Asia/Magadan", >+ "Asia/Makassar", >+ "Asia/Manila", >+ "Asia/Muscat", >+ "Asia/Nicosia", >+ "Asia/Novokuznetsk", >+ "Asia/Novosibirsk", >+ "Asia/Omsk", >+ "Asia/Oral", >+ "Asia/Phnom_Penh", >+ "Asia/Pontianak", >+ "Asia/Pyongyang", >+ "Asia/Qatar", >+ "Asia/Qyzylorda", >+ "Asia/Rangoon", >+ "Asia/Riyadh", >+ "Asia/Saigon", >+ "Asia/Sakhalin", >+ "Asia/Samarkand", >+ "Asia/Seoul", >+ "Asia/Shanghai", >+ "Asia/Singapore", >+ "Asia/Srednekolymsk", >+ "Asia/Taipei", >+ "Asia/Tashkent", >+ "Asia/Tbilisi", >+ "Asia/Tehran", >+ "Asia/Tel_Aviv", >+ "Asia/Thimbu", >+ "Asia/Thimphu", >+ "Asia/Tokyo", >+ "Asia/Tomsk", >+ "Asia/Ujung_Pandang", >+ "Asia/Ulaanbaatar", >+ "Asia/Ulan_Bator", >+ "Asia/Urumqi", >+ "Asia/Ust-Nera", >+ "Asia/Vientiane", >+ "Asia/Vladivostok", >+ "Asia/Yakutsk", >+ "Asia/Yangon", >+ "Asia/Yekaterinburg", >+ "Asia/Yerevan", >+ "Atlantic/Azores", >+ "Atlantic/Bermuda", >+ "Atlantic/Canary", >+ "Atlantic/Cape_Verde", >+ "Atlantic/Faeroe", >+ "Atlantic/Faroe", >+ "Atlantic/Jan_Mayen", >+ "Atlantic/Madeira", >+ "Atlantic/Reykjavik", >+ "Atlantic/South_Georgia", >+ "Atlantic/St_Helena", >+ "Atlantic/Stanley", >+ "Australia/ACT", >+ "Australia/Adelaide", >+ "Australia/Brisbane", >+ "Australia/Broken_Hill", >+ "Australia/Canberra", >+ "Australia/Currie", >+ "Australia/Darwin", >+ "Australia/Eucla", >+ "Australia/Hobart", >+ "Australia/LHI", >+ "Australia/Lindeman", >+ "Australia/Lord_Howe", >+ "Australia/Melbourne", >+ "Australia/NSW", >+ "Australia/North", >+ "Australia/Perth", >+ "Australia/Queensland", >+ "Australia/South", >+ "Australia/Sydney", >+ "Australia/Tasmania", >+ "Australia/Victoria", >+ "Australia/West", >+ "Australia/Yancowinna", >+ "Brazil/Acre", >+ "Brazil/DeNoronha", >+ "Brazil/East", >+ "Brazil/West", >+ "CET", >+ "CST6CDT", >+ "Canada/Atlantic", >+ "Canada/Central", >+ "Canada/Eastern", >+ "Canada/Mountain", >+ "Canada/Newfoundland", >+ "Canada/Pacific", >+ "Canada/Saskatchewan", >+ "Canada/Yukon", >+ "Chile/Continental", >+ "Chile/EasterIsland", >+ "Cuba", >+ "EET", >+ "EST", >+ "EST5EDT", >+ "Egypt", >+ "Eire", >+ "Etc/GMT", >+ "Etc/GMT+0", >+ "Etc/GMT+1", >+ "Etc/GMT+10", >+ "Etc/GMT+11", >+ "Etc/GMT+12", >+ "Etc/GMT+2", >+ "Etc/GMT+3", >+ "Etc/GMT+4", >+ "Etc/GMT+5", >+ "Etc/GMT+6", >+ "Etc/GMT+7", >+ "Etc/GMT+8", >+ "Etc/GMT+9", >+ "Etc/GMT-0", >+ "Etc/GMT-1", >+ "Etc/GMT-10", >+ "Etc/GMT-11", >+ "Etc/GMT-12", >+ "Etc/GMT-13", >+ "Etc/GMT-14", >+ "Etc/GMT-2", >+ "Etc/GMT-3", >+ "Etc/GMT-4", >+ "Etc/GMT-5", >+ "Etc/GMT-6", >+ "Etc/GMT-7", >+ "Etc/GMT-8", >+ "Etc/GMT-9", >+ "Etc/GMT0", >+ "Etc/Greenwich", >+ "Etc/UCT", >+ "Etc/UTC", >+ "Etc/Universal", >+ "Etc/Zulu", >+ "Europe/Amsterdam", >+ "Europe/Andorra", >+ "Europe/Astrakhan", >+ "Europe/Athens", >+ "Europe/Belfast", >+ "Europe/Belgrade", >+ "Europe/Berlin", >+ "Europe/Bratislava", >+ "Europe/Brussels", >+ "Europe/Bucharest", >+ "Europe/Budapest", >+ "Europe/Busingen", >+ "Europe/Chisinau", >+ "Europe/Copenhagen", >+ "Europe/Dublin", >+ "Europe/Gibraltar", >+ "Europe/Guernsey", >+ "Europe/Helsinki", >+ "Europe/Isle_of_Man", >+ "Europe/Istanbul", >+ "Europe/Jersey", >+ "Europe/Kaliningrad", >+ "Europe/Kiev", >+ "Europe/Kirov", >+ "Europe/Lisbon", >+ "Europe/Ljubljana", >+ "Europe/London", >+ "Europe/Luxembourg", >+ "Europe/Madrid", >+ "Europe/Malta", >+ "Europe/Mariehamn", >+ "Europe/Minsk", >+ "Europe/Monaco", >+ "Europe/Moscow", >+ "Europe/Nicosia", >+ "Europe/Oslo", >+ "Europe/Paris", >+ "Europe/Podgorica", >+ "Europe/Prague", >+ "Europe/Riga", >+ "Europe/Rome", >+ "Europe/Samara", >+ "Europe/San_Marino", >+ "Europe/Sarajevo", >+ "Europe/Saratov", >+ "Europe/Simferopol", >+ "Europe/Skopje", >+ "Europe/Sofia", >+ "Europe/Stockholm", >+ "Europe/Tallinn", >+ "Europe/Tirane", >+ "Europe/Tiraspol", >+ "Europe/Ulyanovsk", >+ "Europe/Uzhgorod", >+ "Europe/Vaduz", >+ "Europe/Vatican", >+ "Europe/Vienna", >+ "Europe/Vilnius", >+ "Europe/Volgograd", >+ "Europe/Warsaw", >+ "Europe/Zagreb", >+ "Europe/Zaporozhye", >+ "Europe/Zurich", >+ "GB", >+ "GB-Eire", >+ "GMT", >+ "GMT+0", >+ "GMT-0", >+ "GMT0", >+ "Greenwich", >+ "HST", >+ "Hongkong", >+ "Iceland", >+ "Indian/Antananarivo", >+ "Indian/Chagos", >+ "Indian/Christmas", >+ "Indian/Cocos", >+ "Indian/Comoro", >+ "Indian/Kerguelen", >+ "Indian/Mahe", >+ "Indian/Maldives", >+ "Indian/Mauritius", >+ "Indian/Mayotte", >+ "Indian/Reunion", >+ "Iran", >+ "Israel", >+ "Jamaica", >+ "Japan", >+ "Kwajalein", >+ "Libya", >+ "MET", >+ "MST", >+ "MST7MDT", >+ "Mexico/BajaNorte", >+ "Mexico/BajaSur", >+ "Mexico/General", >+ "NZ", >+ "NZ-CHAT", >+ "Navajo", >+ "PRC", >+ "PST8PDT", >+ "Pacific/Apia", >+ "Pacific/Auckland", >+ "Pacific/Bougainville", >+ "Pacific/Chatham", >+ "Pacific/Chuuk", >+ "Pacific/Easter", >+ "Pacific/Efate", >+ "Pacific/Enderbury", >+ "Pacific/Fakaofo", >+ "Pacific/Fiji", >+ "Pacific/Funafuti", >+ "Pacific/Galapagos", >+ "Pacific/Gambier", >+ "Pacific/Guadalcanal", >+ "Pacific/Guam", >+ "Pacific/Honolulu", >+ "Pacific/Johnston", >+ "Pacific/Kiritimati", >+ "Pacific/Kosrae", >+ "Pacific/Kwajalein", >+ "Pacific/Majuro", >+ "Pacific/Marquesas", >+ "Pacific/Midway", >+ "Pacific/Nauru", >+ "Pacific/Niue", >+ "Pacific/Norfolk", >+ "Pacific/Noumea", >+ "Pacific/Pago_Pago", >+ "Pacific/Palau", >+ "Pacific/Pitcairn", >+ "Pacific/Pohnpei", >+ "Pacific/Ponape", >+ "Pacific/Port_Moresby", >+ "Pacific/Rarotonga", >+ "Pacific/Saipan", >+ "Pacific/Samoa", >+ "Pacific/Tahiti", >+ "Pacific/Tarawa", >+ "Pacific/Tongatapu", >+ "Pacific/Truk", >+ "Pacific/Wake", >+ "Pacific/Wallis", >+ "Pacific/Yap", >+ "Poland", >+ "Portugal", >+ "ROC", >+ "ROK", >+ "Singapore", >+ "Turkey", >+ "UCT", >+ "US/Alaska", >+ "US/Aleutian", >+ "US/Arizona", >+ "US/Central", >+ "US/East-Indiana", >+ "US/Eastern", >+ "US/Hawaii", >+ "US/Indiana-Starke", >+ "US/Michigan", >+ "US/Mountain", >+ "US/Pacific", >+ "US/Samoa", >+ "UTC", >+ "Universal", >+ "W-SU", >+ "WET", >+ "Zulu", >+ nullptr >+}; >+ >+// Helper to return a loaded time zone by value (UTC on error). >+time_zone LoadZone(const std::string& name) { >+ time_zone tz; >+ load_time_zone(name, &tz); >+ return tz; >+} >+ >+// This helper is a macro so that failed expectations show up with the >+// correct line numbers. >+#define ExpectTime(tp, tz, y, m, d, hh, mm, ss, off, isdst, zone) \ >+ do { \ >+ time_zone::absolute_lookup al = tz.lookup(tp); \ >+ EXPECT_EQ(y, al.cs.year()); \ >+ EXPECT_EQ(m, al.cs.month()); \ >+ EXPECT_EQ(d, al.cs.day()); \ >+ EXPECT_EQ(hh, al.cs.hour()); \ >+ EXPECT_EQ(mm, al.cs.minute()); \ >+ EXPECT_EQ(ss, al.cs.second()); \ >+ EXPECT_EQ(off, al.offset); \ >+ EXPECT_TRUE(isdst == al.is_dst); \ >+ /* EXPECT_STREQ(zone, al.abbr); */ \ >+ } while (0) >+ >+// These tests sometimes run on platforms that have zoneinfo data so old >+// that the transition we are attempting to check does not exist, most >+// notably Android emulators. Fortunately, AndroidZoneInfoSource supports >+// time_zone::version() so, in cases where we've learned that it matters, >+// we can make the check conditionally. >+int VersionCmp(time_zone tz, const std::string& target) { >+ std::string version = tz.version(); >+ if (version.empty() && !target.empty()) return 1; // unknown > known >+ return version.compare(target); >+} >+ >+} // namespace >+ >+TEST(TimeZones, LoadZonesConcurrently) { >+ std::promise<void> ready_promise; >+ std::shared_future<void> ready_future(ready_promise.get_future()); >+ auto load_zones = [ready_future](std::promise<void>* started, >+ std::set<std::string>* failures) { >+ started->set_value(); >+ ready_future.wait(); >+ for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) { >+ std::string zone = *np; >+ time_zone tz; >+ if (load_time_zone(zone, &tz)) { >+ EXPECT_EQ(zone, tz.name()); >+ } else { >+ failures->insert(zone); >+ } >+ } >+ }; >+ >+ const std::size_t n_threads = 128; >+ std::vector<std::thread> threads; >+ std::vector<std::set<std::string>> thread_failures(n_threads); >+ for (std::size_t i = 0; i != n_threads; ++i) { >+ std::promise<void> started; >+ threads.emplace_back(load_zones, &started, &thread_failures[i]); >+ started.get_future().wait(); >+ } >+ ready_promise.set_value(); >+ for (auto& thread : threads) { >+ thread.join(); >+ } >+ >+ // Allow a small number of failures to account for skew between >+ // the contents of kTimeZoneNames and the zoneinfo data source. >+#if defined(__ANDROID__) >+ // Cater to the possibility of using an even older zoneinfo data >+ // source when running on Android, where it is difficult to override >+ // the bionic tzdata provided by the test environment. >+ const std::size_t max_failures = 20; >+#else >+ const std::size_t max_failures = 3; >+#endif >+ std::set<std::string> failures; >+ for (const auto& thread_failure : thread_failures) { >+ failures.insert(thread_failure.begin(), thread_failure.end()); >+ } >+ EXPECT_LE(failures.size(), max_failures) << testing::PrintToString(failures); >+} >+ >+TEST(TimeZone, NamedTimeZones) { >+ const time_zone utc = utc_time_zone(); >+ EXPECT_EQ("UTC", utc.name()); >+ const time_zone nyc = LoadZone("America/New_York"); >+ EXPECT_EQ("America/New_York", nyc.name()); >+ const time_zone syd = LoadZone("Australia/Sydney"); >+ EXPECT_EQ("Australia/Sydney", syd.name()); >+ const time_zone fixed0 = fixed_time_zone(absl::time_internal::cctz::seconds::zero()); >+ EXPECT_EQ("UTC", fixed0.name()); >+ const time_zone fixed_pos = fixed_time_zone( >+ chrono::hours(3) + chrono::minutes(25) + chrono::seconds(45)); >+ EXPECT_EQ("Fixed/UTC+03:25:45", fixed_pos.name()); >+ const time_zone fixed_neg = fixed_time_zone( >+ -(chrono::hours(12) + chrono::minutes(34) + chrono::seconds(56))); >+ EXPECT_EQ("Fixed/UTC-12:34:56", fixed_neg.name()); >+} >+ >+TEST(TimeZone, Failures) { >+ time_zone tz; >+ EXPECT_FALSE(load_time_zone(":America/Los_Angeles", &tz)); >+ >+ tz = LoadZone("America/Los_Angeles"); >+ EXPECT_FALSE(load_time_zone("Invalid/TimeZone", &tz)); >+ EXPECT_EQ(chrono::system_clock::from_time_t(0), >+ convert(civil_second(1970, 1, 1, 0, 0, 0), tz)); // UTC >+ >+ // Ensures that the load still fails on a subsequent attempt. >+ tz = LoadZone("America/Los_Angeles"); >+ EXPECT_FALSE(load_time_zone("Invalid/TimeZone", &tz)); >+ EXPECT_EQ(chrono::system_clock::from_time_t(0), >+ convert(civil_second(1970, 1, 1, 0, 0, 0), tz)); // UTC >+ >+ // Loading an empty std::string timezone should fail. >+ tz = LoadZone("America/Los_Angeles"); >+ EXPECT_FALSE(load_time_zone("", &tz)); >+ EXPECT_EQ(chrono::system_clock::from_time_t(0), >+ convert(civil_second(1970, 1, 1, 0, 0, 0), tz)); // UTC >+} >+ >+TEST(TimeZone, Equality) { >+ const time_zone a; >+ const time_zone b; >+ EXPECT_EQ(a, b); >+ EXPECT_EQ(a.name(), b.name()); >+ >+ const time_zone implicit_utc; >+ const time_zone explicit_utc = utc_time_zone(); >+ EXPECT_EQ(implicit_utc, explicit_utc); >+ EXPECT_EQ(implicit_utc.name(), explicit_utc.name()); >+ >+ const time_zone fixed_zero = fixed_time_zone(absl::time_internal::cctz::seconds::zero()); >+ EXPECT_EQ(fixed_zero, LoadZone(fixed_zero.name())); >+ EXPECT_EQ(fixed_zero, explicit_utc); >+ >+ const time_zone fixed_utc = LoadZone("Fixed/UTC+00:00:00"); >+ EXPECT_EQ(fixed_utc, LoadZone(fixed_utc.name())); >+ EXPECT_EQ(fixed_utc, explicit_utc); >+ >+ const time_zone fixed_pos = fixed_time_zone( >+ chrono::hours(3) + chrono::minutes(25) + chrono::seconds(45)); >+ EXPECT_EQ(fixed_pos, LoadZone(fixed_pos.name())); >+ EXPECT_NE(fixed_pos, explicit_utc); >+ const time_zone fixed_neg = fixed_time_zone( >+ -(chrono::hours(12) + chrono::minutes(34) + chrono::seconds(56))); >+ EXPECT_EQ(fixed_neg, LoadZone(fixed_neg.name())); >+ EXPECT_NE(fixed_neg, explicit_utc); >+ >+ const time_zone fixed_lim = fixed_time_zone(chrono::hours(24)); >+ EXPECT_EQ(fixed_lim, LoadZone(fixed_lim.name())); >+ EXPECT_NE(fixed_lim, explicit_utc); >+ const time_zone fixed_ovfl = >+ fixed_time_zone(chrono::hours(24) + chrono::seconds(1)); >+ EXPECT_EQ(fixed_ovfl, LoadZone(fixed_ovfl.name())); >+ EXPECT_EQ(fixed_ovfl, explicit_utc); >+ >+ EXPECT_EQ(fixed_time_zone(chrono::seconds(1)), >+ fixed_time_zone(chrono::seconds(1))); >+ >+ const time_zone local = local_time_zone(); >+ EXPECT_EQ(local, LoadZone(local.name())); >+ >+ time_zone la = LoadZone("America/Los_Angeles"); >+ time_zone nyc = LoadZone("America/New_York"); >+ EXPECT_NE(la, nyc); >+} >+ >+TEST(StdChronoTimePoint, TimeTAlignment) { >+ // Ensures that the Unix epoch and the system clock epoch are an integral >+ // number of seconds apart. This simplifies conversions to/from time_t. >+ auto diff = chrono::system_clock::time_point() - >+ chrono::system_clock::from_time_t(0); >+ EXPECT_EQ(chrono::system_clock::time_point::duration::zero(), >+ diff % chrono::seconds(1)); >+} >+ >+TEST(BreakTime, TimePointResolution) { >+ const time_zone utc = utc_time_zone(); >+ const auto t0 = chrono::system_clock::from_time_t(0); >+ >+ ExpectTime(chrono::time_point_cast<chrono::nanoseconds>(t0), utc, >+ 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); >+ ExpectTime(chrono::time_point_cast<chrono::microseconds>(t0), utc, >+ 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); >+ ExpectTime(chrono::time_point_cast<chrono::milliseconds>(t0), utc, >+ 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); >+ ExpectTime(chrono::time_point_cast<chrono::seconds>(t0), utc, >+ 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); >+ ExpectTime(chrono::time_point_cast<absl::time_internal::cctz::seconds>(t0), utc, >+ 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); >+ ExpectTime(chrono::time_point_cast<chrono::minutes>(t0), utc, >+ 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); >+ ExpectTime(chrono::time_point_cast<chrono::hours>(t0), utc, >+ 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); >+} >+ >+TEST(BreakTime, LocalTimeInUTC) { >+ const time_zone tz = utc_time_zone(); >+ const auto tp = chrono::system_clock::from_time_t(0); >+ ExpectTime(tp, tz, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); >+ EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz)))); >+} >+ >+TEST(BreakTime, LocalTimeInUTCUnaligned) { >+ const time_zone tz = utc_time_zone(); >+ const auto tp = >+ chrono::system_clock::from_time_t(0) - chrono::milliseconds(500); >+ ExpectTime(tp, tz, 1969, 12, 31, 23, 59, 59, 0, false, "UTC"); >+ EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); >+} >+ >+TEST(BreakTime, LocalTimePosix) { >+ // See IEEE Std 1003.1-1988 B.2.3 General Terms, Epoch. >+ const time_zone tz = utc_time_zone(); >+ const auto tp = chrono::system_clock::from_time_t(536457599); >+ ExpectTime(tp, tz, 1986, 12, 31, 23, 59, 59, 0, false, "UTC"); >+ EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); >+} >+ >+TEST(TimeZoneImpl, LocalTimeInFixed) { >+ const absl::time_internal::cctz::seconds offset = >+ -(chrono::hours(8) + chrono::minutes(33) + chrono::seconds(47)); >+ const time_zone tz = fixed_time_zone(offset); >+ const auto tp = chrono::system_clock::from_time_t(0); >+ ExpectTime(tp, tz, 1969, 12, 31, 15, 26, 13, offset.count(), false, >+ "-083347"); >+ EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); >+} >+ >+TEST(BreakTime, LocalTimeInNewYork) { >+ const time_zone tz = LoadZone("America/New_York"); >+ const auto tp = chrono::system_clock::from_time_t(45); >+ ExpectTime(tp, tz, 1969, 12, 31, 19, 0, 45, -5 * 60 * 60, false, "EST"); >+ EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); >+} >+ >+TEST(BreakTime, LocalTimeInMTV) { >+ const time_zone tz = LoadZone("America/Los_Angeles"); >+ const auto tp = chrono::system_clock::from_time_t(1380855729); >+ ExpectTime(tp, tz, 2013, 10, 3, 20, 2, 9, -7 * 60 * 60, true, "PDT"); >+ EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz)))); >+} >+ >+TEST(BreakTime, LocalTimeInSydney) { >+ const time_zone tz = LoadZone("Australia/Sydney"); >+ const auto tp = chrono::system_clock::from_time_t(90); >+ ExpectTime(tp, tz, 1970, 1, 1, 10, 1, 30, 10 * 60 * 60, false, "AEST"); >+ EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz)))); >+} >+ >+TEST(MakeTime, TimePointResolution) { >+ const time_zone utc = utc_time_zone(); >+ const time_point<chrono::nanoseconds> tp_ns = >+ convert(civil_second(2015, 1, 2, 3, 4, 5), utc); >+ EXPECT_EQ("04:05", format("%M:%E*S", tp_ns, utc)); >+ const time_point<chrono::microseconds> tp_us = >+ convert(civil_second(2015, 1, 2, 3, 4, 5), utc); >+ EXPECT_EQ("04:05", format("%M:%E*S", tp_us, utc)); >+ const time_point<chrono::milliseconds> tp_ms = >+ convert(civil_second(2015, 1, 2, 3, 4, 5), utc); >+ EXPECT_EQ("04:05", format("%M:%E*S", tp_ms, utc)); >+ const time_point<chrono::seconds> tp_s = >+ convert(civil_second(2015, 1, 2, 3, 4, 5), utc); >+ EXPECT_EQ("04:05", format("%M:%E*S", tp_s, utc)); >+ const time_point<absl::time_internal::cctz::seconds> tp_s64 = >+ convert(civil_second(2015, 1, 2, 3, 4, 5), utc); >+ EXPECT_EQ("04:05", format("%M:%E*S", tp_s64, utc)); >+ >+ // These next two require chrono::time_point_cast because the conversion >+ // from a resolution of seconds (the return value of convert()) to a >+ // coarser resolution requires an explicit cast. >+ const time_point<chrono::minutes> tp_m = >+ chrono::time_point_cast<chrono::minutes>( >+ convert(civil_second(2015, 1, 2, 3, 4, 5), utc)); >+ EXPECT_EQ("04:00", format("%M:%E*S", tp_m, utc)); >+ const time_point<chrono::hours> tp_h = >+ chrono::time_point_cast<chrono::hours>( >+ convert(civil_second(2015, 1, 2, 3, 4, 5), utc)); >+ EXPECT_EQ("00:00", format("%M:%E*S", tp_h, utc)); >+} >+ >+TEST(MakeTime, Normalization) { >+ const time_zone tz = LoadZone("America/New_York"); >+ const auto tp = convert(civil_second(2009, 2, 13, 18, 31, 30), tz); >+ EXPECT_EQ(chrono::system_clock::from_time_t(1234567890), tp); >+ >+ // Now requests for the same time_point but with out-of-range fields. >+ EXPECT_EQ(tp, convert(civil_second(2008, 14, 13, 18, 31, 30), tz)); // month >+ EXPECT_EQ(tp, convert(civil_second(2009, 1, 44, 18, 31, 30), tz)); // day >+ EXPECT_EQ(tp, convert(civil_second(2009, 2, 12, 42, 31, 30), tz)); // hour >+ EXPECT_EQ(tp, convert(civil_second(2009, 2, 13, 17, 91, 30), tz)); // minute >+ EXPECT_EQ(tp, convert(civil_second(2009, 2, 13, 18, 30, 90), tz)); // second >+} >+ >+// NOTE: Run this with --copt=-ftrapv to detect overflow problems. >+TEST(MakeTime, SysSecondsLimits) { >+ const char RFC3339[] = "%Y-%m-%dT%H:%M:%S%Ez"; >+ const time_zone utc = utc_time_zone(); >+ const time_zone east = fixed_time_zone(chrono::hours(14)); >+ const time_zone west = fixed_time_zone(-chrono::hours(14)); >+ time_point<absl::time_internal::cctz::seconds> tp; >+ >+ // Approach the maximal time_point<cctz::seconds> value from below. >+ tp = convert(civil_second(292277026596, 12, 4, 15, 30, 6), utc); >+ EXPECT_EQ("292277026596-12-04T15:30:06+00:00", format(RFC3339, tp, utc)); >+ tp = convert(civil_second(292277026596, 12, 4, 15, 30, 7), utc); >+ EXPECT_EQ("292277026596-12-04T15:30:07+00:00", format(RFC3339, tp, utc)); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); >+ tp = convert(civil_second(292277026596, 12, 4, 15, 30, 8), utc); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); >+ tp = convert(civil_second::max(), utc); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); >+ >+ // Checks that we can also get the maximal value for a far-east zone. >+ tp = convert(civil_second(292277026596, 12, 5, 5, 30, 7), east); >+ EXPECT_EQ("292277026596-12-05T05:30:07+14:00", format(RFC3339, tp, east)); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); >+ tp = convert(civil_second(292277026596, 12, 5, 5, 30, 8), east); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); >+ tp = convert(civil_second::max(), east); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); >+ >+ // Checks that we can also get the maximal value for a far-west zone. >+ tp = convert(civil_second(292277026596, 12, 4, 1, 30, 7), west); >+ EXPECT_EQ("292277026596-12-04T01:30:07-14:00", format(RFC3339, tp, west)); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); >+ tp = convert(civil_second(292277026596, 12, 4, 7, 30, 8), west); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); >+ tp = convert(civil_second::max(), west); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); >+ >+ // Approach the minimal time_point<cctz::seconds> value from above. >+ tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 53), utc); >+ EXPECT_EQ("-292277022657-01-27T08:29:53+00:00", format(RFC3339, tp, utc)); >+ tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 52), utc); >+ EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", format(RFC3339, tp, utc)); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); >+ tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 51), utc); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); >+ tp = convert(civil_second::min(), utc); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); >+ >+ // Checks that we can also get the minimal value for a far-east zone. >+ tp = convert(civil_second(-292277022657, 1, 27, 22, 29, 52), east); >+ EXPECT_EQ("-292277022657-01-27T22:29:52+14:00", format(RFC3339, tp, east)); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); >+ tp = convert(civil_second(-292277022657, 1, 27, 22, 29, 51), east); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); >+ tp = convert(civil_second::min(), east); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); >+ >+ // Checks that we can also get the minimal value for a far-west zone. >+ tp = convert(civil_second(-292277022657, 1, 26, 18, 29, 52), west); >+ EXPECT_EQ("-292277022657-01-26T18:29:52-14:00", format(RFC3339, tp, west)); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); >+ tp = convert(civil_second(-292277022657, 1, 26, 18, 29, 51), west); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); >+ tp = convert(civil_second::min(), west); >+ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); >+} >+ >+TEST(NextTransition, UTC) { >+ const auto tz = utc_time_zone(); >+ time_zone::civil_transition trans; >+ >+ auto tp = time_point<absl::time_internal::cctz::seconds>::min(); >+ EXPECT_FALSE(tz.next_transition(tp, &trans)); >+ >+ tp = time_point<absl::time_internal::cctz::seconds>::max(); >+ EXPECT_FALSE(tz.next_transition(tp, &trans)); >+} >+ >+TEST(PrevTransition, UTC) { >+ const auto tz = utc_time_zone(); >+ time_zone::civil_transition trans; >+ >+ auto tp = time_point<absl::time_internal::cctz::seconds>::max(); >+ EXPECT_FALSE(tz.prev_transition(tp, &trans)); >+ >+ tp = time_point<absl::time_internal::cctz::seconds>::min(); >+ EXPECT_FALSE(tz.prev_transition(tp, &trans)); >+} >+ >+TEST(NextTransition, AmericaNewYork) { >+ const auto tz = LoadZone("America/New_York"); >+ time_zone::civil_transition trans; >+ >+ auto tp = convert(civil_second(2018, 6, 30, 0, 0, 0), tz); >+ EXPECT_TRUE(tz.next_transition(tp, &trans)); >+ EXPECT_EQ(civil_second(2018, 11, 4, 2, 0, 0), trans.from); >+ EXPECT_EQ(civil_second(2018, 11, 4, 1, 0, 0), trans.to); >+ >+ tp = time_point<absl::time_internal::cctz::seconds>::max(); >+ EXPECT_FALSE(tz.next_transition(tp, &trans)); >+ >+ tp = time_point<absl::time_internal::cctz::seconds>::min(); >+ EXPECT_TRUE(tz.next_transition(tp, &trans)); >+ if (trans.from == civil_second(1918, 3, 31, 2, 0, 0)) { >+ // It looks like the tzdata is only 32 bit (probably macOS), >+ // which bottoms out at 1901-12-13T20:45:52+00:00. >+ EXPECT_EQ(civil_second(1918, 3, 31, 3, 0, 0), trans.to); >+ } else { >+ EXPECT_EQ(civil_second(1883, 11, 18, 12, 3, 58), trans.from); >+ EXPECT_EQ(civil_second(1883, 11, 18, 12, 0, 0), trans.to); >+ } >+} >+ >+TEST(PrevTransition, AmericaNewYork) { >+ const auto tz = LoadZone("America/New_York"); >+ time_zone::civil_transition trans; >+ >+ auto tp = convert(civil_second(2018, 6, 30, 0, 0, 0), tz); >+ EXPECT_TRUE(tz.prev_transition(tp, &trans)); >+ EXPECT_EQ(civil_second(2018, 3, 11, 2, 0, 0), trans.from); >+ EXPECT_EQ(civil_second(2018, 3, 11, 3, 0, 0), trans.to); >+ >+ tp = time_point<absl::time_internal::cctz::seconds>::min(); >+ EXPECT_FALSE(tz.prev_transition(tp, &trans)); >+ >+ tp = time_point<absl::time_internal::cctz::seconds>::max(); >+ EXPECT_TRUE(tz.prev_transition(tp, &trans)); >+ // We have a transition but we don't know which one. >+} >+ >+TEST(TimeZoneEdgeCase, AmericaNewYork) { >+ const time_zone tz = LoadZone("America/New_York"); >+ >+ // Spring 1:59:59 -> 3:00:00 >+ auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz); >+ ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -5 * 3600, false, "EST"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2013, 3, 10, 3, 0, 0, -4 * 3600, true, "EDT"); >+ >+ // Fall 1:59:59 -> 1:00:00 >+ tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz); >+ ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -4 * 3600, true, "EDT"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2013, 11, 3, 1, 0, 0, -5 * 3600, false, "EST"); >+} >+ >+TEST(TimeZoneEdgeCase, AmericaLosAngeles) { >+ const time_zone tz = LoadZone("America/Los_Angeles"); >+ >+ // Spring 1:59:59 -> 3:00:00 >+ auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz); >+ ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -8 * 3600, false, "PST"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2013, 3, 10, 3, 0, 0, -7 * 3600, true, "PDT"); >+ >+ // Fall 1:59:59 -> 1:00:00 >+ tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz); >+ ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -7 * 3600, true, "PDT"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2013, 11, 3, 1, 0, 0, -8 * 3600, false, "PST"); >+} >+ >+TEST(TimeZoneEdgeCase, ArizonaNoTransition) { >+ const time_zone tz = LoadZone("America/Phoenix"); >+ >+ // No transition in Spring. >+ auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz); >+ ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -7 * 3600, false, "MST"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2013, 3, 10, 2, 0, 0, -7 * 3600, false, "MST"); >+ >+ // No transition in Fall. >+ tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz); >+ ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -7 * 3600, false, "MST"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2013, 11, 3, 2, 0, 0, -7 * 3600, false, "MST"); >+} >+ >+TEST(TimeZoneEdgeCase, AsiaKathmandu) { >+ const time_zone tz = LoadZone("Asia/Kathmandu"); >+ >+ // A non-DST offset change from +0530 to +0545 >+ // >+ // 504901799 == Tue, 31 Dec 1985 23:59:59 +0530 (+0530) >+ // 504901800 == Wed, 1 Jan 1986 00:15:00 +0545 (+0545) >+ auto tp = convert(civil_second(1985, 12, 31, 23, 59, 59), tz); >+ ExpectTime(tp, tz, 1985, 12, 31, 23, 59, 59, 5.5 * 3600, false, "+0530"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 1986, 1, 1, 0, 15, 0, 5.75 * 3600, false, "+0545"); >+} >+ >+TEST(TimeZoneEdgeCase, PacificChatham) { >+ const time_zone tz = LoadZone("Pacific/Chatham"); >+ >+ // One-hour DST offset changes, but at atypical values >+ // >+ // 1365256799 == Sun, 7 Apr 2013 03:44:59 +1345 (+1345) >+ // 1365256800 == Sun, 7 Apr 2013 02:45:00 +1245 (+1245) >+ auto tp = convert(civil_second(2013, 4, 7, 3, 44, 59), tz); >+ ExpectTime(tp, tz, 2013, 4, 7, 3, 44, 59, 13.75 * 3600, true, "+1345"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2013, 4, 7, 2, 45, 0, 12.75 * 3600, false, "+1245"); >+ >+ // 1380376799 == Sun, 29 Sep 2013 02:44:59 +1245 (+1245) >+ // 1380376800 == Sun, 29 Sep 2013 03:45:00 +1345 (+1345) >+ tp = convert(civil_second(2013, 9, 29, 2, 44, 59), tz); >+ ExpectTime(tp, tz, 2013, 9, 29, 2, 44, 59, 12.75 * 3600, false, "+1245"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2013, 9, 29, 3, 45, 0, 13.75 * 3600, true, "+1345"); >+} >+ >+TEST(TimeZoneEdgeCase, AustraliaLordHowe) { >+ const time_zone tz = LoadZone("Australia/Lord_Howe"); >+ >+ // Half-hour DST offset changes >+ // >+ // 1365260399 == Sun, 7 Apr 2013 01:59:59 +1100 (+11) >+ // 1365260400 == Sun, 7 Apr 2013 01:30:00 +1030 (+1030) >+ auto tp = convert(civil_second(2013, 4, 7, 1, 59, 59), tz); >+ ExpectTime(tp, tz, 2013, 4, 7, 1, 59, 59, 11 * 3600, true, "+11"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2013, 4, 7, 1, 30, 0, 10.5 * 3600, false, "+1030"); >+ >+ // 1380986999 == Sun, 6 Oct 2013 01:59:59 +1030 (+1030) >+ // 1380987000 == Sun, 6 Oct 2013 02:30:00 +1100 (+11) >+ tp = convert(civil_second(2013, 10, 6, 1, 59, 59), tz); >+ ExpectTime(tp, tz, 2013, 10, 6, 1, 59, 59, 10.5 * 3600, false, "+1030"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2013, 10, 6, 2, 30, 0, 11 * 3600, true, "+11"); >+} >+ >+TEST(TimeZoneEdgeCase, PacificApia) { >+ const time_zone tz = LoadZone("Pacific/Apia"); >+ >+ // At the end of December 2011, Samoa jumped forward by one day, >+ // skipping 30 December from the local calendar, when the nation >+ // moved to the west of the International Date Line. >+ // >+ // A one-day, non-DST offset change >+ // >+ // 1325239199 == Thu, 29 Dec 2011 23:59:59 -1000 (-10) >+ // 1325239200 == Sat, 31 Dec 2011 00:00:00 +1400 (+14) >+ auto tp = convert(civil_second(2011, 12, 29, 23, 59, 59), tz); >+ ExpectTime(tp, tz, 2011, 12, 29, 23, 59, 59, -10 * 3600, true, "-10"); >+ EXPECT_EQ(363, get_yearday(civil_day(convert(tp, tz)))); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2011, 12, 31, 0, 0, 0, 14 * 3600, true, "+14"); >+ EXPECT_EQ(365, get_yearday(civil_day(convert(tp, tz)))); >+} >+ >+TEST(TimeZoneEdgeCase, AfricaCairo) { >+ const time_zone tz = LoadZone("Africa/Cairo"); >+ >+ if (VersionCmp(tz, "2014c") >= 0) { >+ // An interesting case of midnight not existing. >+ // >+ // 1400191199 == Thu, 15 May 2014 23:59:59 +0200 (EET) >+ // 1400191200 == Fri, 16 May 2014 01:00:00 +0300 (EEST) >+ auto tp = convert(civil_second(2014, 5, 15, 23, 59, 59), tz); >+ ExpectTime(tp, tz, 2014, 5, 15, 23, 59, 59, 2 * 3600, false, "EET"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2014, 5, 16, 1, 0, 0, 3 * 3600, true, "EEST"); >+ } >+} >+ >+TEST(TimeZoneEdgeCase, AfricaMonrovia) { >+ const time_zone tz = LoadZone("Africa/Monrovia"); >+ >+ if (VersionCmp(tz, "2017b") >= 0) { >+ // Strange offset change -00:44:30 -> +00:00:00 (non-DST) >+ // >+ // 63593069 == Thu, 6 Jan 1972 23:59:59 -0044 (MMT) >+ // 63593070 == Fri, 7 Jan 1972 00:44:30 +0000 (GMT) >+ auto tp = convert(civil_second(1972, 1, 6, 23, 59, 59), tz); >+ ExpectTime(tp, tz, 1972, 1, 6, 23, 59, 59, -44.5 * 60, false, "MMT"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 1972, 1, 7, 0, 44, 30, 0 * 60, false, "GMT"); >+ } >+} >+ >+TEST(TimeZoneEdgeCase, AmericaJamaica) { >+ // Jamaica discontinued DST transitions in 1983, and is now at a >+ // constant -0500. This makes it an interesting edge-case target. >+ // Note that the 32-bit times used in a (tzh_version == 0) zoneinfo >+ // file cannot represent the abbreviation-only transition of 1890, >+ // so we ignore the abbreviation by expecting what we received. >+ const time_zone tz = LoadZone("America/Jamaica"); >+ >+ // Before the first transition. >+ if (!tz.version().empty() && VersionCmp(tz, "2018d") >= 0) { >+ // We avoid the expectations on the -18430 offset below unless we are >+ // certain we have commit 907241e (Fix off-by-1 error for Jamaica and >+ // T&C before 1913) from 2018d. TODO: Remove the "version() not empty" >+ // part when 2018d is generally available from /usr/share/zoneinfo. >+ auto tp = convert(civil_second(1889, 12, 31, 0, 0, 0), tz); >+ ExpectTime(tp, tz, 1889, 12, 31, 0, 0, 0, -18430, false, >+ tz.lookup(tp).abbr); >+ >+ // Over the first (abbreviation-change only) transition. >+ // -2524503170 == Tue, 31 Dec 1889 23:59:59 -0507 (LMT) >+ // -2524503169 == Wed, 1 Jan 1890 00:00:00 -0507 (KMT) >+ tp = convert(civil_second(1889, 12, 31, 23, 59, 59), tz); >+ ExpectTime(tp, tz, 1889, 12, 31, 23, 59, 59, -18430, false, >+ tz.lookup(tp).abbr); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 1890, 1, 1, 0, 0, 0, -18430, false, "KMT"); >+ } >+ >+ // Over the last (DST) transition. >+ // 436341599 == Sun, 30 Oct 1983 01:59:59 -0400 (EDT) >+ // 436341600 == Sun, 30 Oct 1983 01:00:00 -0500 (EST) >+ auto tp = convert(civil_second(1983, 10, 30, 1, 59, 59), tz); >+ ExpectTime(tp, tz, 1983, 10, 30, 1, 59, 59, -4 * 3600, true, "EDT"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 1983, 10, 30, 1, 0, 0, -5 * 3600, false, "EST"); >+ >+ // After the last transition. >+ tp = convert(civil_second(1983, 12, 31, 23, 59, 59), tz); >+ ExpectTime(tp, tz, 1983, 12, 31, 23, 59, 59, -5 * 3600, false, "EST"); >+} >+ >+TEST(TimeZoneEdgeCase, WET) { >+ // Cover some non-existent times within forward transitions. >+ const time_zone tz = LoadZone("WET"); >+ >+ // Before the first transition. >+ auto tp = convert(civil_second(1977, 1, 1, 0, 0, 0), tz); >+ ExpectTime(tp, tz, 1977, 1, 1, 0, 0, 0, 0, false, "WET"); >+ >+ // Over the first transition. >+ // 228877199 == Sun, 3 Apr 1977 00:59:59 +0000 (WET) >+ // 228877200 == Sun, 3 Apr 1977 02:00:00 +0100 (WEST) >+ tp = convert(civil_second(1977, 4, 3, 0, 59, 59), tz); >+ ExpectTime(tp, tz, 1977, 4, 3, 0, 59, 59, 0, false, "WET"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 1977, 4, 3, 2, 0, 0, 1 * 3600, true, "WEST"); >+ >+ // A non-existent time within the first transition. >+ time_zone::civil_lookup cl1 = tz.lookup(civil_second(1977, 4, 3, 1, 15, 0)); >+ EXPECT_EQ(time_zone::civil_lookup::SKIPPED, cl1.kind); >+ ExpectTime(cl1.pre, tz, 1977, 4, 3, 2, 15, 0, 1 * 3600, true, "WEST"); >+ ExpectTime(cl1.trans, tz, 1977, 4, 3, 2, 0, 0, 1 * 3600, true, "WEST"); >+ ExpectTime(cl1.post, tz, 1977, 4, 3, 0, 15, 0, 0 * 3600, false, "WET"); >+ >+ // A non-existent time within the second forward transition. >+ time_zone::civil_lookup cl2 = tz.lookup(civil_second(1978, 4, 2, 1, 15, 0)); >+ EXPECT_EQ(time_zone::civil_lookup::SKIPPED, cl2.kind); >+ ExpectTime(cl2.pre, tz, 1978, 4, 2, 2, 15, 0, 1 * 3600, true, "WEST"); >+ ExpectTime(cl2.trans, tz, 1978, 4, 2, 2, 0, 0, 1 * 3600, true, "WEST"); >+ ExpectTime(cl2.post, tz, 1978, 4, 2, 0, 15, 0, 0 * 3600, false, "WET"); >+} >+ >+TEST(TimeZoneEdgeCase, FixedOffsets) { >+ const time_zone gmtm5 = LoadZone("Etc/GMT+5"); // -0500 >+ auto tp = convert(civil_second(1970, 1, 1, 0, 0, 0), gmtm5); >+ ExpectTime(tp, gmtm5, 1970, 1, 1, 0, 0, 0, -5 * 3600, false, "-05"); >+ EXPECT_EQ(chrono::system_clock::from_time_t(5 * 3600), tp); >+ >+ const time_zone gmtp5 = LoadZone("Etc/GMT-5"); // +0500 >+ tp = convert(civil_second(1970, 1, 1, 0, 0, 0), gmtp5); >+ ExpectTime(tp, gmtp5, 1970, 1, 1, 0, 0, 0, 5 * 3600, false, "+05"); >+ EXPECT_EQ(chrono::system_clock::from_time_t(-5 * 3600), tp); >+} >+ >+TEST(TimeZoneEdgeCase, NegativeYear) { >+ // Tests transition from year 0 (aka 1BCE) to year -1. >+ const time_zone tz = utc_time_zone(); >+ auto tp = convert(civil_second(0, 1, 1, 0, 0, 0), tz); >+ ExpectTime(tp, tz, 0, 1, 1, 0, 0, 0, 0 * 3600, false, "UTC"); >+ EXPECT_EQ(weekday::saturday, get_weekday(civil_day(convert(tp, tz)))); >+ tp -= absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, -1, 12, 31, 23, 59, 59, 0 * 3600, false, "UTC"); >+ EXPECT_EQ(weekday::friday, get_weekday(civil_day(convert(tp, tz)))); >+} >+ >+TEST(TimeZoneEdgeCase, UTC32bitLimit) { >+ const time_zone tz = utc_time_zone(); >+ >+ // Limits of signed 32-bit time_t >+ // >+ // 2147483647 == Tue, 19 Jan 2038 03:14:07 +0000 (UTC) >+ // 2147483648 == Tue, 19 Jan 2038 03:14:08 +0000 (UTC) >+ auto tp = convert(civil_second(2038, 1, 19, 3, 14, 7), tz); >+ ExpectTime(tp, tz, 2038, 1, 19, 3, 14, 7, 0 * 3600, false, "UTC"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 2038, 1, 19, 3, 14, 8, 0 * 3600, false, "UTC"); >+} >+ >+TEST(TimeZoneEdgeCase, UTC5DigitYear) { >+ const time_zone tz = utc_time_zone(); >+ >+ // Rollover to 5-digit year >+ // >+ // 253402300799 == Fri, 31 Dec 9999 23:59:59 +0000 (UTC) >+ // 253402300800 == Sat, 1 Jan 1000 00:00:00 +0000 (UTC) >+ auto tp = convert(civil_second(9999, 12, 31, 23, 59, 59), tz); >+ ExpectTime(tp, tz, 9999, 12, 31, 23, 59, 59, 0 * 3600, false, "UTC"); >+ tp += absl::time_internal::cctz::seconds(1); >+ ExpectTime(tp, tz, 10000, 1, 1, 0, 0, 0, 0 * 3600, false, "UTC"); >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..75ad8bcba93a49af3969e523f5c7e47e16a589b9 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc >@@ -0,0 +1,155 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "time_zone_posix.h" >+ >+#include <cstddef> >+#include <cstring> >+#include <limits> >+#include <string> >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+namespace { >+ >+const char kDigits[] = "0123456789"; >+ >+const char* ParseInt(const char* p, int min, int max, int* vp) { >+ int value = 0; >+ const char* op = p; >+ const int kMaxInt = std::numeric_limits<int>::max(); >+ for (; const char* dp = strchr(kDigits, *p); ++p) { >+ int d = static_cast<int>(dp - kDigits); >+ if (d >= 10) break; // '\0' >+ if (value > kMaxInt / 10) return nullptr; >+ value *= 10; >+ if (value > kMaxInt - d) return nullptr; >+ value += d; >+ } >+ if (p == op || value < min || value > max) return nullptr; >+ *vp = value; >+ return p; >+} >+ >+// abbr = <.*?> | [^-+,\d]{3,} >+const char* ParseAbbr(const char* p, std::string* abbr) { >+ const char* op = p; >+ if (*p == '<') { // special zoneinfo <...> form >+ while (*++p != '>') { >+ if (*p == '\0') return nullptr; >+ } >+ abbr->assign(op + 1, static_cast<std::size_t>(p - op) - 1); >+ return ++p; >+ } >+ while (*p != '\0') { >+ if (strchr("-+,", *p)) break; >+ if (strchr(kDigits, *p)) break; >+ ++p; >+ } >+ if (p - op < 3) return nullptr; >+ abbr->assign(op, static_cast<std::size_t>(p - op)); >+ return p; >+} >+ >+// offset = [+|-]hh[:mm[:ss]] (aggregated into single seconds value) >+const char* ParseOffset(const char* p, int min_hour, int max_hour, int sign, >+ std::int_fast32_t* offset) { >+ if (p == nullptr) return nullptr; >+ if (*p == '+' || *p == '-') { >+ if (*p++ == '-') sign = -sign; >+ } >+ int hours = 0; >+ int minutes = 0; >+ int seconds = 0; >+ >+ p = ParseInt(p, min_hour, max_hour, &hours); >+ if (p == nullptr) return nullptr; >+ if (*p == ':') { >+ p = ParseInt(p + 1, 0, 59, &minutes); >+ if (p == nullptr) return nullptr; >+ if (*p == ':') { >+ p = ParseInt(p + 1, 0, 59, &seconds); >+ if (p == nullptr) return nullptr; >+ } >+ } >+ *offset = sign * ((((hours * 60) + minutes) * 60) + seconds); >+ return p; >+} >+ >+// datetime = ( Jn | n | Mm.w.d ) [ / offset ] >+const char* ParseDateTime(const char* p, PosixTransition* res) { >+ if (p != nullptr && *p == ',') { >+ if (*++p == 'M') { >+ int month = 0; >+ if ((p = ParseInt(p + 1, 1, 12, &month)) != nullptr && *p == '.') { >+ int week = 0; >+ if ((p = ParseInt(p + 1, 1, 5, &week)) != nullptr && *p == '.') { >+ int weekday = 0; >+ if ((p = ParseInt(p + 1, 0, 6, &weekday)) != nullptr) { >+ res->date.fmt = PosixTransition::M; >+ res->date.m.month = static_cast<int_fast8_t>(month); >+ res->date.m.week = static_cast<int_fast8_t>(week); >+ res->date.m.weekday = static_cast<int_fast8_t>(weekday); >+ } >+ } >+ } >+ } else if (*p == 'J') { >+ int day = 0; >+ if ((p = ParseInt(p + 1, 1, 365, &day)) != nullptr) { >+ res->date.fmt = PosixTransition::J; >+ res->date.j.day = static_cast<int_fast16_t>(day); >+ } >+ } else { >+ int day = 0; >+ if ((p = ParseInt(p, 0, 365, &day)) != nullptr) { >+ res->date.fmt = PosixTransition::N; >+ res->date.j.day = static_cast<int_fast16_t>(day); >+ } >+ } >+ } >+ if (p != nullptr) { >+ res->time.offset = 2 * 60 * 60; // default offset is 02:00:00 >+ if (*p == '/') p = ParseOffset(p + 1, -167, 167, 1, &res->time.offset); >+ } >+ return p; >+} >+ >+} // namespace >+ >+// spec = std offset [ dst [ offset ] , datetime , datetime ] >+bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res) { >+ const char* p = spec.c_str(); >+ if (*p == ':') return false; >+ >+ p = ParseAbbr(p, &res->std_abbr); >+ p = ParseOffset(p, 0, 24, -1, &res->std_offset); >+ if (p == nullptr) return false; >+ if (*p == '\0') return true; >+ >+ p = ParseAbbr(p, &res->dst_abbr); >+ if (p == nullptr) return false; >+ res->dst_offset = res->std_offset + (60 * 60); // default >+ if (*p != ',') p = ParseOffset(p, 0, 24, -1, &res->dst_offset); >+ >+ p = ParseDateTime(p, &res->dst_start); >+ p = ParseDateTime(p, &res->dst_end); >+ >+ return p != nullptr && *p == '\0'; >+} >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h >new file mode 100644 >index 0000000000000000000000000000000000000000..6619f27edcf63895abeb23f3ddb48eff4f9f2ac8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h >@@ -0,0 +1,118 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Parsing of a POSIX zone spec as described in the TZ part of section 8.3 in >+// http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html. >+// >+// The current POSIX spec for America/Los_Angeles is "PST8PDT,M3.2.0,M11.1.0", >+// which would be broken down as ... >+// >+// PosixTimeZone { >+// std_abbr = "PST" >+// std_offset = -28800 >+// dst_abbr = "PDT" >+// dst_offset = -25200 >+// dst_start = PosixTransition { >+// date { >+// m { >+// month = 3 >+// week = 2 >+// weekday = 0 >+// } >+// } >+// time { >+// offset = 7200 >+// } >+// } >+// dst_end = PosixTransition { >+// date { >+// m { >+// month = 11 >+// week = 1 >+// weekday = 0 >+// } >+// } >+// time { >+// offset = 7200 >+// } >+// } >+// } >+ >+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_ >+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_ >+ >+#include <cstdint> >+#include <string> >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// The date/time of the transition. The date is specified as either: >+// (J) the Nth day of the year (1 <= N <= 365), excluding leap days, or >+// (N) the Nth day of the year (0 <= N <= 365), including leap days, or >+// (M) the Nth weekday of a month (e.g., the 2nd Sunday in March). >+// The time, specified as a day offset, identifies the particular moment >+// of the transition, and may be negative or >= 24h, and in which case >+// it would take us to another day, and perhaps week, or even month. >+struct PosixTransition { >+ enum DateFormat { J, N, M }; >+ struct { >+ DateFormat fmt; >+ union { >+ struct { >+ std::int_fast16_t day; // day of non-leap year [1:365] >+ } j; >+ struct { >+ std::int_fast16_t day; // day of year [0:365] >+ } n; >+ struct { >+ std::int_fast8_t month; // month of year [1:12] >+ std::int_fast8_t week; // week of month [1:5] (5==last) >+ std::int_fast8_t weekday; // 0==Sun, ..., 6=Sat >+ } m; >+ }; >+ } date; >+ struct { >+ std::int_fast32_t offset; // seconds before/after 00:00:00 >+ } time; >+}; >+ >+// The entirety of a POSIX-std::string specified time-zone rule. The standard >+// abbreviation and offset are always given. If the time zone includes >+// daylight saving, then the daylight abbrevation is non-empty and the >+// remaining fields are also valid. Note that the start/end transitions >+// are not ordered---in the southern hemisphere the transition to end >+// daylight time occurs first in any particular year. >+struct PosixTimeZone { >+ std::string std_abbr; >+ std::int_fast32_t std_offset; >+ >+ std::string dst_abbr; >+ std::int_fast32_t dst_offset; >+ PosixTransition dst_start; >+ PosixTransition dst_end; >+}; >+ >+// Breaks down a POSIX time-zone specification into its constituent pieces, >+// filling in any missing values (DST offset, or start/end transition times) >+// with the standard-defined defaults. Returns false if the specification >+// could not be parsed (although some fields of *res may have been altered). >+bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res); >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/tzfile.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/tzfile.h >new file mode 100644 >index 0000000000000000000000000000000000000000..90cfc0c42989b040ef9146d1c45d37ad77b22caa >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/tzfile.h >@@ -0,0 +1,117 @@ >+#ifndef TZFILE_H >+ >+#define TZFILE_H >+ >+/* >+** This file is in the public domain, so clarified as of >+** 1996-06-05 by Arthur David Olson. >+*/ >+ >+/* >+** This header is for use ONLY with the time conversion code. >+** There is no guarantee that it will remain unchanged, >+** or that it will remain at all. >+** Do NOT copy it to any system include directory. >+** Thank you! >+*/ >+ >+/* >+** Information about time zone files. >+*/ >+ >+#ifndef TZDIR >+#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */ >+#endif /* !defined TZDIR */ >+ >+#ifndef TZDEFAULT >+#define TZDEFAULT "/etc/localtime" >+#endif /* !defined TZDEFAULT */ >+ >+#ifndef TZDEFRULES >+#define TZDEFRULES "posixrules" >+#endif /* !defined TZDEFRULES */ >+ >+/* >+** Each file begins with. . . >+*/ >+ >+#define TZ_MAGIC "TZif" >+ >+struct tzhead { >+ char tzh_magic[4]; /* TZ_MAGIC */ >+ char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */ >+ char tzh_reserved[15]; /* reserved; must be zero */ >+ char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ >+ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ >+ char tzh_leapcnt[4]; /* coded number of leap seconds */ >+ char tzh_timecnt[4]; /* coded number of transition times */ >+ char tzh_typecnt[4]; /* coded number of local time types */ >+ char tzh_charcnt[4]; /* coded number of abbr. chars */ >+}; >+ >+/* >+** . . .followed by. . . >+** >+** tzh_timecnt (char [4])s coded transition times a la time(2) >+** tzh_timecnt (unsigned char)s types of local time starting at above >+** tzh_typecnt repetitions of >+** one (char [4]) coded UT offset in seconds >+** one (unsigned char) used to set tm_isdst >+** one (unsigned char) that's an abbreviation list index >+** tzh_charcnt (char)s '\0'-terminated zone abbreviations >+** tzh_leapcnt repetitions of >+** one (char [4]) coded leap second transition times >+** one (char [4]) total correction after above >+** tzh_ttisstdcnt (char)s indexed by type; if 1, transition >+** time is standard time, if 0, >+** transition time is wall clock time >+** if absent, transition times are >+** assumed to be wall clock time >+** tzh_ttisgmtcnt (char)s indexed by type; if 1, transition >+** time is UT, if 0, >+** transition time is local time >+** if absent, transition times are >+** assumed to be local time >+*/ >+ >+/* >+** If tzh_version is '2' or greater, the above is followed by a second instance >+** of tzhead and a second instance of the data in which each coded transition >+** time uses 8 rather than 4 chars, >+** then a POSIX-TZ-environment-variable-style std::string for use in handling >+** instants after the last transition time stored in the file >+** (with nothing between the newlines if there is no POSIX representation for >+** such instants). >+** >+** If tz_version is '3' or greater, the above is extended as follows. >+** First, the POSIX TZ std::string's hour offset may range from -167 >+** through 167 as compared to the POSIX-required 0 through 24. >+** Second, its DST start time may be January 1 at 00:00 and its stop >+** time December 31 at 24:00 plus the difference between DST and >+** standard time, indicating DST all year. >+*/ >+ >+/* >+** In the current implementation, "tzset()" refuses to deal with files that >+** exceed any of the limits below. >+*/ >+ >+#ifndef TZ_MAX_TIMES >+#define TZ_MAX_TIMES 2000 >+#endif /* !defined TZ_MAX_TIMES */ >+ >+#ifndef TZ_MAX_TYPES >+/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */ >+#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ >+#endif /* !defined TZ_MAX_TYPES */ >+ >+#ifndef TZ_MAX_CHARS >+#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ >+ /* (limited by what unsigned chars can hold) */ >+#endif /* !defined TZ_MAX_CHARS */ >+ >+#ifndef TZ_MAX_LEAPS >+#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ >+#endif /* !defined TZ_MAX_LEAPS */ >+ >+#endif /* !defined TZFILE_H */ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..bf2d2d2d2b5384eff3ea0ea10ee8fa68f0fe8bc7 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc >@@ -0,0 +1,79 @@ >+// Copyright 2016 Google Inc. All Rights Reserved. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/internal/cctz/include/cctz/zone_info_source.h" >+ >+namespace absl { >+namespace time_internal { >+namespace cctz { >+ >+// Defined out-of-line to avoid emitting a weak vtable in all TUs. >+ZoneInfoSource::~ZoneInfoSource() {} >+std::string ZoneInfoSource::Version() const { return std::string(); } >+ >+} // namespace cctz >+} // namespace time_internal >+} // namespace absl >+ >+namespace absl { >+namespace time_internal { >+namespace cctz_extension { >+ >+namespace { >+ >+// A default for cctz_extension::zone_info_source_factory, which simply >+// defers to the fallback factory. >+std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource> DefaultFactory( >+ const std::string& name, >+ const std::function<std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource>( >+ const std::string& name)>& fallback_factory) { >+ return fallback_factory(name); >+} >+ >+} // namespace >+ >+// A "weak" definition for cctz_extension::zone_info_source_factory. >+// The user may override this with their own "strong" definition (see >+// zone_info_source.h). >+#if defined(_MSC_VER) >+extern ZoneInfoSourceFactory zone_info_source_factory; >+extern ZoneInfoSourceFactory default_factory; >+ZoneInfoSourceFactory default_factory = DefaultFactory; >+#if defined(_M_IX86) >+#pragma comment( \ >+ linker, \ >+ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZA=?default_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZA") >+#elif defined(_M_IA_64) || defined(_M_AMD64) >+#pragma comment( \ >+ linker, \ >+ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZEA=?default_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZEA") >+#else >+#error Unsupported MSVC platform >+#endif >+#else // _MSC_VER >+#if !defined(__has_attribute) >+#define __has_attribute(x) 0 >+#endif >+#if __has_attribute(weak) || defined(__GNUC__) >+ZoneInfoSourceFactory zone_info_source_factory >+ __attribute__((weak)) = DefaultFactory; >+#else >+// Make it a "strong" definition if we have no other choice. >+ZoneInfoSourceFactory zone_info_source_factory = DefaultFactory; >+#endif >+#endif // _MSC_VER >+ >+} // namespace cctz_extension >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/README.zoneinfo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/README.zoneinfo >new file mode 100644 >index 0000000000000000000000000000000000000000..95fb4a91d17eb976f02993d0af3fa4e56939a427 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/README.zoneinfo >@@ -0,0 +1,37 @@ >+testdata/zoneinfo contains time-zone data files that may be used with CCTZ. >+Install them in a location referenced by the ${TZDIR} environment variable. >+Symbolic and hard links have been eliminated for portability. >+ >+On Linux systems the distribution's versions of these files can probably >+already be found in the default ${TZDIR} location, /usr/share/zoneinfo. >+ >+New versions can be generated using the following shell script. >+ >+ #!/bin/sh - >+ set -e >+ DESTDIR=$(mktemp -d) >+ trap "rm -fr ${DESTDIR}" 0 2 15 >+ ( >+ cd ${DESTDIR} >+ git clone https://github.com/eggert/tz.git >+ make --directory=tz \ >+ install DESTDIR=${DESTDIR} \ >+ DATAFORM=vanguard \ >+ TZDIR=/zoneinfo \ >+ REDO=posix_only \ >+ LOCALTIME=Factory \ >+ TZDATA_TEXT= \ >+ ZONETABLES=zone1970.tab >+ tar --create --dereference --hard-dereference --file tzfile.tar \ >+ --directory=tz tzfile.h >+ tar --create --dereference --hard-dereference --file zoneinfo.tar \ >+ --exclude=zoneinfo/posixrules zoneinfo \ >+ --directory=tz version >+ ) >+ tar --extract --directory src --file ${DESTDIR}/tzfile.tar >+ tar --extract --directory testdata --file ${DESTDIR}/zoneinfo.tar >+ exit 0 >+ >+To run the CCTZ tests using the testdata/zoneinfo files, execute: >+ >+ bazel test --test_env=TZDIR=${PWD}/testdata/zoneinfo ... >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version >new file mode 100644 >index 0000000000000000000000000000000000000000..fe86b5cc877292444ab101cd4125ec1026761d7d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version >@@ -0,0 +1 @@ >+2018e-2-g99dd695 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra >new file mode 100644 >index 0000000000000000000000000000000000000000..8726e80df27f8d6794b295674a18a71c9cab4c85 >GIT binary patch >literal 842 >zcmcK2J!n%=9ES0KK9&Yr7h4crvI#}Kgl5W8rz{Z<m@XNlAOv)95J9L22Rn6<4mBVF >zhlFah%?IH&YW%!}M6HP&2!c3O=_ul&R8Zo1j&7YY^n{z=C6GYg=Vo&k^9k8^BK8w5 >zj%P3Kr?h>$>*f9O+;v?Z{#NVLby?p!W$yj_qVE?jsLIC~d2p>@9=40JkvnQOi|=(c >zbyn4Ggr$D$rfHl{>c*dzYR<QHb0?+z_&4!`%cd2H>sG0x9_=p3<K++LN$-=i^Evah >zGO3@XZ>i@ir{%@*z`VS4Rll0}p@PgW9eiC<os%b|GpL&Gp+()TeOA5iYw~*auz52) >zB5$wUG24DdzdJWj{o7gwNih-*jrAIhMt%F2CE5r@QDT`hS(){`gePfx_wQuKSa9$E >zckC~ZSQ1&&X%|ISb=qZ-b&-XUm64^9wUNb<)sf|q^^pQd1*a{6)NtA&NEN3ogVb@_ >zLP#Z~6jBQ*hEzk!A@z`gNJXS1QqyURB2}HXEK=8L3nP`0(nxKjI8q%ckJQJ5djewi >IVen#q0by*H{r~^~ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers >new file mode 100644 >index 0000000000000000000000000000000000000000..2a25f3ac268fd5c605c58d36260759c8f8d125bc >GIT binary patch >literal 760 >zcmc(cyDtPm9Dsj&)*ixH&q5S}N|2oJ4_JbDoWv#`k=#`mqM0b<B8pSe(Rv+DDN%|j >zXxvrai9{3{{UjO{=35GhLTNTL-(+?-+5J9$YBt#+zebTcVKN%cWM7vy%UWVIw$Yc; >z8xO5&^K?yZo%QSOm3Ot1Y0;U)f!<A*>b>?#y}vl5vt7$Nd+ex-4@c!DPSUx@;>^{0 >zr+d9Bax-7+-i|b@`@yh!xxACt=_4IVo$CTGugk6;By!lJ%TrV0&P=+M3!bV<cBiZ3 >zOKwdpE|wiC_;J}zp}B0woQBziZAT>ZWIk3xQL#lLuJ!dVWt@pw>l>^J&ZYM2?$EF= >zqh^lxj<NXSvGL4C#Il07z8C**UrpxGz}MUNJ0E7u<p-W2{vZwm8jlc{5T6jI5U&uo >z5Wf(|5YG_T0gZ2nbBOnV#y!M8qyeM@qy?l0qzR-8zd;*FA4nqxogl3k^nx^lbc3{m >O^!wL<C8laywB!@(boU$p > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui >new file mode 100644 >index 0000000000000000000000000000000000000000..b1c97cc5a77eb187cc8ea8a4031a45a9bf153b35 >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$XOWpIe>wYfq~foB*iDdz~bW@!VvBl0^%}+kYL&m >Tunq=>|3HA>R4$<Lx`tc;I6M;> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau >new file mode 100644 >index 0000000000000000000000000000000000000000..8e32be3e6e843379e69000273552ab8588c5ca34 >GIT binary patch >literal 208 >zcmWHE%1kq2zyQoZ5fBCe7@Ma7$eHwP&IHc%L;(gyrvLvxrZ6x7$qx)HAax8JKE5Fg >lx(0>}?m(J>5rjfWF#ZSF5Ri%g|AVXnaY?X>3uvnW7XTd?B!vI~ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre >new file mode 100644 >index 0000000000000000000000000000000000000000..5b871dbaa7c2969f6b4dfc854184a29010bfb2cc >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$Z2vr`h|g!fkCbZBqgK3z~bW@!r<%}0^%}+kYL&m >Tunq=>|3HA>R4$<Lx<*_8th^MU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville >new file mode 100644 >index 0000000000000000000000000000000000000000..b1c97cc5a77eb187cc8ea8a4031a45a9bf153b35 >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$XOWpIe>wYfq~foB*iDdz~bW@!VvBl0^%}+kYL&m >Tunq=>|3HA>R4$<Lx`tc;I6M;> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura >new file mode 100644 >index 0000000000000000000000000000000000000000..5b871dbaa7c2969f6b4dfc854184a29010bfb2cc >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$Z2vr`h|g!fkCbZBqgK3z~bW@!r<%}0^%}+kYL&m >Tunq=>|3HA>R4$<Lx<*_8th^MU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo >new file mode 100644 >index 0000000000000000000000000000000000000000..ba097504459673e254831edea689c2f8143990df >GIT binary patch >literal 1972 >zcmcK4Z%oxy9LMo<K@qQ5UbPhS8X6>Gl#oH>O)9+(4cD*T%Sy-Uhc#Wb+-c;NQsd0E >znq_Oo16^(DGFzoqW?3|K%eF$aIN8Wew>-3#WQHdMjhjU0ee79Vt_OY@_r?4(o}Bk5 >zz4Vdg<>FsA%>4=9T(kS;=h4c2w6%O>+A>Z0;Ds}${i|+$=+JxN;S)3T*E_n*H(&PY >zj+d7k{myFr?X#gd^1{xbyW*j+yRS4jHL5i{)fwtvPiO4uj~^Gmbu`<ajlJT`2fL+R >zU8H{B@U!h*x<s69oFx0^tXKVYo8`GFF?GJ;h&?})6ay1;<Um)u$P853KMxG53&;1{ >z!EI~RUweDy&~tl)c)iF*R{Wx}nwQAzg>f;g;RiW<<{KhsUd)cj>r}agNtxR-QbdP8 >zWuqMlHR|M`&D-_48hx-#Uhzu5xboeH?U*NvRqVx0a%^3_7`HMm$5(cVtL_Qx)%oMq >zge@(0LZ(LK%dIy5c$1pcm$29D7iw~+l=028#gsi;?X_x!D%f~bPHlKiOj}bgubW>W >z3YSfnMMWufec}r_J?D8*96x7^PkyFKM3XIPuU0d=-j_FQZxp2mezZ5Pe@or8Wt^Gy >zSe`Cx?l<L&di2c?9yPN|w7#Xf)l@`3)Ro2Ghm~hLf~wq4!>aFg1-Es-8qV3>5+vH5 >z4sUN+70iA6fv~#qzTl1xYs{VXjry)9>dm}Fot}U1T$3C-7%V6&FbmA1K}{^n)O-@t >z3++#4(Mzqt-NzzfZNolYyY7Bd`(`Fct-95ucC6E>V|&AN;o2Z8a+$uev;O<*;_nqA >zUgut)D47*;PjPaA7<uvM+Qn&+Os4oq^Y;-x(wBbI%KbC{rvKnSxEpf!%)Z6jkvHyj >z?;LsS$a_cLJo4_5w~xGkqyeM@qy?l0qzSL<0%^nR`al{%Izd`NdO?~&x<T4O`av2( >zIzn1PdP17=x~`D6ysj^#F{Cr3HKaH6&G7@>ajrd}KcqpVLyi`a9yyvsx<uOax;{A? >z^}0@xR*_zjW|3|=+C}<B8b&(iXc_65qiLjTq;0S3o1<~B>l|qv=^bev>7Ju~q<>@s >zkR9OI0%Q+3HUZfMWE+ru;MfSS+X-YVylyX$%|Ld8V>^)jKsE%~5oAk{JwY}F*%f44 >zkbOZm#_M(l*&46g8)S2k-9feo*&k$skR3v{2-zcKlaO6Pwh7rMWTU)pr;x4ky1ha+ >x3)wAXyO90zx()NX9YeOv>-Nm+HVxS|ahYZ<a*0{X{^$4puVIV2l`Ace{tf(fqG134 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca >new file mode 100644 >index 0000000000000000000000000000000000000000..65de34457986ee755ffd614de6378dbee965a64d >GIT binary patch >literal 1643 >zcmd7SYiP}J9LMqh#xl2|hzMVowI{<i*C%ext=ZVwIkU6bW*c^KJ?75XpM(b}CBo8I >zu0>i>6c6OVSW2ShHd3xnaEQ#U`M!UYnn#}bt^fb^Kj*YP+2?&i1y$u~-d`uq-r?db >zw2S8+zTNf*zSK3e_VllZ&ql64c;nwWnihRD`ndP#ZBq1GV)dkN*WN|q7jN_98<s{p >zzwY97DV-ke+Bnfq*z+OM?QX#Do^&kI_u@%!K%eE&8Ixc7GcFH~WDM!+W$bQ>%xu2u >zXBNGPWF5HV&l<HWI=fCaJN~j}ryi2*ic=b>*{Xs2H#H~jh~_L=sll-uG<a^12Aiiz >zC^J`cdlzbM%~Q!e(_ZH!kJUM!Cum-9hvscLE8$)t3EvaVmyens4r>0VF;Z|bRtrAY >z$=t-NI=88h6zV`Jyp^tn-z%l)!dEHwW2E?Sy%sk%$-I5dQZnzElvIbML~FEkQ;U|Z >z9V+vS9_oTAdu8GHD_Y)foL2Ndq80C-O63n<t8VPjMUTsL@#!jE(oic)ch1yhCrf2{ >z<uHwGPnQ*e45=<pl$EK;vT9lfS=}Q+){GdUYobwE*DX%h-M%C1-@eif^%rF0twyam >zcw0A}SRtF&pV!*zCsMoTaJ?5B)8?mLo7ZhW|M%Cit*tH3?SJnjbdPC|UPqq2uD_l$ >zvqE0p)F8Kzmu}ae6Z(gBwfz3IRy(W=SsJo7r!5Xy9kM*9tq)nC(^klzV~I{%BeF;i >zt3;NGtP@!%vQlKJ9M*~~)@iFnmg}_jA`3=Vj4T;hGqPx8)lOTs)7FhF+-WOEmhQB* >zBa3(1>YcWHWc^41POHFaB_K68tq7zFr<H-!;j}`KN}N`T(`rGAaauJ<IZmqwDadIR >zIjtn5CZs6CqbjGBh17)<=CsP3RvJ<pQXEnpQXWztQXo>H(@I2YM2bYJM9M_!L<&VJ >zMM_0#MT$kLMao6$MG8hLc3R0u%}y&CsTwI8sT(OAsT?UCsonYC7vIUg1XB1mNX{BL >QeDv^?<gC;b95J%fPb9Cfs{jB1 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta >new file mode 100644 >index 0000000000000000000000000000000000000000..aaa657ffde7908600a3ec66dff03ca6e91ba13f6 >GIT binary patch >literal 2059 >zcmdtiUrd#C9LMqBqn>00^rfY?MA3-QI>G^j)F9LoFcmc9q@)s(h?;mho|J*9=QNpC >zW9-|;YOeWjI&3V-9OebJmMbUAv9?Cdnrqd{KWoY=r;RcCy??oR(M5M%^n3R3dN|{Z >zo9FWmt=iO>XZ~@<+fTSTF?;hoF>Zex{Ca!j(2?-kZr_ba_vNrT(SLlX=XjoZ|M0TN >z$$bx)4_@D4PDKLoQ$M^JAI^-<A3l2{lCZfgo^Wo<(7jiZOj3RMP;!4sJf-8e$bDZ` >z#U<-#<e@WNW@@`i`p#EnT2oY}uURJ#SA-;^s8k;D7fNPYmOPsDpk(=inssxw&iFY~ >zXAVx($37pgkN4hI|FNq&tMgmUZu>%Wwtb|5h7+1wdr|VDy^>$tC$pEoB?VIsNMT-! >z6pqAX&g4#=bE#hD4maz(kAw2$cQsnnRj0*$^Yp2`3$)~&G@aj=p$ppP%EB_A1{)^J >z)0vmGG&mw<zJ4vw_+HAd|00XVekzLw&dcJTj>?jrZmGENiB@*B%hLCb=(2EFo@w8s >zRV&}n<xT6g`iUkDRg~+qla}fV|4dzRE1)$K%B1F-`}Mh-Gi23=f9UGLL|Jn<Rcd>G >zmFHu>OI_!HtgRcA`d!!bg_1L}uJ(d9r0<vY#XZ`Xa9TG^QQdImZQVE$)lKJH^~Fme >z-TdxqZ92DAw!BuX;jU_VX=A!Z_7=$2sv?OtPLh{%r^>d{KV^HWk>;EU+C225w4~h9 >zmM=e(*6SB_$H^{vWuQ-Y?mw%$dJgFB)?*s$h^aTm8#DIri^n_HINv@0%{4kYJkGv- >z9BYbr33s1OvN37Xyi`6n$rY6$v$B-CI%I<OA;^P0p7A{QCC>}}`%53Uf9hWP+wMEY >zjM}ri@U)W=@H<05#^AJrKt_QK0~rT05M(6CP@Hxw$Y7jyH2hnJ<Fw;J2E<`R$dHgR >zA%j9jg$#?sxR8M%BSVIUj13taGCE{<$oP-}I_(INAtGZ$28oOk874ALWT41Mk)a}E >zMFxwE78x!wUSz;dJ7Q$WPCI5~(8#EfVI$*429Asz89Fj{Wbnx7k>MlbM*@IE011K9 >z#sCR|(?$Ua0}=-$5J)7DP$02Df`LQ>2?r7nBp^sckdQcSOpu^BZB&r3AaOwggG2@i >z4H6q9I7oDm@F4L)0)#{e2@w(_BuGvhB_vEpoRB~vkwQX+#0m)(5-lWLNW74MArV7D >zhQtgBn$t!N37gZ#4GA0)IV5yQ?2zCg(L=&#{#WHov_+hiOA`H+`Pl{80e@v~0CVya >F{{prT0UiJV > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala >new file mode 100644 >index 0000000000000000000000000000000000000000..b1c97cc5a77eb187cc8ea8a4031a45a9bf153b35 >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$XOWpIe>wYfq~foB*iDdz~bW@!VvBl0^%}+kYL&m >Tunq=>|3HA>R4$<Lx`tc;I6M;> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun >new file mode 100644 >index 0000000000000000000000000000000000000000..f5f8ffbc61716d3a421f555fa962a2b3e488d78e >GIT binary patch >literal 1473 >zcmd7RNl27&7{~EfGYZ!{L{UUfi*(V{HoH`WW#UrmjQif=QdXn3s98=OvO`Hh5T(ci >z(E>$C1O<8U6iE<PND&r7w47qvD5992@1Jg+It2ZP_x;SgFsJwX^H(%CEc5<2QTBw3 >zQ(+h16N7de&JIn+JQ_M3^Dfqlt=|-i8(kNS@B0`?cv2XgvE*VPd;ObW_T7bnoJDiI >zoKxe0+=-E3UiIrh{<%BB%_~lZwhX8iOuwrI=@+D+@ro99AJf8T5433Npcb{Xt1qKV >zeK!`UZz4<ldBs{ht4fQzC#CpWl$IoCXvx>LTI%c7(xca<Y^Gnzo{E;sXDu)DY5A8` >zQgJ&{E4~g$WzvXNj?b1Voi9}nGqvhRlT_dOE;Ydjsp%imn$dBoJv$+FwXdYEtxW2) >zTk8*h)2#;=%eLz0x_!eL*|BC=8|JRo#(9I<_+e6-eg?Jqey{F)u~m0nZPu21J+k{m >zuI{;9FMFF(G;lmqS_^ZetszO;)01Ui)->6l7%vA>7wLgeNIDXxYRA}P>3siIyM}Jb >zp@*Z|eSS<2Uuu;joj0|o?WOee^$&RwQzHM#XG%EyNj)zd{t)7g#?OeDZm-ny;_~wS >zUP@ZJSGv*Xx0~NR<>vp3Jih(@SJ)1j@RL-WmJ5eukZh22kbIDYkc^y`5|WeCl0vdV >z(n9h=5<@aWQgd2vPD>8S&S~i(`8h2?BtxgA=(HS>B#|tgmZsD4L=tscrbwzz%N0r1 >zY1ty_IxSzPC5&Y3w3LyYot89`wbRmeTHZ+FNalt|>Q2iYNgm1GY3VyHe`Es443H@x >zb3i76%mSH))8>Ip1epmk6=W{RWRTe)(?RBgObD3~G9_eA$fS^2A=7f&ypV}GZDz>S >qkhvj~LuQ9e51Ah_LFfN9!)V)N8skjPU%qtZ(zN9K^fXLe9{meZcW0FV > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone >new file mode 100644 >index 0000000000000000000000000000000000000000..5b871dbaa7c2969f6b4dfc854184a29010bfb2cc >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$Z2vr`h|g!fkCbZBqgK3z~bW@!r<%}0^%}+kYL&m >Tunq=>|3HA>R4$<Lx<*_8th^MU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare >new file mode 100644 >index 0000000000000000000000000000000000000000..5b871dbaa7c2969f6b4dfc854184a29010bfb2cc >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$Z2vr`h|g!fkCbZBqgK3z~bW@!r<%}0^%}+kYL&m >Tunq=>|3HA>R4$<Lx<*_8th^MU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg >new file mode 100644 >index 0000000000000000000000000000000000000000..ddf3652e159e4c3cd844bdedf4784dcd29da23c7 >GIT binary patch >literal 271 >zcmWHE%1kq2zyK^j5fBCeHXsJEIU9gPliT@>GwXU9&d$p(IM<igaK0|EfRULA2pJfp >z9DoWKL?u9~wG0@6q>KUsi;r&zL$G6T2uKbLLI_*Q4pa!X@&{DUe;~-Mc60#IASZxm >ckTXCu$SEKi<QxzUauNfHZsG#DP}hhH09Bqn8vp<R > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba >new file mode 100644 >index 0000000000000000000000000000000000000000..9fa711904dff7519d3061e1bc81527f5dba0769b >GIT binary patch >literal 683 >zcmcK1yDtPm9Ki9pr@OU>^E$^}Y(gO}5<#I6uUsM?$t1TGg{d5cD0C8+tB{DsAE5C_ >zM5WPcM4}t5C`Ls=p`&8H8!Ck;%x31ZyU8Y-@6VrKSsD;OR@A;>v%2i&K3%oP#o^t( >zILMgL#*hqezMIHGSw~gH#73TVd`y{|PERJh36m5h?TBvUJZ#Ha6F2UaD^r(GrtWxD >z*Pq5z!`8Y??>wr;@`-L*zERE71>G`rrdkV&GSjoC+T4AeO{}Tx%e8EO-8CJ0M&@o; >zP5!*1hpR<TghRhv5h3zN_K!txf5`rR&J#)QMQV1=7n9>94qp`Q{$BncTD*OI^kG-f >zglF3YXoK`Y8X=vKR!A?T8PW}Dhx7}y4UvvWOQa{#6zPhzMfxI*k<LhKq&LzW>5jBV >a`Ulz>Aag)wfy@J$3I5ky96O}GLFW@PZiCMN > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum >new file mode 100644 >index 0000000000000000000000000000000000000000..f2c9e303797396981ce1900c06cb51e65f94b830 >GIT binary patch >literal 713 >zcmcK1yDvjg0LSrj`_f)5>Q$w<LkH1Fq%l~;D^0{BIZ5w=!I_jn3^s|T6B4ob11v%! >zCX3Y~65Fwwjzq%1V5^DqEs4P(2B*3Ab9<8}&G+XotS;xpj}x|UxHwsR@tmyK+r`nH >z5Qiz_Y!1o5)|&|~mUKv!O?c#4N5+(?>-A*Rn=mm^)UL=H_kKs#n}~^D#bx61$ut~~ >z>c-QsYTDkA$=yfQTsqM$D>tfjI;Y#F&QyDDNv8VtRY&|lr=#mC{c<fkU-wLxo{^c` >zHPd}w*29&8H(z~_BH;Y;2?m7d;ctunK_?_c#uG7~MdI^$cFq@*<3(=1DA?=!_<smf >z{rcIvJ+(l5w~>HQNGv265)BE5#6toi5s{Ec%$hbR5)}!H#6<!lk&)0yY$P}m9SM)b >iM+QJfK!!lZsA&g5MnQ%_#z6)`M#6s|%C*}K<lPUR4To+3 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali >new file mode 100644 >index 0000000000000000000000000000000000000000..5b871dbaa7c2969f6b4dfc854184a29010bfb2cc >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$Z2vr`h|g!fkCbZBqgK3z~bW@!r<%}0^%}+kYL&m >Tunq=>|3HA>R4$<Lx<*_8th^MU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa >new file mode 100644 >index 0000000000000000000000000000000000000000..b1c97cc5a77eb187cc8ea8a4031a45a9bf153b35 >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$XOWpIe>wYfq~foB*iDdz~bW@!VvBl0^%}+kYL&m >Tunq=>|3HA>R4$<Lx`tc;I6M;> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos >new file mode 100644 >index 0000000000000000000000000000000000000000..b1c97cc5a77eb187cc8ea8a4031a45a9bf153b35 >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$XOWpIe>wYfq~foB*iDdz~bW@!VvBl0^%}+kYL&m >Tunq=>|3HA>R4$<Lx`tc;I6M;> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville >new file mode 100644 >index 0000000000000000000000000000000000000000..b1c97cc5a77eb187cc8ea8a4031a45a9bf153b35 >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$XOWpIe>wYfq~foB*iDdz~bW@!VvBl0^%}+kYL&m >Tunq=>|3HA>R4$<Lx`tc;I6M;> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda >new file mode 100644 >index 0000000000000000000000000000000000000000..b1c97cc5a77eb187cc8ea8a4031a45a9bf153b35 >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$XOWpIe>wYfq~foB*iDdz~bW@!VvBl0^%}+kYL&m >Tunq=>|3HA>R4$<Lx`tc;I6M;> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi >new file mode 100644 >index 0000000000000000000000000000000000000000..5b871dbaa7c2969f6b4dfc854184a29010bfb2cc >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$Z2vr`h|g!fkCbZBqgK3z~bW@!r<%}0^%}+kYL&m >Tunq=>|3HA>R4$<Lx<*_8th^MU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka >new file mode 100644 >index 0000000000000000000000000000000000000000..5b871dbaa7c2969f6b4dfc854184a29010bfb2cc >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$Z2vr`h|g!fkCbZBqgK3z~bW@!r<%}0^%}+kYL&m >Tunq=>|3HA>R4$<Lx<*_8th^MU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo >new file mode 100644 >index 0000000000000000000000000000000000000000..b1c97cc5a77eb187cc8ea8a4031a45a9bf153b35 >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$XOWpIe>wYfq~foB*iDdz~bW@!VvBl0^%}+kYL&m >Tunq=>|3HA>R4$<Lx`tc;I6M;> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo >new file mode 100644 >index 0000000000000000000000000000000000000000..5b871dbaa7c2969f6b4dfc854184a29010bfb2cc >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$Z2vr`h|g!fkCbZBqgK3z~bW@!r<%}0^%}+kYL&m >Tunq=>|3HA>R4$<Lx<*_8th^MU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru >new file mode 100644 >index 0000000000000000000000000000000000000000..ddf3652e159e4c3cd844bdedf4784dcd29da23c7 >GIT binary patch >literal 271 >zcmWHE%1kq2zyK^j5fBCeHXsJEIU9gPliT@>GwXU9&d$p(IM<igaK0|EfRULA2pJfp >z9DoWKL?u9~wG0@6q>KUsi;r&zL$G6T2uKbLLI_*Q4pa!X@&{DUe;~-Mc60#IASZxm >ckTXCu$SEKi<QxzUauNfHZsG#DP}hhH09Bqn8vp<R > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane >new file mode 100644 >index 0000000000000000000000000000000000000000..ddf3652e159e4c3cd844bdedf4784dcd29da23c7 >GIT binary patch >literal 271 >zcmWHE%1kq2zyK^j5fBCeHXsJEIU9gPliT@>GwXU9&d$p(IM<igaK0|EfRULA2pJfp >z9DoWKL?u9~wG0@6q>KUsi;r&zL$G6T2uKbLLI_*Q4pa!X@&{DUe;~-Mc60#IASZxm >ckTXCu$SEKi<QxzUauNfHZsG#DP}hhH09Bqn8vp<R > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia >new file mode 100644 >index 0000000000000000000000000000000000000000..b434c67fa5a3808cea974aaeec9cb4befa99c3bd >GIT binary patch >literal 233 >zcmWHE%1kq2zyK^j5fBCeW*`Q!c^ZJkg7};{%%`IA7@3&=|Nr`gfdNdi0Le*E4IDnc >uAq>7i><+{*5JK1*n3X&~pql;zK~&YUIUpKjEl3z-H3Nxua{(P<zy$z(wKJFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena >new file mode 100644 >index 0000000000000000000000000000000000000000..bbfe19d60a5fc8b8d1a5e5319e4d687e2a2b078d >GIT binary patch >literal 225 >zcmWHE%1kq2zyQoZ5fBCe79a+(c^iPlq-PB<QBs!fN*t7#Nut85sCvfWi!X0w8rV >v3XB{+z99_ZjvyQy0+IoO5E3l;0nx(n9|%B}fw&+GK{QF0aseHoYsduvED#(Q > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey >new file mode 100644 >index 0000000000000000000000000000000000000000..b1c97cc5a77eb187cc8ea8a4031a45a9bf153b35 >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$XOWpIe>wYfq~foB*iDdz~bW@!VvBl0^%}+kYL&m >Tunq=>|3HA>R4$<Lx`tc;I6M;> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo >new file mode 100644 >index 0000000000000000000000000000000000000000..b1c97cc5a77eb187cc8ea8a4031a45a9bf153b35 >GIT binary patch >literal 171 >zcmWHE%1kq2zyM4@5fBCe7@MO3$XOWpIe>wYfq~foB*iDdz~bW@!VvBl0^%}+kYL&m >Tunq=>|3HA>R4$<Lx`tc;I6M;> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome >new file mode 100644 >index 0000000000000000000000000000000000000000..a4ece7ff2b7aba7f8e99fb8ee4ddbe1d439056cf >GIT binary patch >literal 234 >zcmWHE%1kq2zyK^j5fBCeW*`Q!c^ZJkq-T8%QJx(Fj7&gbwg3i(|Np-y1I0lAsEAL1 >zfy2i)guxw%!yQ9_f{b7sLf9IZl{`N{W&y!}Ac(X1YXG7_)`G-9Rx^-jHy6+$x`tc; >Dq#`8m > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli >new file mode 100644 >index 0000000000000000000000000000000000000000..b32e2202f572b8ca6ef3c5cf1d9e787a24f2c328 >GIT binary patch >literal 655 >zcmcK1y)Oe{9Ki9Xt$}*US=39>YHJ`OImJk57onkU5{bt^(oWAP25I~WOa>97K}6ET >zAO?%6iNq#Co+cUzi5v^D@O)2ACWBx5Jm0%Z+FU-5vyfZ0#jmL`PgqRUEUudiX4`)~ >zkKdjiTX(TTSzf!c$`32LGB~Cx2POTKxo}&yCS<7gO@%)Cb?alF+jg@g+e=4o$JxCM >z7uVg+y^!wOu2<cg&oZK>RCIYm_hc_sEEUl4q~A>>MrH5#iEC$G<WOovC5Q8Rc6Ue2 >zIoE}3u2>L$pZ5t=`+di5p70f-VbQ#&2uFP8rJF2K$F*pjo^ixvdY;V@X|sOD`GdfF >z^+%s(kf3N#L?|j=jSNM{s}Z6o@i$0Ow7eQIiW)_ZqDK*=C{iRTniNrrDn*u}OA)3h >cQ=}={6mg0=MV_M1a02vyP9bQHWWWx70c9krqyPW_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis >new file mode 100644 >index 0000000000000000000000000000000000000000..4bd3885a96f61bbf9c0db6b42956b02d6e2bccc4 >GIT binary patch >literal 710 >zcmchUyGjE=6o${{A{s~>5h6+oNsO`3BBD)5WlVy23%G?^r4S+AB6$Ey0~XN-u+U0T >z@D)@rsEN1MB8!6QWD5%$(fJm%(8A6$ob&AtGcbI=xm;Qum0#7ScW5fAoA0i5J+_L4 >z`Sa9<U0d8K)*hnv<)dj|9hIDVYg#q-d#a7our%t&>UwuvZnnqNZRN?nTMMiExo|O9 >zYdWFIq1Ab?;;3?;72QiYvGkBLFx>0JBLQbHeP$*632UMpbTa96nT)rp+047j`7f&Z >zSX1R+p4F81L>WGh*W>elFa7spiF9o0$BHK@K9NYj(Jm5F68xI%%*>in(4EOHFid^i >zFt|jSe`|^9W3HAr_lC%auBBY}D?}4S6-1Xytqh_Kq7I@DqR^$*=u)eM=!7VRXoaYS >z=;awGhG>SUhUkVUhiHeWhv<hy0Eqz-1tboNNFcF5qJhNYQbz=dN&X?HfDUdX8TbTO >CBFtt0 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek >new file mode 100644 >index 0000000000000000000000000000000000000000..f5d40bafc3912fe7c65f47cb63e52fc6b9b932c0 >GIT binary patch >literal 988 >zcmc(dO-NKx97q3SI_L;`)g%cQ;zCVP$Fa$e@?%s+^CPW!GAalnWVxuRHU<)0%;kvJ >zmFU7nEnEnSD_sgf5h~H9phe6o30H!MgsAsCTnH|rRlniAGd$kg+;g0v@v(qhnb$ty >zVnKWH|Aw}=sqmMlJF9WMyA*p-<Xujb$3Kl!jOVM$H^0T-ajL4Gr076NLRE+N^zEz@ >z6D<0yg9krNjdw-YeBCm&zh-pZ`a4tqF{ba%O`CgbacOutW*TRoOViL>)g0@SQ2k@o >z(i@Q0o9(Kt^18JBxuwDxM-u*#uG){Yb;pNdbN~CH?tGtSx;DP)?x}s#Gry@HjP9D= >ziACMlvSuERY{;X+ITLAK5GQ?A^%qP^|GrUC8J6hwD>aa4lED>6d6KRrr6m93Pei5K >zvyj|8Nfya35T8h?-(&9?%9H6n$?5KKq|9Gc?UzU>;z%^)NUOar&-we=-?8tzXMcS0 >z;hEjD$*$KB7Z4v1C%lFih#QC>h$Dt4h%1OMh%<;ch&z|oAH<<c>k;A-;uGQ&;uYeS >z;TPhV;ThtZ;Tz(d;T_`MrS%VKz@_Z~(gLIhNE47QAZ<YUfHVT>1kwtm7f3UVZXoS2 >d`hhg$(sl%C$))WH(iEdB`JZ9=Y-!~I-#K{P&1e7s > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Adak b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Adak >new file mode 100644 >index 0000000000000000000000000000000000000000..5696e0f8bedee72515c43f686881a561af339db9 >GIT binary patch >literal 2365 >zcmciCZ%ma{0LSsm-^)cYDj-Bm!Hl7RhrdBt9tc86<UwwrWC#iolmVg)3ox8hdC{a; >z&Wf15=#OjEF}7yX*qNL2g>zkSYhaF=n{(Efu39oj-p=>b){C0&@;rN<&*6@@zpuBZ >z`Na&^zmCWJ!pj*jFZYBu%;$W6p>J}<Z*7zHj=VkjoVs(W-SL0wm9ArzPQc+D8Q7KW >z1hsF{!SxlskcuoFnxE-&r^jgbn>&4;$T{s9x$cDDyrdWWIPF_FeM?5@G2f!Er{#So >zrku!k$K?I}r=17(ejp!g9&)0#?32+Yy-rMCy?iLS&WTOz(ThC=PF&zN9k)7hdE76K >zUUDT<#ZPAFrDvkm!(T?}Wgp&B%R7r@Lf^DXtV)(ET7DOg<SdXYOQ*!6(X%pX)oGFB >z_vqyCA(1@uvtIR6uUI{PL8n}NPo)ljq0>gY)tcV7v>2>a=}n)@j1H+Xiw9&@WunSX >z+9h)`gVkehugr~45V_ZKWZry`c>G+feB%47Vy(*3PmY}vPYuNAb?=`LvUN`9A2_QD >z$}j1s8$MBmYrfG%h5f4N*Bi1p^<z<daYB|v92O;`qq20iMLaw7t={n6K~>g$Qg8g~ >zB~`w4P&-FURmIvpdQ)eLs*JDJ-l|2)JD;bkvTv%Yt5tIIvIw#HY_8mL=Z2{HC{8{< >zGa<Gfn3pe%kBZuc8M$rv9Z^?yTh|{tskWzH);pR8RYSzMZY<uT8fTB|rle}sbYZ`4 >zcIT<)kp|szZHapMXrFw=mn(L5?vSslIMG^FB-@V6i}su(xvO<Xbi{b%?s6@5`&a7D >z+{>!-2e<Bu9amlB*Y)1H<Lb5H^ZNCv{i?fnME9I(P`$NB^uA-ysDQwrfZ&k3J)vRl >zd-(YMHQQY-zrWFO1^fLSbpc`ayU_j;Y41^dU9o<DUt7RZdtbbv%<I}%Y2Iq{I$l?S >zxfc|AUHR+HWxctW6TpY_*TwtaBMUeGz{`2tyxbG!_{$u>IqS~+F@ZgYYHE@3Ap^9U >z5h6oGJ4P-Hl4C{*3=<hAGEiis$WW27B7?P>(IUgOn(-n7Mn;Sb85uJ&Xk^sLu#s^i >z14l-V3>_IeGI(V4$ncTzBLT3Q2v|)BkQg9AK%#(z0f_?=2qY3nD3Dkn!9b#cgae6( >z)dU2Ih}DDyi3t)EBq~T)khma$K_Y{M28j(493(nOc#!xY0YV~VH6cP`gaiqR5)vjP >zPDr4TNFkv@Vub_?i53zrBwkh%FeGAD6EY-bRueQNYDn0SxFLZ<B8P+yi5(I=Bzj2r >zkoZ|m0Fek<O$d<~T1^m<C?a7*;)nzii6jzAB$h}pk!T{}MB<4A6p5(SgcOOX)dUrZ >zs?~%Qi7OIVB(g|ok=P=^MWTy@7l|(tU?jp;6JjLBRug0-%2pF*B+f{nkw_z<Mq-Tw >z8;Q2dR695@B=l~N+Y@#VAD8R1EA;XIiuXVD{`(eg%APJv+EdCh(=yUTN?Ce(T6&rY >F{}YG!e4hXS > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage >new file mode 100644 >index 0000000000000000000000000000000000000000..6c8bdf226900d7f4c6a4d47338e6742d4d6747cd >GIT binary patch >literal 2380 >zcmciCeN2^A0LSs?B5>gbMG2`$^d$2B;sFJrC@%;CA^~!{36V--cUTDoWB5j5I&v#< >zv^kuOj&p3aNjuZ6bS=7Rtxe1kZoP~}>DEk^uJtyH<aWNNw*IL3U!G^r^Euq{@9*nr >zXn8uv`qv59zwmMn>X&=UZv7eCpXZ-Q__=MOsaX6zQ6^_kZE^?RSS75%Qn%x!6cN;& >z?4HwJqJo=N`a^1yRA^D6-<chzoUd%~heu7T@R3Qk>xc8|j&H{N5no;vk^T|?ou|jd >zU2mRqM;#s!cke&$zGqv%nA>u|9bMlpVk+9)_ZHNNd8upN^B1+M1>wuwu|c&eHa$8j >z_Qzti@N%Mzn^>&wJL8n`CqmWzN3Tk|t3W)^J0=%-7m9=}-`R_EZ;Hg#=j^1IuSIg& >zaXWc-My0wA*r`)rskG@fJAL$hm2vT9nK^V+Wu4qAm-M`-#H%$j+b2a%M~+-twnr?h >zi<Y^`%_1-7SGnA|O614Qwezo}h=Q44><2$~iH9aXw+mI0didSb_9F+w)QTfVY<KIl >zD%$&wEUrGURyH4&B}?8?r6oIL=}(tLS>~W!cJZvJh}>>hoE#RbuQl40uYI7_eAX?i >zb{<oYzTF_J8~3T2Lxr-o(5KdR#ml<53gz)y((^~U^5$Na-fzpry7+*-?xQqOKYPh; >z7>*E6Or5nG_g)uIjt<-Fo5#h5p+0+K)%U8Y@0ffl^Mcys+b5eNmD*h9lbf#%C|`1g >z^nKE)TAb;!WyGttT#1y=9O@9yj;Gnrbv-7wstCK)yIi#OU$@)y7KrCt$L)@o8PQpN >z!tM;rQ(gHNWY^Shs(ZeY-J_Fg+l>Laeds;4<BLwYv*&fS>y%gatnXDX4CYHm&>Tl_ >z$gQ5xFz0Q20)dWh%hKPCR&XHD+vW%}-w5+dl)1<7wPFK-{@spvb5B@P<*|zD^!vDe >zYxG;rALS(;tDZ}xz7$pJn?4RcoWCxf|K6HQ{{t^)K)>8mZt#~r0ex1Sx%nyX>MJTo >zHi+!dsJDph5zQvKuuG2KCa_OrqsUH?ts;9xHjC`msJDyk*Qhs)>=@ZHvS(z|$gYuX >zBl|`+j_e%SI<j|U^T_Uz?IZg~8h~`bs9RvvJwTd(bOC7t(g&mwNGFh1AiY4Efpi0D >z2htCuAx7O1q$Nh(6Qn6fSCF<KeL)(7bOvb+(i@~XNOzF-ApJoagmegLkx};uX%f;U >zq)kYlkVYY$LRy9N3TYP7Eu>vYzmSF*b;ppF8FkN)rWtkDkhURxLmG#44rv|IJEVC? >z_mK7>{X-gP)Ez`xXw*GKnrPHrMB0e-5osjSNu-rXFOg;<-9*}n^b=_)(ov+PM%`1S >zsYcyZq^(BXSER8>XOY$-y+xXfbQfta(qE*(NQaRY8+DJ7CL48^kv1E3pOHo*okm)X >z^crb4(ru*OmX3FDP)O*l9%p#iZG0^2LmkQgz2W~v{O_BKx);#-jH;zsIawm3DmyzX >IJ4?9!1Y+B7Z2$lO > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina >new file mode 100644 >index 0000000000000000000000000000000000000000..8b295a98bac071e39551940705ea050839e37b9d >GIT binary patch >literal 910 >zcmcK2KS<PJ7{KwLW+InZi-Uvunz$J}-S5=XOj?B$g&*{1XsXDT8XR;Gm1q(Qmx5Z} >zF&yL_&!z%RofJ_7(eui&hKjNuXYu-c-$o|~-{ZZ{ad5}o^L>)LBM-CDiE~ch;c`0k >z^160PpI*(4O5tLEsqpWHUHFlc_r+1Olb@HJuVvY7`0REU?wGx!dMUmwn*F^uQc7a; >z>$P{k&)+kLAMVSax+a?rw@bRbWXhQhSALh;qi@yncV@yiuD+0_v2ELIJDiEvY|HeB >zT)wbkTW?=-tzVv+wyvM9ZFAYk)VN%29I)A2#>Lf-O)j5EF8ydaO|x{aJ+fVgpIpB1 >z+;s0BNYBf5du_$L-Y0eT`r@qg4Su&n&mPFI>9&*J`>3+w)Q?K<H`b%b`-4(NmG@ig >zQO(VPB)TG5y|E67lbm9(>Hm-DH+s*2ks$|l(8#cnfg?i?>fn*#2Q>f^0SSS`K!PAq >zkT6IbBoGoQsG*QpK@EmPL&EX%iH8J4A|fG?m`G40YEZ)>af2EdiHw9sVk5zk=s^vS >s#1HBMAWMKO0<sLqLLf_lEC#Y1$bukCf-DM7>VG}6Wy$pF;`GItV_67C%>V!Z > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires >new file mode 100644 >index 0000000000000000000000000000000000000000..e4866ce1778fd2678a85dc6791a6c1b3fcaa5d1e >GIT binary patch >literal 1109 >zcmc)IPe{{Y9LMqB($yM5gMuO=7AZ0#c+lCRKlY0qtZ)|_6rKtq2!f(R22ra^r(h5x >z2o#rIIs`o(EYX!uEn9k!!Hftx42o_=#Tv`Xr|<iLpy*Jye&gBeVW%Jaywd|Gj(2*0 >zJj>-54o{C9?rSc|*XXsZx_7?czrTJ~Pi)Nk6AP!+<k|~na(qlrHSYR_>o3%Umv79& >zb74I_wazyKS^a2u*nhmUsEQZM=E;V-o;lL&&n$JQ(%ytARqv>0mvjDH>ZYE1f5ptF >zteV&FOeNN>7m~+JZFfl3M(XBs@T97DM*RBQ5#3mwG>uY4eW?xli<NEqYq8sWD;!kc >zZ}<C4L*2?=jr%Lc4(L$psr=^LxNeQ)@@<Jvy6wZ+eEX(Vs=a(TAM-w{nBI}^s8-aL >z8;7Ea`cu7qx<mI4uGGD+GSPjDqk4bgXf$K34J>Q=$4{{Nmrs+s2d$lrd!Dt$ve#^F >z$#@}apO*tI*1oO=BHX=}zEs*v%Gs*oa=PUFzDfG;EA9EYQbR60^5XW)(5*gXHDozt >zJ!C<rtcWb>lr@n>kyVjpk#&)Uk(H69k+qS<k=2pqow7bsfKw_!N<eCGN)bpEPALPa >z11SWl#3`j9wIIbfr5dChr__TKgj9r-gw%u-g{~?tQWpO$bs>czl_8}ewK=6Yq&laR >oht%hk0+9-l5|J8_B9SVcQYKO-QYdER)x7_oX?T~!+tU^P0h%oABme*a > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca >new file mode 100644 >index 0000000000000000000000000000000000000000..9fe9ad6470939d78d5dfd94276f0ff332f1a91e6 >GIT binary patch >literal 1109 >zcmc)IJ!n%=9ES1RG|^ZK78Dc_sn}8y6%K7<#gBR<LqW_^14<_c5d=YTu!3lGaS{Sj >z1fiwTu0oGPwKUZp8*8*f38X~?hk)XysKgMzdi*~}9K=C4@8#UzCDSGElO8yEqBHp8 >zS|Pu1xO(OAzV5O-ZeP!;dl&lk{f*De<mRlNTs)(u)?c(!6JsV{zpJNjJXa51ytWU| >zH<_9I25kqj=F!NAp50SWg-a#-cvH>H9SiHZ<+v&y=&{AhxO#eJNYAHknfZ5D?Lx|_ >z1@qRHV+pgEJZ`J|qN+Mtv!5cTRIRf`*WQep`r4$e7t88%bx?mP?=)Wv3HxpOu=;+d >zUoQ_Ql)KigSB@Pt(YDjMtwR&0tz{_J-t*D4zdx7j*s?}-l#b?NfzvUwI~T8%)wY{Q >zT6=0w%&wWZ(fJQbFRiwHgR4y6%S>y=IoA+s{Kq>I{&|P6F%ptz#JSmY5I9#T1!3ok >zHi$a6RBC8;?p39sh4-NOP%0fH<?K-1a=PUFzDfG;EA9WaQe9rS<ip+B;qmRrYRGcP >zddPxaSrJ*%D{CT)BC8_HBI_axBP%0IBWojzBda6Jdu4s30IyVllz`OWl_HQTyix{I >z2T}-9iC0QNYC($eN;OD1Ua1Eu2&o7u38@Jw3Vl_)NLl>1)P)p=RECs>)aI4qkm|fr >p9#WrI3PdVIN<?ZzibSgPN|{KVUMUna@@c{U&$MZ;#M|4|^aHgk>@xrW > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia >new file mode 100644 >index 0000000000000000000000000000000000000000..9fe9ad6470939d78d5dfd94276f0ff332f1a91e6 >GIT binary patch >literal 1109 >zcmc)IJ!n%=9ES1RG|^ZK78Dc_sn}8y6%K7<#gBR<LqW_^14<_c5d=YTu!3lGaS{Sj >z1fiwTu0oGPwKUZp8*8*f38X~?hk)XysKgMzdi*~}9K=C4@8#UzCDSGElO8yEqBHp8 >zS|Pu1xO(OAzV5O-ZeP!;dl&lk{f*De<mRlNTs)(u)?c(!6JsV{zpJNjJXa51ytWU| >zH<_9I25kqj=F!NAp50SWg-a#-cvH>H9SiHZ<+v&y=&{AhxO#eJNYAHknfZ5D?Lx|_ >z1@qRHV+pgEJZ`J|qN+Mtv!5cTRIRf`*WQep`r4$e7t88%bx?mP?=)Wv3HxpOu=;+d >zUoQ_Ql)KigSB@Pt(YDjMtwR&0tz{_J-t*D4zdx7j*s?}-l#b?NfzvUwI~T8%)wY{Q >zT6=0w%&wWZ(fJQbFRiwHgR4y6%S>y=IoA+s{Kq>I{&|P6F%ptz#JSmY5I9#T1!3ok >zHi$a6RBC8;?p39sh4-NOP%0fH<?K-1a=PUFzDfG;EA9WaQe9rS<ip+B;qmRrYRGcP >zddPxaSrJ*%D{CT)BC8_HBI_axBP%0IBWojzBda6Jdu4s30IyVllz`OWl_HQTyix{I >z2T}-9iC0QNYC($eN;OD1Ua1Eu2&o7u38@Jw3Vl_)NLl>1)P)p=RECs>)aI4qkm|fr >p9#WrI3PdVIN<?ZzibSgPN|{KVUMUna@@c{U&$MZ;#M|4|^aHgk>@xrW > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba >new file mode 100644 >index 0000000000000000000000000000000000000000..8c58f8c23eb0d66d80714a9789b5c20abf043ca2 >GIT binary patch >literal 1109 >zcmc)IKWLLd9Eb5YZKE+13@9if60xNuA{=dF#6R_w3{^2p4Je%yL=XhU!3v_$#YqTA >z5QLV-c2zuwYH6cAjWyb#1X2;fA)vS^A~D3OJ%7)MgE;8s8!n$C(@VZjX7I%EZtst0 >znf$`x>662K^(FZlyOvY;&JXza*FD#h8*={S!f7?N=7O1;7}wLyyMFQdOZDK@Tl4T- >zSkFwa_03>TKN=bFAMYrs(#48-vc92bkF@!-OL0}+lQiYp9rf&T-k(d~)N>!MnEA9- >z^ZLE1#u9oVb<EUvg;agCVLk^>sz!IjZ@e4T%~dJWELYW+`jEd^-KxKq66Ra+p!$Am >zz+W0pD0{WnUp~HHhdNFbHsvRDM<ie9On%axAI}!LHm+1%mBWRYXZ@JoUWnJKYV(al >z(PZPP-Zm50{X;8s|LbgY@8X!=S3DZcT5AI>t^fE5w*CCHV5_?atu0kN&waO9TQ*+E >z+832TyR~m>fe3f6{Xjb7rQ~c;y>fcw{Ju%%?<?*8wNg_qJo4i9%<yfEtcEOytcNV< >zlogRBow6pfD6%TDEV3@LFtReTG_p3bII=pjyi?Xk3UEpVNC`*{PALMZ!YO4Sbs&Wx >zl{lpoq!y$Yr&NQK<CJ=kf{==kl8~B^qR>^vMats8r7ol}q%x#5q&BA%hg9d3@{szR >lQXo<xQX*0#QY2EPQ_4i@L<+^Myqfp_GY#*Qc>8+7KLGQ$?e72p > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy >new file mode 100644 >index 0000000000000000000000000000000000000000..a74ba046226060a01c6255b6714a40211f739a24 >GIT binary patch >literal 1081 >zcmc)IPe{{Y9LMqBa@HCi1_eb#2r1?wcu?1(G@jT&h<34o;Hg6dK~QwaAj-OQh+q&S >z2ozUdqn-}dP|GKm%{<6pMnoM(MYkkkjrGr`@B4uc(V=eremr~q7(4vf=bafkeyl6_ >z<60}<aJYKq@VxP&eB8R0Rrk*g=m%S#nZmZLE-ar?Q=87)smTd5-MFV`uD?(ZU%s=C >z&PL7b^k!{`vgYyFn4a5LRK*Kr`($g~%pVEs`PH~89Z1?z^{!gDl+%mpn`Uw4vRz6$ >zwPZfnN@v0>r;gfMUqsc$>-KZ=303ck>H7O|)7X%*jZ#H@sSWF|mEGoBF=4;Y99BPW >z59rm=gmPDV^ty?ICen5?zdbi;+G4qUd-9WM|9B?f5g)W2Z(f-lD_3-<*_)47D{AMB >z!PaE`so66dH~quwP5<kW))D7iXid{U-pyfd`7t)hX?AXIAqbo+mV>Z!B^yMXdtMH; >zIQO<1it!w@97<<`l$>3vM^3k#-<QbzeVe{t+ce~XOJ3WZ9=%gQwnFwoHbZvv%67<p >zUfB@Y5!n*i6WJ8m71<Wq7uguu8QB`y+bf$RyL)AOWPhXquXKR4;FTVbCXg<WHoVdY >z(g@OtS6V@O@k%pDH%L23KS)DJN9bGPL3-l9r75H<q%EW`q%p5_hP39D-jL>y?vVD7 >c{*VTd4v`kU(j$(@s|5c$%4n~oy1zU66E?ExkN^Mx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja >new file mode 100644 >index 0000000000000000000000000000000000000000..cb184d6a80d3c4976cb78d82b37409190edc65f3 >GIT binary patch >literal 1123 >zcmd7QPe{{Y9LMpWx|J=VK|v7_M*hiF@Sv_mf1mImL|$wVc<K;B5ELCUh+17b1%ntt >zpt$lH^mJH>vwUpXN=OD%BIqC#-HMDg)<2)V@269AsAIqJ?DeqIkA2?Bfs=!s!5_~G >z`Gv!CP!9KXm*wmB^|ZQwp<h4P_}q+dPV4dcGiqY}MLUrjGx^#*J$d7$did(CeRMuz >zrt%xK9Y~w$krDlPZ$T9<mF$yERWoxuq-U06s(2`2i;H*Fvnv@r+jq;%ez<Dq`kb0G >z?`^pwZsvPV*vkG!RT-_?&*4+5+8Nc=ccZ4Zw#U|rW%Z>pq`#JTnQw)-{XThA{kYSw >zmxtrZUF+5>#}1pumebj-nVe~fX0ok`Pp0+bxorEEHLCqZF1xL*O?L!Ks>AHb#um$J >z`^{s`iRx3cdn#sheo5(t)wXwNmFaz*YEC)l>gpT*@e>aH`qX<G!WedLIvE7c6-q(K >zxuOjkom(i?H97ZYu`bFzXgboD40`13RNZpA<orHN^6yh=S;$XSlM9c$xjQ>-b|BLs >z^C1%=GkRr8WKOS4ip+{ki_D8mjLeKojm(Wqj?9iskIe6t1dt58k^+(gl7v^XK+^C^ >z9!MfcCP*q?$puLU$;K<`Ao+MDAtWOtB_t;#DI_cOX>pOf_-{!J$qY#i$qh-)E7>9G >tc_lw2K_o-3q=@8*B#C5+q>1F|l|+$Dy^<=X<Q0Sepx4MgsrW!w<R{OP?j8UD > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza >new file mode 100644 >index 0000000000000000000000000000000000000000..5e8c44c8934960e2010e7b0505966747cb2c6e50 >GIT binary patch >literal 1109 >zcmc)IPe{{Y9LMqBbgLyE1cUw%A*7g#;6Ysrs`ZEmBihBJz*C1P0-@-TL4Q`4PQf5X >z5Gby^20aCqsO3}3RzfnE5kZGV(XEJBV_Et1eLv74I@GP-c=q~j3^w+84-6hV(i!}5 >zt&n#(TuC|Huf8BpH?CyV-823A-uh=|a$`nME}l?RYtGrJiE%SsyRB!gzEt;Ly|WKa >zH<;P!wb~A5%)`-9{b)yC<<A%G;|*0acPOmqmSd{Wldy&IE%o$bR?nxdoB5BI>_W<^ >z1@pm{I^t%r_pq((imJ+3)qaT#scL7FuD%~LwdP)1E0omN%CKH4Z8P8Uar=E{zxr{r >zUoVfumAl-nSB~#B(bnU+P1y<4+LX<;B|e+BPp5M2>$-LO^Ss%-bkug3JtkIuqqkf; >z*pjF|G23TjMw@2Sb0BH^hF6)s*XfqDb1qa@|BsJIn1}yxI8q;}lUEVvX3qwJbNONr >zcCKK9sB<rhp+@K4mP1Y42aWqu13|Bxt*Tp2mz>`>8Tk83yML`zlN&Di;qK(f9r;e@ >zSPfYYSr1vzD=Q*PdSy*yQDjwQS!7*gVPs`wX=H6=ab$I5d9SRG6yTK#kP?s@yix>G >zg;&Zz>OcxXD)CAwNG(V)Ua1Bt$1C+91tAq7B_TB-MWL^X8!3zbmb#F_kjjwKklMUb >s98#TE%0ucy3PdVIN<?ZzibSeJ%0%k)N}-sRpBDW8OdEDeyveSHpJY<*WB>pF > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos >new file mode 100644 >index 0000000000000000000000000000000000000000..966a529ba9ed8a4fc6385077cf188f95d47665e3 >GIT binary patch >literal 1109 >zcmc)IPe{{Y9LMqB)YV!-gMuO?j1-v>Jou+Yf9#1JglHEV6rMUr5C}zw45F+{r(h5x >z2ozUdgPsCQoaIx?Rvu(9C4vq@(XGf>WBv2#`+guOI@GP-k7uvncKWf;JKcZcct`NZ >zwMu^BaP`RHdBa8dxOp|B?w#w?_cuQ`lUp)+a^aMk+IZehO^lm-?T((l_Ch^)`Nlpx >z8#OceP1^Qn%%jm!{diA76)u$QlcuVfJ=UOSSK3waK*AQ6ZmVaPvU)Cc!_2+EZ0A!> >z&6{_&9Pc&@$pKs07g3e5s{IrmRMn1{uD%^Jwe?9`E0)#g%8>q2-f6xTy6v~=!|MC3 >zKD{#1t=yF^y?XqhiL{)|ZOcxWmRL5|n)qm1Kb*<6ZC$6@N=I|?U|Ge@?p*s)S#7_5 >zq&ZQ2YIe=E8=YTPdU37o9a>|0Ukx`8JLf`m_5XN>8-BU#!*%j4?A%OK5I9#T1r5#> >zZ4hy8u@q`_?)6eA#&ghkD3uP9a(1XLIh}HT-z5F_mG=K!sU{Cx^5X9F$lU>CHDozt >zJ!C<ztcWb>l{Jw?kyVjpk#&)Uk(H69k+qS<k=2pqy|O-1fLAI&N<eDxN)bpEUMT~q >z11SWl#4DvBwIIcKr5dChuhfGSgj9r-gw%u-g}y2tq%8hh>Ou-bDnm*`YV%5QNOfK* >p52?>91tJw9B_cH<MIu#trA(wwuM~>I@@m2V&osJM;_c~-{s0qJ>%ss4 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta >new file mode 100644 >index 0000000000000000000000000000000000000000..b19aa222f91d07c4fcdc8b50497244c64f2df1a2 >GIT binary patch >literal 1081 >zcmc)IPe{{Y9LMqBbk-U|gMuO=j1<`-cu<#78c*yXM7x+!c<K;A5F{Nkh+17b1%ntt >zpt$lX^>naAEuUPr@*smPBIqzEx)l*?tbaaz-%oUi4t47{p1mG+`mxV@X!zubuHcVn >zjr_vl>662K<0bjJbuFvzogdWqw>&d5+p>D5GNNWTU9hv$lV+}QSI=L6p&q<^V;`Q2 >znuWQ|+74&Uqw#UQxUZlJ7fbf>*1B0b7S>Cv2~|AMYm3!8>gna2UQXXM%kQt)m9$eU >z=AA9alcth7ZfpG!Rhy{WPc5fZy(^~cZzoJ+L&`RaW%ao>s=t(Xo3DkW{WgDCeV-cC >zt7A#!uJ-7)lLt+t{d9guZrZfRa`}$lkEY|p*?i~r^{TUUG#?L~j+?#tM76AT-Z;|M >zTYqBqEF{dp=sGj-D$|y6&V`zq|MAlj{`qObW;rd+Elvf2bA?h6cCKiHh;z?Np;qT! >zS3@!GLF=LPP>_<dOZCX<mh<}(Lx10<|JODRx$wwqyE9|AE67&JUdU$1ZeH0A+0QE* >zB0C~mB6}j6BD*5nBKsm6BReBoBYS&gb7Xg~Y>(`ZG~ksEkQThs1JVT21=5CB`al{% >zI`K*?NH1P#2I&TA2k8fC2<ZrYOI)NU{#%+tx<cAQ`a&A>N@qxGUg-^K&MVy^?IHak >a4I&*PEqbL#%*d+*|2xWPpQO6KJNg3zGUb2( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan >new file mode 100644 >index 0000000000000000000000000000000000000000..9e5ade6100bb4a12e62827a596c0fcc29df53915 >GIT binary patch >literal 1123 >zcmd7QJ7`l;9LMpSrqLJ*1{4$#sn~~!2!}q5_&g;;LF`fkLMI0igo5H=1<~l@Bm^V~ >zLQA4u1y6@)Nvpk@)@Z>JNJRvPfa0d8#1LOS{=dgb9CY-Clg}a3CBJWK<m8DS?~iAd >z{KDZmD2My{OY(K=T1MSHKdkR<dTOS(Wc2j%X;s{C!7mmj%}jGj&t89_?!SEFKR6dL >zb2A&YKaw#ICnofxy(Lw;Sn=mKH_XDZR=uziSLK0(U#{IzPcCQm;?PaA`2LE&G-TD1 >zdFNMS{bo6N+^_Est9q{Ce-4eRMo&~X-sVhmUD9ustLjUAOn<HJGT%!5{`c7<>c{P2 >zy)xdf?A1QKdh(D7cbv*^%N9&WG@I{Cd@`LM&gQ$fu2tR73i<6_T{`A{R57zBAFox_ >zjvGhY6OG4a_gviQV$KW%l^z^hV+LQP+tb$CKuho+KcUuNpB6_jgduC^<~`5aQpIbv >zw(NUhYoAvFZPvc71)|)&w!=dyFDYlI>XXwe=l5Y!f1gUrLT;+2TzKTo?V0hZS!6n7 >zK4d~<MyE`P%;}U#ky(*xk$I7ck(rUHk-3q{k=c>yk@=mH0Fr@IQb2M*l5k2ENE%Mb >z14#tQ1WCmyxgg0P**GN~Bp;_Fgk*%Igye)Ig=B>;EiRH5|1F6jnIWkmxgp6pB|9WN >sr{squh-B!L6p<W}B#|tUG?6@!M3GFLk}9U<6}|tU*T_Dp_&{&uC$tjnjQ{`u > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis >new file mode 100644 >index 0000000000000000000000000000000000000000..af8aa99860119c9fd4af7b9356f7b548b771ac1b >GIT binary patch >literal 1139 >zcmd7QPe{{Y9LMqB+<v%5he1Jq>5^gz!Gmrs=-(qdtRyeCLwM>CK@b!jGKjJ+odTgo >zC&iU?3w)w1nU;?&TS<vABf1Giw}QgPD)s66evWmhW54nEdKe0BpLf3J#PPP^kEc=I >z;qdI2!+q@~`El!7zj|=KTR+_R!i;U{*JJaiRcYM?TN)iU<Mq3G;>KI`=-mhV_*}wF >zj<46Yr{7Es4(cbn%c^{F&OY5-Gt)<7dU~Z*RXQ@ZvM{2aUoPmGuA64&^A$VW<<zYC >zWUJfLW<Gn&F7A!1#i5%07M@hKwxq6o95VGaSzE7E)%V3-{iC|m{4A&K(!^o4e5YHl >z45XF2n$nHKohIINs<^c<YMPRTVsqxJX<oivY}t^~Ew9RETW*uh)Sj7LldVRVhD=9P >z>0IwBle@lD%vHP1fiGwE!Fwsw`TB_NbIwH?qW|~`W4z>-!)VwL#`v=^bZ+Wp5I9$! >z3u4YyY!G+u&0J))bMF@-N$!E%dFN19KFG@1p;B_%<@`QR{_m4%S;|jVmkW=40(WL$ >z<UTSXG9xl2GN)H2MP~KNw8*^3#K_FZ)X3b(<jCyE^vL{30!Rj4Ndd{hD@h<(AZd6d >z4<r$<WP+rE<bovQm28l7kbJz75R#EsQbKY<l0vdV(n9h=pBNX(jPI7zklc{uknE83 >xypkW1pjR?PQbck@l0>pZ(nRv~N}^uL6iF4y6-gHR<X;T_qiz#>r00F@iC?^;`#Asr > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman >new file mode 100644 >index 0000000000000000000000000000000000000000..bbb03a0c705626dd22776818b61035ff501b7932 >GIT binary patch >literal 1137 >zcmd7QPe{{Y9LMqBrmH1FgMuO=7AfK)c<@h){_%(hEAnDO;i(`3At*Xz5Vg8=3WOLz >zpt!VS)YHKdxAMtlD+5`~h`@tTbSo-sEGwVB?<YD$hdTEA@$B{6PCxc}clY!jYYP6j >zmdP(1E-i=W)fePr_)5RJd$vp8TldtAZRpoyvnSQ~nsau1bi`yUcXaOROLhO%8~fl) >zjhV=<)wZYKJRBU<lRNS%f4*oRtuLFY!_|6fDWM8&Nn4n|t)5&=>*>zxX8QdlJJadZ >zjCp5Ejjd+3{it2o6;%sEW&1gDT$P(*y8L#?R93ayN};5_EcEHc(pK{|-)g_*4yf-p >zyY$jPt8$lH^zxB?CR%qQvnf4l>SF0kee#p3|8P3fuyLhoC?3i*22MAc?U}@UNo~G% >zFrF+wHrpl=MrS`N{p`8!=v!er=2G!Ji^FDb?npf4oC}4k{_&1f|GdLk6$$%q5$7i7 >zg21_aF{pN~V1uZ0FN&dB=U&f;Vmt@6`#ZaXb~#&Ai=1XTzpvB%_r2PF?NyNnE_ro# >zYT(ulWItp>WJhF6uk49z>XluQZIOMEjgg&^t&zQv&5_-a?UDVF2E5V%(t=ldK$<|h >z@Jbs<A6{t$=>%y7>BTF}Al)GCc%>htA+L0Vw1o78G=+49w1vJe9;7k;TRKBpLwZA+ >zL%Q=ydq{s?X%OkqD=i{DB26M)B5fjldZkgMQ?Im&^olf#DS6f4e+ai`r{ui5x#kCJ >CU-o<e > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia >new file mode 100644 >index 0000000000000000000000000000000000000000..07e4e9f0bd5f87ae067f613f52ce4327dae4f882 >GIT binary patch >literal 1109 >zcmc)IJ!n%=9ES0mHqjUh78Dc_sn}8)5f1$@;zvD_p&-Vg29!<?A`}G0!3v_$MI3~J >z6hUZdw5#ChP_1n>M`Mk4D1o$y;1E#U6qOj_SC9YafS@?&<_#ymn=HBHebRmX$J&EG >zu4VEKhpSr-_iHZ5+s&(k>dx6-eRuscGr4h4PcEEPQ)|!JsfjT&T^rXk*Pg5UFJ9XR >zXJRHdy-wS{LGy5AL_gY@SNZcr`*=gu%pM8r*`>HD>`mB0`L=p`aY)alZkV}um+XAX >zsd@9(mfE_^Lh`7s?2f9+Xw`m-99Px$MqPa~YHF*KwpJ*q&y@lFrL@g_&3D;vGY8f8 >zTfKT|xJ$V!oqGA$J`-&|k=;BrVVWC<vMq^^rse(VZ0n{~s<n7H+ZKFKZDvO{UM{IE >z*AF!%s!z=JT-@k;2b5l1X?q4%n4XuJri^ngR9F9xuSocpSAC>TK1H0%)q=ped@%?+ >zSFl0Uxy53r!MRuEP$Tz2!~Rq{NXpr&I^}f8`F)f0-&fl6b0zsPf60TpQ^Vtzk=2mp >zkoAxSy|N;*q*vBN7DZM?mPOV@7DiS^mPXb_7DrY`miNl~NC94{04V{f!7D`|Rd}Tg >zqz<GIq!O=`g4BW(<CSWVa=cOxQV>!RQW8=VQWW~CxRJ8>bEyj{45<t$4XMp5#Ua&s >qr97lQuM~(>h?I!bh!lxb>6J2(I=xaTX5`U=|DS1Wm&DuM5&Hq8dF)dF > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba >new file mode 100644 >index 0000000000000000000000000000000000000000..d308336bec9a539742ca3885c44a4d3c5a674463 >GIT binary patch >literal 212 >zcmWHE%1kq2zyQoZ5fBCe7@MyF$eApsr~GZk8xICXrvLx<$1*Vd|9@Zy1Iz#a#}6=Y >r`S^w~=o*+98!$Kqhk&#KK?n&J{D5cyn)&}f$RZF;l4V>#dri0im60!* > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion >new file mode 100644 >index 0000000000000000000000000000000000000000..3c61ddb5a7a9956e2448ec7185edea75df08bd3e >GIT binary patch >literal 2077 >zcmdVaUrd#C9LMn^nI@7RGzC<$KN^W}_#V$0V8`%BYLfEDKcIq@{}qhzpoC(7L~Ghw >zONy3x<#2AgY4KH-<wf$to61$NVYS&-a@TA!)cGgoc>2AcwRO=&m#v3Azt^*8aKZL` >z-sM#_n`Z_7agA_qxViSZo9AG&JHAM{)pGyL%Vy-g0Zr^~u%i!M)TGmY*avqF$(Yt` >zGqx(M!G^UqdE-1CSMi}4|LoWLP=1=3ka15YrWM<iQ8}72*lbd-ZjiK}JM5%yf0N1Q >z^X-&RCu{nVTJ!M1GMU<Z#6A+=r;o1dHIFSHsgKWJWu`@AGQBWno|sUl86!GP#_gl> >zWdA#6h8AgN_m_6&xlxjJ@}$X*Cu!*2Uu;fUze?RW6V9!cSt~;}GWLu{^MW>dw_9>2 >z-mtlSziZy@OE$mjJDvUGS^HF5yT&?u&7AhL@^pQREjakG%&q#wm~FeIu)g0s6FH^x >zmiCzW<KNQ-;WK8z&A2X{^u1l!yG)A))jrn|)kT*-u#3B5QheOAC2i?adZ5piHG8ro >zK4g}b*2=OaSIqKIsg%nFQ!z$lMevweai>^U4(vCpehO)2PqnG~JgBSBy=9;O=!U*< >zc(Z-6@sh4-Dza<WT$go~nRfl$UfD1^$!?tbnQTh!x0}2}vL#`(+45_XRQFvoHJz(v >zYge~<>BLU0Z98pVe!EiZ_O_aB)iI54ZMXGB>AHQ<`*uf$rwy4q>?_Grq%pC=HVzEQ >z&Z~KLSI-q`x|n8n>jinWBiFpva!g)tO*L=C_sgE`gJzHCdBYO!OBnuN{tWlLZw3MZ >z|8&n^*}wyy_d`!0iF24cc~e|c9w>BownW_>ao_IWSNXqx^>4c0_P_eOfBl*J$Gw^Z >z$t}nVc+C=!H6V*XR)H)7SqHKZWF^Q_khLI-K~{q-2U!oYAY?_pZb`_RkVPS@LY9TB >z3t1SlGGuAU+K|N|t3#HDtPfcrvO;8uzHW`kB9T=h%S6_REEHKOvQ%WP$YPPzBFjbA >zi!9jJtr%IduUj*+Xk^vMvXONo3rALtEFD=pvUp_m$nuf(BLzSzfRw=3)c`4iud4!5 >z2BZ#1A&^QSr9f(d6a%RSQVygZNI{T_ASFR+f)vHqRRt*vQWvB!NM(@HAhkh?gH#78 >z4^khbKuCp<5+OB0isb96gp|qG)d?vSQYoZVNUe}!A=N_4h13fv7*a8$WJt}Bq9Ij7 >z%I53ph7=B|98x-@c1ZD%>LKMr>W382*EJyU|Ic9J92dues5>JCStVf!g+r1fStXHB >Il!wGW0YAGNZ2$lO > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan >new file mode 100644 >index 0000000000000000000000000000000000000000..5708b55ac6bcb7580498bed9721a43fbd5a1773f >GIT binary patch >literal 345 >zcmWHE%1kq2zyNGO5fBCeb|40^B^rRlyd4W0=I{DhaN<XJ!s(8G4VRR^6kJN={J_M> >z#K_FT`v3nb83u;`|95U+WcmMp^#TSCFq;QV3V=uk5g*?W24@!_4hG_IAPxv&a0RkK >zfDuZD5Ox*^P$}41KfroGw*LQL^sXfZM1!0OqCrjt(IDr7XpoaZG|1Ut8t8NeD!ZKv >I=owQk0JN5Mg#Z8m > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Atka b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Atka >new file mode 100644 >index 0000000000000000000000000000000000000000..5696e0f8bedee72515c43f686881a561af339db9 >GIT binary patch >literal 2365 >zcmciCZ%ma{0LSsm-^)cYDj-Bm!Hl7RhrdBt9tc86<UwwrWC#iolmVg)3ox8hdC{a; >z&Wf15=#OjEF}7yX*qNL2g>zkSYhaF=n{(Efu39oj-p=>b){C0&@;rN<&*6@@zpuBZ >z`Na&^zmCWJ!pj*jFZYBu%;$W6p>J}<Z*7zHj=VkjoVs(W-SL0wm9ArzPQc+D8Q7KW >z1hsF{!SxlskcuoFnxE-&r^jgbn>&4;$T{s9x$cDDyrdWWIPF_FeM?5@G2f!Er{#So >zrku!k$K?I}r=17(ejp!g9&)0#?32+Yy-rMCy?iLS&WTOz(ThC=PF&zN9k)7hdE76K >zUUDT<#ZPAFrDvkm!(T?}Wgp&B%R7r@Lf^DXtV)(ET7DOg<SdXYOQ*!6(X%pX)oGFB >z_vqyCA(1@uvtIR6uUI{PL8n}NPo)ljq0>gY)tcV7v>2>a=}n)@j1H+Xiw9&@WunSX >z+9h)`gVkehugr~45V_ZKWZry`c>G+feB%47Vy(*3PmY}vPYuNAb?=`LvUN`9A2_QD >z$}j1s8$MBmYrfG%h5f4N*Bi1p^<z<daYB|v92O;`qq20iMLaw7t={n6K~>g$Qg8g~ >zB~`w4P&-FURmIvpdQ)eLs*JDJ-l|2)JD;bkvTv%Yt5tIIvIw#HY_8mL=Z2{HC{8{< >zGa<Gfn3pe%kBZuc8M$rv9Z^?yTh|{tskWzH);pR8RYSzMZY<uT8fTB|rle}sbYZ`4 >zcIT<)kp|szZHapMXrFw=mn(L5?vSslIMG^FB-@V6i}su(xvO<Xbi{b%?s6@5`&a7D >z+{>!-2e<Bu9amlB*Y)1H<Lb5H^ZNCv{i?fnME9I(P`$NB^uA-ysDQwrfZ&k3J)vRl >zd-(YMHQQY-zrWFO1^fLSbpc`ayU_j;Y41^dU9o<DUt7RZdtbbv%<I}%Y2Iq{I$l?S >zxfc|AUHR+HWxctW6TpY_*TwtaBMUeGz{`2tyxbG!_{$u>IqS~+F@ZgYYHE@3Ap^9U >z5h6oGJ4P-Hl4C{*3=<hAGEiis$WW27B7?P>(IUgOn(-n7Mn;Sb85uJ&Xk^sLu#s^i >z14l-V3>_IeGI(V4$ncTzBLT3Q2v|)BkQg9AK%#(z0f_?=2qY3nD3Dkn!9b#cgae6( >z)dU2Ih}DDyi3t)EBq~T)khma$K_Y{M28j(493(nOc#!xY0YV~VH6cP`gaiqR5)vjP >zPDr4TNFkv@Vub_?i53zrBwkh%FeGAD6EY-bRueQNYDn0SxFLZ<B8P+yi5(I=Bzj2r >zkoZ|m0Fek<O$d<~T1^m<C?a7*;)nzii6jzAB$h}pk!T{}MB<4A6p5(SgcOOX)dUrZ >zs?~%Qi7OIVB(g|ok=P=^MWTy@7l|(tU?jp;6JjLBRug0-%2pF*B+f{nkw_z<Mq-Tw >z8;Q2dR695@B=l~N+Y@#VAD8R1EA;XIiuXVD{`(eg%APJv+EdCh(=yUTN?Ce(T6&rY >F{}YG!e4hXS > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia >new file mode 100644 >index 0000000000000000000000000000000000000000..6008a5749d01875a6995189735aa8b4e8747d250 >GIT binary patch >literal 1050 >zcmciAKS<PJ9LMpWRuWffOGA+Qn21<seY@YKSD7_MLK?vj`ZF|zWDYen)DYUxBosv? >z*z!yf4e>0&83YEFHW^U_rsvf)RYOMEaTZVC_tV%ELC^8K*KzPWj^F2<oEYfOM1PzW >z`VALnpI&@kJFIWF?hS6r*Yy<hKlj`5#jHFmoHw(%`!f5nB6Azxy1DV=W`22t6mA#H >z!u*&Nlh}M6_3qoMlV)k+lzgvku;n9ZDNj8ymDCGYxm&i&pK9dC$R%6<?5Z?ecx@Z) >zPG{m7+jMzAHm{ks&BxZe=6B~zOXnBY@^Z?wHq}Y%qmpfl7Nzaxh}rUCo!dH?vFV8i >z(%wI5w%JkHe&CLg;fu1PzSm}s8W-1`G1*)q+45u4VH%}l=Ctixdg^ldD`wY1Np@dL >z+db3Xb)BuXdnd0;ci(5*H+Ik+?zv%xy!TOc)jzzdy?^sQio7ost5$md>Up&KP;U~o >zOGd9)A1f#Miz&*#Z_!`$o=K2df;tT{4>A!lQ&6Wu<_hX$$ZW`T$b86z$c)I8$ehTe >z$gDw~7MVAw6C*PtQ}g$k8<`xL9hn}PA4veoAgC!IIRrHcB#WS?f#ea?M3797RFGVd >zWRPr-bdY?IgpiDol#rZ)niP^%P}4&4LJ~tVLsCO>Ly|+XL()U?LlVRxeRlsL!&H|h >I*&U~T0UU~E(EtDd > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas >new file mode 100644 >index 0000000000000000000000000000000000000000..21e2b719f33d6195a65cbce81764adc92167b989 >GIT binary patch >literal 1588 >zcmdUuTSyd90EW++VwvDzB~b)XffQzHYIZYiO*7ptx|&(7YuVa%(J@V|yc|e`AaV?X >zNQ5A|QKUhcW)HpOOITz?B?LYQMFpJ#Ns5@xH}w)hP;dQ*Gv6?<`}BR@(qJG-{I+oY >zh0A>U@;+1Q$Hm?^X7{J6(cVC@|Bidu-xrzc@B7xK9=@&dzv#H7gfL}dWvh`?8zYzI >z1dQZ@37HbR-bhUvk;}pt8ELaWi?r8~#`3Q(#ftH0Yh~{fv8pG+T0PJu(%au#YdTv* >zM)e~rv$a#M-PB{bE1G21lGE0@tTLG$RcGZa$dow~9Y${Ge3|>A*4Qu>CiD7=jQpW# >z%5!$1*m!+hZEBb*HlKX1wv@-pf&=}kFmsCZ=69;1x$k6gT$9==hGfZ%b7skCx7;?~ >zXqMjZklUa6%pF&6h@H1HOy3Dhl%1Jp`h$l=d2_njmFpF|eREaC!c?&*Jwyef3uNV- >zF;)2~S?>KdsDi^Wa^I^fYX8j%d0_B?d9Y(dR$aPmR@dB<X4?s~ru3ya6xeUpt{4z? >z*&g%otS(W%B&h1Yw1|eNJk>B#E{=Rytd8Dwi(`+YRO5v**>vNhYCfJRTTVSy!WH72 >zNv_a8oUo98JGR~B6+%BP5o+7l&Wp*m-7ZBW?=Hi(`+Ho|e|*pPc!j6XE8O~S*4LAz >z-}U`<-oG$v;^$9oJ<NjG1u+a_8N@V)+BS%B@P~E$ktum%AH+b2g%A@VHbRVqSP3!H >zp|%rZD8o{SsSH~o#xkshn9HyiVlc#Fh{+I}Ax1;2hM4V8+YK??p|%`iI>dH}@eu17 >z=0ogf6ac9JQUas~ND+`KAZ0-6fE40TR{|*oQVXOQNHvUdAoVZ`f>gvP2~rcIC`eU| >zvLJOq3UjC{gOmoT4N@GWI!Jkt`XB{DDuk2>sgY46q)JAakUANKI@FaiN_D7fWfTjk >nmQgOGUP!@^isAoPa)b^&RR<pDNsdp9Pl)p*Cd8-2Cq#S)zm>O& > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados >new file mode 100644 >index 0000000000000000000000000000000000000000..6339936014862e144f8beb04b55b617f9834c3dc >GIT binary patch >literal 344 >zcmWHE%1kq2zyK^j5fBCeZXgD+1sZ_F%1V`|J6e;U@-cjRz&EAm0{?V|2LdH|7X-^5 >zJrD{BxF8(=KS9L6E`WiNnF$L2|34wkzyKy${{O#vfsy0?|KkT3czk?A7@UCE(FKTu >zLx6@uKnMv=`T^DR9|%BB1JNMofrLR$1k*rgf@qLaK{Uv@AR6Rk5DjuRhz2<wL{sQ| >JE}&mbxBynQR5btq > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Belem b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Belem >new file mode 100644 >index 0000000000000000000000000000000000000000..b8e13b02fe93679946331a1736945d033ea82525 >GIT binary patch >literal 602 >zcmb`@JxIeq7=Yol{vc6wa&WLcofVEo!9m1T&_T$egOdo|Gq^}~RvZ;{xltS>W829^ >z)JZ9bP}&-C)J5<oq{{idaTEl>3zsJZF64Xt<>Few`LR0W4V#sh&2!(T-1d%xpgb@a >zl|N@q<#|F^TY;)io#^^wq8mf^VWYC7n(aZ|I&7)C=7ElUPrdBh@U?42y`8S=_x_xT >z7sqsbex?$)7A8lrX+L%AkL?XJe7UQ0>$fIvCPU?2nUSrc9__s_C2Osd&HQp@t*z}i >zj<pX_rqkM+Yo}*^!FR@WLAEEq&GP>+YW#gfzGy8YBV(t^=*aj;0whDKq(E|{N)jXs >zk_O3xBtkMFsgPVqG9+87q(kzhN<t(fl9JyiCz2G&iljyIB8jmiXa6CyJ1xm)JogLX >C#sD7x > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Belize b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Belize >new file mode 100644 >index 0000000000000000000000000000000000000000..7dcc4fc5b77151e0997e46204d584dfb6b464c31 >GIT binary patch >literal 978 >zcmciAPe@cj0LSt7c7=^CBqYL%gr`y{79$gcJXp}d;6<+(f^_mAbrB<opg<2&SH(kr >zE~}-zblY72AiHImf0o7U-zi2sIMTsW(jlZ%(|jjyoxC*5+t0G_F7y3`m#=r!dH<X; >z`wtJN!9M)1=&@e|t*g0ox=|0FIj@GgtMrp&o#JV$(Zl6|7&*0}N4DxjbojT7J{=IF >z2`xvn+hS~UL1rFQs28PSnZ5N>y^QY3@k?J-?*277QJ+_nUA=nh;A1r%bm-~ryJ{wN >zR?n<I68ZhLIzM+u6n^Z}uhLh<>(v@L+ubDI6!yxuZPjA#;dlA2DK6%3f0heJ4yi>k >zA(!^}s@O0fi<{q6sd`+ON=3Eo_v_^-Qtvlz>Xp7F@nQa={@C?QB-+<xqVOfCym~`c >zW=;lP%-{7V9*f6}$p)Th%;a;w%$Uremo%o3^UGV#h2GKBiQ_4+`9kP5pAPN){XO9> >zZvEHJJH{SvA1Q!TKuRDrkRnJGq>R(nK?*r-C8U(o)<TLQ)sS*XJ)|H~5h;n(M2aF+ >zk+M!(7b)ztm66g;TN^2kR7c7q^^pZ2D?pZjtN~dBvI=Aw$U2aPIPFT1r8w<cki|Id >fYLMk1>p>QTtcW};$!XVwEXw&`SCzCgt55y`P>t&N > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon >new file mode 100644 >index 0000000000000000000000000000000000000000..abcde7d98693a9d583928c6f1acdf46b190a500a >GIT binary patch >literal 307 >zcmWHE%1kq2zyPd35fBCeHXsJEMH+y_ydA9x^LO11INk9m;ga%~f=dZ+FEBAOF|#oJ >z|9`54f#LuEs}~qq{{KIIfPn+d<^hueKE5FgjxInP48-9;91sFDje&s?OoR}21v^k7 >w*cCrOI)LCm5X9M90?q&bALJ?!4RRTX2DuJIgIoxvfv#kr+?iZJ*PCzw0K7tFCIA2c > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista >new file mode 100644 >index 0000000000000000000000000000000000000000..f7769048cb33e11fb0a1486696473e8820666be9 >GIT binary patch >literal 658 >zcmb`^yGz4B9Ki9kJ}C9IxHwd+T@?;n(2B^Zs|rFu@DES~Cl}qSt{nvtbZ}Is8(VS6 >zR@?+1L+NXA5DHq*T3Y4&edFjLf)_5I5Xh1Hp1ZoSHtzfwZSsc6h{@!+dsl9U7pY37 >zZ{;QPxn#1nIel5$SNX{+ov(&;Vc^*-WY<-(71O2Tswx-Hbj6)juSY%JTgRrVdt3Uw >zchoeNr*tECtD518*F5hut!lsiNT*HY`a}=zJer}?c`q6-n&G`|J<|1HChB+IWadC6 >z%Qc;RikOtO)(HlFxq{Z_qK;$j{Y{`<o;@eDu;@BtDlRi2TVc3=*nZ>t6Isz(G9W2@ >zB?poO$%3Tul{`oyU&(}|LUJL=kZedgBp;Fx$%v%%m7GXYU&)H3Me_3dBt|kLsgc}B >dawI#F9?6d!fv+3`rey7ZI*RbL9Lr21`~|^N5w8FM > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota >new file mode 100644 >index 0000000000000000000000000000000000000000..d8934466bb728c88b211dba172369f5105b6300e >GIT binary patch >literal 271 >zcmWHE%1kq2zyK^j5fBCeRv-qk1sZ_FjEK+zE#~3??R~Kh_5c6>XJlq#X8!+w*8~Oz >zFv;@&|M3Hi9RL6C+`z!&;~T=@1jM=qCO~Wo)D8h5ge_$Qssvm51F8pT*Z;UVCLcgF >e$Ppl6kV8N;$T1+g9w^5^mW#M-fbO$1<pKa8PC)wr > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Boise b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Boise >new file mode 100644 >index 0000000000000000000000000000000000000000..ada6d64b1afc93b62445fb8697075fd6be6ed3b6 >GIT binary patch >literal 2403 >zcmd_qeN5F=9LMnkg2;`BQ;8v<l9o3J5Kt1xj0!}A8-!Q58etU3u2$efH!Z|tP>jDg >zOGlJR(37@iD!OK4LtMkPmCaqZrnRu=nq{MhO%@No&inLdfAnu#U-rAN-|k@JpU>O7 >z!M`b6{Np0bH$2>n=HWd_nUCJLR`<O+7^nN5Pwne}`I<hwsx0}V&L|yR^ha~BE?)dO >z{-m7v(I+M^R?Ddm^TqV3Jn0-x5~3$jhICAe(5I&4jI9YOtZuFjub5Ob3np|#=BSDo >zSfC^2u!=l#T)M_yQ`ddjucI!V7SY3PI_CX;5&L$ZlrOc3>pP#7H|%N<H~Q=4?DfSW >zu4I**lb0fHO1VwOFDz1XBV95f)U6VJTdWhmj#Np(S$f`?pVa*0SM-AZb1FG7Pu{%u >zs9Lzrk&8BeEN;p9O5VEWU9mXs1L;oH!aaRir?|F>l+iOf^@>;AKJ>ayyU?uCd!N%8 >zCo0vF)<&JVZ<)$!Y?s;F=cuK{o8+>}ah2m<E$_(wOf8Q{mAQ%6MD7n!GH>FN$Upmw >zyz}!xvErCZ-!*tptnB((-+f?@C}{db-_w3T-CKT4-&em|6)t%}7Zq+)MZb^8;`A0# >zeBqERiLMnTCpzVts|BL;l{a<Sr!~sc(xLBvZ>1`)@#~82Wc9#`Qe7DcRcn*dwRhdO >z$~zgWt8&h&s_)XIZ~iyJHxeV)PmhQVZ;Z(YM-Pdb_Mm)ds8iI|pOhPWw}^*5=XG62 >zhk7J^KtI~(SM|~RbwhEfYPcHEjqY^Sc+RK&5wXgDBwug-{#Ui7yIMYWK1Mtq$dgYT >z9TQDeiL$vXD7NNI$!$$1#rC+%az}Z$*fBk!1Gxh#F#3hw8NXlc96GIcjR(}zz5V)` >zi$2xT+NO7(%2%zm4SG*ck_rtmKjAaN!e{=cejI0CtPqZKP=|y$PL~q19Os?BkSO~p >z`CiPn@9||Guc#<A&swkWRGX*5JiMFlxDfjZ-hZE5kNIUgx$(dM%KQh8QyZ2rj7$)j >zAu>f|j>sgDSt8T4nt37<MP`aj6`3pA$@0Q%IWt{gz8n)qW{gZ3nKLqJWY$(QZDih7 >zGjU|*$kdU!b4(tYJ;(Hs`Ew)y$pA+RkQ{I%0m%YK8jw67i9j-8HK{;yfg}UT29gdW >zA4o!wj36mNa>9`mBr6<gLGofXi9s@BHK{>z!;u^$J4kwv{2&QJGK8cE$q|wyBuhw| >zkUSxYLNaAFsX}takt`%z9O**x#gQ;1V;m_%a)u-g$r_S2ByU!eI3#mclR6}KR+Bs= >zdmQOQ@`of4$sm$KB!@^6kt`x<MDl1gi9|AKHK{~$X*J12vdNK7B%d4!MKa2fQY5Dw >zNky`Xq!r04l2|0OR+CyJw^ox}B)e9VUL?Orf{_e!q!`IDN0N~&bEFx`Ge@G4Oj}K= >zkz89%vXN|CO}deMBMC<`j-(vPIg)fF>*9aZb(hKga+CWs&(e(SjLbAoR#rw<MyBg8 >DiZO5? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires >new file mode 100644 >index 0000000000000000000000000000000000000000..e4866ce1778fd2678a85dc6791a6c1b3fcaa5d1e >GIT binary patch >literal 1109 >zcmc)IPe{{Y9LMqB($yM5gMuO=7AZ0#c+lCRKlY0qtZ)|_6rKtq2!f(R22ra^r(h5x >z2o#rIIs`o(EYX!uEn9k!!Hftx42o_=#Tv`Xr|<iLpy*Jye&gBeVW%Jaywd|Gj(2*0 >zJj>-54o{C9?rSc|*XXsZx_7?czrTJ~Pi)Nk6AP!+<k|~na(qlrHSYR_>o3%Umv79& >zb74I_wazyKS^a2u*nhmUsEQZM=E;V-o;lL&&n$JQ(%ytARqv>0mvjDH>ZYE1f5ptF >zteV&FOeNN>7m~+JZFfl3M(XBs@T97DM*RBQ5#3mwG>uY4eW?xli<NEqYq8sWD;!kc >zZ}<C4L*2?=jr%Lc4(L$psr=^LxNeQ)@@<Jvy6wZ+eEX(Vs=a(TAM-w{nBI}^s8-aL >z8;7Ea`cu7qx<mI4uGGD+GSPjDqk4bgXf$K34J>Q=$4{{Nmrs+s2d$lrd!Dt$ve#^F >z$#@}apO*tI*1oO=BHX=}zEs*v%Gs*oa=PUFzDfG;EA9EYQbR60^5XW)(5*gXHDozt >zJ!C<rtcWb>lr@n>kyVjpk#&)Uk(H69k+qS<k=2pqow7bsfKw_!N<eCGN)bpEPALPa >z11SWl#3`j9wIIbfr5dChr__TKgj9r-gw%u-g{~?tQWpO$bs>czl_8}ewK=6Yq&laR >oht%hk0+9-l5|J8_B9SVcQYKO-QYdER)x7_oX?T~!+tU^P0h%oABme*a > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay >new file mode 100644 >index 0000000000000000000000000000000000000000..d322f01ed1d11856e0f17d1ba5d5f6ca867533c3 >GIT binary patch >literal 2098 >zcmd^<ZA{fw9LIk=6nK3)n_(zmKBQNOd%2(_keLtA4e18q6_E(Fz`Ls!r0&iN@w9M^ >zSDvY3ZYGOW^F=H1VXfvya}8fqG<V&a(~0ZJ&Bvj&$!2jqpR?*sZ}4?rcK)BU|L%o1 >zd_LiZ=;k8%&nDV89M*0R_xajB`tA<t@46?M_`E;b;+rz%UO_|K=)%1t)1uAlvGqa8 >zsC-^cFU^(5a~G=2xfOcG1dp1T?A0^xE-+a?Pte)%bdz)DhMsl&x_P2+NY9Sts5$Q) >z({tA*)VwX<%ag@FsrjovmjxN$C~uw-@7NWS>)9^3!)Hw1^{_lO@R7+s-==-NdyW5O >ztuE+@n81O>x-inIigrxbi-Mcg;@VMN?0rE!U35_|Ny}3uS@)#m>X?+?|8}G-^;%8Y >z+1u)wOQ&UNzsEd#`iLyschfv~c#kY^{lTp0Jgiq%_nTGCyLEZNep6AtL09}fsDi$B >z37$WyDknEd<;iZf`qpx(`rs4u;*X6w)ZS%Y`eK=`Zj73mp4s~4rB$XjmaNxg`%HN4 >zuR8qaR8v=cR@eQOuj*(0BK3n))cUbOY4~_Vy)t}M8aw0a)q!qlYCfel^lp`np>t+a >zSC@Xxcf!0LiR$Lb2Te<`O1IpKnTXe?BSZBjnl@EOKPxj^uHMmGd)BFK=cdRTu~PNs >zu@Pyl%TjIo;__DUUut{nDcO;6MeVHak)31rO|0aEjtyTnyD|^zT?1d6w?||8o!&n4 >z?uB~Y-toTK{biZ%XlgNg4rOaeNlH#hO?hN|KWUGqr;YQY<M@U4U(GI&`1Hf1RQF6z >zB#s!Flt_HlpQPNI40oTwU2?d~oPXZ)Nnao!p><&i)!4Jfp7L@YVOhnoFDmR2NpgS4 >zJ^sChA3}=JzrUZbLk@@_5J?=ZC=gj7!tgbufr!J92O<zdB8W&3nIJ+rTB#snLF9r6 >z29XRR8bmgTa1iMr;xXid2*{8SBBG;}5hA3cl@cN*Lr#dG5J@4TLS%&q3y~HgE<|34 >zzz~TcB12?`2<>R4W{3@u+tCURk(?nqM0SSo5a}7>L*$1901^R62p}<Vv_XJG!O?~R >z5(h^c2uLItp@75!5)4Q*AmM<-0}>EOL?9u7#Kh4C1rilU8x}}h9Bp7Akzs@e5*tQv >zAkkrj2NEAffFKcqga{HNNRS{=a<pNB#L3YH3KA(t8!AYwAi;t}ixDnJychw4M2rzK >zNX!^PgG9~Ih7A%oM;kau<Q#42AhCl44-!2{_#p9v1Q7nOBj~ZwTw;5fA6n!u@(1!m >Lg@yh?f57tqQ<e|c > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande >new file mode 100644 >index 0000000000000000000000000000000000000000..de52bb68143db08d381e441ba26a84c62048f0b5 >GIT binary patch >literal 2016 >zcmc)Ke@xVM9LMpKiaFAn%gtC}7&9Z`d>?n|MMiIBilzsW7ZPeIOo=o}VnkR9vPPSK >zxS7i|D_U#w$5x-VHo;~4tlAulg_Ts2{Ftk@8e6d?o{)X}JU{)}AN8Nd?jARG{P^Sj >zd?l;uwibl`^|--(hbNCV_vHPwR`>GSiI!N`t?Pd8x>jns$Cm2pp}jH?|5yh`r|QMb >z-|WTiS{a<o(V;g+Wq9zIjwF}JAFofhmv7oG<F-Ms+>&Qf<%OC$`;AOwjM$0e>1J|t >zrvABapULVus<WGaGIw<r+wAC|nbY>X-hK18CZ}??&AGH&=Eg&I?)iS1Hz!Nyof$K^ >zp+IvF9+vxly~EDmrY6sRrukdHmT>2Lx?uT7BCQ=7$y#p;)`e{}y;)-MYK^7(WMOu` >zF6?VEi^k8}c-O1)!0?zB?k_YC_Dr{n>+duVeg3u<mHuTOJ}^x+JYtq~r0ddI*QB`o >zoEBdhmSu^}cG<|JDVcFlOHREjD<+IxdFW+%WZ-~Z)%uQEeY(*mHnp45BNeu6Wv8rZ >ze@@G@OU$D+kLlV_u1OXz(&R78r6MO&D|+sg%Ct$XJf0zsUmDb^S4L(1&<?xdsV`;Y >zCu{5zD~vq(R)O6V={1`>%CvgM`=+KgqBRp=$d;1Zbjw!_ruLr8TKi$r)TMu?bw_r} >z(?56XwwATBy|3RsQ+2=W_~4YSFPtUM?mujIW?q$s`dzl+>JQRbw$V0TI3rE*7H#_U >zf@!{egEpTWmlsk++Oqdev+Mh8eX)9vd8sQ+cdt4sdk+1mp|mO2_bUi`dqbfh=s!2* >z#vnLrLsM5LlA(Nwx@XKCD39cSA9cI?m_O>2{|SC$5OCbcfqUJNBZrP0J96+|cl5~N >zd)@IP0U!||As{gzK_F2eVIXlJfp}dcNGM(x3la<x4gWsjAn_mpArT=VAu%CAd0kXU >zSY8(w5}4OThJ@yIu_3`B(IMd>@gV^s5h5WXF(N@CQ6gb_U7SduUKc46DiSLaED|je >zE)p*iFcL8mG7>WqG!iuuw%5gt1nzZ_BcXd;>`3rP^ho$f{Kx<xBY+G6G6u*XAftc` >z12PWCKzQ9qAVcAGV}T5Y*Np};9LRVe1A>eQG9<{DAcKO83NkFnxF7@Lbt8iejn|D0 >zGB{p0I>_*N-S{8_gp3d}M93H+gM^F{GEB%gAp_-gBZUl=*Nqi2SY9_;$Z&bxcp(FZ >zj2JRx$e1C6hKw5eVRN?5|EGtxHrK=TojLyc|Czds#cuYBV(v9sl$VG^!jZ5nki0}e >JILe!hzX46hU$6iG > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun >new file mode 100644 >index 0000000000000000000000000000000000000000..7e69f73de44698b65b61038ea40972f1e7c7affa >GIT binary patch >literal 816 >zcmchUPe>F|9LIm-j+k3uV0qD_u!M(bZEGv@-|jYS?zZkaCr=ZYiy-XKspEr|PX4(H >zUL*(v#X2o5U6v4p&|?%)U4rQNE~04ke4jz^&>_6^9o~Fq2Ilhl_|tQ<N%?E-_6vs% >z*u(P`WpA$<UxJ<&AA=j!s!l#V3I@HrzFGMiq!I%<wJpJ|<ZgJoqfgSkzjXTNAGve< >zLEqhX)xE}hJ@opwy8muT4=;aLBdehvt+muxeK8y_y;PZ*TA00FSGjCCe9$$ky#B$^ >zJA5vA_iC8`{6rr9I0z@+dQ#Zy*2R@;@@R8km!4ge$%Rk4{5YX1^G!W9)~Wo$s`mH3 >zi8!$~F4y_j6*FdQUBsA;HF1sEX*m~+X}*z5+?~sXqA!^#UvgP{EHjp8^UtC0@bouh >zhelpe3DF5r3egHt3(*_VDu!r=sAlMnXq7XxL)1g`LlQtTKvF<*K$1YRK+-_+KoUVR >vK~h0-MYPEn*&^C>jC_!UjEs<!jGU09jI5Bfki3w@kjxSPU+TE6pNgLVO=iwS > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas >new file mode 100644 >index 0000000000000000000000000000000000000000..c8cab1af26b03a7008d34078efdf5ae093f50c10 >GIT binary patch >literal 289 >zcmWHE%1kq2zyK^j5fBCeHXsJEg&KgwWH}w1Z!_L_xJOSa2v=QMQ2+n`e?}%|CT8aU >z{|`DaFaSvx2A2Q-5A0yz`2YX-0R}!F-w+08Al5Z7F*X2^KvN(fgs|Q0K$T#-e?avB >qt^1$ZF698CL2d!jAoqZzL2d%kAa{Z2dY~KwxsKzq0Xo&rgbM%zHA%++ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca >new file mode 100644 >index 0000000000000000000000000000000000000000..9fe9ad6470939d78d5dfd94276f0ff332f1a91e6 >GIT binary patch >literal 1109 >zcmc)IJ!n%=9ES1RG|^ZK78Dc_sn}8y6%K7<#gBR<LqW_^14<_c5d=YTu!3lGaS{Sj >z1fiwTu0oGPwKUZp8*8*f38X~?hk)XysKgMzdi*~}9K=C4@8#UzCDSGElO8yEqBHp8 >zS|Pu1xO(OAzV5O-ZeP!;dl&lk{f*De<mRlNTs)(u)?c(!6JsV{zpJNjJXa51ytWU| >zH<_9I25kqj=F!NAp50SWg-a#-cvH>H9SiHZ<+v&y=&{AhxO#eJNYAHknfZ5D?Lx|_ >z1@qRHV+pgEJZ`J|qN+Mtv!5cTRIRf`*WQep`r4$e7t88%bx?mP?=)Wv3HxpOu=;+d >zUoQ_Ql)KigSB@Pt(YDjMtwR&0tz{_J-t*D4zdx7j*s?}-l#b?NfzvUwI~T8%)wY{Q >zT6=0w%&wWZ(fJQbFRiwHgR4y6%S>y=IoA+s{Kq>I{&|P6F%ptz#JSmY5I9#T1!3ok >zHi$a6RBC8;?p39sh4-NOP%0fH<?K-1a=PUFzDfG;EA9WaQe9rS<ip+B;qmRrYRGcP >zddPxaSrJ*%D{CT)BC8_HBI_axBP%0IBWojzBda6Jdu4s30IyVllz`OWl_HQTyix{I >z2T}-9iC0QNYC($eN;OD1Ua1Eu2&o7u38@Jw3Vl_)NLl>1)P)p=RECs>)aI4qkm|fr >p9#WrI3PdVIN<?ZzibSgPN|{KVUMUna@@c{U&$MZ;#M|4|^aHgk>@xrW > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne >new file mode 100644 >index 0000000000000000000000000000000000000000..6db640981f2b845769834e57142817da8bc61c31 >GIT binary patch >literal 224 >zcmWHE%1kq2zyQoZ5fBCe79a+(c^ZJk#4p+tejheHQ2+n`e+EV-rvLxXePCet|Nr;_ >z2A2Q-uU=r_@bL{{&^0gtVq>6s5C|c`jvo*$KokG}2iXOpLH2=!>w#=y?c}ln+HYsf >F1pxi^IW_<Q > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman >new file mode 100644 >index 0000000000000000000000000000000000000000..5c1c06372c6dc8610ffd14f74e923bdcb9b21d31 >GIT binary patch >literal 203 >zcmWHE%1kq2zyQoZ5fBCeCLji}c^ZI3_m{*Mj7<OkZ!KV80Fn|6EdT%S+`z!$;~T=@ >r48*R%AwX3i5JK2wm@Pa%AX<PX{{NrZt|kDYK{hcEXB8LFR#Pqj=|C+j > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago >new file mode 100644 >index 0000000000000000000000000000000000000000..3dd8f0fa82a60710c0711f35dee93ef5013ca796 >GIT binary patch >literal 3585 >zcmeI!X;77A6u|L=OQ?yOM&c4$mSiHEp=g+zG6aRVAg*Dqh^ag(qNw5HL|RQ{Wu>;@ >zhGvVQk_wrKh~{WcDN2$`xS>(#<C5Xhy*>ZeX~vnF$&Y>LFfYH$oy#!8hx0#iLzBjZ >z$lu1(zQe=(Y9C(vX!|X5jlW*@)it$zegnPY{iAB-z7$#Y;_oIa;-FqVy40*0P%0mL >zFIH<iZk4sJ9P??DkL1&`cg<&)=gQ~#Gt9c;k@7|65R;wLOV+19ZZ>>4LT^kQta9e` >z)L%w+Rhx#l(VP8Rsx9HQb?#j*mDl2|&Z{U_TWi;nt-A}=*QYCFTXvbrFWMv97Z#X; >zp(V0oeYh&jcujW3W|*QelVw-nII}zERsBuFr_7!X6ZM|zv1+eZAHDZTq}ungOCM}= >zMI9Vj*A!2`EQfmhVh#^HEG4b?n;$~A$PvjlrQS=WwEQjeqid5sS}@HVD_g9OfAXd( >z%TLoky)spmXAaXRlH%0K^lti8R3~*hp_M)}DBM&;hRfN`zUG{tul(FpOr`y=RbD-5 >zeyKPqzm^o4s@+9$e)|b^A-i0gWjocyg@yXk+|}xGa+ba_VuAWCcD}yaJxTo@I9^vj >z@{+mMFj`-)lW4A2C(4a;QRe26DEVVgd*jM&FYdKoMwWPq$ASx{#*7P6b4q<xYvkR! >zcHi^rt{zp|Gw6He`MRI3+i0VzyKa@#Gw-Oo%NObTrR$AX!F1gq?`_lYleeYO(iC&g >zD=E@AE#5RqikEwbgc<LsFuAWwbJMh4bMbkwvual7rZlh7Of|pcqg$M~p;{ieuJ7M* >zT={M|rdzGpu3D!yln3UmP!A5gC~YQeGY^Fp%fr#jOk3|w;`iu0<L5e{+tnLw+Lh(# >zM=K*t`}}vcfAJ{QA#;Wf$my*D(}(DwMQv4ZVyc8ptD`zb4wlFISE^9IuF@&wTh-aK >zrG&LOXTmC6(&ffp({*>bJbv_Z6P|rjciZ}gd17Ii?*4%?J(3G_&y3gAld&sxuQAE0 >zcVLE&=-p36T;3v)9VVH`;-wPh6>Fk$W=nKcuzC8!#rm0&J}PETn(nhXNW~5xru)9v >zSoI6<ru$F7q6V~VrQ-&csJNRRIzBX4#h>w&!M=yg;9Vj^T$|0%tdlaVY>643Q6$gi >z&oT*P*2sv=;pVxRLOpUpni|z1OOH+*rp9>9*JC5Qsj*e#b)sJ@mAF4zCwY3Pq;>v! >zLd7Zd{CiO{@jJJfl-gb<XP+?1@m``9?le<EFUZv7)n=Oa0ZEBnU{YLFIyEdyrIvlC >zXZp-nGxIm-wCeF{R^}o-`$)8!lRjO)kn69~69(zIOB$#e9(V9n^R~~_s(srJck;{s >zozJ-4>kf&y-FfRhYPsE?EtfjHmio>+jhyfI-g^I;m^kUx+dc#0B*H$u2HB@?oZW49 >zJpLl?-}hpb{j9SWt8e|1{p)UbLQU6lWKSZy64{r?&P4VmvOAIeiR@5hk0QGi*{6<n >zry_gR(e74czal#p*|W&5MfNSSbCJD^>|SL5B0Ct_!^kd1_A#=Pk-h9_cQdk|9qo=r >z_B67qk$sKqY-DdEyBpcx$PP#LII_!;eU9vOWUo8g-Hz;cN4w*ZJ&){qN4xKlosaB& >zWcMTcA87#60i*?vwg*TPkS-u?K>C0*0_g<O3ZxfEGmvf|?Lhj0Gz94g(h{U6NK+hb >zSCF<KeL)(7bOvb+(i@~XNOzF-ApJoagmegL5z-^1Nl2F*ZJUrjA&o*hg-)w@L9ZCw >zEQW3&?PBN`(lDfBNXw9(IohTnU30W;W9S>wIHYq(>yX|d&12{u(msa%Aq`~cAkspH >z9wJR-=pxcahCVvlMk1X=T8Z=$X(rN5q@4`?L>kJ_QKY2|Jw=+z&{ap<R-~_vwy{WO >zk=7!;MVgCr7illjU!=hd9Y$Kr&|{>@3|&Ur%+O~?+h~SPBduoWHPURP+eo{Sej^P> >zI*zm)={eGLr0b5h?F@Z)w2f!zyrXSBL+_F1Bi%>ZkMtk80gyWYxdo7W0J#Z}yTH-j >z2FQKjXm13DJHgT33JmuGax*a84an`la6ce71j8MH+!Dw=f!q|xU4h&d$bI2xZw%zl >zaJ07ua&I`=n*+H!klTad{y=UJhC2kgMHuc8<R)RbOOV@y;XZM+Hwtp6INDnUxmO(R >z&4S!5$nApMFUSpp+%d>4gWNN6N7u>!2hBeoH1+Jg)5+dF{xKZ`LIQ&PV}gSNf&+r; >F{Ry|ZcJBZH > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua >new file mode 100644 >index 0000000000000000000000000000000000000000..e3adbdbfb25b557db2a2edfc721c365d90706233 >GIT binary patch >literal 1522 >zcmdUuYiN#P9EbnoHEXTh773A1qP3Hq%y9>sv3IlW9ka2$W8N8?ZN}Oh@1hkA_mn8d >z5@E?wJ2;h3LLt+NNiE5i6isq!J?`t}gYrrF;&*pH*V9wax9jp0R`{ajj|JK<TvlW+ >z?_;!mobMQ@xjMMHufw;(+nLhs?FxzWb`3Rsh$^p_=(?bq+35umll!(NcE%DF7u~Dl >zN6u0S6F*Bre~6m%{kbH53N>>(p2)nmU^D;bDOqs%omqHdk1VQwWRmus(8<|tCZ%kb >zPK`KX7N?fzv{744`t&57{-s4_xTfihXLV}n>k)ccSH8-8I91%o<5kubmt;4LSIe8< >zNKR?2$*sI6c}e4pC-bu8Px)$Agf+`bd0`61UepDBx6P_g2Xx_`Gp4AgQm?*rORZ_o >z(#88vtCFLU+FPMj>29~I%~-3}6-P+f%v800!D#V?dQJJHk5WFEY&Hz_NJaN_v+-r8 >zY`PX`D(^nkRV@Q%^M!U@UHib)G#%5mh5c%auTj?}-d9`GiuAS#t*SnvLF&I9R1KpF >zrJ=W4HNKxG+i&Ek9gio=&T~~}*Hw|-d$Y}+L$5>vhH-}5;|ln<$8k<Ji#X0HBQD2j >zJu5+ubG<Dfg!cgT^LwV-Bknwpq;OO1yS=~9^B3BD`Sqh?hdvO6AR0kbg6QO@Rf^xx >zilG)nFNR_e%^<2lbb~18r_~Ok9z#Eff(#8IDl&A0D9O+gq9#O7h@ucpA*w=jg(&N% >z)fS?zpH^Rp!VrxiDl>G3D9z9sqBcWsh~f;*A*wTUhbYg`9-_XVR)0tWkPILxKyrX2 >z0m%ZA1|$ziB8*HRsW5VZB*VxCl8&D?A4o!sj36m7a)KlU$qJGdBrix}kjx;dL2`p6 >z2gweSo}V^9NP>Ra3?V5pa)czw$P$t!BTx7rBpPh{jkn!~xnshk!Xv}nQIX-X;gP{V >E0A>k%D*ylh > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour >new file mode 100644 >index 0000000000000000000000000000000000000000..5708b55ac6bcb7580498bed9721a43fbd5a1773f >GIT binary patch >literal 345 >zcmWHE%1kq2zyNGO5fBCeb|40^B^rRlyd4W0=I{DhaN<XJ!s(8G4VRR^6kJN={J_M> >z#K_FT`v3nb83u;`|95U+WcmMp^#TSCFq;QV3V=uk5g*?W24@!_4hG_IAPxv&a0RkK >zfDuZD5Ox*^P$}41KfroGw*LQL^sXfZM1!0OqCrjt(IDr7XpoaZG|1Ut8t8NeD!ZKv >I=owQk0JN5Mg#Z8m > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba >new file mode 100644 >index 0000000000000000000000000000000000000000..8c58f8c23eb0d66d80714a9789b5c20abf043ca2 >GIT binary patch >literal 1109 >zcmc)IKWLLd9Eb5YZKE+13@9if60xNuA{=dF#6R_w3{^2p4Je%yL=XhU!3v_$#YqTA >z5QLV-c2zuwYH6cAjWyb#1X2;fA)vS^A~D3OJ%7)MgE;8s8!n$C(@VZjX7I%EZtst0 >znf$`x>662K^(FZlyOvY;&JXza*FD#h8*={S!f7?N=7O1;7}wLyyMFQdOZDK@Tl4T- >zSkFwa_03>TKN=bFAMYrs(#48-vc92bkF@!-OL0}+lQiYp9rf&T-k(d~)N>!MnEA9- >z^ZLE1#u9oVb<EUvg;agCVLk^>sz!IjZ@e4T%~dJWELYW+`jEd^-KxKq66Ra+p!$Am >zz+W0pD0{WnUp~HHhdNFbHsvRDM<ie9On%axAI}!LHm+1%mBWRYXZ@JoUWnJKYV(al >z(PZPP-Zm50{X;8s|LbgY@8X!=S3DZcT5AI>t^fE5w*CCHV5_?atu0kN&waO9TQ*+E >z+832TyR~m>fe3f6{Xjb7rQ~c;y>fcw{Ju%%?<?*8wNg_qJo4i9%<yfEtcEOytcNV< >zlogRBow6pfD6%TDEV3@LFtReTG_p3bII=pjyi?Xk3UEpVNC`*{PALMZ!YO4Sbs&Wx >zl{lpoq!y$Yr&NQK<CJ=kf{==kl8~B^qR>^vMats8r7ol}q%x#5q&BA%hg9d3@{szR >lQXo<xQX*0#QY2EPQ_4i@L<+^Myqfp_GY#*Qc>8+7KLGQ$?e72p > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica >new file mode 100644 >index 0000000000000000000000000000000000000000..c247133e334bee3b7802741383bddedb9cdf6cc3 >GIT binary patch >literal 341 >zcmWHE%1kq2zyK^j5fBCeE+7W61sj0G;um7Rf@Yoxg4^=~gvGQIgr^4ts84^8ppm!j >zf@b-l1kFP?FEBDQLE-=Z8;uzlz$DB6|2sD@a{m9ndI1Bkk8cP=uosYUb^+qx5TL;j >z5JK2F+(4CJ=lp=``40q{?OMJd8st2XFvy8u8t6<A4RR`&209l+gPaVaLCyxzAg6<A >Ppz|3ha6cE&GiF=>7LHDf > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Creston b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Creston >new file mode 100644 >index 0000000000000000000000000000000000000000..798f627a81e25f9657c12909f4b0878f55eea9d2 >GIT binary patch >literal 233 >zcmWHE%1kq2zyK^j5fBCeW*`Q!c^ZJk>}%cy^L|=0FfuXz|3B#n1H=FSb0;vc{QuwI >zz`y}v`}l@1_y&hC1OPD%gb=m{W+l%LsHXow5NBJk2SkIc1<@d@Nwu2`=ooV@0J&g0 >AN&o-= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba >new file mode 100644 >index 0000000000000000000000000000000000000000..145c89e0f88a210dd7fa3d953d2f62af803b62b9 >GIT binary patch >literal 1988 >zcmc)Ke@xVM9LMpKiaE-ftIb$p7&9Z`d>==8k+HWjMbiVx3kkIprbLn?F(N1dU8BuE >z+=^+M6|K4XW2;YFo8Yp2R&9>i!b&Phe$1s?jjh-cPsqM~o}d2gkNVGJcaIx8e*E!% >zz7mzSTk}Hydfeo`!;?pwd-DFacK5RHSZi0$9qWGYxn5#=$Cv8K;axHq`&0+Vrt5|D >z-|U6n8X20((&4wqWMt@wjwY7KA8*aDS8l133EQAoZ_hEwvI0$>{!S*-M(yO$R5LYp >zm;SkDkICpeq_dkZnftnnY-V)G%;|VZ@4xkXlT|U>W?kGVb7LVp_uPQYo0FmQPK}%F >zP@vge2jrn&@3Hf@smZZlXztc;CER^j7cBooq`gxk8S72ny0DF=HcNi2O7oNbvM@7O >z7xp)qMHA<2tmjR6WMo_m_7<2&`)1h1_4k^`zI;y$Oa3xTI#YG&tm{%#c2<k7j>xk3 >zX1i>3$`sG+(&7^z$cjm0SMGmJ9v^(eu4;eZtUlRj<C}Jyl7r>8bY-`!+5MuHWfq$! >zs-M)gp=^^VTBM0zmP>h7x|a7nC>1GFT5&W@p1L@sm9LM<`r++%!?Rz@#?RK+r&kzx >z=G{EIDe{%s+*ztsGe0!dH4&|zJR@6*@6;{dG?<zPu4v822~(T;gVrA0A<tdz)om?n >zrLKR#K41B;Z2#zltuL4*FYG;FccfpFhWb|9aP22)EZt}u&!3W}Sc^7&e%>_Sy+NCg >zPsq#3LT%agj%ocdQ(viSGq3if=+0G#q;3Dt8cLaVBfo;+OkF4x1OsQM-5dm`ZD{)H >zcp{W5QTNPuXUQY+->2N+KITt3>3@RX7zCU&a@JmV+Q@k$Cyt!C*PS|Y?p}BD$k`*O >zkDNb}0FnWc0+Iug1d@f<rGez(b%`LEAgS>0lM9jzk`0m$k`Iy)l9AV?gyiIPNg-Kz >zU0O(9UY8h>8Il^38<HH79g-fBACe%FA(A4Jqt_*gWa)KjB6%W-BAFtoBDo^TBH1G8 >zBKaZ-BN=;L%1F*$mo$>K*QJf*jU<j_j--y{jwFv{kED;}k4ykE1IQF0bKrH8fXsr| >zO#?CyUN;fQOdwN%%mp$T$ZR0ffy@UoA;^p%Q-aKi*G&pCD_%D($h>&n#2_={byI`P >z4Kg{%>>$&F%nvd_$P6J<gv^oGO%gIoUN=q1JbB$jAv5K5Q-#bGGFixMA=8D-7cyb! >xXUy3?|DXHs=y3OcBS($D{eOlnZLu4<!hH7{EzF5WBH>6_7D!G!FC67f+TR%~S#SUV > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao >new file mode 100644 >index 0000000000000000000000000000000000000000..d308336bec9a539742ca3885c44a4d3c5a674463 >GIT binary patch >literal 212 >zcmWHE%1kq2zyQoZ5fBCe7@MyF$eApsr~GZk8xICXrvLx<$1*Vd|9@Zy1Iz#a#}6=Y >r`S^w~=o*+98!$Kqhk&#KK?n&J{D5cyn)&}f$RZF;l4V>#dri0im60!* > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn >new file mode 100644 >index 0000000000000000000000000000000000000000..ad68c722f8f56d14a0a9b3e2e98fe56ee17256e8 >GIT binary patch >literal 712 >zcmci9JxD@P7=Yn(Q!B*bfTdRUYh^!L7mcR2hzK+q?i6iB5Hv-jgF$1%7qk`B(Adw? >zXf4qcK@cv{5J*G>EfGk|>AXTy5VZ8kInPBA^!>c~mF0~3G4=Kx4wJBlXI-?{ZgED1 >z^M$#l?58v*UL_KKkf`rQqVE?HtDH*9-GQ`TZcAI~T*r@2bo<`E?${FDS=i8Bt82P@ >zVNv(wJe`=B(!Hs1-4{>l{!mOO1Cx^c7?XjgJ{c@WWaz3vhR>>!I((7z&b^FmUd!lu >zN!+Dlai3>h<@oD-zrF&-yxCuDO!-#%zwgSU(`XF0{Vz&|a(Pds-K;$sHEo}javVP3 >z_WqEj%9rdIJ0xPrgrq`pA<2+zHElX1ACeHsh@?bvB1w^~NLnN>k{HR1q(*Wh$&u_x >k`kFRBvI1lc$SRO^AS*%Ef~*Ev53-_~|Ffo`-J2Wy0%5kDYXATM > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson >new file mode 100644 >index 0000000000000000000000000000000000000000..61c96889b074b751386ba0923b180e4eecbea226 >GIT binary patch >literal 2093 >zcmdtie@xVM9LMp4RFq`<Y>FZs_EAg(;rJooDfY{7C&~%Md3k20#*aZNBy?&Co*S!K >zE8gkUw(9!G{HL`hj%;ogGq>8Ba~ZVOvN6|IHjOp4Eh@*?&+}9N^+$iU^}T(*kMDg4 >z_uuOo+1T1#=KIGr)xP0y?YD>Lc?o+<p1Cma&e>dJE=?ae-ankUaB$JUaPF@i!&}Ss >zZ^dyLU(~PCN`96Zt-JKh*m{*&6VbDlEmgDgD|OcV2AMN0OJ}E6NcPQgbI<p)#XmgD >z<b3kG%sn-3?md24bbPU%ci>~0AI;FYZQrT|6~E~F)_kNEW`3#j3X&>sV$9^HCsh9E >z7pCCaHnn)@lqnqPk)q^b6Byhg#XZlNlEW*dwB?X4>s%m9LS4GNVTx4bMRjG_PqH*E >zsDu8=DtI+pFZ=VVTK?H>U3K|$wPGO4+<*2x^+4Yr=D{~#RS&g)XCCf-S60>ynMWF5 >zk?LY&R#oqiRkucTsOV)C8ab_NGPbLl!DD*O*gCcLtwB@!b(@6u9Wm=Ztd+V=yG{Mk >zfIPY)W*&<xY4BH>$oiWSxt(L86<<m8hvj<1+#71cr+yuq7*QKfOz0;@PpeJ6SM-xZ >z$JFM=^ZKdeUbQ7WYPP;~M79;3Gf%hdmd1>J(-ewH(^#)*$*Yo<i_NArEk|14Uv1ic >z^yHbNO?vw!zuFNG>76GhRC_dEcl2FR&sN^8ceS5aotb00tL}vA@}`-1@SMa)ubVwt >z{jz81qS-s%E6*oSnisxlmVG_1o9;8KrDt=e+5bj?q^8)<U6WELr%p-x4?dpPUF-9C >zUSA?*lII=h@J)5k)7@Qp-rJHglV{%?_ncE3j`(8L_B7b@xIOiJw=e4Li+U?pio5@1 >z<llFYuz&7$F#h-ddG_jl@wE?-T_D>)_JM2!*$J{0r`-#(8Duy7EZaf$gKP-d5way@ >zPspZ_T_M|Y+I=A#Lw1I24cQyAIb?Up_K^J{8$@=9Y!TTbvPq}iC9+MY-6yh9WT(hh >zk-Z|DMRtp97uheeVPwb1mXSRpn?`nxY};w~jcgp*IkI(R@5ttn-6Pva_K!3G=>XCK >zqz6b7oVE){8=STeNF$uK6G$tNULegtx`DI<=?Bsfq$5a6ke(n-aoVmRZE@PZAdPX_ >z&LFKpdV@3v=?>B!q(4Z5kPaa&LVAQW3F#8jCa3Ka(kQ3x6w)fE?G@52q+3Y4kbWTz >zLpp}E4CxutG^A@t+nly<NaLKgb4cr)ws%PLknSPvL;8m_5a}S&Lf`*AhUvDFL0ief >T@RC4TprkNdS{f(~l%(GQc_b}} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek >new file mode 100644 >index 0000000000000000000000000000000000000000..78f9076308013c2c0b46f8d1b9700abae2f435d3 >GIT binary patch >literal 1059 >zcmc)IOGs2v9LMo<$1%l({)7V&E)E2#Z2~I_CE5fUB$-Y0SQsuGaFv2kD-%@EO`aA( >z8|`45f+!*aK?>VMP@5(yr^htCY?xlY%JI?M&iBx+MYQS;_k0e+h>PDhe!L@5tNwV_ >zxNmrQ>fFnHL$5nV$8Xz<6EX8(XroPTTIfu+ZI&m8XZ2H^lV>{~>nZh6Qn6b)mANL* >z3y<uJNh2@QH|?t{S55lPdHZ_ktjUa?vTr&%&D)-1_T9b~^S-s-eyG`QrW=mxkLwRg >zwyI8N=e9|%q*CXSG5IuI(4TKC%9nc?{q<Z*zFl9nGhGuhJDj$2XYQK$laqGg#3l3n >zz?l89XTU6O?YH^rF<Dxdu*;?WvYhYJE7^psPPOZw_Zy`!-k`(FTSQ%`(ZOK3L{6{O >zMP1b<+E!(YgBcSEB1KVm{PU+c42K()3d0c-MBTktmHK<RKZR3O>~D&z=DqGc<lZCh >zZH}uZcjpOypYgx1Qty81SIPUo;lGAq>+bGd$V$jk$Xdu^Ubh;u9I_s=AhIH|q}Q#9 >zEQ+j(EQ_p*ER3v-ERC#<ERL*>ERU>@6o6EKl;CwWAVqjx6-XIK9Y`TaB}geqEl4p) >zHAp!~JxD=FMMz0VO-NBlRbE#XQWsJfQW^TvxKJC9D-Ng*DG#X+DG;ep{r?QhT$ek` >FegO+5`(*$C > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Denver b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Denver >new file mode 100644 >index 0000000000000000000000000000000000000000..7fc669171f88e8e1fb0c1483bb83e746e5f1c779 >GIT binary patch >literal 2453 >zcmdtjeN5F=9LMnkqQH%ZQ;8v<nU)CgtR#>b8FWLuL3o9$5k`URY6U)Y(?UE3#rVT< >zR*YFDf|Ayni4SWwHq<p-TiG0LO>3b&mt~`eO%k}b^FAy8>5u+w>&t$;e%!&IpEvGR >z-Zfd`A2->2!ozi$hxe(9ANJ?zJ^i7o`=tck^V$z;Z>?YNYndW?3oq&3_WkO^wg^2m >z=l6!8>R53#-KR(Ab%;NrJ^EUhPh1;)Mvi^&5##48<irPg!hbwh2Hs2%VrRSzYW0iY >zXD8&O^>Hesdb*xmI<BVVkLl2iVHLU~TZhY&D*WJK=@{9oZn)H=BQBf}ktdsV)O$T5 >z`mJs$Uu_mQw!I*4+EOcS_SVR$E1e>y=m9w`H%Z)*G*8CPE>zRQ9WpLBQN{f_SI2)D >zt`dgA^o&zKs+or`>sx!ys9C-l^0w`V)a(@jIcM!h;`Zz><Q+@j5p!eSmx;+*B>FGv >zB*zAkG<-@YUv`T-2lnZda}6rB>qVV*v`nQp)#;2^7O2d+7MZninwsxiBNvp7s_euE >z<y~2ys)eD+GAI73$oVcp=8jzud8dDtcYoF|7WFywJ^j1I;`X2Py}P!F{Q8geeJ#7x >zl9E1sf6Z1^kp8kRELg1ye;bs})JEYvcR&_JR*9mcZF1?Ad{O-R8+zF%mCDuFsvmlH >zu_~$b>e9|x>fuGjy37}>mM5fY_lmETdpuf~XP;K(-=s*-%&&xJFiNiU4~kX2Bl3~q >z1ER8JNIp8yCaP+V$<<x!#AB|ry1KPhJ)U|*KT+pZHIW^<)>*7-ulRIbVydb;<I&#G >zXyrYar`LY_i(1!NA)h=OC7$x-%BK&Fi2Cw)+0Z^D)@M)14fV&w#+Zw8Q%R@T<R8<% >zoFmFN{JGv7+o3iOoX}fFed@Wc9{v1zk7{gc)?1I~sivx0y=`ZL3J&_~Yf{Md*S|md >z?+pZYcL)&(yxkoXV&1g~v+oi1yIkgS3s-@8mYb)-Jf&{4A|Zn8H}}7<Z;$y!yS`EW >z!d$>yRY*i1vPNW)$SRR#BI`sJimcRXmWr$uS*+Ep7FjN`USz?@imhhJ$eNKwBdbQc >zY+hJ5XBG~uoMY+8+L6U0t4EfPtlw%1fK<S0N`TY=DFRXjjxr#1;3x!A364@AwcscQ >zQVouBAobuV2vQNGBuGuHrYJ~Nkg_0kK?;LZ1}P0v8>Bc$bvVj{)Q6)$NQJDXL`aRS >zrbtMYILd_72`Lm(DWp_Lt&n0N)k4aJ)C(yXQZb}tNX@LKXh_vK%7)a9qi{&&I7)}q >zj-z-;^^o!*^+O7XRM2Wlh}6((iilLvYRZVzk)x1EC6Q7hwM2@ER1+yDQct9yNJXut >zq)1Jzrl?3&t){F<T{#MiRF<Q(NNqWai&U4RyhweK0wWbhN{rOlYKn|h*=ov+)Y)nZ >zjZ_*bHBxJiVk6b&C^u4Xj)Ef<=O{T+bE_#jQgy2-J5qP6DLhhnr1VJbk>VrON6L@X >jUtDkg|1SRy^Iu`1`R|b8nxB@HmXYGh%uLHn%W(V&DI1f# > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit >new file mode 100644 >index 0000000000000000000000000000000000000000..e3ea5c3ef1219fdc1b6e6663d2bf3a38c27df689 >GIT binary patch >literal 2188 >zcmdtiZ%oxy9LMn=L|_+4C@EB;f{cOux2tHk!hjL#71N6;njQ_jyF&3zjX@dOf=ssN >znhtX{mT8S@jnr(pim5qkYh}tR`!hVX#e)`gj2^hy_;ucAJ?l}=TKDdp*WKNIyHD=t >z9chehD);{JO0?f_c=g)D=ggh<>iIBd&4JK9@6%_ET*&=HE~p9pb#TC3^bYF8%1e?| >zdRiqtH(jntJFEiUAqkjgRI=`oly6?qsVAdy?TKzZ_4TJs+JQ|veRs3DuJb;9eXQ0@ >zTV0?t>hjGE^HcPV`N<|TCtppUGG=DPC#xC12V~|CV=C+XFLKkVb1M7D=W_GGBkGoR >z&)oXdUX|1EqsiSosBa6NF|!suuW!$I&Eyqq)p?U2Nq(R~=a0N91wYTzvxjy`;c!G1 >z^~a?6*j!c8wOC5`W~#Di)Rb@eQ_ZQZGj}ZiUIp`Jo4MsfYF<*RshIh#t{DBz%%Au` >zFF1SN-1%L<4h{Y)cfG$;-@WGxx#z`=y0Y!4EbQK)?ycV^RZSaIbxFI_R9C5*@c~m? >zv|iT^_nNxYg}Uxot64Obs~5ktTb6uPslwY^Wa+y(s(x))mh~m5`$HwN{IOBBA}d`Y >z4WFpU#JH>szM)qBG}WxiKC4%qxolQX4(P_i!)DD$uU^}I+&nncs@FB`H|zVCY88G* >zHtcFq8;knnp=ek&rFKYjZHa0gYm{hSx{7`ll33!nioKOBn@7J?Eqx12>$%JN;r1-^ >z$l$PUYnU{$=eT|}sLhtP{d#N0X|t`qQ*WERB<&S_s(s{?bYym@j-f-+d8JW3-rpln >zTnwr0T~T@Ry=>LBu1<Em;3+RI{;GudtN#OU-#<Fb^L+o!m%RkvKk>FV#rHox8JFVj >zG<Q#15{`IPD<WPE=K*_`*;5^{|8>uc`}>aki<Mk)&+x0h&svbhAge)^<FxBR7KE&b >z$5|4xCZ}B#vMOX*PP;B-VaUpmr6FrW7Kf}3Sst=JWP!*EktHH)L>7sx5?Lm)PN!Wc >zvQlKJ$Xb!bBCAD~i>wz}FtTD~$;g_KMI)<r+GQi_cG`s_D@T@&tQ}cAvU+6s$oi22 >zAQeDLfYbmf0#XH}3`iZEwh%}qkWwJEK#GA>11Sem52PSSMUavpH9?AkRK;n_g4D%n >z3xia~X-k9D1}P3w9i%)+eUJhn6+%jc)CegOQYEJ?6H+IqEfi8Ir!5syE2LORwUBZl >z^+F1UR17H@QZuAzNY#+CA$4=w!XcG&+R`DlbK2q|)kDgM)DI~jQbDAINDYx9B2`4n >zh}6+(3yD<HX-kRJ(rJr{R1+yDQct9yNJWv7;{UUz0h`*OO>AL!PH}m0X<@jmthlVW >GH1HR^1#Eo) > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton >new file mode 100644 >index 0000000000000000000000000000000000000000..d02fbcd47f845bd101a7ec97150df7821b826357 >GIT binary patch >literal 2402 >zcmdtiZ%oxy9LMnkp}>tlrxHU!BP|I6<c~Lj%%~tjyg_h5G{Pv5U92FrJ1xXh;E0}h >zDq}X1KqY9cFm;W_2AadIKRS0^E-TTp(pfh8v&F)=o%eaf)}tP^^<}^N`T=7+`n=t1 >zJnPcMKW>Kk2@lt49^Pju^YP-?iSu291NzOOVAZ|rW!>%DuJ*iiN$+i)DfZQWqI;c3 >z)mx<(WnWaU>d*LC_D_8zK5Y-vzJ<Rx`l_SF=Vce<>A0`OpA*l>$x9VtYA{Rs`(s5= >z^&CB;_^O(jGpU19$5cq%Ssf}5D~A}-j`2O}+Ved+?97M=Kir}tKI{>ZZ+A=idW*QO >z{RMgbmRfOxr$)|NoiCya?w7N(62y%Ox5?-Qd1_9mL(UD1S95<|q+`AfRk6MhJ@3em >zYX19|^-Vp;Rh)O8y!rV7wV=!|7uJ6!ZgGAiZ(Z@8SQK?s#wThKKXpzgI5vocu_HS1 >zvRm9fyjLfkYE;Qx+jYvp61BLwPN%-QM5WcW%Jhx1RYv|gxuj%5IpZIYccg!*mIf!v >z%$Pq!=EX3XHF-v4ANyI}`PGnEw%?)e8rm(E@AygI-MLNVG@Q`)w05d{i}vgLYPPD} >z#johR+_ft2w^5m&+$8c(^~r+pDp7E-U9Py2BMRT>)hka|DpymRe(;0ks;JVVi#y`f >zL(2+vi8oM{#wKfb*>}o)HBy&5kE!zSlVrvG3!-8)Lav?~6>Ij5%ZJDML}jZ_J~G@c >zs%j3&wO#AQqpp*>x~)w;mV7`zUguFY;X8G0exa(p;?;HW$*S&nh4utTD$l#wy8ee> >z)cTH9@`;lX;z@6od}?4^G?d54#vMNKwDT{yq2Z9&7<Eo=D(VoMrY5yF^MLY>oz<J8 >zcdE_9BYMk(S3TR+qo4btLNztF=&gg<s=2CGZ`&2CL}0+QuWN#)eKY+R|HZrC|5~>Y >ze*Zh&0YQHMZY@IWdzk%{D_w5k$~8}^c~+UH*llJbM1cKp|BJaz*uUdH`TfienI1Af >zWP(;RLu87`9Fa*PvqYwe%oCZY)yx!`Dl%8AnJh9}WV*<FkqM)nF)wDy9CJn{jm#RE >zHZpHy;>gUcX6ne?k;!w+9+^JJ{E-B3WB^G4M-GrAaAW~V14kZ^L?D?!Qeic@K$3xE >z14##x4<sQ-Mv#;sIYE-bkrgB@9C<+!V>OvUQe!o_L6XCf9V9(Sevkwq8A4Ko<OoR; >zk|iWfNS=^HA(=u_Wi`1%lEslNBwZZ&LK4Q2F(hRiIYW|$WDQ9hk~buAR+Bj-bykx* >zBzaboJtTb``9l(jWDrRql0zhkNEVSaB6&m-X*HQdQfW20M3QMW*+kOGkxwL{92rGY >z%8^qfsT^5F(u(92Ni33CB(+wPTO_$wlU*deR+C>O!AORY6m#SlNis*4ku-DU8A&up >zrjb-zO|Fq-TTQl+bX!fnk%S`|M^cXD97#Hob^ITv-C>Hq)RaHTm64L3lA7d7OG`;h >HNp<`UV`q_f > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe >new file mode 100644 >index 0000000000000000000000000000000000000000..41047f290049eed111a7e1c0e6c605666cdea5f1 >GIT binary patch >literal 690 >zcmcK1y-Pw-7=ZDsDTGBW5k&N5YeHW_M8q8(ijHxoXlN4p1A=I|HUvRSQxq+(IW>hg >z#Mz{#+bU`XZAlP)i6*D_x!4p04V}yJcetP&pVwL2Oif!qR#@J!S>v)fcc<m!D7&A| >z^`@*`YhCA`mAb4P+QqpWRjl=^(m=~A<+to|b4pcC8}?oKLRFm=`}KIxdkgQ_?>enM >zdggUKnNan@z1@gBd5yC^-K<5`=fQ~{y3VTM?H4_gNqVC*k9ur(Per>P^n|`uu~gMg >zY`ALG4QbaHV+8}hJ{`fJF;{Y9V+uMDGA4g+b#k`a=cQ%GicQYSj?3TrUd|tK)Z1T@ >z+ZeJSX?!IQk_gF!r1F(qNHSl^hNMICAqkO;NJ=Cpk`&2`r1h1&NMc{fjHE_#bA6H{ >j*^%@}eq;p57?4pQ<3L7&j0Ii!?SC3gWI;x?7>|4blHVW? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador >new file mode 100644 >index 0000000000000000000000000000000000000000..9b8bc7a8778a0b8caea494cd5995318ca30d4fa8 >GIT binary patch >literal 250 >zcmWHE%1kq2zyQoZ5fBCeHXsJEc^ZJk;;YLP6lUFdpcpedK&fiq17(}q00t&TApHM- >zO#%bM|NlETFtYsrzj^@!hmUUvgR=_|2ZsQ4f<Oofw*7!;0h;*#Kgd=P7i2St2H6gx >QK`sE%q`86%=pZvL03CTYLjV8( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada >new file mode 100644 >index 0000000000000000000000000000000000000000..29c83e71ffa6b071c52b2360295bf55009c09b76 >GIT binary patch >literal 2356 >zcmdtiZ%oxy9LMnsp(Ki)RFwE*C#4t&SN@A){}j7|+(5aKn2{NO24#>CO3@7+TWihn >zMJMGdIyrm5S`o9z{xNdPtu<C*E6m22DKLy8){4q;JMUi)d(^Ym@9vz}-QDi)?t{<U >zx2w7`&GnCGuKk3=(_s(qBU|kCTJNtdT}_2`-P6rey_My4??x-vnXu`p&nAwv46gd6 >zZt%qWb>Bpnx`x`{p1S1UD&OaAm&;|zawQ={Mm_mzZ1FZV9-pMfr_<F$=t4Cy7@@9? >zPN^Syep8d@2Gx)47u5WbZnNORfC}$#Hw)kER*Smc)apdLy5U*Ti<|1zlIs0>Y3U9X >zk>}IP)~!{`6S8#V%3`^3UZjo+&XlO>3=@56xx@@EGqE54E-QLw%uTOe6y3O5-+bsJ >zSy>XUSJiy0;xd2Ix8#4QZjJa-$0v5G_}NL55Z0m+hCern6MNO_z8;fw-Y?0W$Bg^* >z9$Djm+@u`aD5+IPby|I#q<b24M)6$9j4#nyY2&gsG+SrK%u(56QF`5<V`}}mYdYuR >zr)tAnk><7!URSrb{bBBS@rb&!_B(S|YnN;+>@%CnpOf4*#%#{rCwDJ8Y&>y=;+c6x >z=Y^z7-q0bPe|d>)ed)9*__{{C&Bx6>y#-RZ`+zCxaLcw0rDl7hlH!;g<J&PUzH70j >zB=ajNxw2mGT=BEo`ALi}ojtF1otoA64Zovyw~pxh`<_>2<!AK+olR<wci24m%yHS9 >z+;1MLIw0lYCryQ?R4OK0O;vo3R1H*`>d;uJeq)QN84bw89TobKFJjcbMvs29dsfw! >zB<Q-f5%pNse7(Q+tg4Tg)D4BFR6}5%Y0U1I#^I~xVB|?T*f(IBW?JQm&TjMMP^C2c >z+s#vFwury1-aP$6qPT*BgMzOM4w+-G|IRBAI9lLx1p+UND<lwTYjIuA`=ABRt(<#l >zf!F8q7W-U9oLqbEwWr8ucVeHQzi;2aSlEp76@E1kU}?zOki{XZLzaiE4_P3xLPxtq >zWR1uokyRqgMAnHc6j>><RAjA=cCpB69qn?F^&$&KR*Wo}zr&i5MI)<5mW`|%SvazC >zWa-G-k;NmcN0yJQA1MG*0i*<uwgyNMkSZW$K<a=L0;vR23ZxcDF_3B?<v{9z6vWY1 >z1SyH5tqD>Tq$)^Rkh&m+K`Mik2B{5F9Hcr(d64=b1wtx>l*rN62q_X$C8SJ9osdEy >zl|o8|)CwsUQZ1xhNWGAPAr(VP=4fk%6wT3A4JjK^H>7Y#<&e@LwL^-BR1Ya1Qa_}C >zj<$kG2_0<>ks><UDk5b>>WCB)sU%WLq?SlAk!m94MCyqY6saguQb$`;q^ORzsz_NK >zZC#PVB9%o-i_{h=E>c~jyhweK0wWbhO6+KBj1<|?Rv9U?qpdSiXr$6esgYVE#YU=) >d|NnA_*{o;VtS5QX-D&QWByVb}JJp>M_7|antVjR= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson >new file mode 100644 >index 0000000000000000000000000000000000000000..5923cc6888f881c8672d96be9e23fac7166b1c20 >GIT binary patch >literal 2249 >zcmdtiUrg0y9LMn=2m(jQZzf8F^`s_(DTW{@nrS$~KtK)_ty#9B;c99Y*4Bs?t>_;Q >zIs3DUzS&KzCNgHTkqmEKt*i;lM2yHv7)mNy0ura^{abfkbldu!J<sd6v%|Rhyo2{t >zR-}9XcqY4VI6U?4@SafPuEqlg_5HSZ`&C_{cFwu9t#k7{`L67OIc5gs`^+wL-1}O( >z<M*5HzP)l{;;8m?SUK6-sy{S+Vtd<n>yLG>*}le|`cvgLd#buzf6m`vf7z6yzoul^ >z(|LEB{%IvLki6Us3@?$vs3bGk882r}PnfeUmu2X1pZTq!Th29)>-p_%a-qIgho3oQ >zFK+G7OZR<fe=pjjf2?}mUQVmkk@<UMbZUi;Mc2yM$aCh(K!uDSf5`m##T_znAkTz8 >zN)_*|6chGhtb{)~#Z1~h-$ras*2t28oxD0mqZXgF(dLZC$Tv3N9nrw~eRfJ;v&MEG >zk+_Zqz3Q`OncB41$lDEab)7ZSp4uVTR6b^=mzPO=e$dQVmL)S&mYRgwrS{sG1d|w^ >zX%mMt^tw|sZBpk9opor`Uf(jJH+;}zP1OQ(<Fg0t?2U0|&XyB0H}jmiY2D{CFaD@W >zPHmLri6Ko1)JRJ2x0*WmfGlWl(VM%f?ZU=gx~TPjn^ygVF5b1q-tzG4CVj_TyCm;% >zlTkX^W+rbmOVbBzR#djhPKuQ5{zS9vO1~^WJZ^G&zLXXF5_DzT$8u}^n67%~Rk>~J >zNnKsrWY-k6>+KJ|Y;)68*XBNI*Iw*0c?(~XysrHwKkgC9Z++9O8(J@SzT2t=$F|tQ >zr+4f6PYZ0(y*st|jYYO(MY(RM5?h*-qrtLa8yugd;bGyEBHZ=g_(X<6uZ((LDD<8U >ziwK44YrJUxJ=VX4+nZic81#yB-6?hFE_aH9UZH#E3H$pF{`-8a`>8*l5&v)auc6SU >zl~pewb3!JC%nF&7ubUS#F=S@Q)R4I$lk;`6L#Bt!51Ak`Lu87`9Fa*PvqYwe%oCX? >zGE-!#$Xt=h`nuU7)Ae=pMJ9~Q7@0CMXJpdItdVIW^F}6)%p93IGIwP1$n25nBlGul >z2|zM{qyWhQ`bpr0EbzEA0C_+Xfn)+n1(FLS8AvvebRhXa65{JJf}{k=36c~fD@a<9 >zyda4|GJ~WB$qkYmBs)lYko+JCLNes*QiS9PNfMGJBuz-3kVGMwLQ;j~3P~1{EhJq? >zzI<K6kc|1dlp#4ol7?grNgI+kBymXQkklc$Lz0JN4@n=AKO})j27O%$ksKmPM6!sa >z5y>NxNF<X;Dv?|w$wab=q!Y=fuS+PBQD2u*B&WVEsYq6lv?6&$5{qOONiC9FB)Ld- >Vk@O<@^>qpM{-+HNxF}}@{sJZt2OIzZ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne >new file mode 100644 >index 0000000000000000000000000000000000000000..4a92c06593d33d3969756f482e5d3d4b773984ef >GIT binary patch >literal 1675 >zcmdVaT}+K}0LSs?kk@(LFc&RW7jAmD%q$zL)}m8hP9)@yXes=a&Q2uH1yVP-Da?{F >zud{4KTr|uuW;Thu)jw}D*7heCne9CO-+%60xN+k-d!Em8&Q9xG{Ju}1pk!mR^T#p5 >ze8S1G-kjV=y5`b!I@UdY<A-eCH_knA^p$+DJlcKGl_?+Y54%rdzRM?TN9m5re&^}D >zFS;|Y(|I=ik$#?X&FOMl^oz+yoEPelei?3cU)`+Gue%%FH|Gw@?)ECTr><P8rj>4Q >zNkG1>nd`pGnkC;CPIEtfo1#CP{~m6O)ZQ6SIgMfMtL;_k2|<~Wo+dK-&+5#$H7c{C >zUT2M+ud*(e=>>f;YT>aunf+{@@K=}0oU73yca>i*YKRbvQxoKp%8z1c<U|?ByDtJi >z`{lBf^J3YD@j5^1uFAjjRj&x2RRyOy^vdpfwQ5hRUfo`%3X2-`nx-5j{8!}K+ETGD >zu0gIZ_KTviA-N$lL2T$Nki|15isDD9vSfI_D7hFVH+}3Br44g*+2gNjb1+hGY3Wc~ >z^TJvlXjR)%lrG=es46Dk*4uNd)b?<X49;#4!R}i!G&Lkb?I&f`K!MoNv{&xzN)^>L >z#d23$l&C4plDiK(Vu;VahDQ9p8GJi<9X4dx@PF{~yp}nR<9XLF`64{;LbEf{-jA`@ >z30$2?o_Fu2Z)&zb;H0ISbE!F(n{!dX$uRdB<}(hTy+Yvcb1O1mwsRX8{44VdJg;zQ >zxEYxrGC^d9$P|$|TFoSpSt8T4nt37<MP`aj6`3nCS!A}zbggE-$b^v@BU47^j7%Dt >zH8O2v-pIs}nIlt2=8jAr?d-W>`W$BdKmtexND5Yy1CoT*WPzk%HF+S3AekVkAh{sP >zAlV@4Ao(B(AsHblSxrtzQdW}{l9tuvg(QY#hNOn%h9rk%hopz(ha`w(h@^<*h$Lw> >zSt4m#O`b@iR+A}`Dv~RbERrpfE|M>jFp@EnGLkcrwAEydq-`~MBZ*s0=1A&D?nv@T >o_DK3j{>UT1`A?q#qs^ls#XK5f{WIf};}c{3NlEcZ@rk2<0ei4<R{#J2 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza >new file mode 100644 >index 0000000000000000000000000000000000000000..22396bb5151aa9345133b2835aeedcc4d8b401d2 >GIT binary patch >literal 742 >zcmb`^Pbh<70LSrn{-qHvii3Gr4vKm*+Lk3(;-GfG!AWX4aBy(ZI5;Usipz79gWluj >z<ih4eA~pMmi{e7e+UW6oUq=_pv)+By>Rs=?zwmTquFv{$D$O@soNjaRxqj8WZSBvu >z#2QEPvCm-@f9{uu*(H$*9LUsTNv2zG?R0!fWXjDlyPFlc%#O^5ed2Xn+i%q~qHr`T >z-y1xtIME}EiDOZ6U)ZI+qAEYt$d8Q`)poimJ<HdsT@Bd6ccwblBC@kCsl1a-w)bvP >zbopQGuFHh*7f$RzY+VF%_cHi0Dh89<4lOjOsMgx5aQ*64q4mv!Wodn%cU5V9b#B#; >zjfbsX*=H`F`J<fhAL10hZ!y29HIa}|jwTio42gz>b2RagfQ}|25)z4t1Vy4EVUf5< >zU?egU+R?;Df;*b%NO&YZkIw+e2*?n~7|0;VD9A95W*lT7M>7&K6fzbvn4=jD84ei_ >Rqvl!ubwGE>j5*|Ue*r;HC9?nk > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay >new file mode 100644 >index 0000000000000000000000000000000000000000..f58522b674c2e06fb5a184130fbc470ae9db72de >GIT binary patch >literal 2206 >zcmdtiUrg0y9LMp4AQ6dCL7AY5R*1oozlEZKg)t1`s~i+m=vzSqRwxNVlG)ONi)LG) >zWsc@@Sr=sub7ULC%Dl+x0jt?s_>jYk7E7%)H<Q!zer~(!uJt>6ey`uocFwsupLb|& >z)1%pee_T`DI~=Z;+~GN4ySr__@J?>uz)pSh=uh%x_s=>q?~jcmI$>;Ip^i1>OO*bm >zQ)NV=i-z^8%)=5hr(ds*-z~9$UX4B9A=lU~I_-y7P25n8PXD;wT>EaDjeot`T-US4 >zUf;Rc+|abhCe$RG#L^^tWB#PMY5o;EV{Ve%9COCbjJP5*FZ`uRV`n6JcvNQ{J0`O~ >z9MW6%za?|pF4~mmcFNqUZ|%J1{pQxZBlflx&zsv5U$dzT8cgcsN17H}V$w$U=z?F; >z%pHTBnttj&$>>|B!T$NOaNAPNd?i-08f$EJ>#veiQebmeeJy#Zv+SMOAIM$NVVj?H >z(&V2Tvx_djZx(;?nJxJ7WwYdv)uo@bn!9&>s)cWaOi{}LUAAMB+*9#_-dkTO#S0(P >z<;8ij{P(@KBx9v1In`xL<8n-Cf1O=1k!bGUw^hr&&zAD8T7BS1f>f+8RO$UwRxU}= >zRc)uGGC5L1RYxUsd0bcL?UU8x5w?2vfT{lctgV^cYt|k(Zr6==ne{sk+S<W7Q&-<( >zAM7hKTK={^^kS_%oYAe1G!{yIT(dTmq)5X=nKq_IO5;~SZHgY3ruX8t`P>QFushv8 >z{>@qQMEi96<e}rHrRu!hxa*+Vls95qTYAh>iHGgxiVbG-<gm8qcT4+dzjn-MmX5(* >z?YvYbPxo!nt*3+1wXH^<8Hkr{bp`tDo{JKg5-}w*%H948uW<Op$v_|+{?0^1x#yuk >zjDMcy@9|~jp}?|YcPiak<Bo*fA3hL>@VC&v7|JF8IesY|W-!QTkl`TXK?dY?BSMCR >zjES#dP{^o|VIku}28N6b8JgFP4H+CVI%Igr_>ci2BSeOXj1d_mGD>8a$T*RKA|pkH >zij39k28)aq87?wjWWdOXks%{vMh1<H8W}b+Ze-xd$h~gp$k@GZ@W|+q;UnWm0)RvS >z2>}uVBnU_pkT4)|Kmvh80tp2Y3$F_X5)C9ANIZ~$AQ3@Ag2V&~3KA70EJ$3Cz#x(F >zy3io8@w(t3(eb+QAn`#0ghU7l5fURLNJx~BFd=b50)<4%>q3RZ%IkuKM9b^Kg~SU9 >z7!olgWJt`ApdnF1!iK~R2^<nRBy>pZye@c1^t>*7Nc_AmfJg+95F#-|f`~*B2_q6m >zB#=lXkx(MB^txao(e%1-BJuRPfFcn^LW;x`2`Um*B&_(qifgQEZmw%@dU;MTJD8bX >Mo|P5M3TDRs4J6`am;e9( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab >new file mode 100644 >index 0000000000000000000000000000000000000000..ea293cc4066c0e01ffafcc98e2db8a710596997e >GIT binary patch >literal 1892 >zcmdVaYfQ~?9LMofX{?!jNkSzgxt!{Bj&iG9QVku~gItnJ5)wj+IE<NDv#+f&!!Xv& >zhzH?8E^{42Y}U+eOmjE0VQy=GzxUrf^2igLe>?xzSz8a<zVDB3+JZul<BuoU{Du$D >zD)Zrc>-FZfdwr23)LS{Oz301z#k|!Hp^r2?=$3|mJf|I-j%%m8`?d3>?HY0BtVABI >zm8d=Yq)U}bbma!=T3jmKX3UlDIX;O=&6FO_6p4+Dlb)?RN?dS;#(nOmy`INv@5T<= >z=SoZMTlZC+hhA%Z^#e`VbVCzYoKaW7F-^+5FYeMh@ubyDzX>}eIcl$@xXUG_*)Ibk >zs&&BQ*)s4)nGQOeA%h?0YHCfsrqvJ9^v%O`$nHoTS{S3lHVu^FS;3l75FsOCUutGX >zvt$Kd*X)=llKuXLj10OUBO9*CsHTH5y7q|V+&r(|ZB;Vn=m8yDQX=E3HtP5(TXjP5 >zJe}CTSbaI!Iw^dNPImUz$zNQW8<r)x_uA>y&%I>YsZTn+F+^tUZ!39q?_{R`qvTgN >z$gKQEnZ5Rn&KYuA=H}hhg6Lf`FRfM!Tb<PTQL6J_?bM>?QeAMZLKi;v>7v8awfO2X >zS-d4pOKK*{lA>r`x;a^vjZc-*!f;uh)J0Zgev_4L9a5GUrez<VNqL(uT7KuURJ^~h >zt54L(nudC<+;vgc*6!7H6^GQn&98pTvK#>|0)zhfPoQPpHdkd?jdvU^e!rWZ2DGv) >z-Z@^MBi`jPAGbNZfPh~w-(Q^USMw)4=0CJJT^`OCIbr0CkyA#_+18via@NRcBj=5r >zICAF5sUzo(oIG;&$mt{Jk0gL(fTV!rfFxmSvOv;6@<0+nGC@*7azT<ovO&^8@<9?p >zGD1>9azc`_HCZ8P*_ynN#E{I8)R5ee<dE!;^pO0J1d$Ap6p<W}B#|tUG;K|uNTRkT >zQzTU+S0q^^TO?g1UnF59V<crHXC!GPYb0%3lQ)vMt;rlo9myR@9?2d_AITq?0AvP` >zDM01`nFM4OkZC~X0htI}GZV;EAaj9C1~MDSbRhGAOb9X~$dn*+f=miBE6B7U^MXu_ >zt(h5QYHZEiAd`d44l+H+{2&vA%n&j~w*S{0g`}E^O81zzJKgE^BqS%e664)YZ<6cR >H*QAi2VUWP1 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay >new file mode 100644 >index 0000000000000000000000000000000000000000..b4b945e8d8d26ff300b54916bcbea257817addcf >GIT binary patch >literal 3219 >zcmeI!TToPW0LSrNQAE6fSG=U6CaACiO0Ks6!&ngHq=1VF9u*^S4KozY6K3O#Fw=}P >z4rrQ#HaT7%8dIFyY$7a?&Cxnw(3*rt2{Kz1L=AOi`+tu;FylkxOpl$Nv!6e^2OfW4 >zQkLYr5n*`d>McIu=DHwm&VlcXw=#R-hx<?0D-~r)wn}@r`OKy}N51`Np!vJ>nj>cm >z?whM-lpi^_+}~b3tn`Q@y50VLw-dqV$JE)+UoQ#1U^r#39d~bSt=!_cR21v{DZ$H9 >z_vQp={lsR=&lVr2vsbm{a?nlZ<v)&EuK4$~Ua75eG&JU0e?7X!(pZsZy;_`X(aOx$ >zYdPVT>xILuP4NRQzh$_s&B6CAEpY+P-v{_RZcKROywTR~xar;CyjfG{__L+L={kPO >zaqHXx=k0GQEO(B5ZEf9uz|yv3zxD2x4=n9@Tdnt&Wm)bgue3ghde!pRlzG;U;1!OJ >zUshWm_BY9oeCDf<Iuf+UH$qjnGemph=&yF#`)QuTZK`2+t7hDON$plpt9h+$mAcD! >z<Q`J3<Q-ij_Y6BJ`HU%-d-?5>d<~_tZ|g>>w^ktcxm=?5txT8ueYrvHe{{X(x5ujb >z7cbTZY?`SK%$cDLN*}2Xjvt{7F?Xs%gP&*tV@F8Ce6DK4jZdWEZEktQwX4#|nnwAB >zGiRhx$1CO0pL{BfSzqrC+?rz>n`(ED%PnXaAGz24VnViS!eGT6G%4N{)VW8Q=sVdp >zv2n99>1JQo<cbU><kBQtXjznED(_>PQW&U&?YwOZ&z|FsSf|>i#*KDQTX@128Dw<7 >z6j5TE?%m`zkNDhWZmDw5c)Zg!^W0(gtSkAh*~iW*bG}M*y}aX)67{j!6`fb4#B58o >z%}vf#Udftni=C3F%!?gno7Z0Gjth-+#a)u!@qLH7;>+i{6I>5n^Y<-N66=T9l9U)_ >z!54$1<fT!vRQf=AZFZo%aJ^GnG}22>Nj)v4JZ_fLBKJvY%|^{S%C1_^Hfiadd(|Ze >ztF+e}6?N&h!&*i~rka^mtSu{xR^_Ba^78E&(u&X`d1ZE#l+`y^UKJN8t-6&cX9syn >z*%wW6j(4+^^O>KV+fps9-W8(Rer!_LZ0M)Gb*xIwOKsKG?l`Qz9a*cb%PUsj8GKU9 >zPhPF&ch<-o%tg|M#&UUMK(4g0qEz10ktn@eRv>S7nk1z#U4GB*ClzMSlDF)>D;c{P >zy}EaKdH3k@L)R~!J^S>0j#sbec=mbzZr5i$p6aCrgU9njiJ`m4({Rw}BhC)}?Bv|w >zH1^To{XCvJ)i_8zUug*Nc$zfh$futqCZ!k_EE0FDxFvBfPBFxYbBy>bCRQBu%lH)D >zpB_{GeV{IihxLK#_~(~B;>w&edpt5&$Y>$Mg^U+6V91CeLxzkQGHA%CA;X4@8!~Xn >z$mxoqL&gpnJY6w*$nYWKhYTPxg2)geV~7l*t{6pR7<I)sA_IwxBr=r9SR#Xoj3zRi >z$ao?Hii{{Sq{x^egQ_b=6&Y4tF|NqKA|s0oEi$&q;3A`o3@<Xi$N(cFj0`a{#>gNe >zqpT~285w6}pmoJaBSVdhH8R+!k2VK}n@fy0FyP3DBSVgiIWp+Ts3XIUj5{*$$jIx8 >zp-09Z8GK~)k>N+i9|-^w0VD)S43HooQ9#0g!~qEe5(y*}x*`@xFpy{<;XvYn1O$l) >z5)vdPNKlZdAYnn`f&@laL<R|su80j193(nOc#!xY0YV~#gb0Zd5+o!_NSKf~A%Q|7 >zg@j61#0m)(5-lWLNW74MArV7DhQtgB8WJ@mY)IUY!0C#}A)(V1u|tBVE24*l4~ZWV >zKqP`l2$2{fK}4d6gb|4&5=dPUNhFlIB9=%nbwxCha3b+U0*XWw2`Lg&B&bMKk+33h >zMFNXN774Ach%FLaT@hU*yt*R3NPv+DBOyj&j072pG7@Ga&Pbq<NF$-v6|qKwtt+C9 >zgj-j{8wofPaU|qO%#olYQAfgV_`mG`LD_vp`KO8h078<cnj%bLAxYukrf^f3@81mQ >By}ked > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk >new file mode 100644 >index 0000000000000000000000000000000000000000..4c8ca6f7fe8e432b6d0a2f511d7993546f3a5c68 >GIT binary patch >literal 1881 >zcmdVaT}ah;9LMp0PFh$}R&G{i&1!N?j}PsXl|7is>0~Ec9fMh`Z>1ehTK-mc&>pOy >zA$1esu)&59Jun8twH_!|vbLyhdO{kb!hUt(MP&WTn<((V-}_$|!7jFoZuXbIFFB}J >z-}fg{9otao{NovHKjGzRv@bu8-ebSD4L?1QvcJ}hY+k5G#e!z^7uh;B<TD@59Hu|^ >z4K-<*J{dEl&x}nNDq~+Hsc{ecB>naiHU82~$vAmKO*nE=CdM7}$=)`}ta@Z7ZS2&O >z1DDN|MThjKsV7WU_Ew!W@Q3mxRcT+(ah3gehMwBhs&cv`lG_ne{!`N>ucboex1~uz >zG-?XBypn0bkoj!ceF<buHPZ{bWX6ZdrfA$<UDW%`%zS-8&$@Ek%)Zy5i#wmHIlu1F >za}VB9^S)cB=QsSKO7`uR1(n~Z(wenWmKRs$Wu;Qy|APtUuF=8n116MQqC=<Z&7!_Z >zy5jr&YVn`*CA_mvEjgPhm8-&PX?vo4UYw_vZR?fg=_x8wbxk6#`_+oTk5YZC+pO$4 >zpjYiXW4`RF*Q;v|n>8Ivw1iKqwXJosF1KB+kA|ftxk=Rq^Q5+~T1B%`BznDA#Rm6F >z?57O1vG<PDwa+s3H=pZG@pQAfvs*V*4H$LsjQ%R1&6bA4dTZ+Mrm?bFHx4{d@uGH# >z_gqp<X-(49byPLKtd{K^U#lH|70b?+sM>WdLt0jc)b4K`8I<tB`}#`!um8z)FD`W) >z*FBfuB)abTpPeDDd-b<L!}#uuc=O5PaKx#wZ~1cjmPMQr>$^|n-*0xC{eACdU%vfA >z*FLe<jC|yV`ItLKZW*~}<ff6kMs6FqZ{)_2J4bHa)80FB^T^#Jw~yRE(g4x{(gM;0 >z(ge~4(gxB8(uk++1Zl<7_JTBnbc3{m^n)~nbcD2o^n^5pbcM8q^o2BrbcVF%X?sJO >zL%KuSL;6D+L^?!TM0!M;M7l)UMEXP;^|YNLt$NyCk!C$@w@AB4zevMK$4JXa&q&iq >z*GSt)-$>)0wsWL)q<5rwq<f@&q<>@skR3p_0NDd%6Odg%w!zcx1F{jGb|;Xn@U(k@ >zYzDF$$aWz6fouq}BgmE@dxC5VvMb28c-nnIHpbKL46-$zc5jf)L3Rh(9%O%z4MKJZ >g*&^rvIz~x$r2=-Pa>CR6h5r1Ua6y5;z@MM=H!J1*O8@`> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala >new file mode 100644 >index 0000000000000000000000000000000000000000..abf943be0fe277c7435ac9e5d51718028ef216b2 >GIT binary patch >literal 306 >zcmWHE%1kq2zyQoZ5fBCeE+7W6c^ZJk{JF30u!pWmU_U$Uf}~DGg5>!p0qU>bJ<vE2 >zbHODfD8W_UJAi?S5eonRU#-Hx@c;kL4U8;6_5ubDAKwrLXBQw24gs150wE;0;0Htt >v(8T}$K`sGtL9PMQKo@~%kgLEn&}ASR<T?-yav_KYxe`Q^?ouwGqs_Pgm;yx` > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil >new file mode 100644 >index 0000000000000000000000000000000000000000..92de38bed407d9d7154cd3875edbc2e01c993f6f >GIT binary patch >literal 271 >zcmWHE%1kq2zyK^j5fBCeRv-qk1sZ_Fwk1vy+G2k$Xcs<nsQ>@}KO-{}GxPudTQwLM >z{{P>W!NBtW|M3Hi9RL6C+`z!&;~T;d2*kPuCO~Wo)D8h5ge_$Qssvm51F8pT*Z<6R >hwFnRmas)^i<Pb0obPR~D2g)&!<svQ{p!@7hxd7s;LFWJf > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana >new file mode 100644 >index 0000000000000000000000000000000000000000..7d2987677d321fa44fafb72a1a6032432d0c64d7 >GIT binary patch >literal 266 >zcmWHE%1kq2zyK^j5fBCeRv-qkg&KgwjGL7mT(w(l)a!p6)c^ngpMjBynfd?!lNAgM >z|NozMVPN_H|LO$>uK)j!A7J3~@eN_nH83_Y1(85(0yF>uLP)Uo2UHKxw*MgOL0pg% >UKs3l1AesWFaM=JIW@o|$04A(H7ytkO > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax >new file mode 100644 >index 0000000000000000000000000000000000000000..f86ece4c4032634b3526187c5f86364077b9a9b1 >GIT binary patch >literal 3438 >zcmeI!X;76_9LMpCm=UE?iki4l7HWtOD27Y%SQ?{(oMcf_@MM~SrDWogggR--OsP$o >zWk!pJOQn}ELruKyj%FPo4NLK;p=MfQ8*bdr_q^>z<4iBR%yU0?81C@y_x-0nmi=Um >z=O3?|%x`#j)tZOTE$5iGIdvbuzwE~v-#dp}I7Mai<$Ifti4Wgx?XGZ2oR!a~yB~#h >zbc$2n_Z43o?p@t~tGoJWFYnrR@40Ia_H{nKHrM@R+iT9Jzf`;HUTJXFe>uqY&Q5bm >z)-88G8=C7aU0C35=)A@Ge3EoGhWfl;4135e3u^7%)cGghrZbnlTN)qmZK-JGZ1rTi >zTi=cLmS5W7Zd?4l<EuL3+n$x+?09vdyHgZ7yPnB)cRO>OJyZI-dqc)L`+86E?Ymsy >z-QP<1_8*bn0}D>d%DaEht&|s3Ro-F!t^18Slvbt>cPdfe#V*s;p4Zip(0qMF=c%JL >zv*fWgQ$<aAraWGlE_6}6JdqtIP8NjAQ-j-z(+M5*nLFC3vk?LMY~2-guE{BVuHvZr >z`SfmmzNB2$Eh?6mW*3UzCNGe`kC`a`NY0Ue#wUrtdL+vFF4^jG^C)>GXsEhUKSW<W >z+g)9&j?~xpHCGK~&9r}2o$@Tbr~_WEQjMlp>cHHKqOtr{-XtnT6SqR%>}(K0ol4~` >zA#aLc&k`AYafY~6PnWkHc|$ezWyofmrm5y@@^r}CBh~GNBlI0J`>Gb%eRRu=b}Dpm >zm~Iu<pjvmiuG`!dChiP6uG<D&7j5gV$*>d0MZ1a`*?#+W(V@gAJASZ2bjrJ=!{^Qy >zccp!+@6P!^b&lPr?-}x<x;OMK9no#PifH&;b`4HYU2B%gZs)qH`^sm^$f`#~_o7iU >zs<eyfQSg9tUJn-06Ebwnl=GrzLO<PW_}3yfqP^}N;}!Qe@$0y-uT<RW6S~jUb*k^4 >zox0x-i&g*iT0XF4ih6L-4jKPWs&Xf<lmq5HD;`RINj^L-MGWlmlpHiLRt)-WnNH~b >zs7k2H*Mpn(RD(;i^pFdoYUuJ=GVySXNXpNY!#1`Q$)n??Sn{WMw12o9o>whW+6Btg >zw9O**YOPF<T`tmV1N6uaWoqQEQ#zwznR;yHZau0dUyYu(N@td5sjP8@dQ6e4WKyww >z{N+qBw)+D4#DsV;u4#@OpAas_Ur3Y_A_B#PgHbZONv+8KG(_f{-YX`)8L6NC=9GG7 >zS~ERq{cbfm?V`?Iv`Rf2TdAi^E>zEjZqQScC#tCp6>?hK0x_+oRL*FVBW9E@ku&QP >z#q&ke<*e!`kzbG@UnmO^1zG*%?4_54r%}KS{scC@!7tqCKltze-tXTfJs!XRkP2w* >z_wV(2g6!wp?0ZOJQmSXbK=Y)SXM}k~su?PeC&0d?-oU`s+wbw8{C<WG89QX~kkLbi >z4;epX0Fe<yh7cJ;s~JRO6s=|$k#V$|fkZ|U8A@a<k-<bp6B$lqJdpuKMid!RWK5Ak >zMMf1FR%BeQW?+$#wVI(t#@1>E7a3h-c#-i%1{fJ(WQdV5Mg|!fWn`F<akiR)Mn>9d >zh8h`bWU#Gfw2|RP#v2)MWW<pnN5&i(bgLP4WZ02$M+P1ld1UC3u}20U8GU5<k?}_Y >zU^NjyLSQv9K!Sio0SN;V2P6<kB#=-bu|R@>L<0#25)Z2h2oez_BuGrq289nqg_j8n >z5EmpcNMw-EAhAJ$gG2`j4-y|FKvokWBt%GzkRTyZLc)Z^2?-PuDI`=#tdL+K(L%z7 >z#0v=+5;3a@84@!jXh_tMupx0n0*6En2^|tUBzQ>lknkb#vzh=R5ww~RA~8gQh(r+y >zBN9g>kVqtvP$IEJf{8>E2`3UyB%nw{ttO;MOp%}>QANUv#1#oF5?Lg)NNkbdBGE;{ >zi^SJz0*pl1YC?>}*lL1|L>UP)5@#gPNTiWaBe6z;jYJy>Hxh5F2{;mQs|h(0bE^qD >z5_Kf(NZgUYBauf!kHj7cJ`#N-{7C$f0{}S!tmY6vjsdGV2#}+|Y7PVBI6w{r<VZjc >z1>{&j4hH0CKn@4wct8#a<cP4ELjpM_tmdFVjtZ+eERf>@IWUkT135I1V*@!j@c*NO >gGvr^6j$m_(^fEU|WKz$lm?$SQDLOhTI?4(D8&gR`p#T5? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Havana b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Havana >new file mode 100644 >index 0000000000000000000000000000000000000000..1a58fcdc988ea6ec1bb660ceabe85ea19e5b0774 >GIT binary patch >literal 2437 >zcmdtjZ%kEn9LMp)-yCXL{y`%Nlf+6;u<Ixk&n5~6SHHy76okkSycl6dLZaqcNwzk6 >zP?AYJsEoN)8ri^Vbe8yMj^;PWVWTkv<3XES%NZKU?f3q*wzeMhpdNM3&Uu~P-Mjnf >z^FD#XV0oJJw<Fqo!o|^SE}kdtF}L?Oe!1tP-q)n9rr14GRIX=w^WC!<IePZ<Dz7_n >zlXN$)_P*{KFFhGoz20{&%Qta--biVbj)Zo(*Oz4J^`Qdq*ZvG0ZQbkscJi>^XxQwI >zbvPPo9rB!}K@Dp->4n#JX~fn+H?s75iSkYHqTLg6)3h9ST*4t4H&XA#I1Li>Q>8op >zVo)Z0yVslO<;u;+H+#3Vy)Bb=9dvKa|50x%Z}%prcI%WC2fV38&+D`~^<Hd7nNE)` >z_GZMb&>6!^z1v6UYTUUE?j8LxI`c@T8^5DK?rcnO6AFDYt2*4hYgxX|UUkV$oV`%* >zPC4bynfkIO#SVH&W34iGq(|==*eCb)9n<?dx5&Kq{hHk3mz1VDoxgj&ET}Ei)QVh9 >zdt|XL%ud$(-Sy&|d0rN!9hF5l+9f@%ThoVo^?}h3^}$o0Xh#35y7)+sEctAkW;Py^ >zr3VA*mKW*rET1gD@``3B#!B{ghh=5Nby@kb=tD#OlG|J*dEF!Ge{r9#`eK!?uDz)8 >z`Y)2dc(OeF%mpckyDEV-pGsh~PuBXHW$mRax-Py$*L9uO^<!^p;k)fxG_X@Qyl_B^ >zJ4>{rtX>~&akbR{hCJ3#EE|(|$m11DrEKB`*_1s?HeJq?ilhjs_$ony(LYG=gK()F >zJ}q1J$Lka4hO}zCqfZ_=snu%+b!%g*KIQAuZPokq>8bB&&FU>$Gj>9@r@tiI2M$Ty >z^h&AgY>;QK<;jkgpwwSTk)6A9Wmm@}*<F$>&o%ulVG-f~_KXbw%NZ5<-<_dQ+Zo3( >zch89og-&~6<3ge1N1X|O-uWcYA8>NawJghA1p%`j#|aCwIDvoO-CO3Hc6ZnQ_=)+q >zP$<|iw*%QBvPEQ%$R@33m&i7)W}nDLt!AglR*}6Tn?-huY}ab`i)`3xc8qKp*)y_f >zWY=i7%>(=9FdGMUj%*#-JF<CX_sI5<{UZ&qnhqc>u$mqqO+dPUv;pY@(g>szNGp(D >zAk9F!fwTkZ2htFvBS=fErYA^KkggzYLHdF;2I&ma8l*Q!bCB*J?Lqp3GzjUC)wBrd >z5z-{2OGulLJ|T@lI)$_f=@rr}q+3Y4kbWTzLpo+PEkk-{HBCdhhO`ao8`3zWb4cru >z-XYCHx@R@*L;7bm4MaL<H7!JXh%^!DBGN{rk4PhtP9m*DdWkd>>891R6X~bbG!*Hm >z)wC4pDbiG=t4Ldsz9Nl9I*YUx=`GS+q`OFak^WjugOLtfO^cBpTTPRZE+cJ5`iwLh >z=`_-6q}NEZk!~aHM*3|v4M#d|H7!SaZZ%Cux{kCR={wSRr1MDYk={H1=itYfH-OK) >Z3Fi41rlh4Tn7?42KQ%Qa)jXxf{0?B7_b&hd > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo >new file mode 100644 >index 0000000000000000000000000000000000000000..ec435c23bc47f925bd70754b38bc8b1d2c4d3943 >GIT binary patch >literal 454 >zcmWHE%1kq2zyNGO5fBCe0U!pkMH+y_(rqsa)_=--uq`btVY~CCgdIF)2|NC_eK`H9 >zFyY3;Egu*d3K|U4TLg@X#Tty=(*#U{el(b>dkB~r-D+T9WCBBGMiwyq|9|=q28RFt >z=T2Z?`Tu|Q0tSx%|N9#lctC7M0f@MdZwP~La0r7l5C;IUuS*Ef6$lVQg8PA%fx&+u >z0Qmz%gZu)bLH+^JAU}a<kiWn*&~G3b<UbG%@gvBXf(8%?@+*i2`4>ck{0yQ&{sz$? >Pzk_I6`JW3IIObdcn4XX> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis >new file mode 100644 >index 0000000000000000000000000000000000000000..4a92c06593d33d3969756f482e5d3d4b773984ef >GIT binary patch >literal 1675 >zcmdVaT}+K}0LSs?kk@(LFc&RW7jAmD%q$zL)}m8hP9)@yXes=a&Q2uH1yVP-Da?{F >zud{4KTr|uuW;Thu)jw}D*7heCne9CO-+%60xN+k-d!Em8&Q9xG{Ju}1pk!mR^T#p5 >ze8S1G-kjV=y5`b!I@UdY<A-eCH_knA^p$+DJlcKGl_?+Y54%rdzRM?TN9m5re&^}D >zFS;|Y(|I=ik$#?X&FOMl^oz+yoEPelei?3cU)`+Gue%%FH|Gw@?)ECTr><P8rj>4Q >zNkG1>nd`pGnkC;CPIEtfo1#CP{~m6O)ZQ6SIgMfMtL;_k2|<~Wo+dK-&+5#$H7c{C >zUT2M+ud*(e=>>f;YT>aunf+{@@K=}0oU73yca>i*YKRbvQxoKp%8z1c<U|?ByDtJi >z`{lBf^J3YD@j5^1uFAjjRj&x2RRyOy^vdpfwQ5hRUfo`%3X2-`nx-5j{8!}K+ETGD >zu0gIZ_KTviA-N$lL2T$Nki|15isDD9vSfI_D7hFVH+}3Br44g*+2gNjb1+hGY3Wc~ >z^TJvlXjR)%lrG=es46Dk*4uNd)b?<X49;#4!R}i!G&Lkb?I&f`K!MoNv{&xzN)^>L >z#d23$l&C4plDiK(Vu;VahDQ9p8GJi<9X4dx@PF{~yp}nR<9XLF`64{;LbEf{-jA`@ >z30$2?o_Fu2Z)&zb;H0ISbE!F(n{!dX$uRdB<}(hTy+Yvcb1O1mwsRX8{44VdJg;zQ >zxEYxrGC^d9$P|$|TFoSpSt8T4nt37<MP`aj6`3nCS!A}zbggE-$b^v@BU47^j7%Dt >zH8O2v-pIs}nIlt2=8jAr?d-W>`W$BdKmtexND5Yy1CoT*WPzk%HF+S3AekVkAh{sP >zAlV@4Ao(B(AsHblSxrtzQdW}{l9tuvg(QY#hNOn%h9rk%hopz(ha`w(h@^<*h$Lw> >zSt4m#O`b@iR+A}`Dv~RbERrpfE|M>jFp@EnGLkcrwAEydq-`~MBZ*s0=1A&D?nv@T >o_DK3j{>UT1`A?q#qs^ls#XK5f{WIf};}c{3NlEcZ@rk2<0ei4<R{#J2 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox >new file mode 100644 >index 0000000000000000000000000000000000000000..cc785da97de0a5614613f9ba6e502d7dc5f525b5 >GIT binary patch >literal 2437 >zcmd_rUrg0y9LMo52q6eaCWd5SS}_9&Y$$E8wFP5`#6Nk!KM+Q0h-E%1kf_n))+8^Q >zrA@&a>LQnGhSpSU3r(rDnlm&BQVB4LS;(VtK}zTJydN*KKlgpv@4U_qC|931-bH24 >zPm{k~i2a0z+hrf#$7uUfzb{Ge{`7aXXLF?9yX%7b=5?PwJ9$u@EeSQ}^Uq7$#M9>c >zw4>54jiw{IPCB~YGC%kZ>kB8=nv0z~^`-r9s?O#r{o|H3s;j<Gcb9opPj#lg?3u29 >zDvsAz=4Y7RoDBJSMx5zOh?Bk><IGk2+po3`nO}N)<kz+q)Bk0QTsz*a1{%Ax*?me~ >z-+EFHF0N5Ghf3vEpT`Whd*qL=5{<7ZQT!i77^#hrfSLgl`0{{^SRJl{N=E76IoH%( >zPxR}Mly6nY8wolz>SGmp;5`X5Z>v#V+jV%yK@)MJLPs9kW=8MdCQ)_e=I$-!GN!7) >z+*4K{V;82IXivI~dpy?MJ0(_PCe2XeM-EGD;CK~#BSzoXeM?Pfy{Yg2{E~`0bWz9e >zJ+3BJj+O^D?NyWVugl~WpP2{K&dEc$yUoMVhb7^WO(wzDs;7i4F<FmRs_d+}D*Lyi >zk~4Ls$vIaio`~7T^T`Iu?N2pNy}MJ-Y@4O>Hdg6bM^e=6qC!1q#~3v?BU3+JF{tKE >zh}YiyHsu`-&;@Bts^ChTEQtHgEcilXq3?)U)X*b^owcUuwHA4%dA%uKx=$9@7nx`C >zPU@1HD)rpd2EC-TP%Vwvte53vs%8Dlb!kGpDm|U6%R&NF*?}azqW7|TVTVUvJmWVj >zD--3V#%{B!AVSpEQ)YGAfUH^dzF8aHD&@0lOu4ULSEe_p%FZ)-UCd^+uKAFz8d|Q_ >z*KgMw+H=*$>I(fzQ<ADKp08i6jZ}dF_G?6tgSU773jUkV@BGv5)8K#j-hcYv{Qi%= >z7V-O!9SjKa`#;<xBi;LO_Zr2kjJ^H&%sj6=nPs1O_L*;=IbO-O@3{c?3f_NT-#hk) >z-TH=Z|1103{r=(+zCFkqkwqe_M3#xH6IrO!t`u1+vQ}iV$ZC=0I_-Lq1tTj)mW-?! >zSv0b0WZB5Nk%c2GN0yGP9a%iGdSv-dyMCkqPFn$_1V{~#A|O>j%7D}XDFjjpq!dUk >zkYXU!KvxdlP!G-)grg!zNjPeP6a}dYQWm5xPFonHGEQ3>j@lr_L8^n42dNKIAdU(l >zCE}<NQY4NlA!XvI6H+LSN+G4<sFl+e3#k@TE~H*a!H|j}CF7_WQZ$aLA!XyJ8&Wuq >z$~kT6klG=|L#pSr<>RQI(-x4Uf=*jPjv69GM5>6C5ve0mNTiZTDUn(t#YC#<wB<zV >z>9hsqsHoGHl%u9dQ8}uLl$E2dNMSiDi<B0rEmB;hx=4AE`Z{fakqSF)iIEyRZIO{G >zBW32OGg4@dN+YG_s5Me-j%p+2=BT&R796R#)0P~mxziRMsX9`2r0z)Jk;)^bM`|yw >hy#I^bhuOad)9qh{q`b$HrzNK(<)x-3rzWR_{RxkBPOAU_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo >new file mode 100644 >index 0000000000000000000000000000000000000000..a23d7b7596fc3019a2b6847a7593007f985e7e13 >GIT binary patch >literal 1731 >zcmdVaZD`F=0LStFwI^G~2u-aidm%M@z$8sgw$^ZGxR_y%$7?nm%nUR41sh5zZIWgp >zk7=Gm5)w)hi{xRBr_mT^=EWrU?|hH&!V7unfBXMG|8Cpbi{JP73X0|ra{jm?%s1Rz >zesl947ch^y1Brn>7rw~)s;+^(yB^D18-sy+37_S?S&{llQ*Ges;cfCo<%qz`oT2hn >zVc)>(0kN_<JKcHHV~Bp+Ki+x!skd%1f34+ihkn=m!g+t<k#4<y&H1qXqW;*R0>N`} >z+CAthr#7fP)z4L@l}d-mpa>P;WLTaO;Tg|lM9NhWv89iUj5#SIkL}P=x=Lgwm&vTm >zQ6j7Tkj@@BQ)M@9);ZB5RnDmrJ-RhPjoH0Pj(w0JycNYV_iR5gZn{_I)r5-i>B(}! >zie@n}uDkS2x+#2L+vVi6BVzLFZaP2yy2`)Srl$rEse=8DdRo(FHGTaVJ>yb|Dx6!Z >zXV&E^;XN&9RTqod18d|QzgNtSE|>GNlf}H&0_pGHUHEUO%cAghQFJU`E^NLpife}J >zk~?i`QCXZ`+|a0&ObTkb^^97Yru4EUwQ6~<tGaaDDpeYMCd-D^h_a?DvOKn2lwaB> >zS9KJK)pZ->nuqD4qS7zdo{JZig*kHFPDga|m`_Nkh1Z{-u<&0W&#$-N-~H>G>o!C? >zj_aO3?g@3>qxDW_``*PqV|Y3}UH8UiPwZH)&l#0z?uq7}V(vVjlV#qs%y(QK`vl+L >zC%C};u$^GXkKZ!?f$J8A1nZGWBC|xMiOdt3C^A#4nJO|@WU|O?k?A7yMJ9~Q7@0CM >zXRDbsGHa`uHZpHy;>gUAsUveoJ9%E1J(rn2Fn=TgBm*P`BnKo3Bnzua1Ifc`5<xOS >zQbBUDnq-h{tR@{KAFD|S$p}da$q7jc$qGpe$qPvg$qY#i$<1n#L$b4)^pO0lCP5@a >zBt;}gBuOMoBuykwBvB+&Bvm9=Bv~X|t4SBh*J=_*GPatOk(`mFk*txlk-U+_k<5|Q >zk=&8wk?gG|eI$RYIRcPlz-o>H<TyZ%1msvijt1m-K#mCHm~iaD@PD2YQRetaGsj1w >TcW~06q?AN&YHCtyQcBc!Z&+XJ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg >new file mode 100644 >index 0000000000000000000000000000000000000000..f16cb30406e3b28e82ab528d0781280ab5f13a59 >GIT binary patch >literal 1913 >zcmdtiU1-&H9LMqBaZhgU_z)Gl7`w=e5$@3%L@YAe7^ggL=JBCr^S9DYYqNc=ZOt<M >zUz95$qz9%%%!wAFnD*dPgqVp55tXB`0{auWhBfz_vszl`-}n6sqUfTF?)o48=k?#& >z4(#Ih{-m1Q9++$XapmbJ++1CH^IRP0+rVpO!M1mPk-?4AgY7SWB_BSM2~N+xB&S>R >z-M8sm!gJRb$#6rh`R=M4-AHMP8M%0^JFnk9|LLUre)t>n!y8|^(UT|4h3DUOWBbCu >zZF^tFHy;l!Zg^EDI(G(_R`kh_jT?iXZf%pFD<2FlPffealWB8hB;kHNlQ6%Xn&UEu >z=a^_$+?lO$6YCpuQyv>LS!)U<yLDQS({w>{=Zyw=Ri8-SbEQH4%r_-}?+#PoUXp3y >zi$UQR`(6B4cQF0P3$CuRN9yYqO8vwk(@?(JH4JTXiTG_{;;jyM$LQ?v&R3q5`Jd0T >z$#w0r;NW$(ad}dj`m^oA+Df^rd)O{2o+YWpr)=uVge<AqZI_&z;g*%0440i4cXwxY >zh0QyM+&yPEh0C8h;O;%z5w@({;#LeS2yOChY3*yb_m%g{{pqA#8Sj-<4V8A)XtShC >zXW8^ewbGV5VcYhW$V0=Q+4laMUB}1c;p(1Z_wc@<uyb+7$>sy$nwro((zzvk^qS+Y >zt8s1EmHAqFZtAx^XWx_FqF&p3bcd{+Y_^XNJS|V0skQ6Yr{&4RC3byFLN;tQc1lcN >zS=k;Q|N6@L+fRS~CP$xga{t3Cie4`_CW?;ik7Y;Eo<TF!KNtG<nY^2;qv(TUv7-6O >zl)1f5??rkq)w?NW>h-x^KjVt|cS!yF8Sd6U_GftVk8kOJ5JfFnnL*@CBj*}9+sOGw >z&Ny<;y?WM>^NyT(<lG}?A36VCZ2;-Ot1TcsAWa}$AZ;LhAdMiMAgv(1Ak84%AnhRi >zAPsr7BcvsyC!{I#UGYF$T-p~GjUk<J(Hhbl(j3wq(w<lQLmKpIhg`IX^oTTxbcwWy >z^oca;)lRu+)vLWC&3d(4q+O(6q+z6Eq-CUMq-msUq-~^cq;aoyj<oL8-jU|L+C9=f >z(m%2R$POS|fb0RX3CJ!W+kor?vJuEmAY0+py+Ag@tGj`0hgbIl*$`w$kS#&>1lbg1 >zSCDN%_66A(WM`1A@#@|no8#5pLAJ-M`-5x{vO~xgA$x>u60%FkHW|M^|ATQV(9NpR >W%_>XYP%*cnsw`PuT~S?8Rq#9Z#I;iZ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City >new file mode 100644 >index 0000000000000000000000000000000000000000..0250bf90f8fc8716a77163e7c1b92663fc6d96f7 >GIT binary patch >literal 1735 >zcmdtiOGs2v7{Ku}X%8hMq{4;hqJ>10X)jtR1Sz65K5|l1v!|Jrc`Ow*v$F_o*CI%Z >zm<-H_=tW@G!opsQ2uUNNAVy6K%{-}rLCo#^4+T++Xxn$W_jkRFyYGLz`K5bSh(9L8 >zeBow_&CPqHG7n$7Tb;lARkk+HQy0#@kxx$qRPW*`*}Ee|_f<`b7wbl~-&dgeOTBWS >zAyEycu95Fb68%F<BIIyNf_NXkN`Hun5+5cO>5<t&j69##qr(H@<IUH4?D0eK>0ZAa >zzwTGM!lyr<>{b)UF3QRBHZ`@aNq)&_RDsS&?ObyFqB)>lP5u6)<<&AdDN80#-WDm# >z%5+NK8Ic;6p;K=i5ou%bdc(P9wee-T^wig?^o}^0QCOfdPlwB_ghaKeYD#8DMl0{; >zm(u&qrE*qx%ABDnkr(ws=RFc)OQ1vNw+)Dbw=KHx_(QR^t4<f~ZWr5pg?hWETkUA7 >zl{=TUsa+)na(7sxDo#n1#bbL_NldgXd6uS1XS-zSRkzwVJSg{{P8A1w99>quR2;nC >zugi17ggp5`SF9cvhsrPN!wa8_%8Vvm85mR5YujY?+a6UD(I{)WZmQbpy|T`CN*#HX >zChHrj)X`42Y$(cA$6Dse87^}L1zULi{hB$;T)%((*S{U-+GQae=gtjRu;W~56?5$S >zT>G5QQ!H?tC-+?uzy4;U$1Bz+nLFFux#rIFie&SiY`!rr`~3Oh{re*BF~7BoIQ`>4 >z9WzBifmUQOk>x}d6j@SaQITb}nuSG{7Fk?md65N1mKa%NWSNnLMwS{`Y-G8uX2Fpq >zx0*#qmK|AmWa*K`N0uK60Eqwz0f_+#0*L}`7`zY%V*&vpK|(=dv6^5QqOqEA7~-*- >zfEXe|LPBCff<mG~!b0Lg0z)E0LPKJ+n&6P=tR_5$_^c*Ch6s@m8Dd0&WQY<8lOawd >zP$W_$R3ug;SR`7j2^WdiY63<gwwjQUn313vqDI1Ih#Lu<A#x;ihS-td8KSqE@R9hf >z<^Vtr0joI(ki!5u5RgLwIT(<`0XZO$LqgbN;eR+KLd{{a#vCec&&t>pv2kuse0*$t >HY+UGfYubM# > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay >new file mode 100644 >index 0000000000000000000000000000000000000000..e934de61adb342d238789c5dab9155408f8cd778 >GIT binary patch >literal 1423 >zcmdVZOGs2v0Eh8AI`)vPgaQ|Xi(ItP@ex9VfuSOn<8w5dOpm1vrsb(@8p~`JmF1@0 >z7!hU^B}F8ZVJ)O0Du@V_A_(jh<W4wZ3nQA_`A*9gZQ67%=l(9k49w#D2Sc6v3!Fc$ >z<>nI(SFJg``(oxXax*)2_3?K(dTw>>+U1Y(_4!0>I_sO9Zd<9p3~Y@hCVkqy<tk@5 >zp*@42Rnl>#lVw79#ZQ@1qeN+LM3$A7h_b~oU7pjb%4ddjMcOu1alcz{pU+Y|u3V6n >z?~6sCze`p<+#sr(1F|OW6}3gVvhLWNsQ0DIV8bgB{IMt-3vY|YuWNKu<_p#Id_nI@ >zjH%F#8NGXUNHw3C(0iu3RZIJ@ZXKyoBJe=A4R(pWIdQo!91!hkQQ1+RD>~*wGQ2Te >zgx?g&&Si_D^KPa*F!xS$#kc70w+rfE#HSD4n^8Rt2`w*9sKbRyAL$uZN7p~oz14lH >zH}OeEHpfL|_Nk0!L`8J!y6jsDi4!Ad<;f34qJJPPPfccuftCt+`jR7(JmyaJCZ#O< >zN4M*a7dwvYJ{tFUUH8tYv%<cwvd^_VoprAJ@`)#-G7xl1O3kS^XQw$eL8r{TmzmGF >zJoX8}zeiDLzHFmd`u!{O4_vn;IWdYvf`o#^f&_y^gM?!>@gM=AjffXQ;xaJ-K_O8g >zVIgrLfgzD0p;=9ANN`pY9TJ|^#D@fkM2Lil#E1lmM2Uon#EAroM2duJHL)VWT1~V_ >zxK<M{5-<`m5;77q5;PJu5;hVy5;zh$5;_t)61>$!kA!bE@goDUnh_vFK*oR!0vQD| >z3}hV0K#-9jLqW!Z4903kgAB)N#)AyVYDR<%2^kYIC}dQ~u#j;f19Se1g{7L|6`J8? >T2R8W&{CU}d{Ct1DKQHwc0I<R? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes >new file mode 100644 >index 0000000000000000000000000000000000000000..adbdbeee629ea60b60c32d0742a9a69ab5990eba >GIT binary patch >literal 1703 >zcmdVaOKeP00Eh8ATF-a~>7wa^g-H5PR76HXv}uY_kMXLigSL}u>G7J>tL_5D#%?Mi >zqoN)m4dQK4j|dVG(IP^^smBnMGlrxhnd^MVj)la|o!tAonY2w8|L+7#sw&4ge_TDy >zH{4tm=H@-!HIL}gO!wfG@3LuUfA`S-XY%f@q}w*)t881=TeojWI1eX(&?>sv?WhXM >zm-Um}S4HFH>(C_iW>lJt75bgGgU9K2BQu<LUxw-T=C8hg(4{}bUOFGoJk_1IZaSZ? >zcF51Cl&jZ7b$ss)_sg~;GEv*?eqGuizZLIvlb6!9cg#~xV^aGXI#hm6SQg~ZmIaB6 >zPGQz6UD&=y7xkN>iq6*PX`Lg~^aH!)jK`BjU`w@}d11IHE)B?8kyJ6;pCjjNh>5xB >zgJf{t9TEJIkn{6Si1}{@=!F@#)WVx_y(oEHl{B~O#n1Ps((UK<lGYkkR^F(WMrSG! >zI474iREy<V5xF815as>qWJO_)sOT(_p^<|`=$>Cz^+<@SmJGQv_DEDmChD5|akVO( >zu2-LGSGDt!TJAls*5oO@wzg5N8+t>pFW#uuCtt|$gop?~zb@<2>O@`ZVY#uZL~M%g >zkei?Q#g_Vz+<GZP)Rz^>ZTlS2&1XI-sTN*;|8(zRKITg+@Bi}gyq37*c;4mHzEsaU >z+2r)H?|toaAWvtA=iR>MOPdi0I#ct_J=fd|%sngU6qxq{^BtGZJ|Xz`;Z>R+w!`cC >z^;_mY@Vv5=WD_z(WQ@olkx?SUM8;_~14TxP3>6tGGFW7^$Z(PIA_GQ7j0_nWv(*e5 >z8MW068yPn;aAf4j(2=ntgGWY>3?CUk5&#kb+7Ngl1}+l>5Cswj5{K0U!bK!j6ABWG >z)dYh?gM@>`g9L;`goK2|gam~|g@lE~Wi^2zky%Y>NNiRU91<N89uglCAQB-GA`&AK >zBoZYOCK4wSC=#jFgo?y!HNhg$T1~h}yhy-E#7M|U%t+8k)JWJ!+(_U^<W>_p61&v| >zk3?@Z;Un=Q2LN&iAO`_*7$64%aws_V82BGgg+Au6$TNpUW?*dgnC#J+f!y5e-0abP >Feggguh2;PM > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac >new file mode 100644 >index 0000000000000000000000000000000000000000..b34f7b27eee88867fd131f0e9b87b4c3b4c071c4 >GIT binary patch >literal 1787 >zcmdVaNo-9~7{KxKw8j_{#G-kGg-x|eipY}?ZJOd4UkxpFj7_yTrlvL2U6?o6w1`xN >z7()p)MH)nqh=^9HsZI?gr5tKek-Y2tk0pu3&bhhwck}XI@)qC!i)7|59wL4_?d>Pr >zoIHE;9_QId*^zkfz?JW+d`nmF;J#<-?zX5`J>Z+Fp4ZXTtZ5MsM}IK28MWe3zkB9! >z@<mZ6D$J8!d&LvI+dPd{de5${GSBNvy%)!KsrsrS@8$NDN|$AM4Y?8Zs(6(5I(?XW >zlik;QJ0oNo(?a6i@Su4=Feu)C?QNRuzi4{UYCbf+5+Bb#HO;qfich<*n$H#5i(ZN| >z{!w3x(x?e+ZO|!+1u8XVib`#{DAESa)oC?5OnR3wI{jR}8P_~OkKeytO?Wg~hS%q* >zi5L3INwdRha!IV55=vB4*EGs$aXnNd<Bp8{Xi?LXPsr(SyP286TYBcrFJ@Nsn9e+0 >zW3uXZ=-Hbp&77)yoxQNs%q^R!W%#_Bw>3}BA5@|i<b>tIE`@4QTB2OkoT+jK_K-RE >zLMpdii_AS0R7)CbWnRfhlYjq<URn@mmQ~c~<rz_<c2?>Y$=a-3UaD91x?xsND$=W? >zFIB;a5?N4xT^05zl!aA?R8ecDTwAtTt*Z;k^~E`A!=<1s&Q4bw_Xyc0V6T{12d{s= >z+P1S-pbgJ|zkL7neIb1R@|i%a@1HCe9o&0o_w3G7^z{AP*8+Vegd<{XioK`VdxpIy >zM?|W9Pqm+M0`3WszmH|U{jwX&)?dG}|G@XNW1{8Am?EQ!j4Lv-$k-yI>$KyGj4(3B >z$S5P@jEpog*2ri(?RX<2j*K}n>d3ewBae(dGWy8)BMBfGASoa@AW0xuAZa*l9!Mfi >zn+cK%k_(ayk`0m$x_o#cA&$)mND0XaNy=%n;*gfp=7l8Yw3#8PA-N&RA=x46A^9N* >zA{innA~_;SI&GFnnogT1lBm;WilmC<iX@9<i=>O>izJL>jHHa@j3kX@jil|gc_WEC >zZRSYoPMbTDJd!<<K9WDO0+2O;tO8^mAS(e`3&?74+Vy~}2&Y{W$f|JKb%Cr5WNjd; >s16d!)3PIKgvPy(o9{=wy>10<-vRyIp;h_mb5(dYIladmW5(anr2@}h^zW@LL > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis >new file mode 100644 >index 0000000000000000000000000000000000000000..4a92c06593d33d3969756f482e5d3d4b773984ef >GIT binary patch >literal 1675 >zcmdVaT}+K}0LSs?kk@(LFc&RW7jAmD%q$zL)}m8hP9)@yXes=a&Q2uH1yVP-Da?{F >zud{4KTr|uuW;Thu)jw}D*7heCne9CO-+%60xN+k-d!Em8&Q9xG{Ju}1pk!mR^T#p5 >ze8S1G-kjV=y5`b!I@UdY<A-eCH_knA^p$+DJlcKGl_?+Y54%rdzRM?TN9m5re&^}D >zFS;|Y(|I=ik$#?X&FOMl^oz+yoEPelei?3cU)`+Gue%%FH|Gw@?)ECTr><P8rj>4Q >zNkG1>nd`pGnkC;CPIEtfo1#CP{~m6O)ZQ6SIgMfMtL;_k2|<~Wo+dK-&+5#$H7c{C >zUT2M+ud*(e=>>f;YT>aunf+{@@K=}0oU73yca>i*YKRbvQxoKp%8z1c<U|?ByDtJi >z`{lBf^J3YD@j5^1uFAjjRj&x2RRyOy^vdpfwQ5hRUfo`%3X2-`nx-5j{8!}K+ETGD >zu0gIZ_KTviA-N$lL2T$Nki|15isDD9vSfI_D7hFVH+}3Br44g*+2gNjb1+hGY3Wc~ >z^TJvlXjR)%lrG=es46Dk*4uNd)b?<X49;#4!R}i!G&Lkb?I&f`K!MoNv{&xzN)^>L >z#d23$l&C4plDiK(Vu;VahDQ9p8GJi<9X4dx@PF{~yp}nR<9XLF`64{;LbEf{-jA`@ >z30$2?o_Fu2Z)&zb;H0ISbE!F(n{!dX$uRdB<}(hTy+Yvcb1O1mwsRX8{44VdJg;zQ >zxEYxrGC^d9$P|$|TFoSpSt8T4nt37<MP`aj6`3nCS!A}zbggE-$b^v@BU47^j7%Dt >zH8O2v-pIs}nIlt2=8jAr?d-W>`W$BdKmtexND5Yy1CoT*WPzk%HF+S3AekVkAh{sP >zAlV@4Ao(B(AsHblSxrtzQdW}{l9tuvg(QY#hNOn%h9rk%hopz(ha`w(h@^<*h$Lw> >zSt4m#O`b@iR+A}`Dv~RbERrpfE|M>jFp@EnGLkcrwAEydq-`~MBZ*s0=1A&D?nv@T >o_DK3j{>UT1`A?q#qs^ls#XK5f{WIf};}c{3NlEcZ@rk2<0ei4<R{#J2 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik >new file mode 100644 >index 0000000000000000000000000000000000000000..1388e8a4d93dc8e04680aa2aa9e33f32495e26fd >GIT binary patch >literal 1928 >zcmdVaT}%~Z9LMoT(u}jv#}#IRN>m;p&f$QPfUhNVLOMctBs9X8z|+wR-*)B;;@?GM >zT=AbV)}}IDH7{Ce>ROu{%{9Er=5TAhEbP6_)M;JFW^sDH&)T}^$}8ue9X@Al+&$l4 >zd`)s=srlbcaDU;$?Q$Q!XN&vw{k<#XX7MXBI;YP}>CwCglCAc^)lrjO^NgKZQD7b_ >zm}95qSIfhh0Xsb-DAWI#tvNqtO78G|I^*o`GV`O$I_v0p$xF?!kL*7#`K!|Q(M_M5 >z$I5=Nk1zkw%+CJI1`E{$$1Z6>V4EozIje=2<K~IMceLo@76}c!so_%%Qrwx)$XoNI >zB++F{w@;P1(T#Rq!>E)6pS4exek1cI7TWTho2LA?`)$RouTAB-Yj(l6XUxJA0bO+F >zuvy%DMVB1hXO^~qp-*)kl&9-X=(5(mQdN9FtE<*Z^`ApF8tO37i^ptDR*R`Q)nk`m >zU219%y{FH8*(|Y+Ze8*5VySCRYJGp6JioA38&VmvGB>30RX<DougTh2c1{|9DY8v7 >ze=<!&lkDoTA+zS)>-NQwW2U)l*uFH_V_I5I+qDCm&AQkHUEkd;8$u`b<wR0iv--3x >zS}Sc=Q<?~dByqk;lM^RP@`Fm<^y>}T-2Z}o^};0cTB^dne*C&=Z_Ke<dWX%{vcK)N >z_S0s2_9eTcuHWn!yQQh}lad<wPIpf0lbwT~>aNk0>>fC(d%kLtj?Oo9?<bYg+0v%_ >z-p&=1F)rht@ps_Iy)Ad?^!rD~jZde0#bl<_ht*{Hzf1{5BBs8oDsJjm#!ZZm`~Kg> >zZ{rn@{`+rfcf4lgMI*18<7FeS8+qXzuN-;l9IqXD@yM%3UcT48exv}T0;B|_2BZk2 >z3Zx9A4x|u{N{~`GYC($ex@wSeysjRkAdZTVl8~B^qL8YPvXHuv!jQ_4(vaGa;*jc) >z^1QA-q(F`ekrFv-M2h675-F3TPNYzzQlwO*R-{<3s}?EO>*_@c_PUCZk~wNdibkqN >z%0}u&3P&nON=Ir(iubzek@CH+eq;f>ZUvAf;8+7>5ja)>Sq6@EKo){yC6J{+)&f}! >zWHpfG@VfOt7R2jT1X&WVTN7kakX1pJg=1Zih2dBkWNA3o23Z`A)j^iW>(&QZAg@~? >wWQn|PjgUn`RtZ@qWSx+OLRJdz-lYn-@tW_(t0*=%TpErP#Y#%TCE-ZmA5g@<L;wH) > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit >new file mode 100644 >index 0000000000000000000000000000000000000000..0785ac576173f7b7a5e7c2740df5f1f3492a4950 >GIT binary patch >literal 2046 >zcmd_qe@xVM9LMqR5ve<6jTME8m{8Fn+#T2{8kq*{cG?N)VM?ZN4ZEFCd{VpNkB~N- >z%YU4+VOx#m`Y~5)WM-?iu`Fk;Riez+s?n#m_@hPpC~mRX?%U`2>Bm3)Lx1<ZeZP<I >zzI?gA?)gf!Wge~d{&fWH6Hbo3_T+v+uf2TUd7}4H`89P(CiQQT<t-C;W`=Ie#LZ0` >zD|JyKWNuzMOWzWjX^P82GJD3DnUgnD=3EV`xj&3a$;DsPyt5ai^wgJX{)tm^Yt}Oh >zo<1gJtv{Ob9RvEd*g13is-yajqSs7C<t|;3`&fm7tvWRFs;c~XiC#E(NL3A|q`E(& >z!lxHYq-V8?9xIlbblTMJ{9P8s6Xve9-$|@up;=rzC`+ann7X;&=(^FIw{-F|v+Vpu >zbN9FXx_;nSb<YRAdijwdb?*z?^op*x)yjhh<i6(TR73k#X^do5Q)7cPjh{5}>Mc4x >zeApxkR_es*PP1yPT(5rdS#|$cD<rwUL#=tYOqw?(RZCyKJWwA|Yo8pIbtQ!=)%vNV >zCdbwK*z2<XryI<M((`)5xhrO4?xb#eW!OA4a#(LVc*Z<D*r_+SA2(b2*Jw$;qqZLE >zkZsj{>XCF(+6%hX_IO0LkF}|EMWLj>s8^Y3<C1x^RP7kOEFFEzOy`9w`mt<@d3<14 >zceUn>I&wxo5z}U8*Kxh8=p(bcd5_+m`(9=1`XoDYR&^J5OZVW*YR^QQ?CpO>?fbf3 >z_V=XKQ}2~Z&*p?W@VqD9^?|(W^75zlnKpfD?@j3~`vbFw?|<@PAm8`jf6JTU`<I6T >zv)q$HcP;Y$H(v5)^Vh(<zn}AFbu{WVwWPeJb@ps*<YLbUQ(l98&|vSqz@J}lum9Yo >z{=?6I;;(=A?Lh`e3Qn5?k_3_kuagFn2a*Vq36ctu3z7_yjnk%s<bx!HWQ3%I<b))J >zWQC-K<b@=LWQL@M<mR-=A=x=?dPsgqf=Gr)ib#$~l1P?Fnn<2VqDZDlsz|O#vPia0 >zn=S|WA_*fIBPk;}BS|A!BWWXfBZ(uKBdH^~J8kkv_D-8VlE2eV05Su}6d-eeOad|s >z$TT4HfJ_836UbB`bK$g;fy{=}P6sj{PCFsUj385j%n33n$gCjKg3JptG04myQ-jP6 >zGC9cXIPLTx^W(G=gv^lBP7yLk$Rr`NgiI4MPsl_eGlfhQGFQlCA+zPQ(}m2J(@q#N >vV@^9|$ebaQhRhl=ZOFVK6Nmq^nG4!cjM+V`N-hf5hND%<nwoG;I2!x|P;*0t > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica >new file mode 100644 >index 0000000000000000000000000000000000000000..7aedd262a57f096cda47a8542b3b66633561641d >GIT binary patch >literal 507 >zcmb`DJx{_=6hI$^L};s25fDe6%4p)?u2F(abkV7ckZxUFjEP@yVA92vurQD~ILOB4 >zZ*Y5mz~qfgJnyM)nz(qI`%creNzaK+lirT{F$H<TGBsK5gG)Ic$}fwhK_e{%qqsDA >zG_JXgJ$;k<??b&j>!&NzYh4~+nc%6XSMSfv+WC>LB!_1Gq^YZ|(A4&PT@O98u@%OR >z;)mIEyg29Nf4QuEb(G4^g0<6URkZePmh+E0k!s5xbY=G=`KPam{x+%0o0-Y{`x`5h >z+-+Y#%y^6)#4w{+LQEmH5Mzin#2jJ|DFCSeDFLYgDFUeiDFdkkDFmqmDW(1=l`HLb >F-A~yjc0>RG > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy >new file mode 100644 >index 0000000000000000000000000000000000000000..a74ba046226060a01c6255b6714a40211f739a24 >GIT binary patch >literal 1081 >zcmc)IPe{{Y9LMqBa@HCi1_eb#2r1?wcu?1(G@jT&h<34o;Hg6dK~QwaAj-OQh+q&S >z2ozUdqn-}dP|GKm%{<6pMnoM(MYkkkjrGr`@B4uc(V=eremr~q7(4vf=bafkeyl6_ >z<60}<aJYKq@VxP&eB8R0Rrk*g=m%S#nZmZLE-ar?Q=87)smTd5-MFV`uD?(ZU%s=C >z&PL7b^k!{`vgYyFn4a5LRK*Kr`($g~%pVEs`PH~89Z1?z^{!gDl+%mpn`Uw4vRz6$ >zwPZfnN@v0>r;gfMUqsc$>-KZ=303ck>H7O|)7X%*jZ#H@sSWF|mEGoBF=4;Y99BPW >z59rm=gmPDV^ty?ICen5?zdbi;+G4qUd-9WM|9B?f5g)W2Z(f-lD_3-<*_)47D{AMB >z!PaE`so66dH~quwP5<kW))D7iXid{U-pyfd`7t)hX?AXIAqbo+mV>Z!B^yMXdtMH; >zIQO<1it!w@97<<`l$>3vM^3k#-<QbzeVe{t+ce~XOJ3WZ9=%gQwnFwoHbZvv%67<p >zUfB@Y5!n*i6WJ8m71<Wq7uguu8QB`y+bf$RyL)AOWPhXquXKR4;FTVbCXg<WHoVdY >z(g@OtS6V@O@k%pDH%L23KS)DJN9bGPL3-l9r75H<q%EW`q%p5_hP39D-jL>y?vVD7 >c{*VTd4v`kU(j$(@s|5c$%4n~oy1zU66E?ExkN^Mx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau >new file mode 100644 >index 0000000000000000000000000000000000000000..d00668ad189cc7627b9301e08c00d84f1688ab92 >GIT binary patch >literal 2362 >zcmciCZA{fw0LSrr5xCqd)GZ+qiH=Voj~=e^RFt6@Arct3n-Ezfc88UqFovR}rX#nC >zi){{P(Q%Hgw$wA-O4q{DxwcG3u=Ow(rCYO{y4KTdB)9WDwDlt1=Kt>eKZpN#`}_Lq >znx6AH{`0ua7Y<L4IowmXo7cHLNor)?Z!IGYsosebWg`4ehS$-TE}XB#dLuffi)kAd >zh9Vo%RMaX@D7wV0T=Htj_1ZG!_6~*IhffL5&pI^y`=cuMoAchdk9*Z^Cy#n>fA@&+ >z?(g;9u_q+%+}!G&(X>g#*RB-_<$iHjQGs`6dcH`UTN9e)P83NId7-4tcyH1#OZDta >z3smyRe0}$6mr6Mnt?xPblM?Mka?Xx(YHnb*oVWf*F+cC7T(IIZk(%(GOv`vrq)m+L >zbkFM|ee7GEaiv9M4xZ9kqpzy${)0N__y)D8>t!w9s8+c_C4H?vwYY4jytgJ^<)t;s >zeBU3c!1b^!Or9YMFE5lu<G+jhKK01^FMK76b*g^g!;|8{P>f!3;DC6j`HC*t^?_Pi >z^|@ZwxL=hnI--}CcB<vSUX*3oeWGmij4Y4aBFc{s$Q9S>Ma7$+=#^h~sLHK}^rP?B >zsjB+jx_V!+T2&m>kF}?$n&fir4>*+nuS^}tyQBg?JR(=8gvIK!8M1cbqNp2)l~0bH >z5%s&S%clkh#G1xo`E-A`c&75IZs<Owp3NT8YlFL0W1QCO%7SX$wY@r+R<45Q+jNsF >zQ#Bn9==GQ5)bsmV<qN|Z;>GsI<pv!qnga#0rRTcXm_JKyY91D?3FES@>X>K?&(!UO >zL#lo3Pu-EIRmb23z4^vowWa?f-T8H!+S>KD-gY9Oy4LK_FZC5FXT&sT<dnat$*<8d >zu3PvEhj)xS9N}=!c1L75{8q>rW8bm%?d7{O-uzFCBhlWI?S0P5O24DJ#+)b2sWzw7 >z@2KUNZzUDxQc_`V=5g}knY{R?9+}7d1Ba*A9PX(%_{%(D^DH@i^9$V8?K_K%4;i4< >zj1cV*xiCf^Ge}^R$S{#{A_GN6iVPJQtJMq^8Lia}7a1=yU}VI|kdZMXgGNS;3>z6Y >zGH_(%$k36oBZEgqj|?9fztsf5Y9fGy0Eqz-1SASb7?3z1fj}aGgaU~L5)337NI0w} >z9!Nl}CL%~kkeDDrL85|$1&Iq17$h=CXpq<-!9k*fga?Ta5+JLI5E3FJMo5s5C?R1& >z;)DbWi4+nlBvweUkZ2*{vYL1y0kfKjAtAGxm?1$!qK1SGi5n6)ByvdTkk}!?L!yU- >z&uZd_1kh?Ch=kB;Vu%D0i6Rn4B#uZRkw_w;L}G~q6Nx4gP9&a4K&>XCNJy<Frbtk& >zCaOqSk+>p(MIwuY7KtqqTqL?kc#-%b0k)b5BO$h$7$ZTpnkXY-M&gVF8i_O#Y9!W3 >zupOq@kr7c-{-P(py4*3h@aJ%hc9O;aHQfJ}`=6VKq!$tQtjfhXz8slVnVXxFn<G7c >E1GEiWo&W#< > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville >new file mode 100644 >index 0000000000000000000000000000000000000000..fdf2e88b48cecddf4eafa6d8a41ba7363e4874d6 >GIT binary patch >literal 2781 >zcmd_re@s<n9LMp4A_$5~`2!WNr4>VwUxvTJ(v;m$ubN&=(eTmKJJj-<7(p4{=C5>X >z+H_FXNJ~v?j?`>gjntSqTbVMQh2aAwm5DxPE6cpM=Y1;X)*t=XKb^aCUeC^8@XvjJ >z{P~6RGM#^1(e@2D*B*OwP7K;d<@S`|tMC0Pn^$!RZrM~PTZ?{iwsnn{V{zky$If`= >zljlOglYM`Zle1#X$+`+vyER5m<(+cs4i=fS^%cRdcCMHD>eAr3HH$@8P7gK|`lYdK >zc<}4oLGn#O@8J351ZnbSJKqlWnD3H2&iCCMbHV=g3qLoSADSASi>GT$^N||o(uWOl >zxk?9(XTAJ>W|+Bgw3iO;Pc-2-!rG|_nTXX5y491~w3d*HR5zr}M6IGmoRjGE!z%ju >z?h?~!kHqZSXkyJO)lRRJ_FufF;|>O-!+{mL<Id%#(@XPo{F=GumeL3Gt%Y9Gd0Ic+ >zB{$i09ok-ZOKxWp`XsCFZJSMxR_#=eA7iCwL$gXeaZ!35I<7psKa<{DcB|Wp9drA$ >z8&sdXM$>nGmA)gZ#@spP1$|eS?Ix*TkxmMIB+0RPI=OzE^t&)v_pe?pDYbqzpt4X> >z_YP8NWn(3MLxRc(1We}Q-_$^FuDN^CS(TO4-wevER)eGC%#fa6>LE>+&Cu%~=wU}r >zn0x9fb#~Py8UB7y-@EQ}x$ouKdc>kVGIGT-b^nBoGHT8&H9D<Waz>9*IahZW?|_-w >zTf5fe#*Ngudl#B9&3*OQSJue5(<78`=>i%5ZXY#ahEFDzN2&+2(`3>UO=@yty!i8u >zD*yGXG9~LxHRXIqGu3lMPp!FPriFIs{H?WSdi`2GW5qu6aP>l6FsH)ItQ@bE?;V-7 >zdV!ifpj;ja_|%-Z5}E5wQ*)d1C6E-a0-t6}VboPsxXUB+n@*_(<-^Rv<5%>f#fj#z >zs#?7$FJxrhKK*!>Hj5Wk=%Ox%&5{YFdP(S<6b~s^#r21zB%wr=RKG5z*Yed<l`G}x >zGudisSwNoI?@?t1xw7m<N41Lh>(e^2<@ooj7TZMK^oh9XeDnMN>KqPNZE~D&_`ur{ >zk>T)Lo1M1qxxM@B#M9{<4u5<wB4M1*?~EF4@5%Ol$leqEPL4h2*mqnJ?i2j~{>|TO >zf7t!zU;Fd7?0*mr7qkv-MoNIx04V}e1*8l}9gsq}+Dag$Kx*M?i{Wakfs_NO2T~BE >zB1lP)njl3%s)CdSsS8pVq%ufpklG-{L8^n42dR&%Ef7*6q(n%KkRl;fLdt~H2`Lo1 >zmEu6DxNNO}Vj<N+%7xSmDHu{Qq-3tPW=PRoZPk#nA$3Cvhg1$J9a1}_cu4h-@*(v@ >z3W!t?DIrorq=-lrkutj4IwFNcDv6X5sU=cOq?$-Mk$NHpMJkGv6sajvR99P7q^z#C >zu1H~#$|9vjYKs&XsV-7pq`pXjkqRRvMrw={8L2W-W>;Hhq|ivEky0bIMv9G88!0zZ >zZ=~Qz#gURDHAjl>YO9Wv-PP6|DZHz#JW_h3_DJ!O>LcYx>W?e{vI58wAZvguf~#Ex >zWEouTIv@+-YF7eT3S=#i#XwdASq@}9kOe_j1X&VfO^`)FRs~rWSGz9A!noR%L6*kV >zt_`v{$m$@=gRBp-K*$OqON6WuvPj4(A<N`y*9loDSG!WkQn}i-LKX{IEo8Zn^+Fa5 >mSuteEoR<CiUr$-AUAQc}a4EilshO$iDZY%1)Qr^h*gpU+Ex#TB > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello >new file mode 100644 >index 0000000000000000000000000000000000000000..60991aa38f5ca016d9f87bd6cb5b436ec799a10c >GIT binary patch >literal 2361 >zcmd_qUrd#C9LMn=f8?JaP*R9Q1tmlNV<Zw428>}IAw3X~;R9j}q4=42gfe{GEYq#I >zDWd%u!fcIdPLgO^i?lU!{aGTb*(`dxh&4C#M|5Ff=jr$Ub=gH*>#pzFb6yWlHf}y| >zZ++_%dE##us{e(D>(vkMiMIage<Q;_`u=Zn;DrVD;47Eq=P&y0iz&a#i;dyx#-$4J >z$N6;SKb0=rp(rJeM2Ubs*Hqy4Ya(b%qzrDHZ_lf`Dnp8=?a-VHGW4ZXJ3Qv33_pHM >zM5tal-#KVUemkt9&TO+6oIaqU-#j2<UhY(}dppHV-8Jgw)*7*}u0X|A6o^|^B&b`{ >z5=4CRa=9q%hDZopBols#w-^67Clkkiw{JW9y-a%NJNx#*kK`S`XmRJRL77}VBT_bh >zsP4+25O=RSs+Po!iqxgMRH}d6PK(&6(k4gjrB}*S`q&{mW1>lB_HVbdMoMLNPo14} >zaEZ)q@rk^xVRBh{t+;3H6`7w}DDKVsLM{(Y6a|ZaRs~ajv10BsRd{Y(-FLa)DLQdg >z-v5E^Jh1<QeDKvKr?}&!T)BIv^-yK6ENO1EO0#{kthB@`n;lZ+nH!w)iG8XfYNb;# >z(ymrbr#KJ4wpXtHrr7fAXp?K+OSUT4dt_B#u=Pk$wp_by%37BgE4|g{E$`f{tjT}N >zs`)8e)h3;DYCoA#b^alz{`Cp<*yKKE{q9lq_*lEs(0o{J=wIVlo_A&Ao;Ir~vrlep >z@mS4KU2;=-wzX-xUbdvhS}k7|$<~lrtMz!2+&uNQ)z(+2+P|7{p7bTEr%p^b9o2p% >z_m4VT@*VYb$6;q{+{dc3vfJtO{~&z@eU@+Xtn7;Kvbx5O$?og*)-(Oj%V#eYSvz`K >z<a4Kzte%Dnx$}sy0t56XDA>U3zy5^G`_DeEJKQOR>z*DC2zK4K2Sk{8k2K#guKVek >zfQ7t^_|+b-C@Iy?I{iGVpDM2?(?6H#pSb|@4c>p=*dhI&&Bm_(^;`NcaNUL={{XT% >zWOvB+ko_SWM0RM@TSWGVY!b~bd10HJ-Y3UKk)3jE71=AYS!B1!c8z+!$cBx2#~fQm >z_Ka*A*)_6lWZxVcM|RG!b!6`xn@4ufv3+F!91TD^z|jJu?g7#SqzgzJkUk)dKsv$E >z3Zxet%|N=r(GH{^91St*jvy^D>YgA?LArvp1?daY7^E{uYmnY>GzaMpM|+U|a5M<% >z5J!uQx<?#MLb`;s3F#BkD5O(JtB_tH%|g0`v<vAM(lDd$7}7GM?itcFqwX5gHl%Mz >z<B-lFtwVZ;G!N+>(mterNCS<!gGdXFx`#*;jk=3S8<9RDjYK+$v=Zqh(oCeANIQ{! >zA`L}4inP?Idx|vGsJn`^)u{W5G#2SB(psdqNOO_yBJD-`i!>PNFw$b9?lID2qwX@& >zW~1&i(rBd9NUM=vBh5y-jkH^sTK^B?9ie-kue+Y%S(cTTm6PGg&CSZq%8B?BJN%qm > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN >new file mode 100644 >index 0000000000000000000000000000000000000000..cc785da97de0a5614613f9ba6e502d7dc5f525b5 >GIT binary patch >literal 2437 >zcmd_rUrg0y9LMo52q6eaCWd5SS}_9&Y$$E8wFP5`#6Nk!KM+Q0h-E%1kf_n))+8^Q >zrA@&a>LQnGhSpSU3r(rDnlm&BQVB4LS;(VtK}zTJydN*KKlgpv@4U_qC|931-bH24 >zPm{k~i2a0z+hrf#$7uUfzb{Ge{`7aXXLF?9yX%7b=5?PwJ9$u@EeSQ}^Uq7$#M9>c >zw4>54jiw{IPCB~YGC%kZ>kB8=nv0z~^`-r9s?O#r{o|H3s;j<Gcb9opPj#lg?3u29 >zDvsAz=4Y7RoDBJSMx5zOh?Bk><IGk2+po3`nO}N)<kz+q)Bk0QTsz*a1{%Ax*?me~ >z-+EFHF0N5Ghf3vEpT`Whd*qL=5{<7ZQT!i77^#hrfSLgl`0{{^SRJl{N=E76IoH%( >zPxR}Mly6nY8wolz>SGmp;5`X5Z>v#V+jV%yK@)MJLPs9kW=8MdCQ)_e=I$-!GN!7) >z+*4K{V;82IXivI~dpy?MJ0(_PCe2XeM-EGD;CK~#BSzoXeM?Pfy{Yg2{E~`0bWz9e >zJ+3BJj+O^D?NyWVugl~WpP2{K&dEc$yUoMVhb7^WO(wzDs;7i4F<FmRs_d+}D*Lyi >zk~4Ls$vIaio`~7T^T`Iu?N2pNy}MJ-Y@4O>Hdg6bM^e=6qC!1q#~3v?BU3+JF{tKE >zh}YiyHsu`-&;@Bts^ChTEQtHgEcilXq3?)U)X*b^owcUuwHA4%dA%uKx=$9@7nx`C >zPU@1HD)rpd2EC-TP%Vwvte53vs%8Dlb!kGpDm|U6%R&NF*?}azqW7|TVTVUvJmWVj >zD--3V#%{B!AVSpEQ)YGAfUH^dzF8aHD&@0lOu4ULSEe_p%FZ)-UCd^+uKAFz8d|Q_ >z*KgMw+H=*$>I(fzQ<ADKp08i6jZ}dF_G?6tgSU773jUkV@BGv5)8K#j-hcYv{Qi%= >z7V-O!9SjKa`#;<xBi;LO_Zr2kjJ^H&%sj6=nPs1O_L*;=IbO-O@3{c?3f_NT-#hk) >z-TH=Z|1103{r=(+zCFkqkwqe_M3#xH6IrO!t`u1+vQ}iV$ZC=0I_-Lq1tTj)mW-?! >zSv0b0WZB5Nk%c2GN0yGP9a%iGdSv-dyMCkqPFn$_1V{~#A|O>j%7D}XDFjjpq!dUk >zkYXU!KvxdlP!G-)grg!zNjPeP6a}dYQWm5xPFonHGEQ3>j@lr_L8^n42dNKIAdU(l >zCE}<NQY4NlA!XvI6H+LSN+G4<sFl+e3#k@TE~H*a!H|j}CF7_WQZ$aLA!XyJ8&Wuq >z$~kT6klG=|L#pSr<>RQI(-x4Uf=*jPjv69GM5>6C5ve0mNTiZTDUn(t#YC#<wB<zV >z>9hsqsHoGHl%u9dQ8}uLl$E2dNMSiDi<B0rEmB;hx=4AE`Z{fakqSF)iIEyRZIO{G >zBW32OGg4@dN+YG_s5Me-j%p+2=BT&R796R#)0P~mxziRMsX9`2r0z)Jk;)^bM`|yw >hy#I^bhuOad)9qh{q`b$HrzNK(<)x-3rzWR_{RxkBPOAU_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk >new file mode 100644 >index 0000000000000000000000000000000000000000..d308336bec9a539742ca3885c44a4d3c5a674463 >GIT binary patch >literal 212 >zcmWHE%1kq2zyQoZ5fBCe7@MyF$eApsr~GZk8xICXrvLx<$1*Vd|9@Zy1Iz#a#}6=Y >r`S^w~=o*+98!$Kqhk&#KK?n&J{D5cyn)&}f$RZF;l4V>#dri0im60!* > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz >new file mode 100644 >index 0000000000000000000000000000000000000000..bc3df523516d19191aa9d9b88ecc97c3ea1acd4c >GIT binary patch >literal 257 >zcmWHE%1kq2zyK^j5fBCe7+atL$k`z`?a7XJSFhCn|NozniJAHT{{u1%3}BMw|NnD3 >zj2!>}A3wmr<Kr8`;0(l0!66K~1|}eLz#xRMeXKx*AUg$qK(qi&|NlR;T{;CsgX{;> >WKsSJ->wz2wavZ{C19X<12^Rnvh($mE > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Lima b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Lima >new file mode 100644 >index 0000000000000000000000000000000000000000..44280a5c13866d06e34821f8d276178b14d97f21 >GIT binary patch >literal 431 >zcmWHE%1kq2zyK^j5fBCeK_CXPc^ZI3Pl>~o!{@yMj<`N{II8b;;h4Pcf#du-7moku >zKOiS@BtWh|)<OQ~_X`RI6Aq}(dwfAnwB~@WDszDD>^Tng|NsAIWM)Ev%>VyyKf=HO >zB-en*;|Ca7{{P>(fq}!vH-tggzyyd*f!0Dm2w}$x0abz>`va;6Xy^aTcI7=F8svBo >z4e|hp26+NRgFFJFL7oB8AP<3Qpr=5_fIJ4Kft~}=AP<6QkS9Sj$fF<{<XI36@-UbN >WdKyI60}W%K$md)(z;LiL<pKbPQHQty > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles >new file mode 100644 >index 0000000000000000000000000000000000000000..c0ce4402f60a135017d49933afdbee55916b9be3 >GIT binary patch >literal 2845 >zcmd_rdra0<9LMnoMG+J|nJ5w3NlgR+0Y&jr=52tAs33_MUJ@9lp+cx-NQ*LS#+S@X >zH#(ZNTp60PSrnlyS8J9*bKWAdRHotuE%DOxbl&IR{^;-4d3JuU-=4vr&-;@(yC5&Y >z^N-WPe#7N_W-sqO%Iu@+y%h6yO^BH1qs-RVugiDq!c2X?YfJ0r4^T(E#dD69?Udu* >zujE9XsFRKF%FjDKl*Zb%^2@rHrKzewel1ukr%ETwZ>cln_na6x9XV9aBu`RjyH8im >z5z(r-b%;6_&{dtQ4^ijOTviu$Uso*$>(#}|W9m}%MY+7JMqQ~mEUjzy%hke<<=WhL >z<d5`M<<BwC$@Re{(l&6Ly3uWx-0W1YZnizEZ#Czs+edTtU*DuC@4jU1dp}BfwnS>b >z7rLl+D?97<%La=7{0P%wdXRJ+8)yRJE=a)o@g`7xFM&J1)IpbbN#~|&)8*J96<k+o >zx_(-%y6yN#tJf;k9qUAQUsa^;ELg64WY1I~shPUxh~cVN<S-rDH$(0U4Ao)n5+$s4 >zsJZ)8FA1;jX?pL!A$@kYnR~XL5M44z-}}rL(l;wu_gi#a^-sK{@0;|w8W8fMj)<yK >z5#AOP8C0es8-FlS=N70zwYyDpL#f16Z7{KW=E>mFCrsRiaT1^ZicTo%FGG@x_0Wut >zk{FSthb1)2@PH(p6y8B4oek3?Zk<&l58l?JPJF9I?+P{d*L<KJsJLmyys=(ASa{Nm >zE#D#I(reB5g)hm3!NyFSutX+aZP3XvFRJ8*y*f2`u}a;uSx;)2swTg=$4oi0NYYks >zG*dsBBI$Ehm}#40W%}rBGowUFM))X`IkQzVZ}&D?i9bo!>5+O?pDSwC*Wo(b+n{D| >z_v(im_o_MNP5P1A%_?W%0X?^Bm715<Xy&ioC<|ih%%k}$WMS|&lbf6^xh>@;KVp>R >zAIdWY0llSQXNp;L#wU+$%GHYxhpQze$@=kXuPV%n)JrRx)Usin_42|4swkvI7pHGm >z#lApOl2j)pjpxnE&~37^_K;cCRxVFgRhy@d=E>^PO7rx-6e-OqGHbR(NjpFLY47jg >z^}qA+`6>r^JU-uB;^*)4Rg`%;x%V#asivf5dZtaVH^bhC?46crf6*R~pL=BfdkJdn >zAG#8>@gMg1?8)&Dt3%3w)B!03QVFCKNG+VU7)Ujcav=3U3W8JwDG5>&q$o&Lkg_0k >zK?;LZ1}P0v8>Bc$b)2?5NPV2PKuCp<5+OB0iiA`NDHBpBq)<qukWwMFLW+e{3n>>; >zFQi~jTQQ_$NX?L<p{p7%l#OHS1{4md98x-@c1ZD%>LKNG+WH{{blM6cB}8h76cMQ+ >zQbweXNFk9*BBexXi4+s5CQ?qMo=8EFiXtU-+L|IoMXHLF6{#yySfsK@X_49@#YL)% >zlozQlQeda8Fj8Wttuaz$q{>K{kvb!VMk<Yz8mTo>Y^2&qxsiG!1xG55l-y}+juaiK >zI#PC|?nvR0$|I#mYL65jsXkJEr2fbPIPD4`OW?F?fGmR3t^%?Q$T}bkfvg0w6v$d2 >zi-D{LvK+{IAPeHOD}pSE)2<1!C{DX7$g&{of-DTOGRV>(YlAEfvO37}AnSuH5VAtZ >z5;^S}A&ca+tAs3*)2<V;P{>LlONFczvRKG!A<KoV7qVc;iXltpv}=Yen$xZtvTRPf >yZpgwRD~Bu{vUbSgA*+WhpT}+8|8Dw%>>?)FWsFW65}Obk7o8R#9~&PV7xXtE&6qp@ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville >new file mode 100644 >index 0000000000000000000000000000000000000000..fdf2e88b48cecddf4eafa6d8a41ba7363e4874d6 >GIT binary patch >literal 2781 >zcmd_re@s<n9LMp4A_$5~`2!WNr4>VwUxvTJ(v;m$ubN&=(eTmKJJj-<7(p4{=C5>X >z+H_FXNJ~v?j?`>gjntSqTbVMQh2aAwm5DxPE6cpM=Y1;X)*t=XKb^aCUeC^8@XvjJ >z{P~6RGM#^1(e@2D*B*OwP7K;d<@S`|tMC0Pn^$!RZrM~PTZ?{iwsnn{V{zky$If`= >zljlOglYM`Zle1#X$+`+vyER5m<(+cs4i=fS^%cRdcCMHD>eAr3HH$@8P7gK|`lYdK >zc<}4oLGn#O@8J351ZnbSJKqlWnD3H2&iCCMbHV=g3qLoSADSASi>GT$^N||o(uWOl >zxk?9(XTAJ>W|+Bgw3iO;Pc-2-!rG|_nTXX5y491~w3d*HR5zr}M6IGmoRjGE!z%ju >z?h?~!kHqZSXkyJO)lRRJ_FufF;|>O-!+{mL<Id%#(@XPo{F=GumeL3Gt%Y9Gd0Ic+ >zB{$i09ok-ZOKxWp`XsCFZJSMxR_#=eA7iCwL$gXeaZ!35I<7psKa<{DcB|Wp9drA$ >z8&sdXM$>nGmA)gZ#@spP1$|eS?Ix*TkxmMIB+0RPI=OzE^t&)v_pe?pDYbqzpt4X> >z_YP8NWn(3MLxRc(1We}Q-_$^FuDN^CS(TO4-wevER)eGC%#fa6>LE>+&Cu%~=wU}r >zn0x9fb#~Py8UB7y-@EQ}x$ouKdc>kVGIGT-b^nBoGHT8&H9D<Waz>9*IahZW?|_-w >zTf5fe#*Ngudl#B9&3*OQSJue5(<78`=>i%5ZXY#ahEFDzN2&+2(`3>UO=@yty!i8u >zD*yGXG9~LxHRXIqGu3lMPp!FPriFIs{H?WSdi`2GW5qu6aP>l6FsH)ItQ@bE?;V-7 >zdV!ifpj;ja_|%-Z5}E5wQ*)d1C6E-a0-t6}VboPsxXUB+n@*_(<-^Rv<5%>f#fj#z >zs#?7$FJxrhKK*!>Hj5Wk=%Ox%&5{YFdP(S<6b~s^#r21zB%wr=RKG5z*Yed<l`G}x >zGudisSwNoI?@?t1xw7m<N41Lh>(e^2<@ooj7TZMK^oh9XeDnMN>KqPNZE~D&_`ur{ >zk>T)Lo1M1qxxM@B#M9{<4u5<wB4M1*?~EF4@5%Ol$leqEPL4h2*mqnJ?i2j~{>|TO >zf7t!zU;Fd7?0*mr7qkv-MoNIx04V}e1*8l}9gsq}+Dag$Kx*M?i{Wakfs_NO2T~BE >zB1lP)njl3%s)CdSsS8pVq%ufpklG-{L8^n42dR&%Ef7*6q(n%KkRl;fLdt~H2`Lo1 >zmEu6DxNNO}Vj<N+%7xSmDHu{Qq-3tPW=PRoZPk#nA$3Cvhg1$J9a1}_cu4h-@*(v@ >z3W!t?DIrorq=-lrkutj4IwFNcDv6X5sU=cOq?$-Mk$NHpMJkGv6sajvR99P7q^z#C >zu1H~#$|9vjYKs&XsV-7pq`pXjkqRRvMrw={8L2W-W>;Hhq|ivEky0bIMv9G88!0zZ >zZ=~Qz#gURDHAjl>YO9Wv-PP6|DZHz#JW_h3_DJ!O>LcYx>W?e{vI58wAZvguf~#Ex >zWEouTIv@+-YF7eT3S=#i#XwdASq@}9kOe_j1X&VfO^`)FRs~rWSGz9A!noR%L6*kV >zt_`v{$m$@=gRBp-K*$OqON6WuvPj4(A<N`y*9loDSG!WkQn}i-LKX{IEo8Zn^+Fa5 >mSuteEoR<CiUr$-AUAQc}a4EilshO$iDZY%1)Qr^h*gpU+Ex#TB > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes >new file mode 100644 >index 0000000000000000000000000000000000000000..d308336bec9a539742ca3885c44a4d3c5a674463 >GIT binary patch >literal 212 >zcmWHE%1kq2zyQoZ5fBCe7@MyF$eApsr~GZk8xICXrvLx<$1*Vd|9@Zy1Iz#a#}6=Y >r`S^w~=o*+98!$Kqhk&#KK?n&J{D5cyn)&}f$RZF;l4V>#dri0im60!* > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio >new file mode 100644 >index 0000000000000000000000000000000000000000..54442dc737ede2aab1b597ee71a1db3aa8e33aa1 >GIT binary patch >literal 770 >zcmb`^KP&@L0LSt3H&Rj-gF!vSgyd;SH5#!J9V9nkFp22IU?3qSVUie0Sl%cGxv@+Z >z)I@|x8me?;A^u!i^1SaEEhJuZ{WMLkx&FTPXnZ1Q{WvA&8!k?(x%gbQXx`R$Cg+pY >z{n_MapW1usl>3<(k?!7=>4&_$uDf%t_eR7`p;l(LGUE1TQ)cauc-hd-YuT81I~bSm >z{(y3a+N67YDDu8@C%^5g!ehDoSY1%{Cu=e=d!-swmm@-_s&OeUn<`VPdAP=DzMmE? >z;b*7i;#kPVIoVMkQ{lHGr#rbKBDXmic^(iwDeXk3{3@Zfwu*~>`6|{rvus&f=dwkm >zT3?=76@xL`YL`KCh0I^(*ngPG{l3NgqSnlXOy+53L#9LKLnibzGa^%ZnmLh4ky(*x >zk$I7ck(rUHk-3q{J<aUM^qyvZBmt6v$0r4n14)8pLDC?3kVKv)6Ozi)<U*1m*^qQd >aJ|v;1$%v#xa$>?f+dn7uMNQt`knam56e{Ha > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Managua b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Managua >new file mode 100644 >index 0000000000000000000000000000000000000000..c543ffd475e374b39c6800fcc69c3c06b6eb5dd3 >GIT binary patch >literal 463 >zcmWHE%1kq2zyNGO5fBCe0U!pkMH+y_UR{qDY|bSKoJ;Hi1OtCO5WJEfAZ&Q+f$)~V >z0L{dS3R(xf1GJs*J}^4@KENsBzyoLd%m9~=yareK$OJ|vW+oOOWQNlJ|F4%}U;vU5 >z3@rcuuU^2w@&EtM4GcUWl2HI6;^P~_;0wgg!66K;K<w-i0(1oegb;SWAW${f{Xd}E >z{sTc~yG{y-2Kfgh4Du6*2Kfs_gZu`jf&K&0AU}d>pg%!0$gdz8<X;dC@-v7A`5Q!o >b{0^c){s+;ZFaXh@aA2TCKyU#=$czgBd@pf= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus >new file mode 100644 >index 0000000000000000000000000000000000000000..855cb02c4082719f3a51c8401288c013efefe683 >GIT binary patch >literal 630 >zcmb`^IZFdU7=YnTJP7e>Y%DyYZ32TyAtEv!r3%7=;17rhRyNv2ZPSaOg{4|enMjHO >zi(n^;79ojg>;fuyghUy?cP#}$aF*G3SlD6bS$}msJ?{M&ZSsW4h{<H#y(72%v&?+1 >zZ{;cXxn%Osv--Tcr%DqAU8+ZPdEn8O^J}Wo8q?Loy1K8N=$b#HUJiQfYsZFqvzz+8 >zH*Olsle$s7QO#)0HcvZEtKP3avRN~Dd8CK7AI$LaoE=G4Ol)^ck9OUexV_Mc^tH-3 >z=e%&}*DLH?vEX^m-Cl*-Wo^C4!lLgbR8nS24#4pLaOlSOE3%_=9G(IYR1hc-6buST >zP(h)<1Qi?#5Cw?>MZuzgQP3!G6g&!GP(h?X1{F*SC<T?z2bO|M0j3~RpefiCa0)uj >Q$X@>fADxn)FrA8i0o?5eRR910 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique >new file mode 100644 >index 0000000000000000000000000000000000000000..f9e2399c9d2254d5c447fbd0b6dc6be303569262 >GIT binary patch >literal 257 >zcmWHE%1kq2zyK^j5fBCe7+bIb$eFnKgp06mo`Z;q*ak)>W~TrDkL_V#0Fx~L{~tfV >z!1@3G)eDTgKE5FgZf-!rF&KzlLO=$AK?q?BS%C^cmJ0rWXaO4k|9@t?$Po|?asWse >T<OmQAatH%iF5v<?&4dd85=%V} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros >new file mode 100644 >index 0000000000000000000000000000000000000000..5671d25816de263b5de2d310bd974fed88238605 >GIT binary patch >literal 1416 >zcmc)JPe{{Y9LMozB`A^wfe<7L6?kYZH`A7BSz1GLnmTQ%nUy-VKYL0YYGw~4dMXcr >z35A4cmk{eRj7Y-j5`_dI(m^OmB9NY-NJ#wkynh`#b%?&>=Sv6kviB!Y)!gV2f81L0 >z4i6VJ55KQd=Eqp{UEP+7uVQP<6YUN~gr_x5ru%|oSJ`Kok(wnkJ+I{M*d*cI{7HKk >zSH+&6FLl=U7_~P#t+OXqRL<iYdf&jj+J9T>-0)L%p!d2wSTdsW>ccXBXRkVxUn&o8 >zXjHy!>C(4+O%%i=%7VEDQMm9!9=UT%70nh)e|M)Uj;6_ynrd})aHA~E&QWFU-(-1G >ziV9TB%D{?4Rc1`e%8$t+nEX};UkGu0HL9ydKZxr2Azjn^T%4Hd(zW&X#L3|rUFV-x >zr}{hP=^dl$OsHDcC-kWXUyf{8YEq%p6d8J5sG4IPvU%L8S{4`N*}(#FZpPB*BiqG= >ziT65OnIPoAGkr1Ri?|dX)2)ebL|aL}Zd+Ya5$~vs%+IKfO?|Rs>Y?gfZjxQYH`V32 >zLfPHZuC7cvWl!xfb#-XH6pl6j<YieSxk6ah{ktN@vK~Ef#1;7iBCp&$`2q8ta)H0- >zVEOk)%zv~jdf-o*;OGKrgQE|m5sprfRycY=n&Ifi*0jUX57H3Q5z-RU6VepY719>c >z7t$Eg8PXck8`2!oovmq)qd!~IAV-Hti%5@1lSr3Hn@FEXqe!Pnt4Oc5rdgz0ThlH_ >zzqY1fj*gL*IeJE#=I9z}o1<@}ainvkb)<Ksd8B(=(>~I_t=Ryw16#8NWDm$DICg<- >zgJU1aMmTnYY=vVl$YwZpV{5j9?8nw@2-%UX*%GoRWK+nlkZmFRLN<o~duQ=xc9~{& >TPJg<~<4SY--ENoLl@|XC#x-QS > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan >new file mode 100644 >index 0000000000000000000000000000000000000000..afa94c2ac5c1679d39143eae062b812070876492 >GIT binary patch >literal 1564 >zcmdUuYiLhl9LIlSF0GZvatV=8qP3gNm>Ih;V}G;lj~TZAhX0IRZM0$AQ=|xcrbM}x >z2uqXfl1q6dmk?UHq$JsrvZiH7$MZRq7hZYch41M(pVO&xUVT2^++u%}{IS9I4Tt5~ >z!}ADjZ)e-OD_VNXUbp#I_}Y`7_&S1T`Z~Vv>AC;D()X<CYL7^Tjx5@(qN+ye8L561 >zoz<^nrY=%5qh9FPA=A~Yai3*YSFoD>?YYGDg_t>Qk0t(ckePe^gd{Y6F!PQz$o%q$ >zCUN&Mos@CeB(Ja2DdC6Af|Pu{a9FiTosy_i`<ql+;AEZltV%6@J4i3-Sgz6^OcKx0 >zShe(0pk&mHQOowflgxq`lT~s@vJ*!eZ~8@9KJklL5xQSi%1e_o^1RM@ebcP!+oyAH >zoieLCOZ1uxH`LnJr8;l#NtJ&%Li>ufDya8JVOpVDmlrPUr=_S33B$!7;xk3#KS@z< >zlG*sZQ;MHVF`Hhs%jPSCP08)2y0od=l$~qU<(2nL#hxR&GPg@@@z?6AxVx%);cC5g >zY_r-HUL)JS9#A#Ia;4@)xvKpbFWawWsvVCe$j&pRrmjV#epiNRIQT{+V1RoK3<&%O >zm*X6d7jc{uMgkqD`LqmmoJK9dJO`+s@6$bA@nm}?*`8(gcv8I9h2Qi3g+=|pK6C7_ >z31Sq)Du`JSyIfksAeO<OrtzZ+%^l+))<MjJ*atBXVj;vth>b3-kq|2xW<u;_7z(kJ >zVJgH{hOrQ9A?8Btg%}L67-BNSW|!7zh}ABw*$}%ShC?i8m=3X>VLZfohWQZt83jNp >zV3Yu<fl&mc3YWGFNF9(uAeBH$fz$#i22u^A97sKkf*=(!N`lnHC<;=QOIsGCE=FOH >z${3|VYJ(I9sSZ*eq&`T2kP0CsLTZE*38~VhEfZ3wOIs+UQbwteS{cPcs%4Z5|Brfu >ZY}&Cl=}=E}SY%j4s3$TaEG8@>=m(pAkqZC- > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza >new file mode 100644 >index 0000000000000000000000000000000000000000..5e8c44c8934960e2010e7b0505966747cb2c6e50 >GIT binary patch >literal 1109 >zcmc)IPe{{Y9LMqBbgLyE1cUw%A*7g#;6Ysrs`ZEmBihBJz*C1P0-@-TL4Q`4PQf5X >z5Gby^20aCqsO3}3RzfnE5kZGV(XEJBV_Et1eLv74I@GP-c=q~j3^w+84-6hV(i!}5 >zt&n#(TuC|Huf8BpH?CyV-823A-uh=|a$`nME}l?RYtGrJiE%SsyRB!gzEt;Ly|WKa >zH<;P!wb~A5%)`-9{b)yC<<A%G;|*0acPOmqmSd{Wldy&IE%o$bR?nxdoB5BI>_W<^ >z1@pm{I^t%r_pq((imJ+3)qaT#scL7FuD%~LwdP)1E0omN%CKH4Z8P8Uar=E{zxr{r >zUoVfumAl-nSB~#B(bnU+P1y<4+LX<;B|e+BPp5M2>$-LO^Ss%-bkug3JtkIuqqkf; >z*pjF|G23TjMw@2Sb0BH^hF6)s*XfqDb1qa@|BsJIn1}yxI8q;}lUEVvX3qwJbNONr >zcCKK9sB<rhp+@K4mP1Y42aWqu13|Bxt*Tp2mz>`>8Tk83yML`zlN&Di;qK(f9r;e@ >zSPfYYSr1vzD=Q*PdSy*yQDjwQS!7*gVPs`wX=H6=ab$I5d9SRG6yTK#kP?s@yix>G >zg;&Zz>OcxXD)CAwNG(V)Ua1Bt$1C+91tAq7B_TB-MWL^X8!3zbmb#F_kjjwKklMUb >s98#TE%0ucy3PdVIN<?ZzibSeJ%0%k)N}-sRpBDW8OdEDeyveSHpJY<*WB>pF > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee >new file mode 100644 >index 0000000000000000000000000000000000000000..55d6e326692c81a3a526ee65fa5ece091ba5101e >GIT binary patch >literal 2283 >zcmdtiUrg0y9LMnovks8_$)peoN=t?ujt2}ylcIz%P9pv}A_!RshFHe8grlg@<HoQq >zj3#AT4W-Df6;opw)*}0R(VrROT+Jk{<(iH4lwSCUozwGvyzHXOw!UY--|LLQxca<< >zD;popRsT4T{Rt1(X&=5PYy0Zn@6~%hxGeiR;&sm}r{wEr!}|ENi*md+#tgSyP$vq1 >zH<uFv`bu<z2@hnc8w!6CkN-RI?8wkDiSJ5G-y15{yeK!G>CzK^IB4RIw&?gHJ59n{ >zJ5}PIW^>bX&1zz6g}J%0LQSg5H%X=W>Xx}F=GM#<l{|HhOpYE?DdQ$f%3sNP%Gs-u >zI&?+f_Q`2UJM^PY@A+764<)EOw)M!=<$tPa>pn7f<_)X60(;H$r1w<DjBO?(Jft&Y >z>rCcIzn*cv*kld9q`kwdCA)j0_VpLZ%(g1+@0u<-4I!1gAzEgYRI0m|o|n9gd1`j< >zH!{bQs`97&X7bO4)!eIJnR#EHQTLpB$IL%4rVBoN-rU<cqVIcEOkvYeeSiB7d7%7t >zy`a8Hie|R!;-V!|eBpgnlD*!P4DV5;apk78e~Su?=9mXxds#0$xk$>kw(3QP{Zd|2 >ztrzc_C`;xS=%p<eWm#&v4lX|_!LcY^kvAX}zox0mv=gTC3#F>Uht0~~pH=n9Zd23# >zxq4`DvsqQYUp?GiV;(8{RM&2AmDSn3x~`#G>f<`}nvw!pGrCqcWTZ>Ow*lSgiIT=X >zuU>cV7kO+~se1fa#H<fxsV5GcHBA+9N;*F?Pv-rho@#p2Y)BeX&E?xob9hvT@_QvT >za!hYZ?vPD`hji<uwX(UpOK<r;AY0p7^wR@gX<M~IKeIbt#zooBb>kh^^Zmd5L?V5s >zm5M};9E=(tiM+i}MZ514+&huCnsn{w3(JCPL6Loy*=L1)76(<a{mw<XHw6EEMlaZ3 >zb~Czk?XT>Ak3?!WmewJ&LZ*ex3z--)Gh}K`J2zx<$n22mA@f5f$T34?icUL6WRgxh >zOO9zG^F$_!%oLd_GFOhtBD3X~E;3(^2_rM+m@+bFj!7f4=9sqA&KsFHGIM0=$lQ_1 >zBeUn2J~Drf1RxpUNCA=qjwCp37LYVJZ61(BAelf?f#d>729gaV9Y{Vn5`tueBPB>q >zIFf>7g(EFan-`A6AerGv4U!uqIY@Sp^dR{`5`<(3NfDAGBuP%2C5|*XZJsz1<+PdN >zNEMPRBw0wdkaQvWLK22#3`rT1GbCwFn>8eDPMbH5#5rx|I8uk?jw5+U_Bhgq<c}kP >zNCuG<A~{5oh-48-qtoUQNu<+e5=o`g<`PLJl1+|uBKhP<D3Vc*lp;ChNGg(5j<h;$ >zUXjE)ZDx_wI&E%|<RaNc(u?F5NidROB*n_L_y61CSexqEHrd{?S-xDK-&>ZG<IC~+ >GWB&#UvwV2~ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Merida b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Merida >new file mode 100644 >index 0000000000000000000000000000000000000000..ecc1856e1e513bed6a07a80a01e0b9d9dc706c8a >GIT binary patch >literal 1456 >zcmd6mOGs2v0EUlcWEL2O5<Ng75W&W`nU!gy4(3e0ZZ%o?C>@)$JZg!Rj{}Mzl;t9b >zB#5FHh1Md;Y#~7|A_)qqgd!*+YSAf>q^#+Dw_3Go5%dq|d@~pBYQE1Z@%s|QADd;K >zaG2K|zRy?Yx-d9V9?>;kzQ~<d5MSLS5*kBfqRT6iir&fOs5Ft1@IbDby;P(wd8<?3 >zd>5;~-q&f9!D`LmUA=Z-TCE%I(doxusP%nPXVi_T%+6zSL;gACtgMq+v7IVAt5D{I >z`IKu#qI6Alh}__CnftU#Y<%@u=G}4$_t--1ITbB7U7OVT&2vS;(I>jFB1#q24(Z~| >zIm&YP>CKVv)s~o6y;Y1UZ}@5HeL0}EO}5CAkzTcZyj1SE(l2)2%#fwsCq&uF<+9x0 >zAS&9@^{!k?>@JPemC-4pDt(6bEhtje%U<j1Pf2Rew^8kX6ruJ$zpQI+OsU$@dvagz >zgxY`clB}!0qhwdNtS@;c8hkafF>P2J$nnU7i_eIrSif%i(k`0A@^te=g*fzKr9OPy >zDULi0(=F%ARBQi7-PVz*+It>r5i}!c=0ErZ0#~PnF!xyz90&|u7a`n1^L{>Ydo1BB >zwnVl$&MeFP$G>O&g&R}9UJ97u2tV-z;tIqUhBFXv816v)VK@Zwh~bh=;}gRvh*uD| >zAbvp{gLnpU4dNTbIf!=<_aOd39E5lXanYvnk>R9G<0ZpQh@T8cA)Yc^h4{*F7UC_$ >zU5LLBhanzAT!#1zaoVQw8sav@Z;0a%&l#>md}lZh@t)y6#D7KukPa9vKze{QVbgR0 >zX#>&+q!CCbkX9hQK$?Mc18E1+52GPSM~s#rJu#ZHX}V&xWz+P<XbjRBqcuoxkmexW >d!T+(nP?Kbe$uY*0<cN2~#dzZ59LbKj&>umYc47bk > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla >new file mode 100644 >index 0000000000000000000000000000000000000000..c0335970448cf4d433b86e08d79ae4b9a167e1f6 >GIT binary patch >literal 1418 >zcmb``Pe>F|0LSrJU0qk#no9G}K^_H~W-=Q7JB1XO*rMXPsg-4Evi<YlB3fw*hIt4_ >z4`GMwK^S!~hfa3LqUaQgd59vA3ZjcihYm*M^u80F3PI=%Z$9IC{r&>=q0@QVU&o_< >z;c_a}<vXoky<QHd%Eg`E+7=tr^|hH&Vc*Nrwed{hy5`d(y5mG-`!3Vnm?5L8V$J9h >zuk;wprsw*8>DA{=@6;0!`_(ez-cL*4+c`b{>8RZFXj<QV|AEkNj_O;6O|iA7Q{NWq >z5D9fPdSY2XY%ea<lQIiL@{VdV#hWZrBl68){zn=7bkL|xvqkNTETeAigQ%bM8Aq0$ >zi=%@p#<AH+(a^MD9G@5xC;ZD+<Io*>a?iYVs^zL|inpxh(iYkLWz1^HD3dL7VJqa> >zEkjd5>&)kPdG<!9ac&_?obReJE?7R%8Z0#0Mpi_7L5k7Qx*$3ee;DD4hazkzSzSf* >zvTNzP)tzj~?%8)%&+3@GIPuuJ^d>AX_uaO7XM(b?VZgdFUL;)+kuLYTPgL{<9@`$g >zt7*19(yzH~`<Cg7ao#@Xt=slMo0h<TT`7nB0j;uH-NWius(T=ym6WR=O3KxjIxb$n >z3H&>T81-*1r%GME(^mOQ9b27!&wjqb-XS9ui3AD7QN@BzFnkaVM}-5#g9L;`goK2| >zgam~|<*33!;&N1hA(0`WA+aIBA<-e>A@LyrA`v1XA~7OCB2gk?B5@*tB9S7YI;vQa >zU>#MoNVrJ6NWe(MNXSUcNYF^sNZ3f+NZ?51Na&6#b|iR56+IHZqlzCH05Sq(2*?<a >zK_H_*hJlO&83-~GWGIemEXZIS)o766II8g=142fG3<((%GALwJ$gniEEO$iIx=*xc >n1COS?PABXCHn2YnbBtws#cVIzzc(i@$H?~Q=H}$)7_q+qS6XeT > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City >new file mode 100644 >index 0000000000000000000000000000000000000000..f11e3d2d66a2d7c21f498df96c3fd1db3a0d8817 >GIT binary patch >literal 1618 >zcmdUuOGs2v0EUldWF{DuEqXvi5P_NR%*r&a!F2M`q-JGf*4U)!NlUD>4k$rTmW${i >zLKM9y)E4>377-*Eg<(Wx7z0I!EjkL4^tzqzQma-$oBqSO-(}!3o9}ZKcs)_#k4-ke >za9Odryw6hRakXPuwvCnhIy|}V&XfUnS8$xW>-%y2=xw{Z_gqX?-{w(Y-^fr_zkjc< >zzcV*$@It8XO?CaV$dYOiRTU_s9r+?AXGF#>P7rZXPvr6`^F;jIVIBYBhgk9Tu}&Bd >zP%Aqg>Q!yu)asr_op}1KTGK3bQpE$6+;B>+&AhBqc2&sKWesXwYPMV-;!%!8(b6$d >zFVX@+W!kIVV#B-7GQG<oGM>)V&htye#@pjMvu2veI{8v(7cEvfW!-vH@>J!@Xx5t- >zd{nt%bvjQxRr#S8WxlUXZ5gkX1rM6k))$3x+s#(7{ce&hJaI<sIJ;1~y_KTqXrkVk >z<`Tt)3-qofabkC(zxK??Q6=-=>yoh;wdZ@U_72Qedxvi5(mNBXtoM=J*EFcguU(fF >z`|m4x{Dj<J@LE)QN@Z0-k2tX2DG$zR5!K7Qy86p8Q4^A`YX*zNp-)To;d?3KNPmc~ >zy|P2qwT|ke^~vg3<8v+i{5g}%39z5M{o7+%SAvDGtd=t(z_M;#5`mW0-R>7`Kc{Cn >zUBbD^B~rMl=H|JK9>3@M3#}%8ePo%T7eq0LW)RgNy4f_!L9~OY2hq=_Q4pe`O`{@2 >zM~IUAEm|_vgy_jo6rw3ZRfw((Wo;U58R|mxg(wWs7@{&nXNb}ets!bd^oA%7(Hx>W >zM0betHjVZS^=%sc83{l#V59)afsq6x3q~4{JRpfcGJ&K5$pw-OBpXONHcdW|gdiC~ >zQi9~fND7h_BP~c?jKm<BF;au%#z+p59V9)QCO=4mkPIOyLUM#83CR+YCL~WtqL54( >zsX}sPBn!!wk*-aXFC$@_CSyj*kenGwL$ZdX4apn+2Z;xn^5abTVa}NF$nc0TXJkZp >IY<NV_PXY<#QUCw| > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon >new file mode 100644 >index 0000000000000000000000000000000000000000..75bbcf2bcf70ebc700cb98526d0f2a1e5cccc438 >GIT binary patch >literal 1696 >zcmd7STSyd90Eh9>#6pS!5h5Y1EXmx}-Obv{wo__Sy6wr<GBdlViI!THW@=gyND)Ov >z7bzs78&UMooj?vG21Rs8%pi~`kqCMS5ro3&eDl&nPrXF5%>0IZ8~A@GTvWNkYyELW >znSZ#ss?5#%ltbom`jP)uY)z?3s2|ib4(}H;3wrdds<SFF{g$4+x?atRJFb(GH>jks >zn{sZ<A~kp5m`wf}ujX~_lqtP_;pz-Z_x))iwKY|yo%ty|6}j45Hz0gDE<HbAiS(q& >zdV%+<SQ!0X`{TQmf2db4`f)`q?s=$}d^n;q?!A>upOvY=sRwe|rIkw5o|nsymWmaj >zMwwZbEwWOJWOi1P$R0kSb6lA!r?*D0nlxLjx-a$WZ{t<&<!YJtE>Q$qLUPTcXb~#* >zNO|sySep?m^Xp%Vb@3xITyRH(fAq`s=_ked!C_rE{kAIX?$aB`PN<@5kM*X38dZF> >zLvQYqs-&!0Z|U@^t-*_OTYE@scQwh<3Xdq8R4mJLVnzA4fUKA^A}U@d$jaz`QF%8~ >zRt-HBJI_zoyWaGv>IO^K+<UBQ3qI-Hr#jT0^ln{O+pPA+-O&3&o7KLt=d!`yBpL>; >z%f_k2qOq%89vBUXrp`*){60anwC2i#Pa;KYiA%O!7!+-`ZCeqM<NnDn(zag}T9$3U >zP*#*}_i1Z_ZGZk4F)=R~wwA98Tdp*pxqt5~{1<B*HEZKCA7ryS-dP^9K4gK&3Xvru >zYeW`_tP)wKqgf}iP)D;;WU0tnk;NjbMV5=K7g;c}Vr0q4nvq2#t45ZMtQ%Rlqggq! >zbY$(w;*r%O%SYCa6o6EKlz`NL6oFKMl;LRVKnig*l^~@!np%)zkZO=}kb01UkcyC! >zkeZO9kgAZf98FzFVUDIUq%=oU8&Vun9a0`rA5tJvAyOhzBT^(%B~m6*CsL@RsT3*I >z(bS3*>u9P)%0=o$3PvhMN=9l%ibkqN%0}u&3U@S>Bc(f<+L7WNP4!6mNd3qOfSdxz >oNr0RN$cf<iU!Mvw8Rnb__{`HAND2DfUUynb(BpA?+-Wht0Kk8;*Z=?k > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton >new file mode 100644 >index 0000000000000000000000000000000000000000..51cb1ba3d2de0ad19453704e4b796dfdf0dd8464 >GIT binary patch >literal 3163 >zcmeIzZ%ma{0LSrrMH!JOsThK(XoVV}fF%BlYv~AuJSw1=;HfkQ-hx#8lQ*oT6J9ho >z^H2U6&T5itO$~D>iI}3Ma~?qnGw~>bW}u*EBv)?d`}8ul-u9w%_dK6x&+grQ_xmQ# >z$$C4=_K)Lj-f(fwnTzMZ56$hv)&rubbdB6`=!z&CAFImt4{;psAEXX%=;kPIcdH|d >zZ#pV2*Quj3e{}p%R-ukXf9*KF?Q>Px`xD2B+%|R6@2un0tF7u(^B%|Pz8UIt&6$cb >z1=nTOkO#R{vRPH<)#wY3bLwJBsjeBcPyH0LRoB`+RhI%>`jXC5KX+`Amn&weU+PxM >zE4!D7y7F{+wJ=raqBwaiD^^_350Ui=LE=V+muwj77LD-(_03*^>Q<;-|JwJ4y6s)B >zZ$CVterv4MO*LPs<`c#G&XG!Sch7OzvZGkEuG=N=ttu4va|+~xc?-qw)3W8mxFqq% >zh(y^oG)w*2GeSP{nW`SOP0{VQ!j-!=Og}!=Q+1T~(4OK}W!v1M?Q5%5mt|GjE4M{- >zm3L(~Q6+o^mB=UjHwj<cM(NwKTs*0l$?lgnD8Gs{+2i0+)pK{A_TMsFJykeM_gXPl >z_0Afj`=s?(0SUpnZ)}Hpdgx;vI5=4J^SP>n?2koIt6K(NyDIvhuanOlJt_w5tB?bC >zejx_s-P0i-tr3G$F6bfIJJqu>2lR7OK32~Me5ON(FHoT!-^pRV@oHGzW;y)!F!e%t >zx+|=DxHG&c&J|J8-8mvZ#5HpL9cN_b1b5UT<&2IW=pHrWTW3tD-Th+J2Ipw+dUtH_ >z-lo{bO81!d^-W_>6uZY=UeYvv&vDm;vec%R*6nh|ZHsMk<P^9ju1;~jJT2Sx%KXvJ >zNh1<nlPC3aPQJfY$A?c>@zpM!;1{hDN;346<^VNy`%0Nu6D5*d>GHJ$eZ;i6aZ+r2 >zD5j4Oku&mY#mxR*GCAdtNN#VCsWIC{YJ*+R9#E=gAFtPG9b46$FDv!ybuKk`b+Jw_ >z&rlij3-!DrhmuLV<Qr?##hc*;@~zA`G2bs+E{G2i3z`#UW~i6QJR2diyc<N;H~uoa >z@uXO|DNH-h)vI@w_R#O{sZ=>BEjo8yv3f72N-xSOREq=l>m}0`swExg<<i&!v9zv4 >zE)UEW%gZ;)6>W*){i0=ZWo?9T<)_IHO8rHC#yGiZ^F3kr>e9)lYqw5bcJ{^p+B=Wu >z*d&|H<2kt3*45*=sO&x-&&di~ck9{Ty7x&;O14d&nQWUl$y_+gTq4<wh&lGZ@5%o@ >zKgxX5nx8i7C;Y3&lQE$Adt{D~NkV1`nI=m!Psl`BnwdhT3YjZpvXI$ArVE)bWWtac >zL#7OwGi1^%&8#8QW@+XPnK)$TEX~v*bB9bGGJDAMA@he!ATooNW(tuxL?#iLMPwS0 >zc|;}>nMq_Sk-0=B6PZn9I+6KACKQ=bWJ-}awKS88%qlXi$h;yGi_9!CwaDBelZ(tQ >zGQG(BA`^_vFfzr+93zu#X=WLjW@Mg`iAHOtd0?tJX0CzBMrIqCZe+fZ2}foenQ~;# >zEzP7OvyMzVGVjR5BQuXoJu>&m<Ri0>Og}RJNCJ=yASpm{fF!}vWC2M7k_RLaNG6a} >zAh|%2fn)<o2a*pYAxK7$lvtXaAW5+_SwYf*<ON9#k{Kj5NN$kiAlX6EgX9NE5RxGz >zMM#d2Bw3m)A!$PLgd_^d6p|_=S4gsuY$54F@`WS}$rzF{OOrDsX_h8yNZKq--jKv0 >znL|>C<PJ$5l077SNdAxnA{j(dXlZhYB+=4j5lN$^$s>|TB$G%gkz69lM6!vb6Uir% >zP$Z*BN|Br*NwqXtMbc_%@`@zZ(qtA%Es|R#xkz@A^dk915{zURNimXRB*~U0%Sf6n >zO`efNTbfKGsYY^*Bpb;#l5Qm5NWyLZH@wq^`<l3qGLa8UijIhi7#Wrn85t27G1B)h >D+Bm-s > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey >new file mode 100644 >index 0000000000000000000000000000000000000000..dcac92bad609fac72c04077782dd08a9876eeeb9 >GIT binary patch >literal 1416 >zcmc(eOGs2<97q3}kXaxUw&($3fe1D_zA`J*GzZhk)UhTjAEjfXmY-T;<>Lb-5Xy29 >zL=yC%7lqa$$t;i{7m)--R6-FH5w++ulBCz|o@v>tMfAITb7n5w+1ztHrG8(6{IMDK >z9S-x_hwpQ={c(P1q9UqfQkK--G0vJ6NoWpLi7u}s6}?x<(P@&B@IWn}xkyqMzB8$B >zf69t)_f6VVh+a8#*Q^@+u2+xrn)IVD^_qTVG8#s8X7>@bw&1MJs%lW#aou`dcA?4% >z_i5MCMCF?9lH8C8mHVt(*1!Iu@@~2$e|(;CpNNqSSEo!t>ulM0_^BzZjMhc<!=^ZM >zmiFZLo07;6dQ)t>*(~GQ8*x&3Uk&OlQ*Ekrv`=q+Ql_?D9+2%fGE`a5F)2SDr7HYQ >zQrVGicI0|wXIZ4Fib;{`^kCzgTcm3izcDqRlJu@0W5)kzzOH?7$<$q+*7ale)b73s >zz30M3)zElbt3y4ivGln#`RY`2+KBAUajSg`PDx9g-?V(~l-BS((>hTp`#&x-2X1A_ >z!H40d?OeHTADA>9U75PG_py<n;D2&i)|t;DmUZQ{gjm+_wV=>^w@0#y?UU`X-zoF_ >zg$L8WAF=<@vhabQIKl7&;s(PHh$9S7Ag(ZcfjGnPCP3RAhCdL8ARa+ng7^e+3gQ*S >zEr?$b#~_|TT!Z)qaSq~LfVO)K{{plfWOxX1k>Ml6NrsmYHyM6H9EEraaTVe##94^9 >z5O*Q|2537B@fhMV#Ak@p46h+>GyH})&hQ-KI>UE}^9=7H?nC?!&~5<I0i*>;50EAx >zT|nA^^Z{uE(g~y$MlX<N7~MeHVe}KA-4LUr0PU6-JwcjcbOmV((ifyL_`f>~v$IRF >Vvx{{nIh>C8Shq9Yk?e>M`vuR{Xd(ar > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo >new file mode 100644 >index 0000000000000000000000000000000000000000..f524fd219e753111d18e26ea890a8ea16b5e0566 >GIT binary patch >literal 1564 >zcmdthOGs2v0Eh8A<zqC>REWsZF)KBZPFgU8>8P3Jqb3{3w6ImuvZ5%crcFrYBElXE >z!JBP*!T}2gdQDlTMRCaz%OL525?1t}qSxts$9A=-ZTE7|?=p*7%>2JV{f6~<)^As= >z{)C6CPCvZQ-mQ<8`7iQ24mNk5P=mgcZxiIHr>niE@0E%(T`i%rom=IF59dP{ubh{c >z?jH$VZa*TgoZB7>2e-?stqq}TjSaGE=Qi*4qDAt?+InwyTAI8$rPkZyE)c!bQ@y<- >zsp8iDcJH0kZgJ<(`mE6jd*tZ51zE4kD&?y^{hm+Bo8+f2DV}dX3dQ%2iCNa+Ey5b8 >z^+c@NCnLHS+R=woWb~6qN8R1+Suyp?M9ko3PyEy*5g%-}Ck_WiLgNN|(!+j{SX5;v >z?#-3S^E&MGu7H@4xy_St?75sdsnwoU*(7HT7kDz$6GWy{XJ^Oe$ZWaLo-@=Zat=(h >zi>p71k|lG)r4`4W#mQ~qva~9H+527La(9zc-nTAXF|yQI+F25=?8$Me+8TY;C*qx& >z9mT$7&2OCLYchQPjdA`J1(Cj5|7-uslwn^$IR3!bUSCitWx2*hjQ`^u6&V#7t?#kZ >zJq92A%^j)K?HbE6XM|EW!<JjAyFFH%QV$$g5~rol#{;g(N<ABLO;hUSh|4qfUR@Kg >zYV?yU=IbXvUvTOt&%EX7w|V;QPgmd{mi7797w8{Bu`pz1$kLFtA&Wy+hb#|SAF@DX >zg~$?-H6n{dR*5VVStqhkWTnVbk+mX=MOKR}*QnQvEErj_Q7;);vr#V^S+!9w8(Fte >zFC1Apnx*smuy!uJcwqHLy?kW-MqL0>0aAid*MJmZ)Kws5Aax*xAe9((DM&3yF-SE? >zIY>Q7K}KB>Qj$^EgcN1eRUu^|bs>czl_8}ewIRhBb#+L2MqM9LAW|VxB2pt#BvK_( >iCQ>I-C{ig>DpD&_tWj5sLH!^7U**OY=*A24V}Akwd@Wo6 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal >new file mode 100644 >index 0000000000000000000000000000000000000000..7b4682a39e2fc97450c99eed4576d2a4614bf294 >GIT binary patch >literal 3503 >zcmd_sX;76_9LMpiA{wHIikTw0q=>RgxKd&+gnGpVOmRCJdIvQ*xgZo`3u-tuOrt@i >zgSl@RqGFJSpr$rWiQ=B((UcTH5AL~eJKyJRFB;!9)8jn%bH};7{eAy2aS7AA+y3#? >zH~+)SbHluRZ}EZo$SGJZSO0KRe6uw0=$fzdBG#^O)$3xnM66#jQE%vyEH+N>r#HC| >zSDOd7*PE+?)mHDH<<?VnvF+(L`E7oX*nZ(N`P~<uB6nY++>sWb@>Y$MI~_yBuGCPu >zJJMg|Pw<j^e4B{x`#zKfu38j!YOV__PKdoO_x0Xmx75C?XY`M`rK;#qq28alQx&gY >zsY?=9r~~N>^}*;Qbtrza{wZjzI&4psM?CtdqXCoTFP~_6qT@YzLOfAr^RMcY5f{~| >z*sZ0f+pQ};6ZUE8S=-{`b6&Gc&xa;OoUh#^FEpPgE|h1;i(5Vt<wY~)rHpu?a_sVQ >z!eDVFElB<m)kR#L<SDQDxrvI%0R3mP&g#0ahrZGBj;eI6(UlKQs+$#My6W^ERed;L >z-`Za$Zs(qmdUd|2$=ogPEXo#l6SL&K$tmJ~bh3QVZ@hRI6ek~bS)l&%2$zo=j#G~x >zjnz-C_f=2N_R-IdwpFzS-rBjzschM`y3W$es_p`%>&aT-BA&_mBb0EBxFj0{9}o@O >zmB<&Gt`}~$b<#~Q5slPh>3(jlYFzA)O$yVM$Ci(E)32s0&x~ohS<0KLc|xRaF|Mof >zit^Jfd%LR_{Tk_39sI;g4XbtQx{XBZJ8rVg<!a%5yh^q$IVODaev>b+$rJ68Y`Xo2 >z%SDISE4t&1T=h!WA>C=n=c=>UM(x{muJWxtDE-`Gm0$S=*|oB#>Q=N=`j^FsfSd#w >zxT}W<N*gMJm$woj4u|eO=dlQljMA@;x*)=QyXhX?i$u=`jdia!=T)zY+q(CYeX7sl >z<GSzfIVwE&mV9mR2kQ0AQrU0iR27l9Q}$0^B;JT#AqT`y5d(vg<e-5A#Gt#Ib!5O~ >z6<M}SM>X!RqIS*FL#jKfp{p|Fu+tI3o;p(w-_t=vPq51oSuSE^c#s@5ze0@m_LMQP >zM@7t&yK+p}Rx#$9haT&5SdBeYqsP^5R&ndg^!V~+YC?Lxo>(+XO^VOflXHeEVc#vM >zES)K)24u;%9d;4lI9X1M3=-3-<D|paQ#gJNmkF+SMZ$I;Iiuo~n3>f_&pKA4-bwP- >zvvbQ-Vr;FJnfdD7Fs0`tW~;eg2lTw?6g98*l1%EAC6dZZWOA!ykzBM+raX!h@8v9( >z@1G49sc8<mu)s&8O^T9>zO;$Db)M&6J(uVC^?&NOPG|lKo6YGwQe4Ny=`7q~YiNCU >zw?3N=v&Yy54K(j)^S))?5iw@GY_>YqN6f#EUZwe=HF}Tu3-dV5Gv`)v6*7Xz5F%rU >z3?ed$$S@+~hzuk$lE_dZV`*sy6B$iQGn~kHA_IzyC^DqTm?DFUj4Cp$$haZ{i;OHX >zw8+>ZgNux=r5Rpid@aoYBO{CqF*3%;AS0uU3^Ov$$Uq|_jSMw1*2rKZqm2wVGTxSE >zz>yJ0h8!7lWYCdOM}{34cVyr#&B!A|Z)wIJ8GK~)k>N+i9|-^w0VD)S43HooQ9#0g >z!~qEe5(!Ha3M3XtFpy{<;XvYn1O$l)5)vdPNKlZdAYnn`f&>PM3=$ek6B{HrNOX|! >zpcNm!5Fj2CAs|FZjF2E9Q9{Cm#0d!$5-B89NUSVPu#jjW;X>kt1PqB75;7!aNYId| >zAz?$}h6E0Y91=Ptc1Z9nP4tlPA@M^3h(r(xAreC*h)5KXFd}h80*OQt38kfpB@#?a >z6HO$XNIa2%A`wMGio_HNDiT#BtVmpuz#@@FLW{%}39hAyE)rfOzDR(P2qPgzVvGbC >zi82yqB+f{nkw_z<wluLuf^BJ{jfC6M#2X1X5^*HtNX(I-BT+}fj>H`aJQ8^%^p+;} >zNboI9^pWsen)o9J0CEH%hX8U6AO`_*6d;EIavUHB0&*lEhXQgeAP0k`IU10|!O|QL >z$N^z#jtJzCK#mFIpg@ia<gh@F3*^8+jtu0`K#mRM;IK4D2Xc5=n&SgGKrGD>f*c~q >xF@hW<$WekECdhGu94NNuyCVLl7mAxXT*Ax&<8KcQ>>e2GZx0Cx3<(T&`x_HwlD7Z= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau >new file mode 100644 >index 0000000000000000000000000000000000000000..e5d0289b511f89e273438cc487b0dafad48093ee >GIT binary patch >literal 2284 >zcmdVae@xVM9LMnkN$G%)iXufatO$fVzz{@AR2ZFlVtP0@O+OlVLnz*<oktnk#F+f! >z8VzbSw$jSl8kt$T8WVHoKV^>9?8oq9TdcLHkFkm%@A^Ey{n=mrSD)MG9^c*ez5ia% >zK(KjRvFjgan*D{#>9v>V<bC$5r*v8OueA~RZOI1pyEiBk_w3exq*lmeVuPNXs5evJ >zFV=rvDmT~8&(YD7nI`snOuPD`Ca&v>j^C}#G>NJNbxp2Yqt*1v%QB<zj7pq4B-hV8 >zqTH^-;x^ByBz-`VzkEffoDRtir#f}&8~e@77q;oNgH7hf_6PJ$%{AuchCH3_%Qd$w >zO4hgLCYg-vTy<OGn3)xyq-Oo%mf2UvROZDWWzNtAm38b>x&7s1YHrwN?s&RKW!HUc >z=4~I)cb1$rcdd9<-<|%N$;sQPbD|$fuDed>j=U;)Ka}eEgI$t898d-Q&Eh$}P<cC6 >zN?}iiDhh>6@s3HgpvGtJUHgqH$(e5!77wb@87Zc0_E)-W^k=hZ>O)<A?xI=zb-%6{ >z_(|^jV4uGK&}Xvb#jU!s?HyU#xmPW#eNL7)Zc$a<uvAwqSJmT3O-;dOT{GNmd?`z{ >z?|7?OF*Z-HeCeR9`l3?#_q53B_p(*(M!&4-O;8V3cxCP5qiS7dngr_3tH9K_tS@;} >zt^Y37)MuU3^=Ge|hUifpJTh!HjCAXbohQsggROc~W1rdFzgjE*yRxOLMQttUm4`!q >z)tC~IrW&tm8VgD&CryPusgUOB<Er_sEZIK#xoYVxH?0@0>PNzv=Fx#+-BuSha_EG9 >ztVEj~ZGC!Y`WdsUwq5UvUY2lKuL_S0NhBkpB7=veeIlry=szG&UaC-gIzsZ)$t=~e >z$tQcCcPUqV+<)*Bi@hIqxni-8Psb(1VyE7AC9d)ZT-8<ft_#>Da035gJrjSwV*fD~ >zV@1f4kToHTLRN(=3t5+=T^O=5WNFCS&{-T0td3)s2docSAhJSaiO3p}MIx(2mWiwr >zS*W93DY8^#t;k}L)gsG9){86{SuwI?WX;H;kyRthM%Ili99g-eT{^OMWbw%Ak>w-n >zM+$&c04V`d1EdH@6_7F@b#SzWKq}#AOM%n^DF#vvq#Q^+kb)o;K}v$u1Stwq6{IXk >zU68^cm2tGCL282(2dNHH9;7}<fshIzB|>V16bY#kQYNHMj<!%pr5tUkkXkv~Vj<N+ >z%7xSmDHu{Qq-03VkfI?~L&}EK&CwPPshp!N9a1|-TRfzCNcoWZAq7M#h?EeiAyP!7 >zibxreIwFNcD(PrTiPX~3789waqb(;=Po$toMUj#sHARYwR23;JQdgv~NM#*uX_4AG >y+TtSBb+qM0>WdT@sW4Jvq{c{*@&8?Aw+(cO4RyYMfv4D0nC~wt@)UUr-G2cP_@SKu > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/New_York b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/New_York >new file mode 100644 >index 0000000000000000000000000000000000000000..7553fee37a5d03e9163ee19b1ced730a02345cfb >GIT binary patch >literal 3545 >zcmd_sSy0tw7{~FW;u1<|in&Fm6{0L|xKd(jgnGmUQpxbGKnAsVN+m4AN|bP>tkJ=? >z!Q9a_a=|1E(F`4%HgPS*S5s0GdzBW_I;Z#h-geP=(N%xve?Dg%818=GCn+U!T5r!k >zp2qfnczG_{m+x&}v>!$5LS@CrKdJW?d1U3=U#eB<XJz$*i+auU4`gl3dbMuCL9;%j >zKo$4dWQu)j^~Tn(nT^%?`u#dFo60lw=Bn}LgQ8KoWLsbJVQ!?}^6og<nlVyso7YFS >z$498rDIu~W>{j*B;NN9u6QjyHo{+MdLuyyRuVz=}cJ;}*W9HM6Z*=*-GP8ThR$Z~? >z9kVBEnckcCg83{lTklJoYCeyiq$|DiWPk7=eIPPb4%AOn2ZQ3|;PHX#i&u;s>iUZu >zQa5zfoO9-I+$nt|xzZf%yjvfODK^JFEA@$x#pZ-wpuh92m+vdm^~vf2Ikn+sRb4(q >zP8XypUF4NBnGdS7xzX}NLN|3TwUwNo7^Q3CBh8QfTj~p8!RBJyYx+`?tLD;ghxJc2 >zRp#>19lEx%)LhwJrG73sBxXgay1Hb$T${gK)nygRFH`5LUlViWw;_+H-=kBczT30< >zkKkCj-fXhIUO&m)xG-4%d3=!h>%bk_x3iP+ulH-ua-V6Ce?~WaR+~oRQvvEPX*^b| >zCUK{wY0tf?>8tJKmX>SOEt{8_K(k0S*9)b^iB&qNB13L1%hSOd7MPZAP1CIk(#>si >zAJVNe<4v2%-E~MpxM@4Eg}yz!xoOuWT(xgjYdSP+t~y)`l#XX=Ri|$+%N={ZR-s$I >zk~>#!QJu3r=B}5PsxHZAP1orq`tF#0=AMyn=zBxfnXvA&beQim2@g!x;ni!U`=$Q6 >zM|r+PR3)j%qD+a})=x#}j*^~B+o@g|8K(C$*HxeR1k-o?Nfi^;!}RN2uKG6(G6On( >zrw7#hYzE%=L=UR`)(rl>NXM33k^6SNsPA9$jSP9`aUGYnRfguxR}UmElVNF(so~Mt >zGGh2JHKMNA#79om@l}gWLeNm1ux+LpS=&{QdbdDEAB|Jqc{60pjxH*3idV)K2B>kd >z(K3EcjhfJ@l_Vt}P)RrH<l&f&>f!UjW>RRSp0w|(nd~dpDQl|CBh`!bl)O^&X!%T? >znzr0bEgGYhce^~6KSMnpStw6rcvV_Zj-<y&tMu9w$p~wuGQNzJ%qDdzb91OnuQ{S- >z6b>>ozrL!U%<g2KDyh<0$vz`XO7+t*+B}oBT+a&GYi1|T)w6x4C3`@j%C6ocIqh;( >zPWft?Tc4tyD_SVeACFb@ax>(GouMi>H9_XT=}`?E+~mJT0XO*zH~R<vyPx;_KQ8ik >z{QmtF4FdfBvJXAY-1iplv*l=Sl4rzl`%bX$MEj0SvRmfyG;kkD|Gt5>_6OYt*7F<o >z@!Kc0k$D~2L}V9{ZAA7F*+^t3k*!4b64^{-H<9gh+WkZ})M<AV*-~UrkxfN*71>r~ >zUy+SPb{5%MWN(qpMRph2USxlf4R+ccMz+{#_ZZn^WS5a`M)n!mXk@36tw#15*=%ID >zk?ltI8`*HD-Em~gop#TWO-FX!X}2BOcVy#{okzAF*?VO3k==LN?ML<>X#mmzqy<P1 >zkR~8qK-z%x0cix%38WQBFOX&+-9Xxb^uuWzf^-CF3DOg!DM(k4wjg~$8iRBOX${gF >zq&Y};koF+`K^o+=9YR`!^ayDZx-RjBHu2a#0gXaBg|rIk71AuETS&W{wqHoYoVH^~ >z%aEQSO+&hdv<>MS(m14ZNb8W^A<aX&hqMprAJRaigGdXVwueX)kuD-_MEZy{66qw; >zN~D)aGm&m0?L_*CG}LK3inP>edx|s_=_=Azq_0S0k<KEmMS6=g7wIn2UZlTBgOLs+ >zEq2--BTYuSjI<f)Gty|J(@3k4UL(y$x{b6O={M4Fr|me>a;NP%(sZZoI?{He??~g3 >z&LgcydXF?8=|0kar2ohb;IwxDatk=^J%HQ<PJ0(1w*hh=AU6VXCm^>1axWk^19CSY >zw*zuNAU6bZM<BO^)7}%vP2se61#(+B?R|mV7|5N0+#1Nef!rL(-GSU5$o+xbAjlnp >z+#*hUk03XR)7~Y>ZQ``|338(#cM5W=AomJ#vmkd1a=UnL`V#q{9xs9Rrirn)O@y~k >SRPU&s5#C<CqIyO34E!5Kf4#l{ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon >new file mode 100644 >index 0000000000000000000000000000000000000000..f8a0292b25999d4726ceed52d1b55a4713700045 >GIT binary patch >literal 2131 >zcmdtie@xVM9LMo5L`4TAlq4yULB$UFZ73QQChR)(g!C{a(~kz;PAJ}?-JlG0VW|JO >zM#Ea|T4~MN9GTg)8k2J7*2<LC`ZfC0CVy1e$LJ3h8`tOg`L{p%v#sy#^L>1GyYGMZ >zdWM^$TPnSOTvyv~I9z@9@H}&uy~R)V%c~#!s?JRY8$a7?<YK{}a#2m`)VafQUFKos >z^A3s6Jg3t19!dZ9b)9iKBG;el)id6D)?~i4MQ816H8*rWpl^%@%*=H~Iy>k$H!Vun >zv;1i$C*QAbP8~P1lhf4fKYTLhr*V~g;WxQu_`J$H_J!Q~+A%dZ=9$}e_pAJ-pH0Em >zL4AAG8FR<7=k=Z0Z<@lQZMty!6Y=|+w14ysDf(rho;TDd#Uo)=5|2vh@dc`^XStO3 >z=ctNE#8h_vrRE2M=B`ygsH(zwW<lkUT6k@Ssh;zlt{(f{ESmaAFFt$0-2HuA*9=~k >zdp_Ky?>+FP-1qWkUEA@lEa}~;?r(TOmbPqCb!9QBuUo3>Cytmv$wnO**>8dwOLXvf >zyID3~pqIb0PgZ<gt3o^4Waaz$s$qRd8V6F;gEeKc>d7&+IyXzgP3Kg2YC_gjy{*<< >znqk)Foz-j4TrumWkLc#ZBj(}J{d#@x3G>KMyWY@p&}@va)GG9zZ0c)Mn@a}d(MU+O >zWOPYupiH%nH%p{2OGQ4fk?1uODta_ewvK(J+6ESz_VZWtW3gQG_~3}{Xqq;1;Dmmn >zN}JA(gL+%`$7Xv&x86Seqr|EQRBUuux^lWy*U%y9o@`c6#rMe5-_)obJrQ~4WS;8T >z5R{!SdMY_7Iq9kt?*Hj0kvLlGd5OfQr;}0=iBs=*sqQ)5-7{B&!d`uyJ*(|`$ezZq >z{Y!gZlDmcfeF}T+58V_ddBa`_dv#vkU5iWunFlfvWG2W|oOUj}%Vdz*Ak%T$`5+TQ >zW`s-$nG-T8WLC(uka-~!LuQ6d4VfD<Ib?Ro^pN>E?F5k-B2z@>h)fchB{EH9p2$Rz >znIcm~=88-fnXS`K7n!fqP8gXnGG%1W$fS{3BhyCajZ7SwIWl!*?#Sek*(1|O=I^u# >zKr(=&0LcN81SAVc8jw67i9j-eqyotWk_;ppPMZ!SA5NPPBqL6n5+o-`Qjn}5X+iRW >zBnHV0k{Tp8NOF+uIBj~6{5WlbkPJC(ijW*3NkX!OqzTCrk|-ooNUD%rA<06rg`^9~ >zm(wN;$(Ylo49S_(CJo6Nk~So7NaB#pA*n-hha?Zl9+EyJe@>e~B!f<yLL`Syn?xjw >rNE(qmB8fyYiKG(ArT0JRrO#%x%I35<G{3a6w7fV}QBhh^TJHNBVTxT5 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Nome b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Nome >new file mode 100644 >index 0000000000000000000000000000000000000000..c886c9bc0f46a6677e9824fb188761b6dbc418ff >GIT binary patch >literal 2376 >zcmciCeN0wW0LSqQ0uK-rB`6}%^$p@hJb)k+<pW`aid^OKNz7CVVp#GLjNuC?r6adW >zN1MZGcAR6YE!&xHrm^Tr*V?k&6K*BBDBYUrlC@qflH2*7+WMpBe|hfi{T!b0@9*nd >z-S||l^{*49f8piq(J%MZ?fP?OS6Og))=w?NwT}1q;gxFQM62Vz?(<sx)lSF@1>Vrk >zd}mVYia=QH@?iM#`GJU%yr3s%O2G5d#$Z(3^+42-D^B$HUj%OZdL$S#@~byCFc`f3 >z<cRl<H_kh8`v$#t?s~_$YtyUV$&Ck`_?m6rgo<uwN>QzMYWjL7ab{OwT2!f%6uK^u >zlo=nF^h2qderb+O9-gi4KIM@qM<didhptGwqe#r?IU{HKr;Aw|zO`rP-w<;ae`Kd7 >zd?nH{-n7#u##MUs%Xa$cmn!3Gi=8?2p2|A+qMUp1kjg&RB<FQMuf!{k%xRD!w=GxZ >zl|LuuSI5izv^r6c`-@!Qc~}%CPqqs$-z$p7f41-YFk0My;d8rKrK$%8PudUeiBt>s >z@3+0pS5?W5w`FP7$LgWFeX?xcTWV3+7P;uhi=upPzg>Rrw5W*PY*!o`5R0#^v6mcp >zUoHKtQ&w(0td<>LEvwe-RL<UFxxBbRt>{RR)yWmg=eMNqk4)vyza;(NJR(-5xb~_K >zGDOY9MSJx?jCgGHw7q7>n0S0>z+PJy6zdN5+UqO7Q?<Q^<r8zyswW$E%DPyk>dPBs >z{k1;TkX9iZK518to=n+z#IH77j+IaEZ4=J~Gwh8WD@Buvv77x1M9c0myR~4Nc(yrc >zw<U~=_Nt?HyE|2N6rPnGqra)nL?t_iE~rh{`{d?>@2V~5+vV2o*HqUDzwBPyqqg-I >z%8<}WAz|S+dm<t|xA1Y@x-rXg-Fn9gbKSP}A(7@AV}6M<_juRsX|WPrclY*?WOJXf >zw9;oStJd$M`gMF(slJz%`K%gk$r61jS)y<Hgz(|~b@Bc8(xUZ0@N)X}%RTivf9d1u >zv+&f7PqC}FY8Y7{vO=R?BC<v_i{!#8IeMAEI+2AUD@B%ytQA=-vRb2FF0x*uUNEv^ >zWXZ^ykwqh`MwX4N8(BEAa%Abq+L6U0t4EfPtRE==QURkbfl=20DFRXjqzp(MkU}7p >zKuUqs0x1Sk4Wt}MJ&=MJbw!Yp7<EmMq99d4%7WAdDGX8>q%=rvkm4ZKLCS;F2PqIz >zA*4h`T_dDONR^N>A$39ug;WYD6;dmtSV*;yav}9X3TD(5LrP}UHA9MK)Kx>uhSUuy >z98x)?bV%)x;vv;T%7@esDWFkT5GkQi*AOY9QCATuBT`4CkVqwwQX;iPiiuPcDJN1- >zq@YMek&+s9O_8D+bybnF8g*Tf!XlMLN{iGMDK1i7q`XLdkpd$XMoMhdHAaeT)Kx~x >zY}9o|3XN16DK%1Sq}WKck#bu)-C?2O5jT50QIWUsv8>}w^znZ!_&*8%`xZ^xi>Q27 >TWnOk}w#cf?$;r;i7SVqK2N!kg > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha >new file mode 100644 >index 0000000000000000000000000000000000000000..6d91f91452d0c8474f917c41add3395838504ac6 >GIT binary patch >literal 742 >zcmb`^y)T170LSsCMMw#^8gMiv1_?FLRQv--NS=tW2@+FBw${vW69dDI;vdkONF>-K >zSj0=cEY#phs7A@T?<FP+iEFN(rqkv7^C#!$;@*!_VgKQBI_>3mUB-T`Zq3eQ8<NM_ >z&$!A3?Q-X8PMr5^d0u#u7mX+SA~z&1%hmE~{a9RIuE@L}6EACleyti6#oclFRxea( >ztXY;0w#9p7U%ziYs&b(uKbBLf=_n(c7mrkn?$EM#Pqi*h$+p@Z6`cs{=<T$K_1){( >zX-@PNv${XKAQIPSGVu^n$-_Voq&$^2#(3e-uRdX8ZZ<s6nBX~7Y0O>Ts~H~gy{_&a >zd%uJDe~44EaX9u3hDb;#r;UXKL!u$!oHia3&}kzgA(5C!P$Vi67Kw`lMj|7joi;WS >z+-ajD;gR^fodJ*$kRgyUkU@}9kYSv59AqG;9SIo<84DTAX-7kbL&n3jeapWN7#Xl* >H4#p#2M|K~x > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah >new file mode 100644 >index 0000000000000000000000000000000000000000..8174c8828851a7ac72aa65cbd5135664152e3182 >GIT binary patch >literal 2389 >zcmd_qZA_L`9LMo<BZ?5%$;1#4N=pI(0mXo%C?J9)2yX#}FbYKMfy)O-4E2-*<3;l< >z7f~ibq1BoRb8|R0(#+OY=ECN*HcDGh7Im-OVu4(p@9AYP+FI}W-@ES5g_Dgpzpr;~ >z{rVK~w+k@;!ozi%hxbTjzPb-)=vRjVR8L!^?tS?O^-)K#9$9$B8L18ve~dTEiSNtB >z<oPmr^}`G?HJC2lHzS4Uijbc6DdG3zRXJ@_xbm-_r>7TBsu@`mIv{CO1w5Ck1LbiQ >zcxXTd`Ce1keATOiFT5*4j_=m9j`fOb-|CU_rQPDXj%VcT=2~%meT|&6CQpRs-y`Ry >z$BG+bZ<S#Sa@D-RAQ|o#qr!h(q$4f`s>qR<dj5$YRn)*`9o>6c-Pkl=-t_cgwP3X? >z7jFDm+?;w*-cs<6SQL6v#>8n6Gxep84caVXM^EUu%U-c~_;nqB)=>%F&+5b@C2Gme >zI-Rt4nM$r}l_^{1s-=1B<+74-l^S!eT%Pi|x-B41rbYZN(!L9p=@S=3#s@#k+rJnR >zEBb?U=Fom|$DW_`o%?o)tcFkYU9J1n-9`O6yJm;VS@OKj%~_{%e>)}f5?Vyw**9c< >zNR`Mx(jg1Rvc!F_9MCJzRjR_4W_AD3B&VpdLKSz;b{<%fsY)8JIIAL~m3Q?y$2;j! >zrKy8X={HfLJnA!F`6(gROda*D?Ykr@M!S5Kt?!EmhqwExY7UBZ-IczF3g1)J?aj`^ >z34Q93x(cTzq)pZ4WjeKE8&q9Pv{QGwK-C9$occrYYU8(GJCAnei^tBmzQ>yuizg0W >z^fi=*2xrep-=@@G#O8(rzAd4jimgTMzO7SZswu6{X&ODFwuQAh+lB{J^Y{j5d-q=T >z)cFFZWoM(>F&OXctSVExx@I|k9`l*zZ{hVn{>+&EuRgBZ^MVkr`*x4V-*xwEG1I;W >z+i&T*$ND{Uco$(S3%#N+$2_adQ)ZrGugEq(XPcinkNpPkKd<dY^Plb7#{c>)^B1^o >zm49$QvOZ*i$O@4qB5OnzX*H`vmWiwrStznnv`giMwQ^>$z-l>`i>wz}FtTD~$;g_m >zX3@y1t!CNCx{-w=E9Y1`vUZNeBdh0FKC*s}0w5LOC;?Ifjv^pcK+1sB!D<SDR01gl >zQVXOQNHvghAoV~Bf>eZ~BuGs-ih@+dYRZDt#cB$JREDE8NNtefAk{(2gVYBp5K<we >zL`aR0A|X{m%7oO(Y6^u^ilbCWtvHH>REwirNWC};hExnG8B#N(Xh_wprff*vtfp{C >z<*cT3NbNX^hg1(KA5uT0fJg<A5+XH3iilLvYRZVz(P|3GQAw*QB}XlhVscayDJMrg >zk%Dqm6e%fEQ>3U!RgtnHb+wwpB9*n8(jv9Bn&KkWMas)jU!=es6-G+TQDdaY992fj >z%u#2nDKt`Pt0^^7YpW?XQf;K%NWGDQBNazVj?`S(e*Z6W9%Kr?+>}1PaA{&nVp4oz >La&lsFVp7nb$wqRA > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center >new file mode 100644 >index 0000000000000000000000000000000000000000..8035b24fafeff6fad833094f814905213b2f3a0b >GIT binary patch >literal 2389 >zcmd_qUrd#C9LMqBL6kp%J((235lRa}0Rh8+q%0r?c?9*yA0Y~Z5X<=a2NX5>l?>*E >z`D`x4{t!5FwK8OGhI1p#YOQoGY|hq3YRego^{l*Lf#>P>{&m?!>!Pc^XU};*IN7-Q >zy!`7MpUV(`yAb^^JY1K4c=sy()pIn*e&=+E>h18_eQ*4%zTOvMk1o6^M{A?SACt}2 >z)Qt);eYxDa^<|C-3}svHdtM>BV=Yf-Km_f$WzE<Uqk?Pa*)vP0)vOg$c1YTo3fZ4& >zhgl;k?AV|c?i^9KUFowUzWYQ(j_kE(pXw90zu#+Fhxdv*_PuJ&X{{G`Hr82lD+@(b >z(G%8P*-7H=qzA0%1qEteShy7vl&E5UOR!_Fg(>f7s6GG8FDh<u+>Y-%ukLA?Z{7RK >zfLgH5wH9tVC+^F<YTaM_kw}O-Yb7qSMPlFwJ1KmtNE$n1FB<oY#lx?w<ck|*O3x0J >zdLmygX{%Ie2NPs^LyO4R7Alt(R)`1JjLXc#9I-6poO~$6E3#s5I9b;NB75p9C+CYR >z;^FT<be0cHtK8GCIgcC|Q;)tWofS<Z>aq6y^6`=*DzC0d<}Ybi1^KIG!S5f7!j#QU >z;l;zED6+&UI<Z?6Poz6fzI8~gytGRC_Oz;1C(~p}b(JdZnj=>)&sA%hZ_2gac;#Pr >zN&2Tfsw{Izmi-hbD&oF%Dn1vYGH}va-+xV1jdeTK?VpLKhIctNbw|b1J=M-LzE4$c >zXRF+h(yyLvsFHP&9jd-CSJqE#R1Jyovf+HOY7Ftn#$(B9)Ab+a^Ib*ag$u5;xn;3< >zap0=cR2C`ZfwRt*%wNUUrgxofQQwH|C7sUpz=Uea>X$8J7u3$^4!Lu9P_<5Ol)HKk >zs@<21<({@?_0mwXY^y0(FL%$DK_2~?5p2Tizxd3W`Ja7Uw=Yx(*ZrW^6YRQg+alDw >zN0@KRbx$4l%;jA~uk`taFJC`v^;52&QoqR4Kj-P6Igj}!{(oNEA^o4t+9v<{E&Ug` >zZcT8+amxBA3#6=&vP8-nDT_4KtE4QGvQElEDJ!LBsl2dOPA`_QT8`yX)=OD1WyO>w >zQ`T&%7fo5Usa`f^-IRq>R?e|>%Gx;=Pgy<3@+s@*5P+fphXfQ2I7FbRK#_r>gQ*sR >zq69?>iWU?xC~8pTpy)vngrW$CBos|JM4_l+s%4?*VycCqD8nHQMH`AZ6m=-_Q1qb) >z#Gw#HA`XoxB5|lhk%>bmQ!NySQWU8;w4#VbQHvrMMK6kA6vZf#Q8c57Mp4aF%f_Lb >zsTPhyIa4hihjtY4DC$w<qv%HwkfI<(LW+hI5h*H~Y8fdynrb0Alr+^+a%f2rlS564 >zoE&;m1m#eaA}K{vil`J-DY8;@HPymWlr`1TQnWSI;!@P5$jhNGMPLqvDH3yNOc9ww >zWs1xkI-6>tDN37asVQ2UYOyJ5Q{<-TO%a@;I7M=b=EC^>zu-Jv3%^WDpX^(jnvt58 >N>`PBiO;1e={}b5BehUBq > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem >new file mode 100644 >index 0000000000000000000000000000000000000000..5b630ee66715d60ee99405709d86e0e6a0c8b29c >GIT binary patch >literal 2389 >zcmd_qUrd#C9LMqBLG;K8?3allAe5E_0s@L5Nm)Pyc?9tYC`3^pVi}KrAW_3#NiZ** >z&*p|$Nnqq^&4jrbj*T#@wUu*Wb6Ojvt$!BvtlVOOJpJCkF1zTW?)siR=k?%Z<L2`Y >ztgqXUCjNF_{VzORyMB0&R{E>+Sf>5zfLC?3M%&#l{h&VH7itgBzitgzMTkGf8szx* >zWn$t|sl4$~rkLzsCfzrph3JTqp0-I5^z02eWlN+Au9{;{Et*i%R*c);lo93KpKgc9 >zAr*4GPx_pr>ZY%{?a<5bim;)*_Kefr;^sHIq&&P=+_LWlIkTxo+*(&HXRXT<;rS2A >z*~{X^ZSi-@h<UkcPKZxN2F0n!Ul-U>S3^|v@N|3bnIBb5-!(h7`<%MHajv}M`4ej1 >zT362B^oh7L{ffM+;BB!W{H%;iutnVDmv+2wtB4;tV<%h-h=qf%*@+h{mDKs7oqV!b >zEo!c{Qw}asskJRKZQE?MIB$boQaq;8;~thv(>_=CcoSqs)bAqWyHL4o{IbaW@Mn4N >z7XxB>ug}gJI3n&l@RNQ2%X`F%`XTi|%YN&@!lNp?y57oJ)S_~8R$IBhy(99HHamG2 >z4vYM-LMQ*^E>SR=>OAtwA+_@2D$BpSNv%4SVii`DtD^Rq*6QV1s<`30wI(`N1=e1) >z0uvrplHPBXd=n$eVm@=qJ`iHv<SA!;&s9-A(&1FJye}Rd-04(S9}|ytRydFQ-&0j> >zP1X}hJ?hEYa;rM5Rn_EWSv8{@Rc&0XReP>L)p<Qu-SI@V>D#ZZr`q$y)8}1hbK^qs >z%!w;beMy+G4xDwir2ite*1zs-3;$GXFKlzRPmZd_j2^3T<h<Gu(Q54&>{Cr+8?Bw4 >z2i2}i1=jB72K8KjqSahks`hluu!21LGbPx->%aa?oBAJoT(@gf2-kh9%M<LnM{F_O >zyoZ`^>AI(TJ+pWh5i9)x;m^^}8vT^&rzjw@_0QS*XU=23A@I*@JEZ@!S=-oOzoq{I >z*R2c=?M2pyED%{CvP5K!$Rdq;mB=!Ybs`HzR*Gh+ys%bIFBVuW$8wSNA`3=Vj4T;h >zvr#V^S+!9w8(BB9aAf5iOGnnuv3O+l9Lq=6&rtxR0vshkYQRwhqzXtGkUAK3A&^QS >zr9f(d6a%RSQVygZNI{T_aFhh82}e<osu*=ykh&OkVUWsjlm@8{QXHf@NO_R@AO%7y >zgp>%W5mF?iN=TWIIvI7LkV<is3aJ%Gv5;zUlnbdBN5PPaAtgg<h7=8{no*aHqi#lB >zIF8C0b?G>2hZGN~9#TG}en<h43L+&$YKRmOsiIMr5vik57m}lrMqNsdS|Y{ds3uZQ >zj(Q>m<)|o9QlzFxQIV=5Wku?0)P+SVYt*GhYHQTRMXHOGm!rN&fjKISl$fK&NRc_J >zjFg$9&PH8mq|!!RYNXaiU2LS<NV$=EBLzn)j+7j!xiJ0yU*z1U3%^vCKGDB8IW0LQ >N(Vv={oSK~C`xB@nc3A)b > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga >new file mode 100644 >index 0000000000000000000000000000000000000000..190c5c86dd8f1f00ecc13448c649acc97e93df58 >GIT binary patch >literal 1522 >zcmdUuO-NKx07mbarHJVx3IZj90wHvAG=DS8w9Is}bebkLwNi)4(kW%I^5;U5wDJ}r >zfhh$^iwH$zG6GxKt}qv2K^9~`M1cj7VEVe})govWwCTItcODPk?i^Q{uP#aau@(9Y >zmzC?w`)a8lgTeRyp)U=uf_3idySY=<W09%VV~ZE(9NvIPY6|x!=X=DKk`MlrxIIQ{ >z(sP*>w#i73`6kleMH(3k&qU_eRcdSSiO3p`P}}bJi|p=?YI|RY*wOe{<#hJRoyEf{ >zx28?zZN8#*<yFbu(akD<V~)(9zibqQZjc4jO~&5Y<+AYFpelM=A)T#VYF{v07FYPx >z{@(TSKvtnD353Yf*aYP|I4fP>qm?`5p>)5AH$3ZJ3(rK9ad>G$l--;&%4cqgiq0wH >z$oM5uSu<)>4b+Qj=cGE?)g_N5jHu&YpR8HgqiXXDW$mYc^2Q}d?<0@$g+)u>olJG& >z?Ppovd&oFB86{2yGK_|yInn5jG5p<A;&jTQai(!pG_84QG#B@Z=A{J{NFR}bnHQ>M >zZI5gjf1u9J2jsbd8|wVDN4B<KP;FzGvc0labzF^=!WP0=rcbEt-yYK(h!w&#`;`ba >z&D+;SxM|)Swng%8Gk$(Aa=L`G)FpDcdHP-7-{<-ZZRUUdXzHO4L?MVq5S1W0S=37L >z8(J~cg6PFi45ArCHHdBy<t%FLAnGyngDA+*5TYVOM~IRPEg@<`^n@r1(G;R8L|2Hi >z7PYnzbuDUrAqqn@hNukD8KN{qYlzwqy&;N2G>52eQR@y--lEnXqP|6~KO_N029OjO >zIY5$NWC2Nokq0CZNG6a}Ah|%2v8c0wq+?O%14+oD&IpncBqvBxjI1DOG4g^W#>fnk >z8Y4GIau#)Vkn}9-{2&Qh)EPojgyaZG5|Sk(O-P>bKS(q}_nW4>jdv#7lkAD{PKU$p >IuqQ_R0G#QIJOBUy > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Panama b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Panama >new file mode 100644 >index 0000000000000000000000000000000000000000..5c1c06372c6dc8610ffd14f74e923bdcb9b21d31 >GIT binary patch >literal 203 >zcmWHE%1kq2zyQoZ5fBCeCLji}c^ZI3_m{*Mj7<OkZ!KV80Fn|6EdT%S+`z!$;~T=@ >r48*R%AwX3i5JK2wm@Pa%AX<PX{{NrZt|kDYK{hcEXB8LFR#Pqj=|C+j > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung >new file mode 100644 >index 0000000000000000000000000000000000000000..df78b62682a5b376f6d7ca894c842f6b3d57f363 >GIT binary patch >literal 2108 >zcmeIyaY$WN0LStB(l(Pxjk4Ty*0iN=`rgy^$}Lx#+T*R>yt(JvbZuu#dpIpmYZGnD >z8EsViXMYqrD5PP3j3QPoM-hldtSF+pnGqFwD)NuOIA)Nv_HO5US`-99(4XDMxu460 >zry%~miRShPE1bVwOUxS%*8y{QF6lS7;mOASkDmTUoG<)Io)@#;&!KSjLUGI3)$Qxl >zHQVyM>{zb4wld{iSA0?B6y&<gGN#q?z(sfY+^-_{>uERd+>}@`KJMnfJ|?a|G3?&3 >z|3|g*i6d@7)2FI%&k66w$QiY2<CES^*~eAU>Nc+^H6ltfqh86>pjiEViMM97SCmfN >z<(3V#h~VjBH`KR5grCh3<;kS3*!zoE8;$9k8^02fqBZ)KicxXv;w)X6`-Q5UNjd8- >ze5lu-J*RK`a!6I3`ay1Zr(fNE%#(LKzgtyzy&-E39};&qJSS^gcZs@Cx2&(L74`Ec >zb+l}!icTEWv8);uJKd=_&K9b>UwB5|^I5fsAMB8u&J>7-?Q!W2q>Fp2Lb7rHjM$vF >zR3@4}5Qz)(a!cf8vE{of_165eYU_J*dRywGYJO=#w@e*X+YgWE`$s#~j@CiFb7+$i >z@i*nJr#i&$vH|%(GA>%PdSqKPB-&=1WwL0gNPb);+ZWA?_E+=eo|#F}F|b~Deln*X >z>dw;-pPEozO(`vpji^T=O7HC&RF7uAtM@hZs(q<x*<Cpxx~IlvPfm~M86B3r3(exO >zp(FCZ=T+ihUs68)R=()l5tE0GJHkl|T$YxecKJVk7A?N?$++T=r~g3nUuG`fpY#Ih >z_MYMU?~gf4eE(Y&xXQlC=1pLk@4x+;v%>dZdC^(Pb70k9-<O5MPR)G@r^YpBvpIEj >z+!9Vb$GoWJm}kcc*kAek?a$}Lzu3mYrJvxNi;W;VLAGKwdqFmX?1rzg9b`YqhL9a0 >zTSE4PYzo<x)ocsd7qT&AXUNu&y&;=Jc86>a*&nh&WQWKWkv&??CXroQ%{GyJA{#|^ >zifk3xE3#Q+x5##p{URGic8qKp*)y_fWY<=+Z7%kWY#iA+vUOzd$mWsVBil#zk2C=3 >z0MY`a2UgPrqzhKl2BZ&G(+H#!NGp(DAk9F!fwTkZ2htFvBS=e-o>)y&kgixwTadn3 >zO=FPGAgw`qgER-}4$>Z^KS+a+4k0Z<dW19y>5|p73F(v7Gz#gI)wBxf71AuETS&W* >zejyD*I)=0i=^4^Aq-$2wHl%M>(>SDaR?|A9cS!S)?jh|%`iC?S|L-7w1;@!Wv5c5# >Umd4ixD}v$DczJoSJQ&XW4V<53a{vGU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo >new file mode 100644 >index 0000000000000000000000000000000000000000..1b608b3e57479c8ba49789483e4f19e037058d9a >GIT binary patch >literal 296 >zcmWHE%1kq2zyPd35fBCeHXsJEg&KgwMAp6?`?S1|TuRc}BE8RWNB#f*{}~vWm|0l< >z|3BlwzyKs|7(i?v5P9wd1IPdWS1&N|`S^w~1OTzFfw8dxhy<Di10f{1;RjR`(AxhX >gw}5Dndq6bEO(1EIyFhe3P>fQyaoGUfYG=#^0M%qrm;e9( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix >new file mode 100644 >index 0000000000000000000000000000000000000000..adf28236a2feb68f177f5b002ea068db59eea997 >GIT binary patch >literal 353 >zcmWHE%1kq2zyK^j5fBCeZXgD+1sZ_Fyk%As=I>^2SkNXjVd1Qo4W~PKCY%?)FLS>C >z>6#0TQZm1OlnVTQ5y8O32!zZ)$jJ2n|Fm}u4FCVHUckum|Nq<x3>;uKkB@H%gRct^ >z2Lo|<2+(i{2qEkw9-vCFlYT(;{0D+K7M=|t8stO}4RR)k200Z(gPaSZK~4tIAZLSV >apwmG#$oU`|<OL87@&+aT-~xKgoC^R+MSyDn > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince >new file mode 100644 >index 0000000000000000000000000000000000000000..7306caeffa0ba1d1b8a9b37d9459ebaabaecdb20 >GIT binary patch >literal 1455 >zcmd7RO-K}B0Eh9}G9kf(2f@;`??uyfSF@rFmRggd%}IAHSF^X$7C+M0k8JJ33JRf1 >zNVR$hA?gr8Sea1}k`dG;QY`2Y_IB|QR3l!b!tH$~sK7&XYloTNFuThh_W1`wb%*ne >zIj?yAgp*gfKDkdiqc2yRTD~tz-8Q<|@x{A%>a&^pVa%I0Hfk;z8T6*#y=P`zyW(Bi >zbJ<*W_Lz5h@U>b|KcH3?JW#84^r+Rzeae~Drkt}wA~PYVGADXP*2nc~&2Xp49uJ6| >z{z~B*Tqkn7HVgNq6yXV1sJzy%BENW(T3h-~Y$=JDTWgBEzTA*m<a2sUs{GQ7#);j9 >zxw7==q$o>El7Zk05%@MO%L{Iaz0ansirJegbYtAAoVcK>&J9`nh8tCNO|P}Tf0q*e >z`|?0{gE*KIm50K9QIi;vwZ*xj_ESiPok=46vQXB=Pm8+S>9T(EjcAB&v>IPcsUsa} >zR@1<^Y7Wj?^5T$cDNt5xbFXSkermOsbgK5*_p)O{RCG*?$Vf^=M24@+&Y6%n-hW=6 >zcv~n=c7^4shv}lLdb>Q`X9&mqdB2Xh1#^$z@BYhOEcV!K82ain;$pGqPaF$lu}61| >z#6RzM`U8e(>PwMNpJf642OEaNVPgdTp2i;iNjr_1pI^~G7mL+(XP8JTJSG<;8C#tV >zk`9s&k`R&+k`j^=k`$5^k`|H|k{FU1lA5i~4N1;cXNRPR<cB1PWQe4Q<cK7RWQnAS >z<cTDTWQwGU<ccJVWQ(MW<clPXWQ?S2t8+$@MzTiIM)F1yM>0oJM{-A!N3uuKNAgD| >zfXo1yf~}qdG6`Ef3uGF$dLGC`keMJ;LFR%?2AK^q9b`Vpgpe5_Q?k`_LMCOaXN645 >vR?iEW7&0?tYRKG>$sw~trf2-8+e^@6EYPFO_UF6uT<&bY$K&$2+zCGbaw3PQ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre >new file mode 100644 >index 0000000000000000000000000000000000000000..b612ac23562126db6b0aa3ce26dea6760c15be24 >GIT binary patch >literal 662 >zcmcK1J4nMo9Dwm_Z9%H&B7%sIb{BjVL_{)nP`pYead0ZQxd`HtI_TokNfZ}XJ2^?~ >zbX(CWb7`xBn?(>`rL~;@FVsm89K3M(jzGfYckbF|W?KCiQF+2-#AUMX&C2a4e~>Hm >zXH=oRZi>%ZU)6F>dG1D+>w~&7)b=aIZKv9r(zVm3b6dUCckYVwdOYmEMR%Qdlhq%6 >z^QMtb=|<_^X~v%X=J|kW)f4*j@WhN<=k@5$iy1ph`{Of@Ccd|?6Fm<mwc+ViFJe4v >ztqO;Jxw^t(Yt5EY)|N~tVr}t4b+cBT_0qDdCMIWPCgo?ohx-SFM&~8jiv@!M5>!wq >zFccgLP*6dlKm`>n3K#{A0!P8408$VskQ7V`Xi!0=zy=ju3NQtk?E_80rhrq>Dex40 >W$^lRgfqL?-e>sTQf*j0ZGWG?L1Q>+? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho >new file mode 100644 >index 0000000000000000000000000000000000000000..2423fc19a8a0c15451876f0f8f7c469112c2d078 >GIT binary patch >literal 602 >zcmb`@y-UMD7=ZD#eo*Sy;-G`pk5%EY9YjP<T~!bQf`5P_IJxLn?b=-g9UQIGjjcFj >z5Q>{1I+Uh%5gY<4_z_y=e4jW9g5ZVAF9a^+ecaWJwF&3PYLPc=R!TO{ox5_|Kg~T9 >zdsd!`pG&6nJg3iUIaQfF*OefltNo8&wY0AM=BTb62I|f~(RFuLy&QCTuWg&^&D+xN >z-D4(Pp3-6YS~Ze&uTf|>&7fC*<nw0W@<<Qv+?&+#yf>8g&G6o~9_hF>S!=BmkNtAR >zt-a`T9BXf`Vy)JeJtwiS=sM#nEjuH>&2s-RYWRIbzGy8YBV$L(=*aj;0whDEq(E{+ >zN)jXsk_O3xBtkMFsgPVqG9+81q(kyWN<t(fl9JyiCz2G&iljyIB8f38Xa6B{a$1tl >GWRhRy+5kfU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico >new file mode 100644 >index 0000000000000000000000000000000000000000..d4525a68a60351f19a16e0b6f4f1422b71ff3fcf >GIT binary patch >literal 255 >zcmWHE%1kq2zyK^j5fBCe7+atL$T|JZ=)fiAF9nwp-d<p2W@7yR{}4L^!~g%s4=}L& >z|9|xYBL|q|@$n5|a0~|G03Z$z0qSG~;}F93u>uu>>=gI`BtYOl5L7*zx)Vf$><7^x >SH-KrNI~d4u2p7<GCR_kVPD_#i > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas >new file mode 100644 >index 0000000000000000000000000000000000000000..4d84eed4e235bdcfb3ed8ea457e1bef3717db3bd >GIT binary patch >literal 1911 >zcmdtiYiNye0LSs?oHIMK8Ji)-nEPcee>=m*Hvf&?%;m6QX(S4h7%?xXA+fwL7D-4X >zNt*xWvQ3tM(uB!5FHWOK$t9A7+%J#+_YrTr@X8y{)AM{zr?c9N|MyqCpln&P^~V)q >zzTx58U>-hq+hShTA}{w)=@b9a&5v4+S!=agw6UdbV}`8HvI6Hy%JumHDgFy-C*(!X >z@<2m;n{Ie~$lv&_R5x8u^tbj|En8PT3xs@gb*Q37eha3{?=_#5-FjPF>+UPp2ETU8 >z0_B;TtiuwMRENx2GTe$*-l)sc`><U_e2<eIuLM=(gLg9O)GN`cxlKk_1w`i~O|r|1 >zdJ(fDq+|2<iLT2Ublk8C(Jl9&?jBpCdJNg5d%Rw+dWJ95J%jU9ucwoBd|j&QeWz6R >z*&DAC&SuKK<zH35>O`4X=@I?cxaEMfFJj=#$8u1w2V!ulr3ZhyB8I&AsE6J=CWd{u >zriWi`RwLR@>ZIdG)yRe_J!;!lHTu9xJ!Z*LCARF8W3zKq^5Qb-%V-lRvQUnTnkvRe >zH_8d&A(d)%k*T*LMB4KtJ@NDlG3iFMPT$okGETMY%$2oba#c{vqMIsf#W|hrJENxL >z@7Gh~cB`DR^)lyexyp;(C-d6fBL8)TEV#TzObeFC!bVF?ubU`mw0Ol#|294AaINxZ >z-_x@<?@@D--piuWb*eb(uAD#NshEHEr7oGWLsi<g?Q*+3t}yqn+v7HOhwy)Td%d>Z >zyxp?Q`;rxA+fB-fu<h&G>crb+-l2di=GQl&fE6=+MzK|7o>5|)c~Z>dGe^-}F4u31 >z|9+4w%#WRe{PE{sng77H%XTJwMGiJ{xRC>n9CGBKBZnP1@W`P@4nA`DkpPeg98CyF >z3`h`26pkhgBo0Rt2oec8q40rNxJ)oWG)Oo|JV-!DL`X<TOpYcfBq}5<BrYT{Br+s4 >zBsL^CBswHKBt9fSBtj%aBt}OQBod{g2@{DE2^5JG2^EPI2^NVK2^WbM2^fhO2^opm >z(FBb|jf9QFjRcNFj)acHjs%ZHkA#oJj|>1Z0>}^`V}J|-G788rAmiX@1_BugWGIla >zKn4RD4P-cw@jwOy84+YikTF391sN4bGc3rsIGTY$Mg|!gWNeVZK}H7|9%Ouw0YXLy >k86sqikU>I52^l6wGfv1rVWm0p)_=27k?Cf;GJTOh03OvyAOHXW > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River >new file mode 100644 >index 0000000000000000000000000000000000000000..70dcd2d8014a3dccb9c3cdcd83158af262afe6a2 >GIT binary patch >literal 2131 >zcmds%YfRN;9LIl$Y$A!0Ng)z=DG7xm2Sbl0WeH=Dh?gT5A@hPEmhnr0M2#LdCiWuT >zq)b=CXjE&}lvswf$gXQ$#*pS}71LU-xlvE$3rfc6`8;oX(aW~JXV3Hb@9g~FozEw- >zzV3k>`Nytx-*8x)J3LP{?&|36G$-EvQ$HOk-}w2#F>`MA6+O3Uf{mTgZzd$Xp>fh} >z;_Op;-Gz2D@tadN{%oU}bmoYi{K^qYINo5df1*LAG?&>M>dItlW!NSbh2_S@$@Zp< >zWJ#K}NT<b)N^;CJP5wQ}Ouu+lQwIJrH^2YArgnd4(mLPM8BLRA=KfBdweB~Wz5QK# >zOYWfDT71IJNqke%=kB-ZV*@55Zi~$r>M?UK7ub1yPn*oa&6?Hms0sGu>-?5VlifZ? >zL$ytkvny5?6jsRXYc6YU`Vv`~^Mx)NpCaMuKilx7F<E@|GrQ!I3v$P|ui2$1M@`;4 >zhwPn)hs<5is$Eup*4*9tq~25df>~Zuule&^O+o%@E%@UtDa_ho3kQ!&QGBT_>e(yB >z!y$X`bI+I+=T~aUzGk!XbhegOSD95ur|9aXd1g)H6<wQ>W+Lm(Yh*NF%5r<P?59+z >zNd3xId@NEqcG|A*`a!COj@jzgkL13-J$6IQOLBilwcS|qf!Wm7tedmC%$C|Jt%*Ni >zwif2;*5PfYHa$&izbrO&;{#gvdZyWa=|_F=XpubBAGJH0=E=h+FWUODc+tZj+DCGK >zm7Vo3+FgkQ(oouF8^(rBQ@Bf;hWgF!qyxIUuiG?_Y|}j*?Pl-S#k#Mh(LC0hsVy7I >z&Ev-=X-ps{aLqXG|MU}$zFZ*^jh;Cb7#EGc`n<&Y=ZXGKSWyy@<@xTcb*J2&RT1}> >z776$(^6x4fbU*YejPQnA)NSW4ZMQ+xfan2H1fmH<6;G!N@1hJu8;CldP9KOu5RD)z >zL3DyB#n1|(7DF$HVhqh7sxfqfD96waq8>v(Pp2S6Lx_qH9U)3Ww1lY1&=aC4LsN*V >z3|%40GPLz{>O%DObP7W>hNukD8KN{qYlzwqy&;M-G>53p&>f;YLwkt&4E;S_0vH*9 >zq=1nFND?4ffTRJE2S_3ynSi7Mk_$*OAldMA>0so;(<OwF5l@#AMou6}fn)`e7D!$o >ziGgGWk{U>EAjyGb$J3<;k{?f(AV!8fU5Xevf+UHNB}keWd4eR0kts;3Ai07h3z98J >zx*+-TbP0oG%+sX|k~2@2G)UGUX=CIKk~l`@AgN>I4w5`Z_8{qF<j>P35RySpmqJJm >xJzWwZS%jn!l1E4)A(@1v5|T^#AM`TLWpts-X=cfSU`{YQvm_J>hJx8~e*<d@HIe`T > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet >new file mode 100644 >index 0000000000000000000000000000000000000000..9f50f36ef45a0210a0dbcfda1ff734fab79f8153 >GIT binary patch >literal 1930 >zcmdUvT};(=9EZOLT^buTGYXNQ%tZ8XI0r+ICTVdP14Vo}5(t_piulIYw<Gw1KR2c~ >z8W%3J)i51;qfQ<3Z7wqHWotUeaIURlTFaap^JlfmlyUk!|GH@FLcR3E{^wx_&bj(N >zPjp`0(p>r9o^kK+um<<=d$MsazwcTt_j9H%>>a)F#?ZQQd9gBVlZ(Uh(!^Bza#pIO >zjF_Oq2KPy7!Z1z!BgG8A`B2k3ADCCZ`dQOY{$w%^e5tR-o|o6QAJ7qV@5$@Szpx|o >zy5x<L{dQFHDajnO-DdW8nykddHmkecjJZ>2$98;V{9TJQyLF=pv_~|jsnP`ZjM7kT >zOmf!^)^SA@^5*P2nwL3A#^+wv34_ukJp8r|-|Cl%55KpQzP%xD{dm+)KHg{Y&wps& >zZs|5tK2<xl{(^a@dAGh>cF+{m)N3TC*%U@*Y2lw|q$qopE$aG2ij&H0ar<T|=?U3s >zpM7kmU!S3+TN=%b(?Kn(t}-+CzM!)v=bPCZ{?a*V874aSx<>narabSgmj9M673tS( >z#Wy0A{ip4`wqK;Gd!Mat{#xdDY_bb#4$J$k)plX&Mf1VVMqQNMW)|00X-(1&v!p0r >zm-H+%wV4@Od!@wG4f1K-F~3=U>sMW|w^&wQjoVeRv9kL3O<P}{B-(PxuF1PAYwHi$ >zb;+HwzHFym-``_m;WmwRUo{OWJG7zWq-pG3rkh&#n9V<w=$57pX6sqMHZ6G1Y}@yo >zN`fz8z~lZ5eC+>x<Ttvra*M~myWkrbk01G5o{h)Po$w{`DntHxCp#FFf=DDP1#{fv >zSm^lQMW5i1d;k4l+>L{V95v*y`7_7OIB>|3GY%bc?2Lnl96jUkJ-XwE2mp})A_7DP >zh!7Ad7-B%=U<d+{gdqw<7KSh$oiq?}JUV$G0zo8#hy;-dA{0a_h*%K07=l40V~7Tk >zjUgOFI)->2oqP-dArdk~gvbaH5+Wr;Oo*HiK_QYtM1{x-5!R!VmLaZ3Coe-_k4|ES >z$Pk$!LPMm6hz*e&A~-~Hi0Ba6A;Nof(nG}e=;UVvz@v)*BLt8bFoFPy0wWBNI4}YM >zi3B7RkXS&10f`1A93EXfAOZ2{A_57CM;8-FP#{rZgar~8MqnV3VT1+}8%A&-(P4zg >zql*tDKptI$AR+STVgv~iBubDlLE;1n6eLpcsSj16E7*8fFn{T|KyD!DFAaqPp+GS4 >EZ|0Bbod5s; > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Recife b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Recife >new file mode 100644 >index 0000000000000000000000000000000000000000..fe55739dd36e6dfea5f340f2d099c30424ba4e62 >GIT binary patch >literal 742 >zcmb`^KP&@L0LSrb{fU&6#bCgrF-S;W94XO=k%U3g0fR|MCkBH>%3zWhNm$+}2D!0J >z7FrV#B5C>$ldur#(vs(W&uAg>n(L=&a?SPoi%!SpdaNI(!hFNU=`<Ig>sHO%*8Y4V >zQ9oKpd=9I_=U#b~TN3I11DSp-$xPF&lR2Cc*>a=I?dC*2yCVxxTfA;-=dEf+6pv@+ >zd$2{h6J63xo`_Q5(kbn^s{B+fKQ>lW^Vz0sS-w%Ns?QPjxoTUB$@bcm3QaaRp}R%V >z5q@zxu96~LJazgL>tY~(F9#m#)nH0Hk%gd&YppH6?^iFs*7*_3()zyOtJM1X!m1e? >zk6PWb$6U7gqnzj;;<(?pm|xVINJuD86AKB3L_@-Pns`V+PZJRdiNr*LB2kgBNL(Z^ >z5*Z2YX<{S6Jxz2ZJQAPBX8>dbWC&yoWDsN&WEf8~4l<CZ83`E*84DTA(~O1;hm41D >P^DO^5U?5_~9I^vnF4rb2 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Regina b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Regina >new file mode 100644 >index 0000000000000000000000000000000000000000..5fe8d6b618e34c4c87a7eac43f7a27af41161d02 >GIT binary patch >literal 994 >zcmc)I%S%*Y9Eb7Wl%-5VyqJMViy|}(1r3t+8kQv%jsz`aOcZA2p+6uFEegTK3$7jA >zL`0A)FT<2XUdjsyW0`kP-ZCvYM2iUO_&%@gbmPi1yytT`%rJ}R8@(TIz9RdsljaSF >ztIQmpb6s<L^0)n5qQ6^rrZU~0rW(Ju<c8OGz0~hlm%U{E89(VqywvFuCpEd_z23=o >z-Xu@O-aX9n2OGA%p}SlD@U`~XNa=+C{zA9+A@7?r8lH%a{uy`1wqC`?TO&Gs@t2cs >z$d#$aHubT#MLyN7s_F9!^7-npnvnsSJ^NhEdR;R2Z&1&_eJl%0&-CJpgu68GR4=!> >zu9t}GFYyQN%A;F)^=5^;R$r{w3k%$h$}06WyIeLe6{*di`Ley?tMAiO@?#{e<XGsy >z&+&`{U+;bSL=beWi3GvRu26<~){<qPBlfPiOU~`;s8m;&Q)|vWbM8c?+&puI{@<gA >zDDd0<hJOtLN+30mB1jda3{nRvgjBMcQb;YUDTY)-$|3cTf=ETABvKP8id03)T1{P~ >zFj5&QZ8f!#;z)I*JW?N70I~vP30AWPWD&?JkYyn2Ko)|m1X&8Q7GyEVYLMk1>p>QT >XtO!|>)vO6w6tXHj`elX9)XKuUTnF}q > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute >new file mode 100644 >index 0000000000000000000000000000000000000000..884b1f6470c78c482f0daa280b85e01312c764da >GIT binary patch >literal 1930 >zcmdUvZ%ov69LGP0E{%;^DTPQ-S`vC3cNlt_^p9f<5=lJ?gv=B}EaOw^32O9VWBRCk >z;540%(os*UnPZu)N%nthHODB|Rxz#Rnj7oepDh-Q>-+lE1Gb*n!`|$7uiJ6=?DKjh >z*S0-gD*xIw{u3V7;UC^-n}7LgtlR!5S-yVs&Yc%$wAIVZ#<<I_j>}C;a^1~Exso$y >zvCf)4F1Z=AH22pWn|*0a^9KL4Ti*Xp^G|(i1;^jhTT|D|ZQaLp&YE9j?v}Ie_Oc<l >zqvj<yFZ(SioZsyVCkCx3bE7L7?zj0@D&2yCgBBjzpvApAEz+ORlCDOJ9+;=G)|8ZP >zo30D18sx53SG25fsVpk}To+HvllbhPT>SEcEE)UEE&b%8-2Kh#ZrRCkD}VO|chCM| >zyZ5NN``XXh{XNg?19c~?qNQCEB|TP|SgDo2y)9M6TV2)A5vk6qbJhL3rDi1N9z6D< >zEx)irYxi{8iqlc8Yi_cK4&A6LmzCS99lz`9yaG$ExuD7Mkkyx+(fS|rr6K=I*YL4O >z<HTvVw(oms8b0irdp?p!26nl1Ew9R>z0GcY?FaVQzE0gx+-DnGo3tfsuWhO-*G(gv >zt+lW~TfeBWwrL@4dn0UHF8`oU9IBQl&!^qi)B<_x<R#Z$pC!8gL-%yq&+<(BD{fo% >zplq+(=eAFbSSsG9sp0e1k+WAj22NS$=w{v3d%$*oU88%tcG$CL!rHa&VSDcIbt)O5 >zj44<9H+9lCC%?bi-%t9UKP$g<`qOivsp<4<FUz&*^gC~cvUrsn{{Eym8kLGfA}JNC >z{o`5bIeE$daLA+o{4njuK|_uja@hQv<7ON<<j5I^4mozl!9$LoargoK@k0cFNB|K5 >zA_GJSh!hMlAaXDSfk?s-1tJSWn1Egyh&TbgJP?5(5<x_Q$OI7zA{9g|h+GW8Ad)de >zgUH4Z4k8^xyntRlhJX+W86rYtga`?d5+Wu<PKcloNg<*_WQ7PD&`Zk@H=vi7A#gx1 >zF+*gC%n+d=QbWXs$PE!3A~{5Ki0lyI1A6Hp;s^BdGXfCMM}QFmNDLT3fJA{221pzj >zfq+B;5(-ExAi;n{0}_saJ|2*O1oRPsge0Jk2_z_xs4&6;i3=kzkjOAX1BneIIFRTt >z!V}QP2NIxwK0=TX1@tk31PKx)NSGjTf&>Z@Dfqt+Ri-c4B44m@?ZQZDBpR-b#Uimt >GH1jVLtLuRP > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco >new file mode 100644 >index 0000000000000000000000000000000000000000..b612ac23562126db6b0aa3ce26dea6760c15be24 >GIT binary patch >literal 662 >zcmcK1J4nMo9Dwm_Z9%H&B7%sIb{BjVL_{)nP`pYead0ZQxd`HtI_TokNfZ}XJ2^?~ >zbX(CWb7`xBn?(>`rL~;@FVsm89K3M(jzGfYckbF|W?KCiQF+2-#AUMX&C2a4e~>Hm >zXH=oRZi>%ZU)6F>dG1D+>w~&7)b=aIZKv9r(zVm3b6dUCckYVwdOYmEMR%Qdlhq%6 >z^QMtb=|<_^X~v%X=J|kW)f4*j@WhN<=k@5$iy1ph`{Of@Ccd|?6Fm<mwc+ViFJe4v >ztqO;Jxw^t(Yt5EY)|N~tVr}t4b+cBT_0qDdCMIWPCgo?ohx-SFM&~8jiv@!M5>!wq >zFccgLP*6dlKm`>n3K#{A0!P8408$VskQ7V`Xi!0=zy=ju3NQtk?E_80rhrq>Dex40 >W$^lRgfqL?-e>sTQf*j0ZGWG?L1Q>+? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario >new file mode 100644 >index 0000000000000000000000000000000000000000..8c58f8c23eb0d66d80714a9789b5c20abf043ca2 >GIT binary patch >literal 1109 >zcmc)IKWLLd9Eb5YZKE+13@9if60xNuA{=dF#6R_w3{^2p4Je%yL=XhU!3v_$#YqTA >z5QLV-c2zuwYH6cAjWyb#1X2;fA)vS^A~D3OJ%7)MgE;8s8!n$C(@VZjX7I%EZtst0 >znf$`x>662K^(FZlyOvY;&JXza*FD#h8*={S!f7?N=7O1;7}wLyyMFQdOZDK@Tl4T- >zSkFwa_03>TKN=bFAMYrs(#48-vc92bkF@!-OL0}+lQiYp9rf&T-k(d~)N>!MnEA9- >z^ZLE1#u9oVb<EUvg;agCVLk^>sz!IjZ@e4T%~dJWELYW+`jEd^-KxKq66Ra+p!$Am >zz+W0pD0{WnUp~HHhdNFbHsvRDM<ie9On%axAI}!LHm+1%mBWRYXZ@JoUWnJKYV(al >z(PZPP-Zm50{X;8s|LbgY@8X!=S3DZcT5AI>t^fE5w*CCHV5_?atu0kN&waO9TQ*+E >z+832TyR~m>fe3f6{Xjb7rQ~c;y>fcw{Ju%%?<?*8wNg_qJo4i9%<yfEtcEOytcNV< >zlogRBow6pfD6%TDEV3@LFtReTG_p3bII=pjyi?Xk3UEpVNC`*{PALMZ!YO4Sbs&Wx >zl{lpoq!y$Yr&NQK<CJ=kf{==kl8~B^qR>^vMats8r7ol}q%x#5q&BA%hg9d3@{szR >lQXo<xQX*0#QY2EPQ_4i@L<+^Myqfp_GY#*Qc>8+7KLGQ$?e72p > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel >new file mode 100644 >index 0000000000000000000000000000000000000000..29c83e71ffa6b071c52b2360295bf55009c09b76 >GIT binary patch >literal 2356 >zcmdtiZ%oxy9LMnsp(Ki)RFwE*C#4t&SN@A){}j7|+(5aKn2{NO24#>CO3@7+TWihn >zMJMGdIyrm5S`o9z{xNdPtu<C*E6m22DKLy8){4q;JMUi)d(^Ym@9vz}-QDi)?t{<U >zx2w7`&GnCGuKk3=(_s(qBU|kCTJNtdT}_2`-P6rey_My4??x-vnXu`p&nAwv46gd6 >zZt%qWb>Bpnx`x`{p1S1UD&OaAm&;|zawQ={Mm_mzZ1FZV9-pMfr_<F$=t4Cy7@@9? >zPN^Syep8d@2Gx)47u5WbZnNORfC}$#Hw)kER*Smc)apdLy5U*Ti<|1zlIs0>Y3U9X >zk>}IP)~!{`6S8#V%3`^3UZjo+&XlO>3=@56xx@@EGqE54E-QLw%uTOe6y3O5-+bsJ >zSy>XUSJiy0;xd2Ix8#4QZjJa-$0v5G_}NL55Z0m+hCern6MNO_z8;fw-Y?0W$Bg^* >z9$Djm+@u`aD5+IPby|I#q<b24M)6$9j4#nyY2&gsG+SrK%u(56QF`5<V`}}mYdYuR >zr)tAnk><7!URSrb{bBBS@rb&!_B(S|YnN;+>@%CnpOf4*#%#{rCwDJ8Y&>y=;+c6x >z=Y^z7-q0bPe|d>)ed)9*__{{C&Bx6>y#-RZ`+zCxaLcw0rDl7hlH!;g<J&PUzH70j >zB=ajNxw2mGT=BEo`ALi}ojtF1otoA64Zovyw~pxh`<_>2<!AK+olR<wci24m%yHS9 >z+;1MLIw0lYCryQ?R4OK0O;vo3R1H*`>d;uJeq)QN84bw89TobKFJjcbMvs29dsfw! >zB<Q-f5%pNse7(Q+tg4Tg)D4BFR6}5%Y0U1I#^I~xVB|?T*f(IBW?JQm&TjMMP^C2c >z+s#vFwury1-aP$6qPT*BgMzOM4w+-G|IRBAI9lLx1p+UND<lwTYjIuA`=ABRt(<#l >zf!F8q7W-U9oLqbEwWr8ucVeHQzi;2aSlEp76@E1kU}?zOki{XZLzaiE4_P3xLPxtq >zWR1uokyRqgMAnHc6j>><RAjA=cCpB69qn?F^&$&KR*Wo}zr&i5MI)<5mW`|%SvazC >zWa-G-k;NmcN0yJQA1MG*0i*<uwgyNMkSZW$K<a=L0;vR23ZxcDF_3B?<v{9z6vWY1 >z1SyH5tqD>Tq$)^Rkh&m+K`Mik2B{5F9Hcr(d64=b1wtx>l*rN62q_X$C8SJ9osdEy >zl|o8|)CwsUQZ1xhNWGAPAr(VP=4fk%6wT3A4JjK^H>7Y#<&e@LwL^-BR1Ya1Qa_}C >zj<$kG2_0<>ks><UDk5b>>WCB)sU%WLq?SlAk!m94MCyqY6saguQb$`;q^ORzsz_NK >zZC#PVB9%o-i_{h=E>c~jyhweK0wWbhO6+KBj1<|?Rv9U?qpdSiXr$6esgYVE#YU=) >d|NnA_*{o;VtS5QX-D&QWByVb}JJp>M_7|antVjR= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem >new file mode 100644 >index 0000000000000000000000000000000000000000..d776a43877dc872da5bc370cb2b186f7b0890b47 >GIT binary patch >literal 632 >zcmb`^Pbfq|9Ki8eyR@x;7Z(RCuGC~5Bx!Kj14_M8PEMp;xRA@@x_2oKjyTP6R}SyC >zDF-DE+wR(n+ZM{7ZI{OH`?x8k%xm6vdi7p2pXV*CEDfn2BO*_jjJQnJE!%S2JKaiV >z+UFlLAG0?5G-=LCyE;E|Zt|6=DRe&gh3v8}*85HAprY@J$ENH}=;!@b|D|zNzxwOu >zt!=<o=SEF6cdcu&vR^xCvh_-bc~7Tp*Ttdf-n_RxM^k=0QMA1~8>X-M)+QI%Ov*W@ >z8bZHZ;jnX;8Ks=Nxe7&`%lRtGT1BR3JT<5jGKb{^U&H&uxvSsr$QB&urx*kk2Z{y7 >zgJKd?Tqrg{#fM@<aiUmJyeMWAH;Ns_k75{994VGT#gk%6ab^41QhX`K6laPx#hYSI >RQ}T`fbdQb6pBPWXJ^@0N3Q+(6 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago >new file mode 100644 >index 0000000000000000000000000000000000000000..ab766a41bc06db2956154da6e2fb0dfc3e9c1b2a >GIT binary patch >literal 2538 >zcmd_rZ%kHI0LStB00M!esHvbPS&|0A;g13acq9-=!KZ}$hlb<`%m6`P1SR<*skKOE >zBWFdn*330MU<EdqXRV<Y6|4wdI$JYat;Nhr%=C7?XYr~Ry>070yZ3YV>|x{0?|TY1 >zl$Rzr|F{CpH{4vWo16D(&F0Z6vR51^`p(<Y^lkq^XNOjs>-#(F(`46jXYkm%D*f)f >zMDKekZ_4+5A06xtAJN?x4|scS6zSt9BfJB%E9AiT?+3p)*Q&pqby^K46zbu+HhE(x >zRo-m-L%9Q=YNz^~^3-~@kIYrRh4I=iB1%n2UoHKe5ET&ID+4Z!s=%95<t-<MRM7d~ >zWbmP%#l*f58PYN+ZhiH*oK)5&CO<Q*Lv!|tDW%<d>Vi5kZN+|lTWFh_9@(g;U*4%^ >z`ft)RhaOU4mzL@9&SW*~^CCHWZ@8LsG+o|a^{1NK8X+Tg`HDL#edN59>*CJ*i}J3p >z^J0Foqvu~cAtHYn(|4aeC>C7(NH6@bPu(-}mX3O(Lq&JD=taAqRx$0{bZp5ZN;L10 >zaT!@EzPMZ_q>YF~xl%3;&J;^RdSsISuu66&$>dK0MamCRdg<XG#l5FPbn0^hBJI$q >zPTzJ!ENdCka?QtTdD$_Yk?@YXFXttlIrRmV71t%Ru2iY)(0wv{)JNo8u9LaFmE!)P >zb#i5oqgHh;m3jREBHz1PuYTo-@@AaX4>Y}~9*p{3t|_Wk1;J<J+N4Wj?a`m~`WdIh >z`qt0%hO39g#!97&MxGa&R=4TR-4){D*qyq#-7B`t+$&3(x2uw|8o9MNUu`{8C`+YK >zr9DZqEMkf(dpS&&yT7V!_1EQN7rs*4x6IIwpSmI{<TYJ+XjoK5e64r1bc<@IPuG;~ >z7d78>=-Qk{QG2>q*2lH0`nO+`4WSLH;n`;S#N~~uvAje!4W+3kb2H^ropaT$g^_ZX >z>$)BvkFUqiXZ+*q<2%9J{sI4ykH72oec(9u>F2t~l@sW?C$%$?r^h^p2R)O=pM1Y6 >zufSPj?nPp;xf9JjzC@45OwC*#Pr<+M^Pu^m-RGG78~y{=E#EVzAK5FiS!B1!c9H!e >z8%B1FY#G@zvT0=3$hNI!-^j+1og-Vfn!O{NM|O{F-)i=cGyrV}c%cPcrUyV1kS-u? >zK>C0*0_g<O3ajY_(hQ^<NIQ^zAPqq}g0uwb3DOj#D@a?Az95Z3I)k*vYI=h-$7;HR >zv<K-A(jcTmNQ;mjAx%QMgtQ6i6VfQ8Q%I|<rdLR_kZvLELi&X?4CxrsGNfln(~zzq >zZA1EoG!E$;(mJGfNb`{HA?>r8{vi!SI*7Co=^@fYq>D%!kv<}gL^_GI66qz<OsnZ8 >z(oU=CC(=-)qex4Uo+3>}x{9<F=_}G$q_aqCk=`QBMY?M>?M3=)H4R2OjI<c(G16qD >z%SfA%J|m4rI&C$rMtW^E%|^OyHSI?FZ8Z%?I*zm)={eGLr0YoAk-j61M>>zR9_hW+ >zG#}}{)wCb!ztx-p$T?s&X902^AZG${E+A(Eay}qugw>?O`9B^ML8;~lNl!G-g!JgV >T<e2!FC9&~|(Rqviehc~wJPiO4 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo >new file mode 100644 >index 0000000000000000000000000000000000000000..cc2cbf2b1209b83085dd63f3df98e8f5c4fc3991 >GIT binary patch >literal 491 >zcmWHE%1kq2zyNGO5fBCeK_CXPr5k|6uKP|2zc{=v{91n4;s5fF7Z{wYPcXJ$zQFja >z-h;W|Ljdz#77x~dO98C=J3ZJ9wgj***mHtYU|N9X?>!H!G#@4~GBYu=z#%I$>;M1z >zDi|1mWC8=r|NqAiFmnF?zjFfv@BjY?b}$NpL>R<<d_x$5U4VqE3lIl~Fz6bX7#lD+ >z0$Io)gs@+Pfa<}1`2p4V9|$trWjR1J$ZsGT<UcSC@*@a<{0Ra;zk(=`f59}+&mbD) >uZ!it?JBSAPA4~(o07Qer0ZaqK0z`wt14M(u1Vn?vg@Kj<!vzc}6D|P9{f)H% > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo >new file mode 100644 >index 0000000000000000000000000000000000000000..308a545ce5931939fb6353fa4273aedf00b49372 >GIT binary patch >literal 2016 >zcmc)KZ%h<)9LMp~k|maZ+FDstzedK$6Tf#ydYX~S5J(OpZ-!JxA|U<=Wn^esN0zy< >z$*hcxw)UG3n&p<iwwmasBWEFNjdb>p=}EHn&s^C|uhY7I?_UplP|rMe_qws;&x7y# >z6R&A%2nYW4xXyitCy#db<o%5a_wvTOEg$rZD;w(hbG|unp+FBNTV*i%o(`T%>#2#~ >z+EWLX$>}S%X!6aZoH^aCL-B}QtQoDpk6JF5dROY@v6D@zDyXTxk0qUb!lw76%$1+B >z^lHZzGpT=vPHy|kOfmObi42&j?M-^;m}4fVdc4g!yI!Wv{>@H1*(bSE$7$}NVUriQ >zpn0!%$UQ&ZWT&qQn_%yUI-}vJ<eM&?x#(@t#3l_*ika{uVk23rr63yDg49PcOQz_o >zfmLSqrB7_M=Vh65W?1KT2F-oPGIn0`Sabi;omyD&t9fAOUphbkgjujHr3-KUMT)A9 >zXwl{4QXE@ii-*pek_p?iWdANHP4Bj4UC+pagD=^|iPuc|!3G<vecDuXm)gp*SLLCt >z^;#u!%)@mhx+HLii5KN*{Ku#)%^9Oh`)`-(k>|B~&sAA=c0g;kC*{#(t$l1&uRMNu >zp<Q0OTb_99E?XNqY@U2&fv%WfOkHD+)};?geaR@TKfcm5-u=BczQ4#cW%X-Qcb%;M >zZm+J{Tr6t``s})zTzP8WJGOc5Xj$LcVK+=XCoRqEY|9^?No!@LZT)7SY>ckejYmE; >zZMRiu+uk2!Q%ZI7i=F1#uW#1pR%|d^_FvTJ7w?c4y1vxF$Pw4}E0Z}{9tdPI!$Tvk >z&t$&%Ja9vKEFPGlVfT!<1LYC_@1x%8KIV@)<$r?Tn8|S5$boy^kt2tW96NIGUU&4! >z;d|ZjBLN^0AR!<zAVDBeAYmYJAc1&YBuFS;7Yh;$5)J=8;UMuK0U;3~At5m#L3v$N >zNLXGM7ZRA)MTUgtb+IAAA<-e>A@LyrA`v1XA~7OCB2gk?dR?4Ipk5a#5-Jia5-bue >z5-t)i5-<`m5;77q5;PJu61LaHjRfv>kt3mdUF=BkNc2efNc_kEAR~Yb0Wt>2ARwcF >z3<EL_$Uu1ANFYPubz^}HhS!Y-G91WwAOnJo2r?wdm>`3Kj0!R=$haT_<8>p042{=~ >z4Kg@hH#*4hc-{CQ1B8qaGDOH2A%ldB5;9E4I3WY&bt8ogmDi0GGFV<WTF7vD-FP7b >zhKv|8WXPBygNBS6`eAb>rvKAJd&2c_ZD)?Z{(q(}d!C!U!iakf7Y1XYP<|+1XKFAO >J&X4dW`){q=QK$d_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund >new file mode 100644 >index 0000000000000000000000000000000000000000..8e1366ca39a856d17bf16d5eb331e308890c7ce8 >GIT binary patch >literal 1930 >zcmdVaT};(=9LMoL0m+ziUmp+(kP->VBb<YP4;?^6VAMGjcrp}`kO#4ll8m6FW0NuG >z82h%d977gP$DBjzg6ab7IcJMln`2Ik)nuAhb2f9}8vFNq|Gns<t8Usl?3~vh7~|&q >z{seaHZOE|x@mgSh!kgD?=FPJlG9Ueid@)P?&6}2GuKF}8@!sI_r9WtN=(ieu=VOhT >zc~2j@IH(VQ@wUc}pOd)Z5s5$kuB_-*NjUhHJkr!6kM69MmA-%^dJAQhD_fG{lI5|5 >zF_Ii!pviYLHRW28rcN!_$G=*jt4HV5b?T<B>Aj+9o!@BsfpK-$omEfOWyxq6m9;rz >zl3D(aWW^6ic1D|I&j)3FY_G1Lu8|FYw(7=n1@grA73v+T)||18n%kAHdHr#^sUcDG >zJ2%MYqHry!i<K=&KWkyZycC6ht;LByO7X4hQWE-^luTZbCudH|QzK`@H}Q%3d%C4` >z_=G;)+$_&@AJ($xj%s;Ry>4CCqyb;CJ{w)C+gz!-ZPu+7QAJX5X^C#Xn<6_t{6j0J >zB4y{`VyPPaO?CzENOkX|JYPK}H66d`?!1qrwrWD_68fY*XG9w!KF~e!s(Wr6)5iH0 >z-Fu;3UziT)i>E8K>HL1#cO*xfhqlT~jS2d4SC;HA^GZuYw7lY3AqNWY$*YSkX-$vP >z*4tO5ZPBc@efOob-@2@?zds~zOpfWnzR$H|WI*3+Kc&H*payN*wn82VeK0KiKmH1{ >z?Oz)$%eH5Jvdr`Ew?iWSezqday;&g(?|=II0c(vr!@ND#YPXx;m>0h@4_4q`objCV >zNBmdY=A8MKlSa-OIc?;;krQ_`XO5gYa_-2<BWI7CK63s@0!Ri(3P=t}5=a(E8b}^U >zB1k5VCKV(XBpD<dBpoClBq1atBqby#Bq<~-BrPN_Brzm2N0S<oo1;k%$qq>m$qz{o >z$q-2q$q`8s$r4Eu$rDKw$rMQy$<@&$i)8C)(naz`5=JscQbuw{l18#d(nj(|5=Sye >zQb%%kG|3~`JDT*7{E-PjW&oK2WDbx?KxP4%24o(Pi9luonF?eskjX%1!_iC!G9So< >zATxqY2{I?hq#(0`ObaqE$iyHsgG>!FH^}55v*T!{2bmv7GeO7<Ayb6R5i&{0EFsf` >k%#-8)f1)D2X1a1cUNc^~F8|uJtTcDJ+vWGTohMJ^Ul5tY3jhEB > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock >new file mode 100644 >index 0000000000000000000000000000000000000000..7fc669171f88e8e1fb0c1483bb83e746e5f1c779 >GIT binary patch >literal 2453 >zcmdtjeN5F=9LMnkqQH%ZQ;8v<nU)CgtR#>b8FWLuL3o9$5k`URY6U)Y(?UE3#rVT< >zR*YFDf|Ayni4SWwHq<p-TiG0LO>3b&mt~`eO%k}b^FAy8>5u+w>&t$;e%!&IpEvGR >z-Zfd`A2->2!ozi$hxe(9ANJ?zJ^i7o`=tck^V$z;Z>?YNYndW?3oq&3_WkO^wg^2m >z=l6!8>R53#-KR(Ab%;NrJ^EUhPh1;)Mvi^&5##48<irPg!hbwh2Hs2%VrRSzYW0iY >zXD8&O^>Hesdb*xmI<BVVkLl2iVHLU~TZhY&D*WJK=@{9oZn)H=BQBf}ktdsV)O$T5 >z`mJs$Uu_mQw!I*4+EOcS_SVR$E1e>y=m9w`H%Z)*G*8CPE>zRQ9WpLBQN{f_SI2)D >zt`dgA^o&zKs+or`>sx!ys9C-l^0w`V)a(@jIcM!h;`Zz><Q+@j5p!eSmx;+*B>FGv >zB*zAkG<-@YUv`T-2lnZda}6rB>qVV*v`nQp)#;2^7O2d+7MZninwsxiBNvp7s_euE >z<y~2ys)eD+GAI73$oVcp=8jzud8dDtcYoF|7WFywJ^j1I;`X2Py}P!F{Q8geeJ#7x >zl9E1sf6Z1^kp8kRELg1ye;bs})JEYvcR&_JR*9mcZF1?Ad{O-R8+zF%mCDuFsvmlH >zu_~$b>e9|x>fuGjy37}>mM5fY_lmETdpuf~XP;K(-=s*-%&&xJFiNiU4~kX2Bl3~q >z1ER8JNIp8yCaP+V$<<x!#AB|ry1KPhJ)U|*KT+pZHIW^<)>*7-ulRIbVydb;<I&#G >zXyrYar`LY_i(1!NA)h=OC7$x-%BK&Fi2Cw)+0Z^D)@M)14fV&w#+Zw8Q%R@T<R8<% >zoFmFN{JGv7+o3iOoX}fFed@Wc9{v1zk7{gc)?1I~sivx0y=`ZL3J&_~Yf{Md*S|md >z?+pZYcL)&(yxkoXV&1g~v+oi1yIkgS3s-@8mYb)-Jf&{4A|Zn8H}}7<Z;$y!yS`EW >z!d$>yRY*i1vPNW)$SRR#BI`sJimcRXmWr$uS*+Ep7FjN`USz?@imhhJ$eNKwBdbQc >zY+hJ5XBG~uoMY+8+L6U0t4EfPtlw%1fK<S0N`TY=DFRXjjxr#1;3x!A364@AwcscQ >zQVouBAobuV2vQNGBuGuHrYJ~Nkg_0kK?;LZ1}P0v8>Bc$bvVj{)Q6)$NQJDXL`aRS >zrbtMYILd_72`Lm(DWp_Lt&n0N)k4aJ)C(yXQZb}tNX@LKXh_vK%7)a9qi{&&I7)}q >zj-z-;^^o!*^+O7XRM2Wlh}6((iilLvYRZVzk)x1EC6Q7hwM2@ER1+yDQct9yNJXut >zq)1Jzrl?3&t){F<T{#MiRF<Q(NNqWai&U4RyhweK0wWbhN{rOlYKn|h*=ov+)Y)nZ >zjZ_*bHBxJiVk6b&C^u4Xj)Ef<=O{T+bE_#jQgy2-J5qP6DLhhnr1VJbk>VrON6L@X >jUtDkg|1SRy^Iu`1`R|b8nxB@HmXYGh%uLHn%W(V&DI1f# > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka >new file mode 100644 >index 0000000000000000000000000000000000000000..662b8b67e581cab42ae250c672580bf224bd17e8 >GIT binary patch >literal 2350 >zcmciCeN2^A0LSrr5x8)LdP+z{q$4U<UOhm(6=f(!hy=#<CPWs6F{}iIF?=I69l2Fp >zY;!P+j&rQqQqOcNT?<Rs+A<m8*2`R!Zq0J)T5q$F+|KuGwYJLjm*?4eJ`dc#e_wxn >z%aggTf1D`uA1<fYT)tDbn%AjaiE3=l&uwFksm|olauIqX-EsA&3HS3cPFUAeF=gHS >zV0fcXMJ)FQBTJ)|M_vkgUR<oAosnSlf#bsagAPvp=8%f{^0X8CexJJO*dgcUHxCMD >zpwGEwS5Vx#q1~C*vR=g1t#INi{NlFaLT7qffk;TH4bF&85Q$;=!NiO>C-KKcdgl3g >zDrs!4o^`^bk`G7f+xLC1L}#&_z3r4r3Cxsp)_f=C=3kTZmVPW!<G+@^^tXg>azdwh >zUlM8KU+MIVZ6ag%xXwKDg321)r?Zc&RSUYG)AHpSmD8+bZhNlEE8i~fsEt$kz9w0a >z`>QJS+$W2Yrir2p^JVeGFXGORyz;KIpNkTms_%aHn7Ahxr5EnqEADN*s7rUeqZU<v >zq8B#}sImnI^^&qpYROOMWO-J<C_i&jR>W=;6-S2T(#s8^@|6$tvd_9y)#m;Bfw${b >zb;C|wv!_HYFKN~fb|$OZqzdg1xRn3*3?0ZnuL9rRFIOgq#L5rTW!>aCQ9l$TA09s` >z8g^Wfj|>lqRZXMv(ZL?^Sk)!n*t1_fo;9MMXx^!sVzpjf-mF$%-mRN`6{`7khi>s? >zsFni(z2-u!dTLL*e0nrpJkz;CuGKN3HBczqdasCe1vBLO)=|+OKOsA+4~ve_blq7r >zqB_Ta(_IN#bq$}@8?NqF8wcOho4)8!o4a4rTaE@)_o{9B+5RHs4x8c*zupt!iM)YN >zD74Mza)m;@TV3Iy(5pdrlzqq8w_|>7bH(wiJHdX>T2|$E)zq5%khwMHmib+E=I_!< >z^HEx9zRYp+GRNxw_hEU>?_5rwxqPQy<u7wW<}5sM?Ni*+lQ)124jG-*3=i%2_+Wq> >zGeTg9$QY49BBMlxiHs8&sMU-V8LHKc6&WltT4cD$c##1kBSwadj2Rg;GHPVl$heV# >zBO^zKj*J}{yw!}}YKD)D9|-^w0VD)S43HooQ9#0g!~qEe5(y*}NGz--7)Ug%CLBmS >zkboc&K|+GW1PKZf6(lT3T#&#ZkwHR(#0Cit5*@1v4-y|FKuCm;5Fs%_f`mi~2@?`0 >zBv44CkWeA9vYKEa(XyIwA@Q=BfFTh>LWaZ)2^tbLBy33Bkia34Lqdnd&T4{(M9*r% >zhs4in0*FKq2_X_gB#1~9kuV~0L;{IK5(y;|OC*>`G_59_NIb13ph!fmCZtGAk)R?` >zMZ${26$va7StPVbY?0t1(Y2cJBJs7F03#8$nh+x~MuLn)83{8IXC%-_q+O=c;b9Ti >zdm^KwZs6l`jlE75|9`AavXgAGXa85S>uj<AmhHc~{b#|w1ihHFXIAB9=Vr^ys+^qc >IoNVd+1O3HSBLDyZ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns >new file mode 100644 >index 0000000000000000000000000000000000000000..a1d14854af6b82bfe814f2c64aac01bc053d5fcb >GIT binary patch >literal 3664 >zcmeI!YfzL`9LMp+3%4}yh1kVX0ZWmK)@oU%AV*uo4Cz>#89ZrJ2Gyfx8HM9?nNnve >zyG#aDR*(`ArK`qfH+xddQPYm&Mz@U+Ei@N1B)9WD_Qsl~rkUQg%=&p))Ny?A|Ne5X >zEu5X^`qL{$f5MwrtA6v`{{j8W%I*2xo?q3}QRXXotbD_sMHOow4!qzFdtO}8-}};% >z4$mt4xc6nN(euj8GXt+?Z1Pl&{UuN}_(jiaXYUKF?y|(Q`q%ovn&50t^%v!V*S9Th >zsHravyisj6)V@;YeRJu=hPnqI@V+%Ssp0L}`QEkJu?_1cW_W$W4mPY$NbqhrBgV6_ >z$N0d;wgaAbS_cQ}cW?9f%d&6tZ;z~e_wAavO}<q3dkb4D-+!i$`-2%fDnDG%=Kg4O >zUFGH*d-*=@zoOC^cf|Ker#F+f4BYM8^39V;4X$;*or6NfJ7+aHyB^L^pH1#8cHf+! >z_6+?_d@iDuiuqXVO>9wn_g9I1y`tp4ogX=YMq7SSHCHtH^W>M0<cP1z-16(fRPjwo >zy!>`j9}&F1Lw=XkCYrM1)c3u6In4>}s`>B{rzJ9=T6XMq4mA1I!P<4s51T90kMH_L >zYfZg8R9+ztFE5ur-M?5IDJqqr8!XY5Qy`CCK2iKUB2ykq%6ES0kto}vGo1Eg6V&nM >z1gAp{QNKFT&Iw<X3cuRoxSrmxA|7gRIxX0$Iv4L3U1l}Qu2Z*)$Z=a_R7$mo9=Jxv >z^jt1tUCU(bp*zHBUlq%4dzU)hH%*hLuP<_XRNbz6K6{nZ>yfFd_ri3iPhpzsJENb| >zZ&F`%hWlsd%%r0#?)<)@zy5EDk2osg54XtyUn_Cej?d-U?`;t0)UKE3zOYgZoVPu6 >zUTMB{{`A_=pj(PR8$9ZX(2&Wqf(iZRg%U3qA51*)xIHv>aByg&ZC}t58NAS+XAj#o >z$QoYewv+3+S|dv0?UcvAw^HX^6iU1E6DvI{E;Mr5YHL(Nd+4IHrPjrffslJZRnXn! >z4~;(lXmHHtiqIwd<_0gVskg^&%n4q$yxhM0xzymeqEh>cB~z^NIR*9vE5*tfk!fdU >z^tLjOEC^){PY!17nh~1Ry=QPz-6f&P2Y(7)xl-DmJw2@KMPuwKYrBgauUk%C(JHRG >zG+s`dw?kY#phM<PuM@e)8)e?86(TR#uH-qjj{Gp7W}JA!xptLbUDr6z@h+)Q*ZZ$= >zW?GBY4P~R9S=r_C#)tAm{_s*+Fvl&d?gjFutax$L51DdKLWh{MEm0OmHj2XP7<o(6 >zCUNUiL)2~C1J2y}QR?;@zf&}Qzbal{;oLE5tGcsjv2$0yYGvnGj(uW_obN6b^BdR5 >zyW<MP-Tq~A;jv6{Pg$|NS0#!?CDY`6z8Fz5bELfg=>wuu#6S4z()pCH$gZb+d+HDW >z{dZCS$=`bFzb732^huX191g6C=whCu^|Lb1j_c%eH}gr)aJZ#8qVLI{da`p}Q!@1X >zYW<$7-`DWH{=mE<PU3R$ko)&{^N{{+=58MQ{SSuqYv$OI2a!99+*0J8A~zMetH^Cd >z?kjR*kvogrTIAj$Hy63P$n8b$FLHy8`VJ$v7`eyDO-AlAa+{I+jNEACP9wJ(x!1_e >zM(#FpyOH~i+;HTM8}%(m?m2SPk-Kixw;j3f$c;ztJaX%idym|F<nAN4AG!ZX1CS0N >zEimdHAWcBJVAO3u`hYY7=>*aWq!&mtkZu@tJCJ@DbwiMjAT2?9f;0u`3epy&FGypM >z&LFKpdV@3v>5fsi2kDPdHwftv(jufsNRyB*A#FnXgft526w)fBS4gvvZXxYL`h_&i >zs5^$V4CxutG&Eh~fwu9|eFGYYbPj19(mSMiNcWKTA^k%dh;-1XTZr@!X(G}^q>V@) >zkwzk&L|TdT5@{yVO{ASjKaqwa9YtDd)ICL-igXoeE7Dh_u}Ei;)*`({nu~N7X)n@W >zq`^krVWh=I-D9N5NSBc|BYj31jdU7mHPUOO*+{pMb|d{p8jf@vX}MAN9BDezb)@Y` >z-;u^6okv=a^d4zG(tV`;NdJ)yVAMMR*#btr2aru*)Vl!L2FN}@HUhE}kgb611!OZI >zy8+n_$bLXJgi-GZWJ?(Jo<KH*QSS<5TOj)a*%-*qK(+?5H;~PN><(mmAo~N^Ajl3u >zwun*h5oD7X^)5lSiBazpWTPNE1=%XdUO_esvRjbtg6tP$!yr2b*)m4GXOK-})Vl`R >zHb%W~kd1@v9AxVtdk5J($nHV5kLw>ypNLL>SSA0DpT8bIv3ek-k4aC_TWMH!dU9HF >P%CPLz)a2CUl-S<@u$syt > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current >new file mode 100644 >index 0000000000000000000000000000000000000000..4db1300a26ed4ad20bed915020eb3af8ba639e33 >GIT binary patch >literal 574 >zcmchTp-V$i6o=27PbXvG4T{eu7*<Sz{sS5v2zxSETN#+tVqOw#*J2RVHG{~iAlS65 >zy}7x8K@i47oeKtwT+es0h{@u4oZokN@Ob>bxU^AOkY6*VZ&)VM<<vyPpTq@kQO9 >zT&Amyy{t{<-nWu+B+Z?`+!i*awf<<@v-fhhcx^gzCEcl0(|xE(KR0ilrYGdNH#9Hp >zro7%HX0YFoxB9>ix6dUk&sa$XsgY3Q=QHZuVPC|#vsw^3cVuPU-&voAl*!e6Ecq4P >zf^JcFEtX}ynczF)KXm=@-|$!G=nUx%=?>`+ap0*QATA(2AWk4&AZ{RjAdWoM6T}t7 >Z7sMIF8^j&NAH*TVBl90FGb(o}^95{L?5h9( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa >new file mode 100644 >index 0000000000000000000000000000000000000000..7aea8f9989fbdedf0527a172b41871e70d439060 >GIT binary patch >literal 278 >zcmWHE%1kq2zyQoZ5fBCe4j=}xc^ZJk5+83Dg;{qVD8|eVP^#MZK-s1?z$Lclfy=cM >z7Z{ir!SMh8bv6tP|NrmYz{v9d|LO${96r7w49+e<92^2P0|Y`yu=fW<3(&;>|3UVH >hxF9!xXplQVG{`L=8sr`j4RRBhCedA7Kqs1U0RT7DJ_!H- > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Thule b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Thule >new file mode 100644 >index 0000000000000000000000000000000000000000..deefcc8df5a1111fb1ccacd1d67f44165d9a736c >GIT binary patch >literal 1528 >zcmd7RO-PhM0Eh84Lqak<Bm{kcC#}}iUEQ+O)Y8OqbJSJ*ZYs^x$~5yk^B|=sgRnrw >zljNxkjF1A0%DnV3C58~lgsi88C<>wQZJxJdrw&20%>H&4b}#$<{iU_1J&r$4u=#|` >zk>>JxV~=?n?rHrQ^{qok2P)Lg`EtE$CROd8ZkNuv!y;z1Ou8ncMQnG9jJpvk+%+ZI >z)AUKiXC>)`{MW)8wO#M=+!K34ES<RZrAl1>sQ3N2tM<QmrjtHgSIHAvraWp=2L_(X >z)M39$YZ#O1y^Z2v?p1lHsz7AKo{^auUXl5ANN2_5sjRs!ogEghvL`F`k(CH_bfi<} >zy!QxSSA{(GV6(_APnBZuyU0t9l=+tyM8URT=`VaJ{67M+$U7p60ztZX$CN65zNAam >zhE(a;j4oU3Qsuqlx?;LgRaW)u<D+Rx`fke;*DA!xm_B)`CRJ30)ye9tNKw6#BWt39 >zMa?UhtPKf>+B@O0Zh2PJ-*oD;Z<f@#mQDKn#Efbv{H!kwjH^cPJKfaKuP#R1*Uh>0 >zs(J0LY)R}BEsK+~ZA+bKn;w+yt2v@$v{iO4xI|ZXiM%`&F1jm|<ds`rgkxRMKYdu% >z<6eiuvgTFLddr%9;@FVm^E=Wr%q{Sn|DNOji(XcLf5rTwWzh|9X$R>CX$a{EX$k2G >zX$t8IX$$EKX$<KMX$|QOX%6WQX%Feo)-;H8h_s0Gh%||GiL{CIi8P9IinNOKiZqLK >zYirs?`n5F;BOTkCmXV&3rjf3ZwvoP(#*xmE){)+k=8^7gP5Vgywq^s!4s6X9kUb!q >zKz4y_1K9_%5o9OGR*=0Qn?ZJiYzNtot=SN=BU`g2WKXtcQ^>B6Z6W(YHiqmB*&4Dp >zWOK;wknJJ+vo#w;c4%w1i0skUY!cZevQ1>4$VQQ!B3s4(Wv`)Tx(Q~&PG7vs<BD_o >L+-{fK6&LyoQ=^pQ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay >new file mode 100644 >index 0000000000000000000000000000000000000000..aa1d486097689f5c686d24abbeea0868667118e6 >GIT binary patch >literal 2211 >zcmdtie@xVM9LMo5h(-q_loTnEg2fK`ZKr5d8n6rXg!C{a(~kz;5Q=wb1Zil7k><vl >z4Qe%3Y0Z9(%xt+DlXBM9%9PdmHTu{Vf3&cV(H}0>U7zP?{nsD;+xp%<pU3TXxBKh$ >z4A(bpDfRyGOtYVGc%HO}_ZhqG)jM~G{`3hW=W>3Rb81q1{ZSLwb6&?kq|FqGss#0? >zOs&-_arUrWo_bjMyhGwMkE<lTSCYSZNvE8Q$Q38L_4HRCGpWyR(P{e{&6S;Z=&PE7 >zX2!ZaonGxXS1(G|*Z7l6Mz&vFn>cP}#wV$nzxia=`Eiwb_7}Ns_>9Ur`ng>H;!!ob >z-7|9@J*cwlel$5-2ld>*DRaZJr}T~KubAAtZ8|slk@$Ue+CTcT<o&!*&l~EI{E@IK >z7-*8hV+&MK*K#R7n4wA{5mVashngR(HaD&MUIlXJnFXaoYT;!mrfk-?x@_!MvuN@I >zz4-K5bMtotx_t10-17czeQWO*a@%v8^^(@NWoh>=b$iXzQqizURTi~NRb_>$nmA&D >z1sip6WWT9SS*oj#wU}k&IePi?`((veOH^oQv#fkKTh*)&No`+(y0g4URy{bTR%fP3 >zxb71bo}7?1f!EZUpQf9&S*P{dQy0y;=n-9ic*NX2x?ivFK5p(AYS9}S`pw3Hm0E?~ >zkxf0#YI8xK+#3n0hLjFz3>K-z@p_5mrm4th<<c~5LN&daC0ob7RLy;hP0N{!`o8u| >zbN}FoZmo+N={>F=2x!yR+OM~ze`vPXbn5NVAEdpkPqmK@OGieB>KHmCotNs>!vlL| >z$Jga*XIDfXc`r+KZK#%A&v+^>eo8|8)c?dQ7JDP?d9m2*FL(*D*on8i#8~X(lX1!J >zPIdQ;6``<Ku{!KkaqhCG)}BiHGyBB-eTV;jDhKRW-Bd2Q-|(-oSlfj?`N(vT`5+T= >zG9w;4C16g-q>x!5(?aHjObnSBGBu~28!|a$cF6RQ`5_ZTW{6A?nIkeuWR}P@k$EB$ >zMP`aj6`8BkP8OLhGF@c8$b^v@BU47^j7%DtH8O2v-pIs}nLF*&k-0nV<dNAU(?{ly >zBml_(k^&?LND`1NAZbAIfFuIR1d<9Q7fzcDBpXONkbEEsK{A4*1jz}K6eKH1T9CXT >zi9s^sw5dUI<Fv^^vg5SrLGptn2+0tVA|yvhl8`JRX+rXZBnrut)20f^mD45*$(GZm >z3&|IfFeGD0%8;BPNkg)Rqz%a%k~k!DNa~Q>Ic@Tg>^W`vko-Aq0+9?NDMWIJBoWCX >zl13ztNFtF;BB?}j>9om2vgx$xMDpph2}LrBq!h_1l2jzCNLrD+djG?|`fPjyHoEzt >S`Guv0#rdI<lERY0V&7jSTy6jW > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana >new file mode 100644 >index 0000000000000000000000000000000000000000..29c83e71ffa6b071c52b2360295bf55009c09b76 >GIT binary patch >literal 2356 >zcmdtiZ%oxy9LMnsp(Ki)RFwE*C#4t&SN@A){}j7|+(5aKn2{NO24#>CO3@7+TWihn >zMJMGdIyrm5S`o9z{xNdPtu<C*E6m22DKLy8){4q;JMUi)d(^Ym@9vz}-QDi)?t{<U >zx2w7`&GnCGuKk3=(_s(qBU|kCTJNtdT}_2`-P6rey_My4??x-vnXu`p&nAwv46gd6 >zZt%qWb>Bpnx`x`{p1S1UD&OaAm&;|zawQ={Mm_mzZ1FZV9-pMfr_<F$=t4Cy7@@9? >zPN^Syep8d@2Gx)47u5WbZnNORfC}$#Hw)kER*Smc)apdLy5U*Ti<|1zlIs0>Y3U9X >zk>}IP)~!{`6S8#V%3`^3UZjo+&XlO>3=@56xx@@EGqE54E-QLw%uTOe6y3O5-+bsJ >zSy>XUSJiy0;xd2Ix8#4QZjJa-$0v5G_}NL55Z0m+hCern6MNO_z8;fw-Y?0W$Bg^* >z9$Djm+@u`aD5+IPby|I#q<b24M)6$9j4#nyY2&gsG+SrK%u(56QF`5<V`}}mYdYuR >zr)tAnk><7!URSrb{bBBS@rb&!_B(S|YnN;+>@%CnpOf4*#%#{rCwDJ8Y&>y=;+c6x >z=Y^z7-q0bPe|d>)ed)9*__{{C&Bx6>y#-RZ`+zCxaLcw0rDl7hlH!;g<J&PUzH70j >zB=ajNxw2mGT=BEo`ALi}ojtF1otoA64Zovyw~pxh`<_>2<!AK+olR<wci24m%yHS9 >z+;1MLIw0lYCryQ?R4OK0O;vo3R1H*`>d;uJeq)QN84bw89TobKFJjcbMvs29dsfw! >zB<Q-f5%pNse7(Q+tg4Tg)D4BFR6}5%Y0U1I#^I~xVB|?T*f(IBW?JQm&TjMMP^C2c >z+s#vFwury1-aP$6qPT*BgMzOM4w+-G|IRBAI9lLx1p+UND<lwTYjIuA`=ABRt(<#l >zf!F8q7W-U9oLqbEwWr8ucVeHQzi;2aSlEp76@E1kU}?zOki{XZLzaiE4_P3xLPxtq >zWR1uokyRqgMAnHc6j>><RAjA=cCpB69qn?F^&$&KR*Wo}zr&i5MI)<5mW`|%SvazC >zWa-G-k;NmcN0yJQA1MG*0i*<uwgyNMkSZW$K<a=L0;vR23ZxcDF_3B?<v{9z6vWY1 >z1SyH5tqD>Tq$)^Rkh&m+K`Mik2B{5F9Hcr(d64=b1wtx>l*rN62q_X$C8SJ9osdEy >zl|o8|)CwsUQZ1xhNWGAPAr(VP=4fk%6wT3A4JjK^H>7Y#<&e@LwL^-BR1Ya1Qa_}C >zj<$kG2_0<>ks><UDk5b>>WCB)sU%WLq?SlAk!m94MCyqY6saguQb$`;q^ORzsz_NK >zZC#PVB9%o-i_{h=E>c~jyhweK0wWbhO6+KBj1<|?Rv9U?qpdSiXr$6esgYVE#YU=) >d|NnA_*{o;VtS5QX-D&QWByVb}JJp>M_7|antVjR= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto >new file mode 100644 >index 0000000000000000000000000000000000000000..7b4682a39e2fc97450c99eed4576d2a4614bf294 >GIT binary patch >literal 3503 >zcmd_sX;76_9LMpiA{wHIikTw0q=>RgxKd&+gnGpVOmRCJdIvQ*xgZo`3u-tuOrt@i >zgSl@RqGFJSpr$rWiQ=B((UcTH5AL~eJKyJRFB;!9)8jn%bH};7{eAy2aS7AA+y3#? >zH~+)SbHluRZ}EZo$SGJZSO0KRe6uw0=$fzdBG#^O)$3xnM66#jQE%vyEH+N>r#HC| >zSDOd7*PE+?)mHDH<<?VnvF+(L`E7oX*nZ(N`P~<uB6nY++>sWb@>Y$MI~_yBuGCPu >zJJMg|Pw<j^e4B{x`#zKfu38j!YOV__PKdoO_x0Xmx75C?XY`M`rK;#qq28alQx&gY >zsY?=9r~~N>^}*;Qbtrza{wZjzI&4psM?CtdqXCoTFP~_6qT@YzLOfAr^RMcY5f{~| >z*sZ0f+pQ};6ZUE8S=-{`b6&Gc&xa;OoUh#^FEpPgE|h1;i(5Vt<wY~)rHpu?a_sVQ >z!eDVFElB<m)kR#L<SDQDxrvI%0R3mP&g#0ahrZGBj;eI6(UlKQs+$#My6W^ERed;L >z-`Za$Zs(qmdUd|2$=ogPEXo#l6SL&K$tmJ~bh3QVZ@hRI6ek~bS)l&%2$zo=j#G~x >zjnz-C_f=2N_R-IdwpFzS-rBjzschM`y3W$es_p`%>&aT-BA&_mBb0EBxFj0{9}o@O >zmB<&Gt`}~$b<#~Q5slPh>3(jlYFzA)O$yVM$Ci(E)32s0&x~ohS<0KLc|xRaF|Mof >zit^Jfd%LR_{Tk_39sI;g4XbtQx{XBZJ8rVg<!a%5yh^q$IVODaev>b+$rJ68Y`Xo2 >z%SDISE4t&1T=h!WA>C=n=c=>UM(x{muJWxtDE-`Gm0$S=*|oB#>Q=N=`j^FsfSd#w >zxT}W<N*gMJm$woj4u|eO=dlQljMA@;x*)=QyXhX?i$u=`jdia!=T)zY+q(CYeX7sl >z<GSzfIVwE&mV9mR2kQ0AQrU0iR27l9Q}$0^B;JT#AqT`y5d(vg<e-5A#Gt#Ib!5O~ >z6<M}SM>X!RqIS*FL#jKfp{p|Fu+tI3o;p(w-_t=vPq51oSuSE^c#s@5ze0@m_LMQP >zM@7t&yK+p}Rx#$9haT&5SdBeYqsP^5R&ndg^!V~+YC?Lxo>(+XO^VOflXHeEVc#vM >zES)K)24u;%9d;4lI9X1M3=-3-<D|paQ#gJNmkF+SMZ$I;Iiuo~n3>f_&pKA4-bwP- >zvvbQ-Vr;FJnfdD7Fs0`tW~;eg2lTw?6g98*l1%EAC6dZZWOA!ykzBM+raX!h@8v9( >z@1G49sc8<mu)s&8O^T9>zO;$Db)M&6J(uVC^?&NOPG|lKo6YGwQe4Ny=`7q~YiNCU >zw?3N=v&Yy54K(j)^S))?5iw@GY_>YqN6f#EUZwe=HF}Tu3-dV5Gv`)v6*7Xz5F%rU >z3?ed$$S@+~hzuk$lE_dZV`*sy6B$iQGn~kHA_IzyC^DqTm?DFUj4Cp$$haZ{i;OHX >zw8+>ZgNux=r5Rpid@aoYBO{CqF*3%;AS0uU3^Ov$$Uq|_jSMw1*2rKZqm2wVGTxSE >zz>yJ0h8!7lWYCdOM}{34cVyr#&B!A|Z)wIJ8GK~)k>N+i9|-^w0VD)S43HooQ9#0g >z!~qEe5(!Ha3M3XtFpy{<;XvYn1O$l)5)vdPNKlZdAYnn`f&>PM3=$ek6B{HrNOX|! >zpcNm!5Fj2CAs|FZjF2E9Q9{Cm#0d!$5-B89NUSVPu#jjW;X>kt1PqB75;7!aNYId| >zAz?$}h6E0Y91=Ptc1Z9nP4tlPA@M^3h(r(xAreC*h)5KXFd}h80*OQt38kfpB@#?a >z6HO$XNIa2%A`wMGio_HNDiT#BtVmpuz#@@FLW{%}39hAyE)rfOzDR(P2qPgzVvGbC >zi82yqB+f{nkw_z<wluLuf^BJ{jfC6M#2X1X5^*HtNX(I-BT+}fj>H`aJQ8^%^p+;} >zNboI9^pWsen)o9J0CEH%hX8U6AO`_*6d;EIavUHB0&*lEhXQgeAP0k`IU10|!O|QL >z$N^z#jtJzCK#mFIpg@ia<gh@F3*^8+jtu0`K#mRM;IK4D2Xc5=n&SgGKrGD>f*c~q >xF@hW<$WekECdhGu94NNuyCVLl7mAxXT*Ax&<8KcQ>>e2GZx0Cx3<(T&`x_HwlD7Z= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver >new file mode 100644 >index 0000000000000000000000000000000000000000..9b5d924173e6e71c2c0a73cf2aca368d3af002e6 >GIT binary patch >literal 2901 >zcmd_rT~L%&9LMnmUl4>mnJ5w3NlgS50YOnT({xr$L}ev0!<PgG(@?QhOVK8pvNsNy >zFHJ@N$cvmxbQl{OlhB!*nxYcSL~SEWWl&Pl5|ws4-{-cAuA9!zc|OnVESG$Lp7})u >z$*zB#ZuT24r`BHH`)sz4$^(bw-Gh<l>n+jJFzEWqhQ&ivqqmnnp1o21F!!oHp<C6D >zsg3%i>l@V+xnDOm?@_1x$K-UKQD=NL^3(2*jIVZ^{JiBg(_Fb$ekodM&X(rNuNia9 >zZ+Yo*E-uBKchA!ode2rZvEy`0`zX~K5~EuiBGtw7etl`*4b^tES^r+qq%K!?%9T|I >z)zxyJv~N0Wt`*nG^@Z=7KeDRi&xy~Q8zal4V`!DS*{eWq^(a%fI-b+FTMAU?$$b6S >zm(!I0fLjMXh*z$iaXRS5a233+r|z<9sOh>mR=Uj&Gu<bJN=V`*(?egBQ1z_|bJa`O >zmA$5CbG3vw)vJiQ3c2IcYSnA^9<AQ2P<L)Iy7&4Lbyv}9-6wahip=onzGKIzesQC9 >z)WB?WcW9K34o)@E?J084*?uObp|A8meA5ir*CF@5ciL$0Fn!;%hs?m72t8=oDK$9t >zvc7-%XKF~~F&!IUsbc+Y5*M~v#reLI_|_$ASnWO;-dJizRBn}onnh-0=~I%pb+Sn+ >zd|fA(3^t?OYjjF>cas{MqemyVm@y$~IxVJ~O1luP$KJl6#vSd{>8HO^<M&3%go7Wd >z2g+~B#J65m4;G)1NoBju<g8kGXz9yl%1Du^Q&yO%*BZ5Z#7oNExL;>PELRydJM{Fn >znd;%UYh=cWWhQgOHktX!43o8Bt<2h<U}lfcl{sEzvSZT4Gq>G%I{Qmb>T#2EZk(Ps >z;HsMUMU2k%H>&x&{Q6Pfezl;iSwB|0L**?!q8C=KSBo-zviOB<X32;;dAx9~SsGC# >z`R-hk-&Q7tvFWC;zCemX`kSJUr^&MO0rSN6e7*ep7`4Ld)=yUZRdG(7URmC(R*mkd >zR~H{qC6R4<P1Y{8CJ-v#v^wMUU6gfERc2jny{zvjGf!7m%QGhn%!bkm*?3@@Da|X9 >zO*`XFa8PiUuJ-ZY`~(88yy0>M0`Hihu7N=LW>*jAJ=}S!8JQl}tSR<p+xv*Uvpn{{ >z+~o>#9-e=%!{_#gP8~Y<3wr|g<W2BiLTZ5&1E~g54o6!Lq##H|kdh!ZL5hM@1u2W8 >ztqW2Zq%ufpklG-{L8^n42dNKIAf!S_iI5s0MMA2Cl*!T72`QALtrSu!q*h3=kZK|2 >zLh6MS45=7WGNfim(U7VkWkc$Q6b`AJqb(g$JEV9>_0TCFFVv4?3kXyYDIrorq=-lr >zkuoB6L<)&i5-FvlttC=Sq?$-Mk$NHpMJkGv6sajvRHUj%S&_OTg+(fhloqM2qb)8{ >zU8KB7eUSnq6-G*o)EFr;Qe~vfNS%>FBb9cvrABJ)Xp4<h8!0zZZ=~Qz#gURDHAjk$ >zR2?ZhQg@{ANac~zBei$5#Yd`-lpm=-vH-{mAWML(0kR0lDj>^%tOK$T$Vxccr9jrg >z(JltE8jf~3ko7<o1X&SeNsu)`76n-qWLc1PK^6vC8ArP`$l5sC#X(lb(Jl|NKF9(g >zD}*c&vPQ@vA*+Ne6S7XoLLn=KEETd=j&`w-)pE4Ug{+sOT`*+DkR?Ob3|TZ})sSUF >z)(u%WWaW^hL)OmGE*`Raj&}Kw^>effh^!#8gvc5qi-@cuvW&<&y8gfO7-m;9&93M0 >U%uxx+35mlqladmW5)#Ay2A}k~%K!iX > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin >new file mode 100644 >index 0000000000000000000000000000000000000000..447efbe2c967cc5642b58f51aff86b67073134fb >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eC<zyoQ1C|Nmnl3=IGOA3wmr;^P~_;1~?#0zn7~ >Vru_ix0GaatKYmlWfX16}0RSy&9%BFi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse >new file mode 100644 >index 0000000000000000000000000000000000000000..6b62e2d3c39a8406cdc087b387fbdac0709f9141 >GIT binary patch >literal 2093 >zcmdtie`wTo9LMq7Qm4zo2XZ>soqcrX+}v(I+~(=*mrc&u&MkLdo|(Ve54N-|w@xjc >zCyXK^_AXI_?EE<VM<kpKMX-hm1tF4c5s@(@D5Dsn1+A2Q`#eAOUw`yx(D(R$AD{cO >z-G8rVbVFN9x$hs>RQraTYrnlY&rRA#>cW+Q;}`Rcxi)>^ME`K|${Py@hVy>y9Nt=? >ze=AAI_`-g5H?Ubf(6&?0h_6%GwNX8D=@K=opi1Y=Yn0j3a&&HbrR3hJFb{q=OZ>w# >zP2l6-WzN}g^U#Uwq7#es+yfuUyjYgbYyU>gue_xnUj3n3ko|?uFHEWYi7``<nN$U% >zpPRy;wy8x!XHC&aj})g4nc(0SDd~CHlpb0kWv%b%@~-)^INYr(8mCBQeoR-D|0qi` >zLOSH1tU@<)_0qdH)v{0T>FVpBspSJX=8=o1)uVlXn8)6GOFiE4t$CvNl&q*9GEX+W >zDK#a=tgP7~D}Nc$;o^fTJaSIgW^GrsgGcr1u{G+cV}qvdt9FU(J#5yTuao+XyG+B8 >zpgg@iZq_E0H2SMebln|^-V2ym<(CrsewkiB=eAn^iC@PjM%0Fr6Z+ZFb82Jn4gK8E >zQMIY*vfiB9qqamw&DPfs%eLZ6=K0oL(v;P2n!|Bv9_ux&`PI^TwZ*h$1f=bQRi^z1 >zPhL3EthZnDs~w53e(}tN>WCHS&b}M!rK<b&&W_8fD|<|L*Pm3~-ZYa4U6RD;&t`W{ >zzw92mYW9rx$}6ce=GCuTWN**gX5WQX(zB_{?0>gV($nnczDenm)2C$o2OrNn(B$)Z >zUSBe8l0A3&rn>WV_f($uzNF3I?3?Y*fx1Z47q78*qrIQ8cLU$;iw66m!OE59o_`tr >z_Z=kdpSvB5|NVcSz4pC!@EEcSWE;pnkc}WaLAK(wdqFmX>;~BmKhJ)U4Iw*1wuI~n >z*%Y!XWLr+VFJxoL&XBDkdqXyd><-x;vOi>l$PSS$B6~zO>9o5<w&}F{L^g`-6xk}W >zS7fuuZjtRG`$aa4>=@ZHvS(z|$gYuXJMF%ajUzipwvOx_**vm)Wc$eekp>_gKw5zG >z0BM5Lb^&RF)Aj*rgwu8cX$8^?q!~yzkai&bKpKK{1ZfG<6Qn6l+ZCiOPTLoxF;3eV >zq%}xykmexWLE3}#2Wb$}A*4k}kB}xIT|(OAw0%Mv<+PnbTIIC8LYjqi3uzb9FQj2e >z$B>pGJwuv?bPZ{n)AkK%oYQs=X`R#d4rw0JJ*0g||BwbE9Yk8_`@hF9(^fKMD_Im- >S94rr(7DdX+f@Q(d%s&C-P%%gV > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg >new file mode 100644 >index 0000000000000000000000000000000000000000..2ffe3d8d8e012445aa961fc53b38934681dd2a2c >GIT binary patch >literal 2891 >zcmeH|YfP1O9LImh8;GK2VuS>y6+;mL#qdH|>KG(~dPEd5H4L$g#~X?l{56@ES8A4* >zQKXJqt`$0$;$>uN&aIq7lq8K1m7GdGsavST>HqoH3%A^S)62eR|L61Y49+=k_<X!m >z^WKV+f6dQ4;jlyIaNk4CrNr}~zU0`!^wNqQ`pLn2&e83|^;lZ5`~BKhJ=6EDb7n?I >zw|ebtIXiK>dv4M>sp);n{V{&OoR@O9HfWpF)^Bt#n76xdGTXgaw?%*6wZW;YEYx4t >z&3Eccv-DD)*J&t9)XT|3oGa79^=f3W)0i|ue(gTky%rHB*KYT8ubXdky{g&0(byn2 >zYmU23CyvW+8xOm8^2_vY>`eDw*A%_)Um*9JbLGLcOldivEPtLHCao3y#rJur$kssd >ztZ9`ti*HHWc_G?vMkj5b-l82wHmP4so%;7atsT1^(E!<_0q#!iRKH0(*M1{`M;2+9 >z13RSauJ@(ewpH@Px`oocaF#rommxi-BuP+mg7h33DNjX)NN}Gq`m}$GgtUp!klVr9 >ztD&QYR^8WUzP+JgdoF7Dj#JvZpsPIlUb*&}^t<$(^MgDWUoFq4d?hageJv6FHb_Kk >zl|}~4m&m%k+V8qo`d5CaQPqwPC|#`4dnf3?qA41)X|TrT7D(KJo;oNgQwC3H*7%5F >zG9>ONebFye5_<h135~5X^g*o*J5evgFC3B)<t>_c=wo?leVx8svQkFoAJJEeOZ3&W >zojNLKg^t>vUq5<av5px%-WhXeza$Nq>n2riljOiOH+k<eNok68U;Ai_j;$Hzq%JSi >zar<JNwCpTR-`w39KO#{lEV}DV3=LQBq#DQD;?a!w3Mb=gm}G{Xbu+&cnbNw?om$o) >zS#?|8?Be6{dgW4gTFz(kMrpP?J@u&0SX1cC98jij=4LrLfva^^Qlc}fX}0D@ggd#X >zQZ&!c<K%rArE?lDJ8y4JmUmA3+_?q)<=yg2Zhl6fIO~tO^WtyG{QOVd1wmD^Fl~*y >zu(e4G63U!{y3@KOc(t>na*q}^&vurUZqjAvQ=H{Ri*!Xrlv6Zqvaa0P#cAWQueR;} >zx%vCYM_t=@_-|j2{lG_kiHD#0d}TL9e7*y_J?(tHFSd)nz3*(V-5!2EHq|SmMw>Iy >zoXO^-d(FSNh{xlx5b-`<4~NaKT0J!LH)cMwoGZIOfat=~C<CGmh&mwpfG7l_5r|4G >zjZPp+foKJy7KmOTih*bbq8dx18;Ei&jdmdFf#?UKAc%$_DuU<;q9llxAZmi>38E;7 >zrXZ@aG`fN)%hG5IqArNOAPR$M45BiK&LB#IXwA~74Wc)Q;vkxXR(0H<J7$!}&>lm5 >z4E;eA2+<%!g%BM=lnBuxM2(h4j}S#dG|5mUM3)R@GPKE1CqthMg)%hCP$@&F45c!( >z3Q;RVua-u!5Y0kV3(+k^xe)C_)XUH>M8OOVGgQpbF+<4=En6BjL-cHE6b;cdL)8#n >zLzE5CHbmVJeM1z^&^Scp44p%i&d@qU?F_wJ8pSg-&rm%>_YCDjw9imKME{HgKr#SH >z0VD^OCJB%%K+<4o^1w)hrO5;%6_zF!jATHv0Z9iWACQDVG6G2nBqxxhK(Yc!i>1j6 >zBr%pIGmO+&n%ppw1IZ2}J&^n`5(LQ*BSnxLL6QW?5+qHKJV6p=X)*;#m8HoQBw3aw >zTaa`?^2JCPBx8(}L2|}O8YF9sv_bO5NSvj~93*v?CU=nJS(@xY(g(>OB!Q3&LQ)9H >kAtZ_Ne-n*Bjr&Y4hnQ?er4EXYi;js(jg5_tjgATU3t;rI(f|Me > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat >new file mode 100644 >index 0000000000000000000000000000000000000000..523b0a1081ade2feb2e163279c0b9960f8550099 >GIT binary patch >literal 2314 >zcmciCZA{fw0LStFMc@KKQ9?XOx04Sbj~-B-iZT?UD-sabn-Ezjc88T<Foq8hn2y{k >z$~K3y!EuhQwrpp*m9D_jwYE$~xb-lK(ydu8UF&HU$?bg4=Bt{on&-ds|6K0fc=!AI >z8d{#rbN+SQ<{K_&z+66idd=(fp2d1{!EbGoP0PgWu{ARIMv-s^3#IFYWD(MpB<E}? >zP@zrvI;=KPg_kC1xBN@FU#iuSv0tmm!)IjF&tvMQ??!d>S5qS9gJFI1@lkQhoA1lm >z{lntcJwx)gt$ku{ORtQp-yq_>>*ejm<su=yOeW56Qc01iGC5?WO3sXnP5xzto_Btc >zN|{`!?>OmJo+IJ<&VxTH(OE3->N~CG`{&68n|=@r^RLQ9t3DB_@!!g{jJHJE?2Jy2 >zdRe4Tf1@)lwu#KK6FTeciz<8Qpw2nESuN>#Udz{NRBk}Yy!Je`v|^`RRu`x8)0$;L >z-XE&a{eUb=nJbDeESAMHzl*y+j*|CGeIZJ8s=oKV<Kn(oBJ}bD2gLoY7j@~bch!pO >zPxZ>?{i<xq+q%4LyDI<noUF(m6cuMrNpH+H;XOJcS6ylpm9KxOSAX86s&*XG553c% >zsvCFfntdgzwj`h*?)0d-6tDLA9p(EwQ~UGJEC2To%C(-LSo=|ite-t68b+e!qtmBE >z<F3o{v9S@cu6aT}KGZLssQO7a^&e8}v&Z#@z;4wXqxHs$fZBLzuMVVnRp3mAZgFR- >zmcxF%=|YTpYG1p2dLlzS)44`&*3qKXUntuKE{iP%N%Gm&3DF)uBRi^(h>l=_?kpNt >zozs8nu0*Z6#-{YvD|^+pp;5j4%MP`pXIOV1^Q)e9efqh<BIOF1;|jg*6CQR0pJ1@t >z<v77$Uz-ye3=Z_VBJ4ZbzGLk>&i<OTy2|I&*O~i>xi#jN`JB>9`!e5}WB$)IeE&VB >z2=hCa^QyUg_FUmFbAsk9KY8^t?Cvi-fs70pn$?UA?cn&p=s0G0!1#~>A|phGh>Q^# >zBr-~?874ALs~IRVQe>#eSdqaZqeX^`j29U&GGb)N$e58qBcn!!jf@)^I5Kjp8M@Vs >z9T_|_dSv*>_>ll05kNwK!~h8b5(Oj-NF0zrSWP65P*_bYkYFIuK*E8<0|^Kc5hNr? >zOpu@;Q9;6j#03cq5*Z{kRudZ}I7oDm@F4L)0)#{e2@w(_BuGe<kT4-}LIPzqkwQXc >zHL*g1Wi`=4!iB^O2^bPFBxFd;kf0$^L&Ao{4GEmpL=Fj^)x-`7p4CJT2_F(aB!EZ+ >zkq{y=M1qJ!5eXv_M<kF)B#}^BO)QaMT1_;Oa9T|~k$@r*MM8?i6bUL4RV1uPT#>*c >zkwrplHL*p4Yc<hD!fQ40MFNaO7zr^FV<gB(l#wtyrp%!sVb^`!;WzMcobf)g_`e1E >fTA{5`rImHQVgjC3wKOL$M`l&!=H}$)$f$n+=weO| > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife >new file mode 100644 >index 0000000000000000000000000000000000000000..d9d6eff70d7aadc55e202b7d31ccb1359870b81a >GIT binary patch >literal 1980 >zcmdtie@xVM9LMnwV5v9M&sG=;nrV4L+;N~JkeL;9Azc`rh(wqM-cBn>-OUp5-NG^c >z;=OXL&1AW1{?STO*J^Gw*YKaRxpQm%Sh#*~mJO>-Hj8hc=jY%4>aVum?(X5-ZvOLm >zzLIU}9hK%Eccc3kKHPry;qME?eT|hCnvVzbHM{JOp6s?lbFI9sXKKZv$(z!h_U0{d >zQ_%3BonKR8ZYfz|3zyc*g4rRvFgGj<e_O6a-_Dle>?~b$_GelA?q$98*m+r!S!8c} >z;e;&R6xd}uKQXsgePi!f|BhK+@R1FdstHeD(vr|_Q!;T@OD`wQonx<S*~K1-j2zPF >zsb(qfOKI%oRZ@}ax0QS5%gXo;yQ+Cgs=^Q1yDGnw)iX<Nb<s6b{ZqcJx&DQzJ@>1< >z`>Qi%&1gvPIdjyk9r{J@J#x^j>;6>l>pvp*H;w88od=|@{3Wfg+bZ?HkK1^p*TgR# >zw+(YTOv9-`yZ*{L)A;I}`tWD%lIR`KN8Vd2P3>vjFuX(_UDK$|nOxae9MR;a?<M)? >zJZ-5uCoMme+1AD1nbz^ScFXj*X?tVRJ~naOwD)K2<70!Sqw}=gI<m_=k+`7S1_oq% >z<fJ~CN=xUQ!`c;Zl&&ioO@$+pI^U}4ne!z5cCGIG@v7_^-fW+`FxNbtsj<(Tm^9rj >zMYd-sYo4w8%kJ(zZT1vgvU{6`&EDzjnyEf1nTfA;U*TcdH};`EH<gj+M~><K&s(Lp >z??pZEey#L%bm_rYipAvR<mS!DyWv0h<6fD&Ab9JwoEiRmRuCLjlOF^hjOJMXF9nfU >z%p^7^O=5%lY;>QxI=+(bhdKV|d?)|K+n(~j;=c_7-Z=8kk+<%3?;Uyb$h+rfynW>T >zb2NZ-z|jKI1JVT2h1a!#^no;jbb_>k^nx^lbc3{m^uy5*(h)~XNKanZ6w;N~wT1M> >z(HPPh(i+km(j3wq(jL+u(jd|y(jw9$(j?NQ*R_fC$<Zj%DMzbFuN=)H-Ey>x^oul% >zbd0o&^z3y_BVBu4+eqJD*ErHSN9#!MNb^YdNc%|t$Oa%gfNTM>2VS=c$S!!@HX!@p >zbsK@~1jkk&d%>|8$Zl|K2eKa=8-nZzvL(o#Ae(~hiq~xmvM*k@G04t%-PRy`gKQ46 >zI~?1C><`BVAv?seMaUj;Y!b3dUbjuiK6%|nAv@)DTZQZuvRTM(A=`!Q7qVgaf7!8+ >ZTe#J3+{zLwqm|KES)!sMS`m$f{sy2q-OvC4 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey >new file mode 100644 >index 0000000000000000000000000000000000000000..d0bbacc8a9647d6d31b36a561c6b5922c71d505c >GIT binary patch >literal 311 >zcmWHE%1kq2zyK^j5fBCeP9O%cc^ZJkKe;mvUbom3y!%gm@LM@Y!Qc7pga|I{hNva{ >z0`>p@|7T!iVq{`wVq^rW1%rYHkmgw%7&sUhKx|zD0|spa3kGdNLy$a39b*Uyj`#sK >wm4N|h*ME>>KwOZ6Ks3lvAR6Q_5Dju1hz2<jM1vd&qRDnBmkrSAcDfc^0IIGt!vFvP > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis >new file mode 100644 >index 0000000000000000000000000000000000000000..40a992664e2b228b0f6ab99a7aa655df53015dcf >GIT binary patch >literal 311 >zcmWHE%1kq2zyK^j5fBCeP9O%cc^ZJk^EnO--`wvD{BvK;;B`yHz<c^H2fvl84E&wH >zAE^KT|33pG10xeN6EibVEf^#ffHb=WFmNz1fY`bQ1`OH;=0I!;l4k_r5E2~m18gb- >x1JJJjAjg1ckb^)p$Wb5wau|pPISxdF90;O8js(&5K(%B!l*<O_bUR&hE&$zhJeL3f > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville >new file mode 100644 >index 0000000000000000000000000000000000000000..06863534c4c733f9a1a11800b614ec901e64cc6c >GIT binary patch >literal 216 >zcmWHE%1kq2zyM4@5fBCeRv-qkIU0b(l|5w*_e>HJp4%`r)c^ngpMjBqkr5~k20aTH >ySab~x7_<!y!2A#r4F3T&18C-dkR>1*WD$r4Sq74>2eR>6$Ylex+D_NdfC~T|oGK## > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie >new file mode 100644 >index 0000000000000000000000000000000000000000..aea2be77cccb5187ecacca5673cc5b42543dd3c9 >GIT binary patch >literal 1543 >zcmdUuNk~<37)QUWK1FjV6EmmO2It{fnWjF|oLv+olA;z=ri-9Og+%EGS#Oh@5|Ruw >zLtKR>HY@})gH}e1$`%b+i->4ggar<-|GDL=MXMJ59`~Nh<^L9scTR0XTT8b5F+cN$ >zi#3{y=TJ4bzGv-vZ6faLfP4JlY+$P_Jm{9iu?|^!R4>b?M%6Q%FH(0&Eq9D~6^)4Z >z@jUejiWbM-D0R%|s$b@k`aO?S|ByH8e|u2_zD((={`C_0;<W^IEJ*OZ`x4UpN>=v{ >z${N?Cgtm9d+Suz7w!cNfmd{CeZl$dA-Xjt5hc)7zQzET$jT}CtQFBQe?Jm=psQ`^V >zny4GDj7eO5hsNt;O(^M;jcp%gQ^Hx<Ts0$GybefW@`xmUyCX@T<}~?fucXXOYwGxE >zNxM0u={=2-(e2jE6E4X*)~3#;2F<R!AX^IybX!iVY>$c6obYPNSrXkbpC-94-)i3Q >z2i-aGQ1d5Kv|wmX3i|`qb$(ikIzH>JBSTW${6tI2+_Kv>rllD-v@Etq%N;dR;de_a >zz7I;}`^!=_+a=YHPD;()7U}eOJeHT`ZTUF<!N=Fv{FU}D4v3G))ltiT<;}0>mG=^y >zo|PrVW&3K)t+ZBBolXu~mbG%e_U{HYnX|S*KYoA7{5a1UN4P+Yf>;GH3t|_<Fo<Ok >z)1Yk|4;aUcbpZ1i_Av~ESjaHZrm+!Xq)lTb#7vvUPKcopOBtpzY-JeBu$Eyi!(N8L >z42u~i+cY*ajAmHPFx#fFn_;+3V>!fhi0u&LA=X38XV?!Z08#;?1V#;vA{bRL%CKqb >zU=#wWgi#8l7Dh3UY8d4}>R}WFsR&XMqb5jEjH)1I*)(-Q3S(3TDGgE^q&P@*jPfA$ >zF$#oK$S4s~Bcn)2m5?$abutRIX)0xu%BYo5ETdZ1X_S=zBi(=kld~(`=?wS@y2w-r > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson >new file mode 100644 >index 0000000000000000000000000000000000000000..5197dd97b9f871f533ff418b1870e593530cd501 >GIT binary patch >literal 225 >zcmWHE%1kq2zyQoZ5fBCe79a+(c^ZJkBL$-duUkqE_5c6>XJBMv0t$gaNCHTmTL1%x >ru7LrAwt*QCo5JKsu;T|*577AkAiF?ZkbNMU6g#<WfcD$znsNaEFL)jU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo >new file mode 100644 >index 0000000000000000000000000000000000000000..a5f5b6d5e60f15ebdbb747228006e8fe06dd4a01 >GIT binary patch >literal 2460 >zcmd_rdrXye9LMqJpwhVKWemws!@O`gTvUW2LIninl6fQ~qi>S%pdpkbbb(AGa|~<R >zvNfZU955{rNzhUdL#TBjTa#+pH=TL5LUT2xEbMtd>%Z3evp;&y&hz^1>^y&*KR)l{ >z$}cI3HU4(pV12@yYnS!rJbt5fYi)0HA6U92udV95d2r!*Y0v93-wExLL-8$U$EX(R >z45~9bf9%!6!=>htkDBz|!5s6wb8bEQ_7(TB6CY~Vwn2Ay<32sU?uff*^EN$^z03W6 >zVY&7?YuqO@>!r_M-2D+{(towuJoVKp$zDN!sMo$d>V0XC_%!^kzJtfrujY*UcQ$H3 >zLAT!ca;=U{+O6ZNigkR*GddwJLnn+BX<&S~242`KK~vKusBg6dJHjNmX_4IYov%#V >zGD~jmz9=EZJ~H|B0hy9EBvUuG$t}@d8d~y+P7C-!Z*@9ky2k>Y;df4EoSmjKhk9jJ >zkEe!x+$7<9LnY#^trA%`Mx6C)C2GwDi7w5On8hDRY;K9p4%;hp;+E)K?|O*~jMTWF >zTXf!)0FD2=P7}VkthXI3)!V!LC2>cN-qG-rB(0CpJ8Mo!^2%(PU(hZK5~F2d(o2#u >zX`G~nR7vW!UnFfLUlv`h)$}uol5x6N7at3eB^?=>*<eW4&T!4HJ}WtuetK8Yh%S{d >zxjRjDS+cLVruXRb$rmNp^G(gYJ|Ope|E%VH+a@bcnwsDBqTIW`R#rB*>V3}_OTly7 >z_5QL95wk)c$O)HK>A6}M<tGo$jMvrvm!xRyaw!`2(c;VV#5_HuC7(@{H65So+SY6G >z(9Q!|`ocG|u5yQ#m3K+Gw93OPzSc*Qx6As3qgpYgLLQy?nr<+1Wy7yeYo*3Z)t80( >zSa+~IemGU1Xo=G&cdwG_twCC|DMg+#e^U>K$EbgLd5#|QpS}#EanPEBvA^Fj+A!Ye >zG`tL>xtsH$0f#?l!#Z=%%yJpo`OCQ3rxX{@84ibyb#wju1YfnjW>0YVuZON%*Zhvm >zW@M7cERks<^F$_!%oLd_GFN1>w$^Ns=_2z*CXCD&nKCkGWYWm2k!d6IMkbET9GN;Y >zcVzO&>}{>-BlG9yk^oyP14s&x93V+RvVf!k$pexIBojy~kX#_iu(h&*q{G(A2a*t5 >zD<eosY^|IiNkOuLqy@<fk{Bd2NNSMWAjv_pgQN$^50W5TD?><%kQ^aNLb8OU3CR<Z >zC?r!zs*qeE$wIP)qzlOxk}z8<V@S%7oFPd=vWBD$$s3Y5By&jWklZ23L$ZgY56K^r >zKwB$=ND7f0B1uHDh@=t8Ba%oYlSnF&Tq4OtvWcV<$tRLfB%?@5ZLORlNky`Xq!r04 >zl2|0ONNSPXBFROvi=-FHFOpy+!$^ve9NSt+MzV~g8Obw}Xe84}s*zkH$wsn`q#MaM >zl5iyBNXn6%BT2WlvW}!3$vcvGB=bn>k=!H6N3xHk-}s-j-<yAi$e7sd{1jJ2R)TY` >QGddz`jx)v?9W~qgPuMCAVE_OC > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer >new file mode 100644 >index 0000000000000000000000000000000000000000..43a01d3e62d45456e5f7317d2a9d17a5e746058d >GIT binary patch >literal 1432 >zcmdVZOGs2v0Eh8AI_aQEg^Sc)R@%#~qvK;V9Zx>cw9Ir!34<tzbTiVTHi71%B%%it >zwGiw95n+0?MJ|jE6-f`MLBw1HK_L`@^uWfnZs)t^s#Ub=Uhe!ZGt8aEeE-0nrh}Q* >zABV@h!^IIW7xxR>%**8E+t%cGmkP(1=<v|6nEHBDejm<J(+{)t%wV1P(OoNlc4iCv >zbe4?1Ua34O!7Gc!ph}3^s}n-IRpNM&PU`ciB`+G~((_4bS+8F%Z<$dm&L+#`)=053 >z7$H~XO^eml?_^5iYmw@+bn4W7vF3AFuN}K8)_r@V*FU(YHjLiTY1g{c#=9Llz5Te_ >zbg5Zy-hV)ewv#fWxJ+g4Ym(l=QIRF9WOi(+$cY<}xltp^XDyJvXC9IFK27J}`XIJE >ziPHtAo{Pep6WZV0BZ@jgTGl;PTMymQ#olgJQgKn2#-CAT8U3>CON%OBbU~I+M2Lz{ >zN94A_pr{Nr$f^NLZSTvMJ03@i>Y8@Fv$IFl6p!g$$IhwRv`JalcvuBuU&;F1aZ%s< >zQ8$#FP_4FYTM@3g(;ew{&5Qcy)9p5YkvVL8NLy~(9(n2V*!J5uuKC<s=6?2_xlb)m >zx)4^n$TFALT)#_jxn>_@4E#kO;n{DQU$<>KaWt(Uy*Qd?kZzE6kbaPckdDx4i5t@s >zkEbc5E2J%?FGtfD(izek(i_qo(jC$s(jU?w(jn3!(j(F&(xszm6X_Fa6zLRc73mde >z7U>pg7wH#i80i>k8R;2m8tEEo8|fQq9O>NAw2t(SG>>$Tw2$<UYyjB-vIS%h$R?0o >zAlpFp;b=C3?8MP*1=$O-8Duxec98ub8$x!3Yzf&DvMFR&$hMGuAscfvJ43dHttO%W >NVQ(=7W{G}p%r6}>oFxDN > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera >new file mode 100644 >index 0000000000000000000000000000000000000000..56913f8a10cb61305ddc4025c51f72e56b195781 >GIT binary patch >literal 186 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0ZjFOx1q{r~^}85kLXJRtc0|LO$>7F`1a23-SV >but*3AM*aZnfDj;~L4bhqTsA<9?2Nepj*AyY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole >new file mode 100644 >index 0000000000000000000000000000000000000000..a5f5b6d5e60f15ebdbb747228006e8fe06dd4a01 >GIT binary patch >literal 2460 >zcmd_rdrXye9LMqJpwhVKWemws!@O`gTvUW2LIninl6fQ~qi>S%pdpkbbb(AGa|~<R >zvNfZU955{rNzhUdL#TBjTa#+pH=TL5LUT2xEbMtd>%Z3evp;&y&hz^1>^y&*KR)l{ >z$}cI3HU4(pV12@yYnS!rJbt5fYi)0HA6U92udV95d2r!*Y0v93-wExLL-8$U$EX(R >z45~9bf9%!6!=>htkDBz|!5s6wb8bEQ_7(TB6CY~Vwn2Ay<32sU?uff*^EN$^z03W6 >zVY&7?YuqO@>!r_M-2D+{(towuJoVKp$zDN!sMo$d>V0XC_%!^kzJtfrujY*UcQ$H3 >zLAT!ca;=U{+O6ZNigkR*GddwJLnn+BX<&S~242`KK~vKusBg6dJHjNmX_4IYov%#V >zGD~jmz9=EZJ~H|B0hy9EBvUuG$t}@d8d~y+P7C-!Z*@9ky2k>Y;df4EoSmjKhk9jJ >zkEe!x+$7<9LnY#^trA%`Mx6C)C2GwDi7w5On8hDRY;K9p4%;hp;+E)K?|O*~jMTWF >zTXf!)0FD2=P7}VkthXI3)!V!LC2>cN-qG-rB(0CpJ8Mo!^2%(PU(hZK5~F2d(o2#u >zX`G~nR7vW!UnFfLUlv`h)$}uol5x6N7at3eB^?=>*<eW4&T!4HJ}WtuetK8Yh%S{d >zxjRjDS+cLVruXRb$rmNp^G(gYJ|Ope|E%VH+a@bcnwsDBqTIW`R#rB*>V3}_OTly7 >z_5QL95wk)c$O)HK>A6}M<tGo$jMvrvm!xRyaw!`2(c;VV#5_HuC7(@{H65So+SY6G >z(9Q!|`ocG|u5yQ#m3K+Gw93OPzSc*Qx6As3qgpYgLLQy?nr<+1Wy7yeYo*3Z)t80( >zSa+~IemGU1Xo=G&cdwG_twCC|DMg+#e^U>K$EbgLd5#|QpS}#EanPEBvA^Fj+A!Ye >zG`tL>xtsH$0f#?l!#Z=%%yJpo`OCQ3rxX{@84ibyb#wju1YfnjW>0YVuZON%*Zhvm >zW@M7cERks<^F$_!%oLd_GFN1>w$^Ns=_2z*CXCD&nKCkGWYWm2k!d6IMkbET9GN;Y >zcVzO&>}{>-BlG9yk^oyP14s&x93V+RvVf!k$pexIBojy~kX#_iu(h&*q{G(A2a*t5 >zD<eosY^|IiNkOuLqy@<fk{Bd2NNSMWAjv_pgQN$^50W5TD?><%kQ^aNLb8OU3CR<Z >zC?r!zs*qeE$wIP)qzlOxk}z8<V@S%7oFPd=vWBD$$s3Y5By&jWklZ23L$ZgY56K^r >zKwB$=ND7f0B1uHDh@=t8Ba%oYlSnF&Tq4OtvWcV<$tRLfB%?@5ZLORlNky`Xq!r04 >zl2|0ONNSPXBFROvi=-FHFOpy+!$^ve9NSt+MzV~g8Obw}Xe84}s*zkH$wsn`q#MaM >zl5iyBNXn6%BT2WlvW}!3$vcvGB=bn>k=!H6N3xHk-}s-j-<yAi$e7sd{1jJ2R)TY` >QGddz`jx)v?9W~qgPuMCAVE_OC > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa >new file mode 100644 >index 0000000000000000000000000000000000000000..94a9d5a282eab90fadd38e144b3987bf6f4e7da6 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(^NkS<_5c6>XJBLm^1wjLfPqEVz<@#9z!=OA >cA;HKWP&0rg{s$Qi0tAfbvH@CTr)$gw0Lh>jKL7v# > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll >new file mode 100644 >index 0000000000000000000000000000000000000000..3757faccb282a975e3130e5ed9a84bc0e5881a79 >GIT binary patch >literal 1176 >zcmc)IPe_w-9LMoznlMJi*FZe<#~^~Dsm~_TMGe$#Sk5w+nP&D!r`B4jC9bjsK}3jr >z4?%bcib5h{bm-5aLlhAPGP+1~h(MttLV^nGAnW)3)vZ%>=o!D~^=yY7p3ghh-X9M- >ze_Tt<FC4CrIXo{tXKuC2B2I0%K<m0!O8xrx8me2AaKQ_Wta~ew`FGNg|3n(HQ?hmL >zhHT5+md5GF8XX^#raRYldon3I#?EW=?n}Be(W5P!6B=ub=&s@>ZS`-|)&*DFio(+N >zYK89kwn5q-eASK_pX|L>D4q8{$-eX#>AIYi{arJ1VDzIN-11Nkbxvz{$%OP&XEg4; >zuf3~Pdp}&!zQsZ9pGxWBH!(eOt3wmd2ju9*YE4eI$g#c>J$|852AZp6FkUP}fi-d> >z^g~V-Ix<{dq{E+QWn}q+j=X#(srlD>>h7eR&OXvJ6Hj$Cb5+l#Zfbfwt?67Y=j40x >z{`He*-mAS<t@ZqR>0bNQTk5*bCO2q~>o^{dJ+Z$S?ECNk1%|Vl@sI(L5s@L0F_A&7 >zW>jQYs~Hy=7#SHE8W|fI92p%M9vL4A0Eqwz0f_+#!fK*G!mye+kU)?~kWi3VkYJE# >zkZ_QAkbsbgkdTm=kf4yLkg%*KE+jA{G9)x4HY7MCIwU+KJ|sXSLL@{aMkGiiN+e9H >zi4zIbY9d8KMPfyQMWRK*MdC#Qw*HTZeN`su8rR%|HKjp+w4$uC%q<W2qXE}GRrr1a >D*BAYi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok >new file mode 100644 >index 0000000000000000000000000000000000000000..9fa335c4478a8205ecacb645c636ebc07ad714b0 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(%ZSc~`v3p`GcYm&d0-Hdz`&wwV8EblU<Ton >bVB`;|89)>NgNz1o2^i011GLCa*Nh7QJb@Xr > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen >new file mode 100644 >index 0000000000000000000000000000000000000000..239c0174d361ff520c0c39431f2158837b82c6e0 >GIT binary patch >literal 2251 >zcmdtie@xVM9LMqRfk?4(Z-2m9fRIS1cJdqi5tq^l%)GOd(?~^75wR}H%NV3anRBi& >zeCt@|$f@O+HN*a(`~$6(+GyeBFXpUVTdb@!x<tZitUk|gYyDAM|Mf@T@9z8f?z{W` >zaofF~fu-wea;(1{vE~UMju!Lb{`Tk0rOnl6wO!a))qT`o)pKROoPOP@;a9!#$*w#( >zvn5^5h7#o5s#v*tBvr2+^2zrvd!&DRhWyZwB9U5=AIlwbz4W>aOz)E$t_w2gJS9I# >zM29j*%24E-jtTFMjP=izak;-}eA-n_82h<8qfe`I;9VWxcSP?vzhCb>u~QR|9haoT >z9g_UYKAF(0lCtS}NezbNuH~y`qAwt6g~c+-T_EX6F1h=*@#2c{s%tP$Cx4Z$Q+gA0 >z>Zw@0r}L(|4}PoDT0hl{tsiUVhGUvl{ibGDT#}qnr{sFNByZ76lApX+3UV5xV7N(U >zB(~~|%PVE(uk||XxL5A|tXvD*E7j9AOYhrOq_f+SbWTm07Hyp=_m{+|w>nYgreD!w >z@354_e59pmUr1^H*D^2qeVG^TmIwM?lldKQh_B~8^|v(3g2M;&!MZwmsQCq5`0$Im >zD7Z$;rUy0PE7ir$1-isNMVAa^X?c8!lwTa9j|@(hrSII(Wxa8-eE(>v=)5K?ng*n@ >zH7r$?y|Qxice-l!QCVHlqtz*UWR0goYi@a4*Cwm3{bsk;4u^DIccVUfIiQanTBgAd >z*URJEJzCdZCQsC+=#$&>W&OfJ3Dr2|sq6`|q4;NcdbB0=nekd5`BEB24Qa!flhW9K >zNuPPET{echbkm*>baTgEeYWwSHnlWqlq1R!J>nnEsF;!e{b^Zo<IEq~N=kK%u&hyH >z-TLSCk0*aU_xS^sx44W;fHxfGKywrL_u1?)U$kd)(|*UYeltg?e^L;ck*%2$GACqG >z$gGfQA@f2ehRh6^8ZtLza>(qE=^^t&CWy=snIbYrWRl1%k!d3Hv^5ju=P*-bs>ocC >z$s)5wrfX~Fi%b}qF*0Rj&d8*ZStHX%=8a4onK?3bWbVl1k=Y~DN9J#95`bg?Ndb}r >zBne0skTf89KoWsu0!amu3nUpxHjs26`LHz!K{8@%Qi9|JNeYq`BrQl@ki;OFK~jU{ >z21yQ*9V9(Sevkwq8L~AgLULqll7wUlNfVMMBvDAFkW?YLLXw4K3rQD}FC<||#%xW> >zkeu0?q#;>D(uU*>NgR?nBy~vckmMoRL(+%j4@n@BK_rDp4sA^mkt`x<MDmCv63HZz >zN+g#^GLdW|=|u90BoxUgl2Rn6wkD}aR&7mMk-Q>_MKX(|7RfD=TqL{J|FFApCdJdT >UiL%?Dn~|T9<@RT1VP<aJ?<;p%>i_@% > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden >new file mode 100644 >index 0000000000000000000000000000000000000000..e71bc4e802cbdfd9f90598029e0fda04c4074ab3 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(RcW&=_5c6>XJBMxV9-7T6k*UZU|{j_4PnqW >jFa~iMLP#+32UrIK1JK0(AfrKC0>*RM04=i9HRb{Uf07!( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty >new file mode 100644 >index 0000000000000000000000000000000000000000..49a4b4de7b31924d138a6e22aa0a16af1868cf1a >GIT binary patch >literal 1031 >zcmd6lPe_wt9Dv{H{KGOBfzEAOX4YKGoYSr4zkXdJ!D`3|iGqkygn|$mL4|^O>ky$A >z@h~ttM3+P_;o%o_^iUvOROn!b4kd&K#dN*Tm%`9fx89HUecrv__QAL3N#7Xgi<tw% >zV^5fjxSj01BX)V?f4n?5y%sGGJ<V2B&Uk&L?`nLT-(FOHU(NcL{NBLAKsGp^(W<xo >zT0PaPN1u1;u_vusb3dZTZ&qn-_hCKJwxe~CH9Z;ps;3Tp){uK!LhC=Je)UHx{AeN- >zUi>7dKYozN?2MdwH7yO}<8t=dm^2P$Bzm`Bnr^++*x&<g?ikXRo@*MfzOIQ_lP0#4 >znhai*<Vrx#Z$+hb{<pR*9g+6ee(89>E}dgra$)j|$h{T0IQmP6bGe*x6&C!x+(mg; >zaY^2X{2T1u#$2wm|Ao1fGIoFGp{vxG^lekNx9**|?8*M`bYDrENHlKeIXe?P#<-l} >zY@H?j4^lREe`en$ha89?j*$cr1(D^@3WG?4h=a(32!u$4h=j<52!%+6h=s_72!=?8 >zh=$092zO|uL&QVmJG22nB7lSdi2)J>Bnn6vkT@WLKq7&J0*M6@3?v$dHXKMi4sAe? >lh#(<BVuAz(i3$=HBrZr`kjUV$b@E?^=4rPHb~YqDe*g<+-Uk2x > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman >new file mode 100644 >index 0000000000000000000000000000000000000000..c3f0994a75301237adcad05cb13a085a59359c70 >GIT binary patch >literal 1877 >zcmdVaYfQ~?9LMqhkz7v4-2*e1A|%JDj*?3*p%SID94#SVN-dY-NXz{a9+?L*vzZz3 >zfY{9SfqUiwJ@B9F=K6ITv#{A*H{<vIo6WG9ht665*XgXDeczv8L0O64`t22NzTt;g >zmHFXwn>FTfqVAU6BD7Rndg=qMqLZc7s|U6_e6G5$b__&3f1{o|OYAn6drRBeD|Wm6 >z;nF^I(C&8VrgY!c+U`;NMS8B&KxF8lM9ppp^vb;;y(d1fql-^Vp8@CXzR4BRFJg}! >z6R}uh9#07Le|lD88%yi~r{<`)e!M+!M~3>UkK1wUizPmPpC%Nii$AqN291l6#HhWJ >z6z!J5u8oqsY>Onn+@nJtuh5~_&&jZcLLGi|x1`k7%7`sBGP0&pMs3fL(M5TZTK-<g >zWQBBWN|BE91~n};PSZVuH6yBnW;AutOt()m8$auWm+fU@{XNaP{8qBJev(Q1Z%9t% >zUCBLK7?_;6OM<z_bV}#7lIP#1d0%#Fe#dIfzrR|izAey#GqZHswG^GcbF9ud(nAYZ >z_R*O;hKtN-sk4@Mm)YsjQdIC&iu<;ZIl~@FN%#vX?Rrs4pIwo%u!mZ9>7dMgazW?q >z+br`h*6D)H2eiCygI1Jp(uFmpx@c0lhKe$Eu`i&NStYWhtzWCW<E83Dj#PVMrTTV) >zEN$}0vXh-;dE;wYvF)9#Jnq(2RkvmJ)+V)@x&HPJb2;zkVZ6V8{^i;1m*4;VS3iAg >zSy6}0L0Pf!uI852Ez)ZJ<H<K!*+DBUZ8DD_f8}!Vw1WR|t{<KMu&l4<#o6*Jr;D5~ >za>9=0jFD4zH0O+*G;-F+X(Q*2oH%mk$f+aej+{Jl_Q>fY=Z_?SWPqfA<bWiBWPzmN >zX!1Z3K{7#7L2^NoL9#*8LGnQoLNY>9LUKZqLb5{Aax{4%i6NOGsUf)`$sySx=^^<c >z2_hLHDIz%{Ng`PyX(D+#nnaOI9Zjl8u1K;-wn(~2zDUAI#z@LY&PdWo){Z7^ByUHP >zIFdP%I+8n*Jd!<<K9WB&0muv>Q-I6?G6~2mAk%=%gQJ-UWF{QVR3LMKOa?L=$aEm{ >zflLT8BL<5pLFNRR6l7MAX+h@2(M$|7Gmd6zkhwu72bmpYdXV`+CJ6tt8FHId8t7-A >YyxD_%NxsB5f1)=#A>MpUic4^R11fmc_5c6? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr >new file mode 100644 >index 0000000000000000000000000000000000000000..0e623cf746b29bf73989ffec96f26c49e737ccc7 >GIT binary patch >literal 1222 >zcmdVZPe_wt9KiACbz6-U6qV^*EB~a+)@++5mO7Vz65BL_oeJScS<s(DM2A2^qk<rV >zf(~U;K_x>XcBr5*@Gzo-M28@-f(MeIOYBgP6|Cp`u3*urWAAvL&%1Z;2HWqu)Sg2J >zqw252W3I3`I?dvI)u`E~y#9%Yx5s8m1HSO;@?E#e+yj}ih0EdckC)=!xooClwlwaW >zu9h|TR*HYZDQho$k#)l#r1HpXsoMKosuPc;rgciz2d_)5Z%pczoRWYutplI0=?(K& >zbM+_Vx%yYbdSmve4n7#vo9+zg(3K9|a5k(rpQzH|p%pqZ7?bF6uQaw-O4IJ|vc+E_ >z&5?J~{9|5PDi(Ch+h?-%+Z(-YIxVepPj%bftZsjDQ^(Ft>W=Z#I)321-hSqWboLz9 >zUHeC+yEdtNy7tKqSA*`Y>6YG43F&jxN#Bc*?0oN*#QkNGoQ>xCFXoSp<nwuDIZ7N( >z%RF3*iXMyIMNf)f`19P{=2B{M$o!ZpJ)@jTWwqs2>d{NJl-)9W;rj1$%iJ@bQOgV0 >zll>_bj6}_9GON+72p^@C#ZfqAPyNGWzy5lg`Eq$Cj7*u!Od6RsGI3iob!76$^pOIP >z3Xl?z8jvE8Dv&aeI*>w;N{~{JT99IpYHUq8NIghFwx%MaB%~&!D5NT+ETk@^Fr+f1 >zG^949IHWqHJX=#AQlPD=5GfI<5h)U>5-Ag@6Dbs_6e$&{6)6^}7AY607b)1*RE(5t >eYidS{Myf{2M(V~9GyDIea8H~0AH+hDsOKjf4;u^s > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau >new file mode 100644 >index 0000000000000000000000000000000000000000..5803a3d3e3fac98ec8bebf8a7cce414a79e137a4 >GIT binary patch >literal 1017 >zcmd6lPe{{I9Kheq>6jv(+-zyn{w!VUTHBa4ZC#?ngh%`!h=O-0LGvU=9Rh<!5Oj$0 >z6dod@LqsU#Nres`Mc<*DRPWHGO9$(q=vd#+Z$*KpZoS8QpSSnh2HWT3T^Soqt9>IZ >zH!Ma*7U$M`vb}Dfaf@@6Vq0`Q6$vfGBRk)pN55{(w{Irm2iI=T$Ck_X(3@MfV|LVb >zKDulV-@Rz#6N9$vYOn1s#q5znvpt%u*kiG8_IT50n+P`P#E(6F;>)h-xie>aK77)> >zs~bA`?!7+wazXdaywLsSr+Q%OiAi0*Z%$o%>(Y}C-RYsnE_3Oo%XUn<TzbUiDxS;7 >z#!dcX&JFIC%$b#_JG<F$3a_$eXsOi<KZuxf&$dkQ#*R5(ZgJDqYE=d54%FAl3^x2V >z8$-1hp~n3)7*uK?E`Ni{7gfDd7qki~<r&q?9+3U_P3;_zr+?mA8u3&zm64T|mE&ua >z3NUI%cJCj2Z2$V0{FEwQAa1zE55$pA@dR-N@da@P@dj}R@dt4T@d$AV@d<GX@d|MZ >z@e6Sb@$6GvLwrM=`xNgG_YnV(1|S_kT7dKbX+ogr0@4Pg4@e`BP9UxLlwKgs_>^uS >k?Lhj0Gz94g(h{U6NK=rmAZ@{Eaq&O)6)s49!+qKCPt^<F0{{R3 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe >new file mode 100644 >index 0000000000000000000000000000000000000000..808a50261335b48599f0a77e448de23b301ea78a >GIT binary patch >literal 1047 >zcmd6lJ!n%=7(j2*Mq|>!McW#y&)?TJ*0!+;sitXMf<uLm5-3Ou8ER2*5{rU`N(nBC >ziw+_V#fpPCq@a@u9UKe&2DhRvT|{tD2c?GeJ1-pqo!q>Sd(X?gFM+&sN|&zAq}+}X >zw;d)UZIk=GcWimt`QXZ%rCMR1f3Lc~W5sKaE_>~NelB)={ZZ{)_q_wFH>-(v6+QTB >zR=b|g=%M=)dU)=Fde?^a$Yie`9ZTr3T$>(G*7QW;yPk}HQ9lwF|JPsX-q<Yn+*&I4 >zeEclEAJ!!KdPPn>UzWZ{&*XIFq4eLV$iVch3{EX->iTUxGqRvV<5QaMn$}EeR5P`r >zW)qW={nV|)n|V3=KBni^J;}ZBW#nyG@^|;h=#vd8T>d8KD^BO@^|}j%TUuMfc13nI >zUAv=AADR!ikJvkTZ12Kl3$E3<qPVDYrE;i^)!Ev-Q<RXMHlA!e!|B+?l1mN@*-YEa >z@MF$}g3-7S*3v)7`Mv!;`%iTwK}4~QEQm0Ow16fKA`c=EA`v1IA`>DMA{8PQA{QbU >zA{inYA{!zcA{`<=pvi{>0Er-=g#d{G5(Fd)NEnbfAb~(4frJ8y1riJ-8b~;hcmi5L >qkca|WNRXHyK|!K|gawHU5*Q>hNNAAQ;Ji8cuY-%_EXaIcI<^Iu9Nj|z > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat >new file mode 100644 >index 0000000000000000000000000000000000000000..046c472827eb47d46e31cd69611cff04e45400c0 >GIT binary patch >literal 651 >zcmc)Hy-NaN9KiA4rIx8fOQ~Hi_Ii~B5-9}|4iOCo4hKOrI0->(*bvyzR{aMJfm<}V >zv<dYGG(3AlOG`^bH54V+?|UW$O-((=^L&p-@3{M%yR}nUkYA%$cbE)YC+B^Kx?Chr >zSFh@=Lcep|7)act;^FH|{Qc!T@%Y?G-Z`nk+iJsZ9+{!bJu`e(F(W6NX7pg)q;{9h >z*!G+mFWP1zA2XBbmYK4j%yjhLIH73CdHpQSJbaXA_v_`F=XqiUy4puD^yBF62?RuP >zO??tsDo9YoEn8ucwUWd-YiGyOo%VnDwYcF*I<u%Vr!&h9#M0rP_>21oins5}^hrHP >zC@gG4L*bzi`Bf$g6@`mJMq#7SQTQl?6h;aqg_A-`VWrSgcqzmbX1_{J;iiz&n!dw7 >Nut)OxIacPgkuUo>fWrU) > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad >new file mode 100644 >index 0000000000000000000000000000000000000000..046c472827eb47d46e31cd69611cff04e45400c0 >GIT binary patch >literal 651 >zcmc)Hy-NaN9KiA4rIx8fOQ~Hi_Ii~B5-9}|4iOCo4hKOrI0->(*bvyzR{aMJfm<}V >zv<dYGG(3AlOG`^bH54V+?|UW$O-((=^L&p-@3{M%yR}nUkYA%$cbE)YC+B^Kx?Chr >zSFh@=Lcep|7)act;^FH|{Qc!T@%Y?G-Z`nk+iJsZ9+{!bJu`e(F(W6NX7pg)q;{9h >z*!G+mFWP1zA2XBbmYK4j%yjhLIH73CdHpQSJbaXA_v_`F=XqiUy4puD^yBF62?RuP >zO??tsDo9YoEn8ucwUWd-YiGyOo%VnDwYcF*I<u%Vr!&h9#M0rP_>21oins5}^hrHP >zC@gG4L*bzi`Bf$g6@`mJMq#7SQTQl?6h;aqg_A-`VWrSgcqzmbX1_{J;iiz&n!dw7 >Nut)OxIacPgkuUo>fWrU) > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau >new file mode 100644 >index 0000000000000000000000000000000000000000..27072eb51cd838727233db12dee866fae3b81967 >GIT binary patch >literal 1025 >zcmd6lKWI}y9DpxvV?$D;gP7D<jelbkTVK;Aq&5BHQaVI9Bv2?8Zm0#tNh~c?sFcvD >zTb;zAXmJpS6zZgcgQMtga4TvCmo6QugQb@E`(CURoZP(Q?z`OM4SC;J8oxP}F@KG) >z-mn<Gx;P)XuiLY>W&2_^Vvok&d(qHZBD(W!CAPU;Y1>F9j=h_y#9x)=`15ILe>5d0 >zmd51dy-`Wr?vqp3Q*yc(motSHIh)>-bMY-XANeB5V8kZB|Fjpr?z)cIC$8h;XPbKa >z!KT;W*o&)cw)4Sb+f`n+m+qFWH#u#)CsrhLXHI$s7Nqyugk;+%C6^hJ+}?=f<F{P? >zQ?A;#TXg-eW7W$WU9Rvn>jqx7y1~V$8+y3yhHvb+E9Jx0`C6@J0u7B#4LXB|4$S7z >zfge0*4*i+IpfO%WKZ8kmrpcHQYeL49oM~YX=)QkbKL_+_e%Q3u?~7MUChhg;%IeDL >z;?wE~FzQG4(my!)@%uIXJ2l)u{BVsUh$o-w3gQdm4B`#q4&o2u5aJQy65<o$6yg=) >z7UCD;7~&b?+Nb)4IEQ%msqP{EAq_w}fV2SV0n!Ad3rHJ~J|K-iI)StT>BXlu1L?-6 >nwgc%0(h#I0NK25OAWcEKg0uzc3(l*H|FyAjK`R{W%!Ypfi5lAf > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad >new file mode 100644 >index 0000000000000000000000000000000000000000..3aacd78b1d503a3adf7fd3a9085d1c1eed94fa16 >GIT binary patch >literal 1004 >zcmc(dKS-2u9EZPWUWkT9i=BTmv$9jKUOn^P@>So|bUEQ2j)oF+s7NXra*&Yxf)EZu >zP(wi>f>A>_=pqP0G+0D~Eh6ghTMk{C0;w>r-}AZz4$;)-<#*4^@g5xS^JK0L-E5M5 >zJ7~Y*u#`RAA6EM@<#?vlxfPWDEO~cydnt%*bophUpRSZIee^44KLnL8ht09c8>VXX >ziaCC#*Hrhr=0rMfYP>RYvZ2VFD&IAyi@uuLXl$@{XGG3yEoyx2m(+dg(E3G38{XcR >z#Ea{4cJj5J8-1qE-F0aksL-ZhK$3nS&5cj=eD%1t99foB-h!mQ{ZKdS$%WO2dU5%l >zwl2(z_hv@go@cdvVpTgH#KgaSO)vFNNoV@8bhUla?!<e&Tosj`;vMM~SI2U>TqN(n >z-jyHyhbvzs{>r`;iBF5YuXCh8#PuVG{=853Wu()ddM9a5GmlFo5<)V6fBmj~GJO5t >z_kJSw-{yuM&22(-@HI+8S}hPY5Iqn@5KRzO5M2;u5N!~35PcAZ5RDL(5S<XE5UnAt >zT83VTVuogjYKU%za)x$@dWe2T0+0+CDKK(?Bmv2Skw!?H2P6?jCXiGhxiFGpWCKYD >lk`E&xNJfm57&$?bf@H-=i;))`v##VnHCE`^^4b&0!rvMC%&q_c > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain >new file mode 100644 >index 0000000000000000000000000000000000000000..a0c5f669628d8ecd61c398bc475cf2405d20000b >GIT binary patch >literal 225 >zcmWHE%1kq2zyQoZ5fBCe79a+(c^ZJk!cTJzSh^-1sQ>@}KLaBZ69a=m08p60!U3dC >y%YcEy$2WvQ+rR{fjX@GX5JG|-KOkBdfX4p^*#+W)>;uuH*vVxBwBJtGm<s@Gqaf1& > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku >new file mode 100644 >index 0000000000000000000000000000000000000000..a17d1ad8c8ef1fe25c033ca2ff88b75da7627828 >GIT binary patch >literal 1269 >zcmdVZO-R#m9LMqR+GaW}cCo3;p3IiIV(r0ZO<Vaev{^nZg{at}q(Wjv-6VfdNe3w? >zJVc&5ghf%ORM??QU_#I#li&wYK~kNfuwwn*{~AOcqGO-&-+TUj0QY+>wg1>aQ2v<9 >z+~Hzv=Hj(mnWvlOV=Zr<mvoi-u4Px0%?3P$kK>+2+nutvk}aQ)1S)1OWW7^Y^va2I >zx^n!qUNw3|uO8~tYX%c~?SZIXm#ooMu?oH3U#zRWU-gFKciQJHPy0T)(i>kDWon)- >zW@;ZUWCE`jvRe+$xr3+fyMvE1*-+yx3HMx-Nabaz4<48LZzm<{9Z}I2z0&aIsM<Ci >zk?r#xDt4n=HBS0f(@03|xV~J)2TIk>^L4VT^^<Boyi8iE=TvL+2WfLoszlWjNxXk1 >z?e=@pKKnpAUXID`+vAd)xvM%aos~TkSJmDVY3Uk0qq_TtRL@|)>fL%srIHP5pC_*R >z{9ZMj%jLvoU-IMOaQ^ZrSX$t)7Z&Be_m|p5Hcy#1SZV{}FmHO7txzNymy-N*{*KMu >z`Tb{-ohhjcgv=E&SC~H|Hfz>P>#Nj1ob>0Pzh?fq94AgWb#8O=l+&jOuxb=gBv3R^ >zL{L;vWKeWagiw@Fq)@a_#8A{w<WTfb1W^=OHIgWrD55B;D6%NJD8j57WfW-)Z47Y? >zbykf$hCZuCAVVQVB10oZBt<1fCPgPjC`BnlDn%<pEJZCtE=8|ZBbcGss*%jl%n;2` >oO_9yeO%cvePLWR0P7zO0Pmxd2Plt_-|Kk(jikZ(w)26WNJFq|ijsO4v > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok >new file mode 100644 >index 0000000000000000000000000000000000000000..8db5e8a61ee9e63164ce7f07969557fafa982dde >GIT binary patch >literal 220 >zcmWHE%1kq2zyQoZ5fBCe7@Ma7$XS$?ex&~Y|No3kObiThHXwN*$-=;pRKURD;~T=@ >z1jO0~<{$|m2qA1dP%qdDo*!Tx3=BZi|A%dBJp!UZ)`5iUfoujM?c}ln+Ha?8&IJIu >C{UtE~ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul >new file mode 100644 >index 0000000000000000000000000000000000000000..60efb41b45ba1dc51ad67f65be0361085ba9cb2b >GIT binary patch >literal 1255 >zcmdVZT}V?=0KoCHoNmkr3CfSPvdorE^SElRrgqAf=%zsop)v^V!=Pw{&<BMJtzIHV >z6hs6eN>33N`gjPTLj}D^4`KEoQc^GVP*D<v#ybCNgCGcc>|D<MogMB5+xaiC^WgrV >z_+xm?4wDfzlXXGL+y-8pp1C(TS-QY~B)za`NEEsU3ktu#OclKwOBavli;|IDY432i >zwdmFk%XhuST6`g5Ejd+bl^*h0OFQOS%VHU;Eb_@(9+<Ssz0a)``HwBX^P}`ny_PHA >zzETy(&#Q{jM{?DZJ2G&0NLCJAkyV$^$<_VGWOYxstbQ6#$-M_u&F)J&c=WJdQ{SW4 >zZr`TY`Py|TSffKf!aD42Q{jmcy?$D%4Z|}!GCp6`-7Hr152jSZ*=e=$+L%)NCe)_B >z&w6w8p=#_J)mzF3RJ8HF-kRH|n#!)~rVlrCbIwWK{OpWwdDEd|x4U$F<b-Oy7}bf` >z7uo*xz3R<mGQyEFXZCXD{&wZLvM=1OyuV&fm(wXkTfg~jMPiRI>txE|7NRpL=4S8N >z9f#SOeWo+XnrGsz2@#MXGs9-q@-f0;hH%(R`<D2JL;m*bZRWdWIBev=+2+uZgJ*E~ >zwk7~10we?mF(5%8Q6OO;aUg*pkszTUu^_=9(IDX<@gM=&nuw5)keF;uP)JlrSV&w* >zU`S+0XtpLcBse5GBs?TOBtRrWBt%;iBNC*oi4qADi4zGFi4+MHi4_SJi53YLi5CeN >vi5LkPi5Usn)<lhjZENC20!Jc8LPugpf=8mqUem;X5x%F+{3RNyYCS&z3(gxL > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut >new file mode 100644 >index 0000000000000000000000000000000000000000..72f0896341a76e6be611d04e0b1aaec26f6f4a45 >GIT binary patch >literal 2175 >zcmd7Se@xVM9LMo5AciPvwPqnC280239vD9|k&-SlIenWal8Jm2PlALJg%mQJX}M*r >z?3~eRuGEXlF(ks8xms&YUBi!C^pC@RR;`#K(4<u}SD)v%Kl`Kp^n1JS<NLiI+x>B` >zXK;1x#$4xLM~r=iC&w%H$#ud`dwMriZ4S5Yk|RrZs-wldI+C7Y-pgpyo%dWdotJxL >zD07b)8u!Sh$)BoA14>^W9yY^$VYzZ{vl;2QLq@xgs<D<bJt4AI#b!OLCziyRo2Gmy >zacKoA?#e|SA6sYQ&)p)Ee;zecjvthSGpTCo{<C`8`>|?z<1w8$?lm*dzonA~)~n<m >zEqC@EFtfrjI_2OQHM^-m?mC=pQdfN@X*E?Uy>L|Dz2IY&k(erTl84NkYvnrAsW+MZ >zlXO;Zzsf#xTs+}!<=y?d%-y<Q`8G63PGy(L4ZNo36}@Wi^=#33$&DsIVWrN$9yEnB >z*GS=DzPaz(LYaT+c60xQ6j>0-Q$;7EW#Nl6RPmcX$^)T4)PuVny~uw-l~jMPA4)%^ >z{3T!Mhhq<^($t799XV+h$L!UM``<Q?{!pivbhVkXZ(fo>`#Q7qSgkB;C^52ci7a2G >z)MJ}GvZ7#-3YJZil{3;*dDbsd{@X-Vaa)3}_-;r&K0c~f_nlQwe0yH6IrNjM?EOfu >zZ98qM!Uwdf`oOH)(Ie}N_nGR-uxyysU_wRBvN7&uRg+vHHAD64$?Nl__VhAUH<%<( >zb>^r|Ul;27y|=1{NTPna=2!L1o<H^G<u{wg&_%t)chzk5f1#VE513}}pfr!2Fx#en >zF57g6**@})v~;(c*8UgdxsEr~j;@eAzr97ZwU<hC)D84-oY{}q|FDzki<;m#Nh!{x >zvOv)B`&V!Z@{T=%|GkKI`!RPBzq{XXoWJZ*-uLAv$U=~nAWK2kf-DAE4YC|pyB=gg >zu69Mpl3eYYkVPS@LY9TB3t1SlGJYOQL)L~Y4p|+tJXgCuWPz@Bg~$?-H6n{dR*5VV >zStqhkWTnVbk+mX=MOKR}7g;Z|U}VL}l94qdi$+$BEZfzt8(FxkT{*IJWbMe}k<}y1 >zN7j!N0I2{{0;C2=5s)gl+A<(@aJ7X%DuI*&sRdFDq#8&$ka{2mK`Mfj1gQy96r?Ih >zS&+K8+QJ}}akZsEYJ(I9sSZ*eq&`T2kP0CsLTZE*38@lNCZtZTwopi=Ty3e4S|P<k >zs)dvbsTWc(q+&?PkeVSyL#l?94XGPaIHYo}wsc7Ckm4cLL&}HL4=Es0L8OF84Ur-u >zRYb~&)DbBpQc2gb6Yf2=<ep+8)kMmP)DtNvQc<L&NKKs^D5g=-|0}2Qwyd698k-%M >S=gsr_=K8V&Ilh0c;{OIN*MD#T > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek >new file mode 100644 >index 0000000000000000000000000000000000000000..e3f81ee3327308132b4e9910fffef558850d0ce4 >GIT binary patch >literal 1045 >zcmd6lO-K|`0D#}Pn=EU=bSRxxbNbzMQ^!?z*WWh57}14@QHJOsQOZ(>PMz`x6eZ{o >z9i_v9=|Q>_bcuf6A!rX>f(`?+&_NL|8Q~#WY<u6R6m{y>d%X8O9y5oT?{ltZN8{qJ >z5mq-WMnWyl`jpz1jS2n5!lrd3I-WaP^<1wEJu@q}*B(}FtmcdrLqGN*n~S`<E32Q5 >z$(qNmJpQ0x*52!o=Ixj~ajjaO96TgXb^eg2W1I3!<g+|m@li&DJL%}wm-M+e3$kuK >zY1O}5G-K}#>->{Bvtg-dHO^$srrCmJ-54;NN8eiU%vi3a`@YwDWjNnfbIVJ_Q~AVB >z#!E$p>{Ox2YcD44j@O61&K1M%T55E=Ul#42S>3%bU$E0RzquEuxAVPypWNQ!BXhD; >zDhVx6wmX9dew*dmuNl(*n1O&0eP7iN5tlBDpb*#ZXdxk-5pi&T-@nn+&F(YK2xp!d >z%s3)uwW*a<iyth6riOpm+nj$e^L_6f^)V$3K`e2NDTpnIF`vpB#2myP#2~~X#3aNf >z#3;ln#4N-v#4yA%#5BY<#5lydPh}orA5s9M0!Rsv8X!eLs(_RMsRL37q!LIekXj(c >zK&tVn%7N75QxycM2vQQHCP-0`svu=S>VgyosSHw@PgNV7RBryy;=*03#h!*l_$T?; >B-P-^F > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei >new file mode 100644 >index 0000000000000000000000000000000000000000..cad16b0dfea2ec12074c8cb674cffedbac27b0c6 >GIT binary patch >literal 229 >zcmWHE%1kq2zyQoZ5fBCe79a+(`5J)4+Ab!SUFq%}_5c6>XJBMvVqnPL0~BV+tN^Ji >zXkg&-@eN_nHZV6f0Fo9UDIf?T!ImEoEet>l{)21-(I6W^!u3El@wRf=09|0GYrzEo >DhVUm{ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta >new file mode 100644 >index 0000000000000000000000000000000000000000..b57972dd8ab55785d8cb21b90b5277d8fc850fdc >GIT binary patch >literal 312 >zcmWHE%1kq2zyK^j5fBCeHXsJEg&KfF``kUdPTlU&IKx^fab~K~ic2LzGZ>kefslbA >z=mJmygSQ(<wQmFi2LnTN1|yG$ZwP}g5PJrPFlZZ?85@8Ufk6m%yIFyfAPfRPGr(-I >zA7Cy6!+#)9+a;j^qMe_=HUQBeH-Tu7yFfI^ZD1PcJ`fFZBLmQpEI<f!<qeQgK(_*2 >h33Mya2B2Gcz-|@r0lE{ndl?wGfS%AbwK6u~0sv>)ONsyh > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita >new file mode 100644 >index 0000000000000000000000000000000000000000..95f56456e5264b11295251f941115a9b877a64e8 >GIT binary patch >literal 1257 >zcmdVZPe_wt9Ki8sZMvZnze{N?bEV5{YIBvibXuv2Iw@)tC4tZ%$|6P-6+{aCJxKfx >zMGzf~{y|8W{v6C(3Kb$$o~(mlhq{<VL=v%{@0){Br;a@@@AG;0?A>5{zHegpp#u@~ >z*T}UioQx)WaxJ}fy7g|h|H<tUv!HZ)a$&)x$$a0%nf%#jT?L;8lZz&%Cl`-4B>h8i >zT`~~U!kd-4w692u&WHw%xO7?P7hT>yrNy=5S`r%3p#Q0^$i1(np0`r^by!w@cpfM_ >zbvRHqeos~nUzgD1%Tj*lv{YQ}mdf*;vif*j!uw)UwdbHljy39<Sevfh7Swfx<ysx_ >zYW2_gTH`N~n)fpr{gEx}hu&!I#7C*S`&nXxucZFMYiYPKARG2Sl8xtH=%(gt(zy45 >zHU&>gb7P-w&e|m{#YeSe`h>Q+w`%LyPHmftX#2yc#z(hE#}&UO+FzO--^KzxsZ`3i >z-1B}Po~(=`+nezs^Nl~ReO|ZQnC>q7x0+<H@fg$B@A4UQR!v@dPOrG^O8OpS?@6zl >zym&{#gu*o@R28;H`7+~jhI2VLCH`Tbzt4Tf{=^jfjqEvteMj~l*?&jd0MY@{0@4H0 >z1kwf42GR%82+|4C3epSG4AKqK4$=?OkfZGgX$k4c(Kdy2g|vnAg*1kAhO~zChBSwC >zhqQ<Ehct+E=xAF+dUUi+B3&YFB7Gu_BAp_wBE2HbBHbeGBK;x_BON0xBRxCXrjf24 >iZQDrSNaIN7Nb5-N44TIt+rt0UeNLTyCh9AqIlln5o(JLp > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan >new file mode 100644 >index 0000000000000000000000000000000000000000..15b358f2f4ddec8b2543f883ada86d2aa3771136 >GIT binary patch >literal 991 >zcmd7QJxCj29LMp0Vx*!%ZBb~osW0_C#zgD;dz%!8nog;TMR*h`NIE=&TT6WgDYVUS >zgHut-pjgGxv1368H#>>L4cg*j4_d)3K40k|bg^6SxO^@L2O-~Ia$@#ntNeA`uur%+ >z+U>=Cv9TZT_J7phEI4%Toa~yr2d8f7-k>h~Ql;)~RqEhUK;2L0=<?U!RYmGpSH9R) >zRZn;HgWgS59oo<}WocDg@KM(VKD%|l*S-3q4{pP^_g>@IS8ixK<u$E7bHj@XuX!Qr >zM&=@3bmq3(GC87K6A|^Wzgf41Z>jcRk?tt`rFu@*oZjsf)3>_p^e-ASurTio&P|)4 >znJMQ{GHxEnV@|BC*2Jr8oF~DU4FBBpo|k;ejOI@1(X%(1vE!JY&t|jY^9ORSfBJLn >z=@&_j+y6qQwFE@8kvx&NjueWdGrl73efFN`BZ;JhqMi2YvRAi+TB5vo<w*WRfb&1^ >z+25Td1Ye1P1VN%8VURdTAS4nJ3W<dTL!u$!ka$QyBq9<LiFv6FibO@iB5{$xNMs~5 >z5*rDQL`T9S@sR-_BS40Li~$)0G74lE$T*OJAR|GBf{X<j3^E#IILLT77!WcdWJs6V >TF(HG(|6)}6eRgmI;ja7(v&hqR > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing >new file mode 100644 >index 0000000000000000000000000000000000000000..dbd132f2b0bcc8beab08e04b182751795c853127 >GIT binary patch >literal 414 >zcma)%y$%6E6ov01AsdnK0RGwCh(;k=S&0xTQ;84_wi_?7<`F!PCs;~}D7?f(B^vIT >zl7ch2`)zh+C+8E>VAZ0p#Q6&b$@1Vmt@shmEEPQ+dAwxQ={D8*Lz@c0P8P$BDh-yh >zJRhox=gVq;O|{%Y*PQ{??_KRC8|0oVI%a(=qV1LMrEqU0h@_&_Xe`L@@k|6ZIO2E7 >z93L|!ALb9D7bk4{9*EM0TpUDs5CS+32?Qb_WIzakkOCnFLJol-2uVX01tDw5!t~*5 >M#r`q2S-#n^-;pX<T>t<8 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking >new file mode 100644 >index 0000000000000000000000000000000000000000..dbd132f2b0bcc8beab08e04b182751795c853127 >GIT binary patch >literal 414 >zcma)%y$%6E6ov01AsdnK0RGwCh(;k=S&0xTQ;84_wi_?7<`F!PCs;~}D7?f(B^vIT >zl7ch2`)zh+C+8E>VAZ0p#Q6&b$@1Vmt@shmEEPQ+dAwxQ={D8*Lz@c0P8P$BDh-yh >zJRhox=gVq;O|{%Y*PQ{??_KRC8|0oVI%a(=qV1LMrEqU0h@_&_Xe`L@@k|6ZIO2E7 >z93L|!ALb9D7bk4{9*EM0TpUDs5CS+32?Qb_WIzakkOCnFLJol-2uVX01tDw5!t~*5 >M#r`q2S-#n^-;pX<T>t<8 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo >new file mode 100644 >index 0000000000000000000000000000000000000000..28fe4307d75db1d500d815b4269cfd82de7cbfe7 >GIT binary patch >literal 413 >zcmWHE%1kq2zyKUT5fBCeP9O%cB^rQ4``o=Ur=w&v&P>%_aH+Jx!f+XbhEXAdf{Xnt >zjr#xp|1&Z%voNu;F)=YPc-;Z2XYhK$z{0@b8v!yRB!Q8Sfgw7BQ3ymb0LhR92A~K? >z*2g!5!54_N4NQ#<fTS4+16k-Ggs_9TfO^0V{sGktbl3l|Z8KFsG{^%W8srHO4e|(x >n26+ag9ONMo4e}I-26+rb*8|ls(A;-iHemnT>6%&@8*l*ty`oU( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca >new file mode 100644 >index 0000000000000000000000000000000000000000..98881f093ae76753e8757dc3fa50fcf7fd1f8b63 >GIT binary patch >literal 370 >zcmWHE%1kq2zyNGO5fBCe4j=}xWg39QsoQNE&af6roSAC0;_iw|GrX*i2zcAvm{9-! >z|9?g%W+oO^78VAEkRw2)3_%wdfb8fDkO{sK417TG1O^cXhNJ>U2_N4O1`i<CHZU_b >z0FtI)(hSHl2Wf?a5W?=`1S$r*?*~*D&?)~j+uHVkXpnnBG|0_h8t85i4RSk3ImrDW >Y8srBMT@RFFpoK@cY=B<1(>3D)07ULl`2YX_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus >new file mode 100644 >index 0000000000000000000000000000000000000000..ac457646bb0205eabde9526bff8ae41d33df550b >GIT binary patch >literal 2320 >zcmdVaeN0t#9LMn=AVP>}q$?i=q$0+{1+IVv2o@4)7yAVl$Aij`C<zHV3K0s(acw@$ >ztSxIU(pChh)moZ!%dxgfo4V$&TCv4yM~h`ocH}{WR66hDpZ(Q;^}W0Ib$0LgkI&m* >zUc25a{&7LhH@vz1&YS0{rt|T}(AzC<Zc8@1)*Ue3s=D3m&gn3EmJOS|QB}sFn6J&l >zA?@~+7mCDC#cRfJ<05k;YpXF@@~(L`+HYUWxFD`gWY}X7--@vdC++dEhs0kW|6yDo >z_*~rRZZdB633Fn5uPqLyiGZ2`Be0{!3|bLkPpbOO3{H5-o}3pWLc%{YLKhU9p}&vY >zVZl2@*m;jJ<x;o^fB%><^-QiAQCDV9JJKko`<^%M8aX9q4b&U6`&WuNeM3f6$$SyL >zd(em}*dp%UHOrot-6ZDM9kdsCKQd!u^Nocwmz#0HaYo$L3Tx3%FUor^&QbAaXUc@5 >z2`aIxQYUp5Se`v?GP$i)rPRNtQ!9n?$~3(==b}nWeNv`JeX24dJN1&lSFI((=jFYF >z(bj$6_+{qlVwH7bhtBTZZY|w^Qs(UZP~~pEte4g0s{7Y8>IZzAth}YYa(PmZ%8$Gu >z9}Lg13gUBQ!Dz8sF=eA(ac<mN`AeXD`1qa5cjiY~xNl6YI(%9_(lnstu0!%sf1fI< >z-7SmLURVC29$hkHn_BJNsaKCwtJ25~y7apat8B=p%loRViZ4BS&4D~??a}FaU3;um >z*_kBO+7PR%b((xE`)8}V{EB>h;biqh=2vok@Fi6<`?#zbJgaJhzR<O&-ccKVIHv2m >z_o}Bpd0E%*Jz_O<J*%H?*kc*bmFbPE8mvv#S-R09ttMZod?vzcH791u=F2mzmhic< >zr9V||{`IEZa^eovdd`w<uZ*hp53cL2&Hbul-}hPs2K*;qLd*+w{`EzCO28x`=EjKI >ze1(3IpI^*}pI@Bw|BE60dFxNagmVlE85J@tWL(I=kdYxnL&k;-4jCOXJY;;x0Fe<Q >zLqx{t>I@PYrK>YcWSq!Ak&z-pMR%+`Fj&qREyr+?@gf68MvM#@88gSAkx{!k!$!vK >z>I@tiImghEu_J>=M$a*PWc(ZfKq9~q0we|;K|rFw5e6g<9DzV0frJ8y1riKbCmKjN >zka!>gK_Y^L1c?a}6eKE0Sdh3Nfk7gJga(NX5*#Etu1<K6_#gp7B7}qpi4hVcBuYq_ >zkT@ZMLL!BP3W*gGEF@Y;xLlohApvuBB8G$vi5U_!Bx*?5khmd%Ln4QS4v8HSJS2KZ >z_*|X%ApvxCB8Y?#i6Ih1B#KBFkvJlOL?VfV5{V@eOeC5}IFWcF0d;jEiiFhFi766P >zB&tYQk+>p(MIwuY7KtqqTqL?kc#-%b0d{pFjD*<Li7^snB+5vbkvJoPMk0;>`%s5D >a%}(-C@5I8zo^(%oa!O)hYRavru)hIHh^b=$ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka >new file mode 100644 >index 0000000000000000000000000000000000000000..98881f093ae76753e8757dc3fa50fcf7fd1f8b63 >GIT binary patch >literal 370 >zcmWHE%1kq2zyNGO5fBCe4j=}xWg39QsoQNE&af6roSAC0;_iw|GrX*i2zcAvm{9-! >z|9?g%W+oO^78VAEkRw2)3_%wdfb8fDkO{sK417TG1O^cXhNJ>U2_N4O1`i<CHZU_b >z0FtI)(hSHl2Wf?a5W?=`1S$r*?*~*D&?)~j+uHVkXpnnBG|0_h8t85i4RSk3ImrDW >Y8srBMT@RFFpoK@cY=B<1(>3D)07ULl`2YX_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili >new file mode 100644 >index 0000000000000000000000000000000000000000..c94fa610f952981a865abe4a9d9cbdc26946ab3f >GIT binary patch >literal 253 >zcmWHE%1kq2zyQoZ5fBCeHXsJEc^ZJkq-PRGPR}&@!2Qag!1C}+hWh{i|1&T$F)}eR >zFqG~ADqtvRU|?ZjsGGpR;o}>^plx6Q#FiilAP6DBwjU5J3_uJ1gKP!SAe%wLAlpGS >W$ORx!50oR`6<jtz7uo4rasdD#5->Xe > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai >new file mode 100644 >index 0000000000000000000000000000000000000000..c12f31a141db7e6e02f7274e114c1cd6be2ff1e6 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(!cQ|-)c^ngpMjB)fx-9&P=vw4fq})xH-tgk >jzy!o)2qD49A7C8}3_uhAgNz1o2^i011GLCa*MtiIP}?0H > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe >new file mode 100644 >index 0000000000000000000000000000000000000000..67c772b4d9d711dba166b802bfc5e1f64ae004da >GIT binary patch >literal 621 >zcmchUJxc>Y5J30zG$ATnqsb*v<L3!M2tpK8B$XgUNO6UTg;*#73oENg0=9zw0E+`V >zu~D$Im|ASCZ7j5~F^z>5dd@oy2v#=EGV_*U7iQo3tJTdZ^DE-oA&Immd#9o0)ZK4f >zo-_-+-d@m`x^R;5^IY=n@hJ855V&`)lfJ12nX6sNo^470@rn!_EXiPPR&v{U8CuKA >zaJffD=00RJ-;}Y;y^MF=if6x<yqD+F#PwmN9)_W@+S|UC-SJ~}#$v{l7{V-8jBU)u >zj-_+?>!!O^TOCU~oGCB+CSNFO&S*|^)mR$QMvMQ4*S~&W(g8y(Kupla2E+)&N<=jS >zu>&y#u>>&%u>~;(u?8^*u?H~-u?R5<u?aB>u?jI8QSCwu!@AD?f0h&T`UeY>#l$CU >CZF_?N > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta >new file mode 100644 >index 0000000000000000000000000000000000000000..021f8a2dd78a0a493f58af2ae4107dfddb4f2d40 >GIT binary patch >literal 2042 >zcmdtiZ%kEn9LMo<LsnkYzGy~v`D2nPc!3L7Objw3#6Mg;#!X8ljtLhmqC_Dm?Yc>< >zIp)49n{(-A6IpAHbkllZf2KKSo1?R(4_afLvQ=xs+RWLXvHHD__NWKWr=7cdUT0_b >zKKs2t@wJ;0CDwngyUiQETuJlgIemw@9epi3JbvT@FF3r{P5ZOKoABv*dt!f?Gild% >z?!Db1N7`4q=^MwK$+ez6B{t2wFM8IVntR5%e@efdk#fYzxYlDoaOEv$+E>l?gP%7! >zp^v-W%ws#ftb++RySLHH*|x-;-cs#7v_9XRQIqH8mQQdW4ySoDL!<5^X(QgO)HHk6 >z^`JBRhY>sP(p4w_+?V#8lS59p|Abx8cibuL-e(tW-Rnde+U?@HL9ZmX$BkB~H@9Gm >zTbkA8%`54Yd1FbLAL`Tj!yBaRuMS=CNu@mY&9hoQP_GrI7wF?Xi*(^TnfgQ`R~L1c >z$&-sywXz{3PtE*Et18E2aq1UZo%^j+kNzl2Q_jfJp$oF?$`M&U_`cL!{7hrJdu7G3 >zcXefJtJu9eb=8_(`gBX9);`*z@tSIVCS!%J4(I9W8xdXOCf(<*&z7|x{-*0L2W9=? >zbg4UeRh~~?lls0Paq2J2hV8%T3kyGzjdd5bA?JWJRt#$5o>SVCrP}oKer+CW(@ht; >z^u^)0zVzNYZ8^VLUVghmTL)_8mF66MwWm}zuPT?eM22iB&X%oJe@J_}B^^amwd2?C >zrE}5^?R3vc*XY;!`tbpIW9YPQJ8)LF4<6DtyZSY`JE_)Pfjj%8jJy3O_4Yrx^$W|& >zxnxeCl^+R=v#iYN*7$$#H{aw(tcf?@)WqUeRaGswxHTsd<zIn-6}UzG4$k}U{MTH6 >zn~QVLGiM(;|40K!2S^J@4@eV87f2gOA4nreCrB$uFGw@KrW>Rkq#vXqq$8vyq$i{) >zq${K?q%Wi~q%)*7q&K8Fq&r{J9?~DuAkrbyBGMz$B+@0)CekO;DAFm?D$*;`EYhv7 >zX&33&*EEcDjI@mOj5LjOjkJyQjWmvQj<k;Sjx>*SkF<~U?`t*y*#Td(1;`#Cn}F;B >zvJJ>SARB?~1hN&#ULc!+>;|$O$bR^m4MBDU*%D+=kWE2$1=$v4UyzMKb_UrRWN(no >zL3Rh(9%O%z4e~WRglrMAN6022yM$~LvQNlHAv=X^6|z^zW+A(UY!|X$$cFiv9YeOv >v*X$XxX~?c2+lK5LvT?}H;s0stf@T5>N*Kd%ELvDv7%7T|W5p5wX>RZzDF@N9 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza >new file mode 100644 >index 0000000000000000000000000000000000000000..60d0de00ad21c8a7260046dc49fdfa9e040838f1 >GIT binary patch >literal 2295 >zcmd7SZA?{l0LSrj1xaDl$ZXCLLL!QC@$z)TBnY~onAj<=Opu2^$%E$8DbYcI+?uhO >zE`~kL$-)<mjZG)!m~)LDSdXUN6Kbus*1s1jLx`h1C^)76_wcf*>s{yU+|Pd(?wh;& >z`+5tvRwioyx`Na@JX|g6;XK!;UcN8*RGz=`m44y)J?*D&M@@for8GNh&7b!R+4t@b >z#>I**-=%HR?00V#{i9BOAmpqVxGc=;gOk=^_YQ5y-)Q~)@l9>G>$G9jF7n-IxoX`k >zEYL=F&o@R_9`cQCXfwtm!hE;feb%k1Y;9s*kTLPsIc;)cg>`3fmOiWgpqzEL%bYzv >zAc8xR%<#`|%cl<9FeA=Si3Q?_9{Khu5tZ9*K3(#OTo_rbM;E%pA}vFY2^o?xzg#sJ >zU-!!;Uk2#0mj=bs&IRVO&njfx0f*^4x=O~EcIwOPVx?>KH>T^_BQl{pM<izUiX_hx >zksQ@7Qlf)}+tDQ42S?;HPnL<)Adj9p)gV_43-j4OOXW&`mYMcNrhM*Xw3*(vP-Zj- >zna?-Ql$k|u$*huV@`cPZmdDv4vLC;z=REqG%<11{tQwprSDy(pbAOzaYmTLf7f-~u >zt}W{^^FEkpU6<0Uzf}FZ&^NWnm%TmW70)q!eR7-d=5E(F%<Yr;vFr5wv0iKAoO5F1 >z<#wxJ<hUs8Zn8FAd`}d8xWy_yZHSV6?--@6homT}GRo?A%2(5Kjm<^6ERR@bRHP-! >zihH3(RrnLK>W^V#%bjt#^}7)3wJUSPwvHid``2S)N0Z;$+5W58Re8!X_Ma86=e%#d >zQGQhHj@e^Xdm6-^#||5Nok!%};cBBMv`*Ie^Nre}V)^FDRHN=fhOBR%Z#0~UlKX1h >zR^vzMVus_vcVNJM?-`Dn+z<ZzfBvhcMe6Eztu1vq0yQl>Qk!j`L+x|e^gC<wyjphl >zdS1L*u17uUY+sIPyboW|VfCN(if&JTM4M7qL(iHnWL3zrkaZyoLso_?4OttqIAnFm >z@{sk}ss$n|v{g$))`%<;StYVeWSz)Dk(DA#Mb?Te7FjK_Tx7krYQe~gZPk*IH6x4W >z>tNNkYT3xTk%c2GN0yGP9a%iGdSv;?`jG-46+lXW)WB910jUB~2BZ#1A&^QSr9f(d >z6a%RSQVv^H52PSSMUavpH9?AkRK-@61*r>C7+X~tq%=rvkm4ZKLCS;F2PqIzA*4h| >zjgTTCRYJ;y)X7#A3aJ!QDx_9Ov5;yZ<wEL(6bz{tQZl4wNYRk0A!S4Ah7`_LRSqeg >zt*RYTJfwO^`H=b{1w<-{ln|*QQbeSRNEwkjB89Y7l|)Kut7?f96R9RrPNbelL6M3g >zB}HnA6cwo|QdXp{NMVu6BBixewMB|+tE!8X7pX5&V5GuGiIEy3Mb;jc%=-p8An<>j >d<Y3imXCl>(%S(z+j(0Clh|5cG#iwuz{s)+r^!ES& > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin >new file mode 100644 >index 0000000000000000000000000000000000000000..dbd132f2b0bcc8beab08e04b182751795c853127 >GIT binary patch >literal 414 >zcma)%y$%6E6ov01AsdnK0RGwCh(;k=S&0xTQ;84_wi_?7<`F!PCs;~}D7?f(B^vIT >zl7ch2`)zh+C+8E>VAZ0p#Q6&b$@1Vmt@shmEEPQ+dAwxQ={D8*Lz@c0P8P$BDh-yh >zJRhox=gVq;O|{%Y*PQ{??_KRC8|0oVI%a(=qV1LMrEqU0h@_&_Xe`L@@k|6ZIO2E7 >z93L|!ALb9D7bk4{9*EM0TpUDs5CS+32?Qb_WIzakkOCnFLJol-2uVX01tDw5!t~*5 >M#r`q2S-#n^-;pX<T>t<8 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron >new file mode 100644 >index 0000000000000000000000000000000000000000..a2e1b364f9b50814468b5bf76290bfeec2bac37c >GIT binary patch >literal 2323 >zcmd7SZA?{l0LSrj1xaDl%xvZeArVEn$m0!@An1Z#6FTLU3G(nKdC+`1B{~QYYQ$!` >zm}xbq3tuocmQBpD<{Uk+9!<L^)LP5dzZVKah@(6xIHmvh@Up2}uR3Sve*U{~-`w5b >z*PFk&JYM_P6`<bX;X0@u&T|^n%lCPo%5zt~($62itNrxti0NxCmu7pl`E#R?J@5Qr >zTqx^kxVS}{eXfn7Z^Wth2b~uEmxOt3V8R;c+@=ls>aD*&yrB(soHDHHg$>saT(xfG >z=V`+`=NTg__BV{KYca+`XEoe(^;kD2Gqv%#0mk@WXSIp(<<{**8TyRceR9T~4s+&M >zzX)tgFhf4SC7;}T-3&c9DdvmAde~bhMYyNae5&Xpxge}ikI0V|3$-*oGH6gn{&Lk^ >zbj>Fhf9a=3T^tZg+UJ`~&y>mNy$;iPWTlKLZr7L9M9J7y-<Ywz56QUFED@jHEfU;| >zMPhiXNQwv)E=QAa?HiU)KVBk|1KfJ@WSv|-B+O_2ES4*L8D`2C>GIhV5oT)30-4qv >zU_MtrU8WbjDKm<C<@4#ES#D>W$b9sUp7ro=GOKTgv2tLpTy-Wu_xv~^S076eFMNDi >zt|{p<vk#3Q%}MIka|(iFPUB_$#me7>zTtp;$=fAfb|2H%CbkH#XRE$$PLIru%F%O2 >zyRG%J&x-YzTCKd{<08Ma$=Yz?T~YA<Cadt2A&U0AZ4@8fFGW#>QBu2IzLM%OHWuiz >zG<2y^mJ%<^?gkqbA&<$5KZcA=x5wn>?}DsXugn%(+6JwyUyq7yO+IUT>#t%*`AN%Y >zJS|?!I%vIKdPMAu++|g|>%^`{-ZOSP56j&{l}1%?jjZzJ8r6e^@{JS8M$P#&S=&6% >zsQV;b?x}KF^&g~)X^#8f{(kqor#Yr`-~aRf;jfw&)~kNu+LBm@zovzRX*2C}uzj92 >z_0F1Xua=p)mKU$)ajQq2?aMKR_rZHQr2f<1)2*qGXp`!y>stK;vM*#~$j*?hA$vnM >zhwKj79<o1VgUAkT)fSOG+Nw<=yF|8$>=W52vQuQM$X=1nBD+Pli|iNKFtTG?wPj?_ >zwrbPJu90o?b+B(+wQ*$U$kvg)Bb!Hdk8B^=KhglC14s*y9w1FXx?ro?fb;=r1kwql >z6-Y0TW+2@_+JW=~X^5@r2+|UyCrDF}t{`ne`eLgZgLDRIjjiep(j25aNPCd}APqt~ >zgtQ3h5z-{2OGulLJ|T@lI%TU`h4cz(7Sb)GT}Z!>h9Mn8T4t+yW~-WpbPZ`6(l?}W >zNav8&A-zMIXREr0w9i)c4{0FML8OI950NG!T}0Z5^bu(!(n+M1NH39Q+Ny3M?X*?> >zL>h{86lp2aQ>3X#SCO_NeMK6JbQWnX(p#jtNOzI;+N%B{4YpMsMp}&Y7-=%nWu(nW >rpOHpu4~pnL6Yb~!zm9aEs<$(qjz?!F#3aVJmc>P9$Hm4ZaSHqgVbA@L > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh >new file mode 100644 >index 0000000000000000000000000000000000000000..92642679c8f9e68c125a8c6fa740ebf61df82417 >GIT binary patch >literal 389 >zcmWHE%1kq2zyNGO5fBCeZXgD+MH_%bM~`#E#KqcNXHB0qT#P(daLL;4!&Rf*0#CL* >zX?UwYgMrKTI79va|Nj{nnV4Can1PUqfguH`k%1xk8v_diLs9_)Cj&!40|PGuL)`=h >zL5PTtZwNyGh|o4L2Vx5#wghW}5g{bF^9NKD&>8<h?gh~xH-l)9yFoO_?I0TDeh>}v >g1BeFs14M)T0s<iafIvM^jM{$UvH|+mPS>0Z0QvW1Z2$lO > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong >new file mode 100644 >index 0000000000000000000000000000000000000000..dc9058e4b578ca8c9bb954af1bbe26a964eaf408 >GIT binary patch >literal 1189 >zcmd7QOKgl$9ES1JxivGCw22K1;+B(05gVrxw3R5GRu?8|QlVubhN3I1CL<z|5Rpho >zNGz=WMMPLQHkNu3;#y<Sx^=3h>e7xGTH`z)iG`KeIFs-DolG*Dd7oHQeCrbR#|gS` >zcsQ%w!@V@=UI*h%*{-2R+nrt}H>3NK_v*H^-QRxIJUCt}534Vko>SN4(TXaYS~yoy >z`3jq!5|Z@e8TQHW8+mFc?6X_l(tCEg>ASE&Ki@xYUYzLCFB{_K)t>YE^`fZhZ|;!H >z)N(VhvRwvpYwh67!!np!V227j<*hBT@A?{K_~eLv-`T21_TIH0WS#!lc*TA?v{-+x >zykkbUmFclrmrb^2RDYS5Fu7@)bw1c)@?)#?*Zykrt+!dmZ*Q^_*Q@0F#Y$T^Ge^|X >z*|sPV6yL6Z^=}-IKz+srYXUm7)NhLCXLRv_<t7~J)ZuK0iDb^{Nj>dm@{J?9^mK(O >z+ubV4SLE}%=ifd`?TENPSS5}X1(a$_sxWs|^7CF-A5&|h>v_dgt@HPZ{l$d2Uq36j >z!<5LJ$fU@u$h643$i&FZ$kfQ($mE`Gc4T@_H$Rd9k^zzek^_<ik_D0mk_VCqk_nOu >zk_(cIr^^OO$J6D5B!pyyq=e*zB!y&!q=n>#B!*;$q=w{%B!^^&q=)3^=@LXTL{da@ >zM3O`=OD?3zad`rXBAFtoBDo^TBH1G8db)g(ggsrxNXkggNYY5w_#dPlakZD5$PYD~ >B5Gw!x > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd >new file mode 100644 >index 0000000000000000000000000000000000000000..f367a550ff9affc140c118081917effaa31d1f13 >GIT binary patch >literal 921 >zcmchVJ1j#{0ESOJ5>etV60cJ4N7b_)LF>JsgXAJ1(ndtQ5(cBk8AK4n8M-mtK`<EZ >zU?CO>CL6IBF%Tn(K~m>yY$l7pIsNXvxlNk?`_0jrsXFm13Hk|#`1Il0kos%m_A8R+ >ze6=!O?p5Z4Q)JzYsqFKB%sKWe*PdJE?&PVw<v8h{cc}caCt1+{s0v%JWs&Df6=xsG >z66c{RO}G-J@0Ui|)1fH8J1{CPw}j_p)2Q5^6W++IQMDcv)k_0L&1AKx9iLWp!G2lq >z?^8anS2nmRRby(JY<an`TTjlcw*6DvAK9}4>$`UQ(yG-lxng&kVXLbrWOw_zte&Dy >zyVn(R52YX3!-)%W_+#51c^;H&(P&gS;^Y4Ki5Ft%P1hjIFr6$)N0JZ|iy~zpXbMkF >zqdv|0H1SF-<{$d~{P~UkYf*aUmaZXvLpmq)4(T4!Kg0pV1H=Wy2gC`)3&ah?55y6~ >z6U0@F+84wb!5hRK!5_pS!6U>a!6(Ei!7Icq#4p4##52S-#5cq_#5=@2#6M&MkR3p_ >j0NDd%6Odg%wgK4(WFs-^oj|q%|7$PFZF)TcZ&UI&a<;sc > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk >new file mode 100644 >index 0000000000000000000000000000000000000000..84136366d176279caf6b7a55c0cb1e270b41d334 >GIT binary patch >literal 1276 >zcmdVZPe_wt9Ki8sxz)135t`Q2o-$i&t=24?I{(zPvE~lNh!`1ISqL3QL>NepOu9sL >z$PUusN9HX$X@m$Ocqovdj0y?*d+8De5k=X0zV8}H9Xj{EJkR&t^S&GGeLrt9)qOIk >z{@PZW6$V?x433L4X1cYiXmV_L)>Y!^%&aaOoG*0_s?u){(`6qXWY*06m|r`S$hap` >zQhp~c6*t3DdBrd5dMibrE|T>}lx&E9lB$Ncve7py)$VE8v|>y=_BYz|`H9~A{&B$D >zb3WjGI;yu!k7(cM4ZZdDW$nM-qqkk^*4xjfbl^l>@8~!u!7~S>rtz@sJXj;UD(a;+ >zSR%Cx<q~oSb?D_!srz26>nC1I!`v4g9$C<h<1cj6z$@K6G_G5^ru3fvXR^0#SVxZE >zm)7b5-4+>=eU4K)TGcDjkNpxWI4ZG6U9$gOi^T6nrG2JDC$4%W8Gr8T%Vx8-CH8{c >z?pV5LU*=r&VeyGSkC!_fN_9?|JIZWV>R4JimAY`vW^Q#lqg?qpzhW~h`D=I_`E})L >zPb5{$3}0Zk8Fgla_*tcFxh?l0Hz)u7xLeJY*5m&A`-|q^W)I!F*i3o+6at)v0fhpE >zgH=O<!h%AB!h=GD!h}MF!i7SH!iGYJ!iPeL!iYkN!ihr4s$oT;Md4-D5Th`oP@{08 >zkfX4p(4+995Tr1qP^56AkfgA*YG_h;S~Wx|Oes_;Tq$HJY$<dpd?|z}j46~UoGGL! >rtSPi9ysaAI6y{b9bqaS1c?x?9eF}ftXAG$S^c^S+n>VD%A1eF>x<V9k > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul >new file mode 100644 >index 0000000000000000000000000000000000000000..9a53b3a39063e86859b12aa755b78cfb38a26709 >GIT binary patch >literal 2166 >zcmd_qe@v8h0LSs~aUAC%)b)e#2L33-Ls3H@It;<Wlc5Ja>4}@+_AJqKI`%DVt8C*I >z%*}N3aoJ>}IZ`4=&bD-ITIsP`!!UYMED2aoYqmKz{nnyi%&zbIskWMb)cUvYv*%vN >zaq!3OKJWOtEt^WkO=qfpg`3l^Z=Qz|`oY>g(b<)iYj#~cZ6DgW!8yF+1*4}iVZK&# >z!tN~$JFkb^?7pHRv+t`L_8UL%a*n>g$QWq5W)7tK?XxQ;%#Vf=#^B&F^W5cr<I^Xu >zI_I|rj0=Y<&EeWK<6<n^`E2eE`}5-K&ZWS5dnE0EIdY}O{^I%(bM$<(F*a<Q<Hz^f >z-+q76{I2DcJ+V2%{9$Iq7Tu>D&(`C1TH+PQyYgi_ealJHSN@if(fX3~R~||DC!ZF9 >zP;Yl&bg`4E{B~Aw$jlm<ZDjXUnz!`sGj8q3GlM&~8@E5+nY^Q+Lfl#RTr#I%JaJdJ >zIhpG{lbGhOPKI{vH$r3klldQBu%~zB7&G>4S2Le)QM0zKQFk{lSNFv3R|Qo?YWDn) >zD$LJRbEZzJurDmb6VqhT<$#<!{EM9T!Bts&Voc8O`B*O4-L4jPyeaQ}s#}({?30Vu >zzpF~0JfO;!98~42o>livPpFF0M^(j*$5bTm85tR0rYa}b$;I!@Q4fq($*SI3x#XQ0 >zvU+EstmzVR=_bE?up?hR6ulyAH~gxW6%NX1t)rryrOtBSS*xz#%V6ELZ-VvS{$Tyk >zKyby^hl4AR^#x<+&R7k5$F0VruUZecwg!zo?bah}U$j<j+i0zhoDRlgb=I2PMysj% >zpw;waiM95Vg+^N{mGXGg{>zo_`}0ckX88Z@<((3^>GJu6$Scy{NRhW$qzf^x#4|;R >z{8=Jfh{#gUZM-6K{{H%3-@|WX4RKMg?`U*24{=dkQm*eZ{;NJ7eSUxD{vhK2yp<09 >zPIoIm{qcwTqe?ZsJ#Y!x4zeFty&+^r$d-^jA)7*Wg=`Dim#f|wvNL3B$lhG_=8)YX >z+e7w;Y!KNYvPEQ%$R?3pBHKjviEI?vsjJ>9vR7oY$ZnDCBKt))jO-ZQE%UkQJp-FY >zc8zQs**CIrWar4%UG?5MY~EGx9@##!e^=cAqytC`kRBjSK)QgmfkPjVMj)L)T7mQe >zX@;xr2GS0sA4o%xjvy^TdV(|s=?c;oq%TNgkj}X3)*!t>nuBx)X%EsLq(MlBkQO05 >zLYjnh32773C!|qGr(AWbkY2g!W+B}|+J*EBX&BNmq-99YkftGBL)wP)4QU+GIal2} >zq<2X3Ty^)5_POf*Aq_-2h_n#tA<{&oi%1)hJ|c}oI*GIr=_S%kSKUpdo!F+o>*D_y >O(99|w*XjjjnZE%*@2d&` > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta >new file mode 100644 >index 0000000000000000000000000000000000000000..37b4edded8bcd470f1afeab00ad16b6b1090ebd3 >GIT binary patch >literal 392 >zcmWHE%1kq2zyRz(5fBCe4j=}x6&irV%8J$pyTtA#oZjEuaVhLw!F8Ks9Jl_fF?`v& >zuY-|^nT45^nT>%VMFFT3M6xh2q$_|-$gE)CV_>M8z#ziFP|(02!N8DIz#!w}8^YiO >z#M%btMg}0#7(`kEu?0i8rxVB!BoIQ_t(-vRV7LB&>iZ7__Gz98AR6R$5Djuahz9uq >dM1%YRqCtKE(IEeTXpo;6XzeL3pg(oZxd1b?U(^5q > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura >new file mode 100644 >index 0000000000000000000000000000000000000000..39ddc84363768c6b407df1077f69ba9dfca8494c >GIT binary patch >literal 251 >zcmWHE%1kq2zyK^j5fBCe7+a_T$k`=!aK?p*ogcnzU6jGV$i&RR(EI|VsBQvCUF!@6 >z4ltX~$2WvQ+rScpjSU#WJwrf>z#xPK8-GCc{09P%%^(_NJBTLV1zbSq=vs0C0F<0E >AHvj+t > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem >new file mode 100644 >index 0000000000000000000000000000000000000000..df5119935c5b01676e63d1fb1efd7273b8b4b452 >GIT binary patch >literal 2265 >zcmdtie@s<n9LMp8WDL=qEV0%QuuMboa)Ap{Ng4_Qf!yN86a$VCn5p!b#55tF?1vc^ >z&SkCnbIaK1heO4-<|1p;*+y_umZ_LeKft>LcU*$tru4i|t=jsdKim4U!|Uu0{$YIH >zfs*A_DdHa&W<KHJ8qLFdlrrCTd$V3UvG|~F@A<<2^+z{F$MLInXJeJNo7dUjylm-{ >zuYV;^Rko<E71};sGQm21A@=BZiHGHxm~4G^e9$?2>5x9x>J#0c#_99=4e@<zhq|!u >zbEO+<#Sg{x;>Wf;>!&oI{qxRiqG#enySL_)z8HB@1*eUOV6e~*uWQiZH(Kn`gTGi2 >zO(}MC+mN2L`HCIWK4QgM@A~659<V0o9=7i)+pX`8EA>w)@mlwYIsU0*`t{Urd+lkL >zI`zFrNBQHs`mE{AvG$B3l{#T_h&^-10_`bp_9w27*WR3Cc2dsUI(c@rKPBmq<-7By >zof^5_O1;wLpA{OeW_5<h^ucm<U-z)S-|m+W>|bKdes8bL*n7}=@THA%PTd|ocTJjn >z$iL6Z%x@I)ath`Agw-M|X3)tVTO_jkDx3v<sUqj%fXr>bUF5axbRPb2SmbXR?G$W} >zQVTcjkcBnZl)o&~c_eT~J-RYi7Ws~-K>iH**o0lGIN?@Ve076b6cz6*>RPH64~%h2 >zTIZ=HUH#7EyDU-K+Ub<lXNvN-4mein6tT3vLq3raCMrr><de}sQJJw#R)vMCWs_>; >zvYuY`)Qw`f{MZTg^!aqT;{6ZQ%HsiN)hk<6byJ%2Ol7r_uioLTUf3X>t-S86@vIUx >zS>4Wa;|fKsXIR!=P7-U!os(-jZWHS+e<q**ctEW0*dy!SiB$FbUz9J@{;D>-Ss_D4 >z-SX#G=wGk@)teBL-GA@6ArUIXbZ<zw5YcgBtPtsQL&pF9Nq#{<<e4XTzIlq!y!`zF >z|Gu5A=I7n*4E^zoBj$=f`SLolC1g*?rjT7B+d}q*Yz)~MvNdFH$mWpUxti@E`$IN} >z?9kP05!oZMNo1GEHj#ZI8%1`CY!%rnvRP!e$aazaA{%x!JLb>9mR-%Bkxe7JMz)RY >z8`(Irb7bqt-jU5CyGOQ<>>p`>tLXsJ0;C5>6Ob+-Z9w{fGy>@a(h8&(NHdUbAnic< >zfi%R`bOdRMtLX{S6r?LiTadmWjX^qtv<B%7(j25aNP9T?gEWYvLr9BUO^=W!adZi3 >z6GxwrMsaisX%*5dq*+L}kai*cLK=p23~3qCGgs3zq-(CGZAjmc#vz?UTF22lq<I|O >zL)ypDKcs;i9Yk8l(L<z(NEcmA8<9RDjYK+$v=Zqh(oCeANIQ{!A`Ru}DAH1no+3@< >z=&Gw}D@R{lO=CGai?o)bw@7o5?jr3)`YZmA0gf<Po|$a=oKTSB@p*iS$!Q4%NnTH? >H#~bk*I^)#B > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul >new file mode 100644 >index 0000000000000000000000000000000000000000..80429ec408040a47f02ad8ce33fd203013071acf >GIT binary patch >literal 229 >zcmWHE%1kq2zyQoZ5fBCe7@MyF$hq+Ix<mc{|Nj}8m>3uw9sorcEF2hE7#Qq57&v@< >zLm0FTOhDM!03-zjA%rae>IPfF_XDhhfdOd#|ID^o3qUl;LXdDhkj+4}tz0%>H`wW# >JSQ#5|0RWOzC!YWS > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka >new file mode 100644 >index 0000000000000000000000000000000000000000..fab27defad0cacc1110a5f513671def88583e0e9 >GIT binary patch >literal 1198 >zcmd7QT}V@57{Ku}owY0|4D&0?k94gy+h&QS&gDm9n?bRwYVgn(^l=f<MIfP3K~O<~ >zM6IZczD7js!h&Lf7bCim@FEDT;DIFQCU#Mf6|DDvmayomyUuve@9aHigYEgpb{;$s >zwEj94m>m{Jk6BzV88xT-JFa9N-%d=GyFKA$mGM-CYxhLO>}7xDr%U0g=}fA6vOHXq >zZjj{<mrCsor>r>tRaOpvl)A%jq<+^+X^1?P#*PQF%6na!YA#6g!js~5Ce{7rny#L? >zn)RFrXFacnbxr1oddK6s_Rco-jdg3w8NaSOUa$UrWg3WwBzUY!TD$6G{q`TSp|(ic >z0`H~m=Zv&h&uaU-7qapDTiujSO2_nb?Yx`Ou4lJ2boQQhCr)X2|2f@!`lj^sAJX2v >zqte$D)&AZ+vZbU&2O9fi;B!O<i<@Qel~1;Qa7pCRVu?-$vqKkiM@MqGoaHDk%D<c? >z1+RJY3*Hpo`19I4=CrJ_wD~iwM9MPPPo^9$%SujIi{{RAI}Wpxe}=o!p_t_j1k7qR >zD?c>{2VZ3$v45E6x8I*JKPbmkk;$^nbdd=oQ?@meMy8ES9GN;Yd1U%X0Z0W%2}lh{ >z5l9tC8Au&SAxI@iDYm8-q!^?cTT>2F4^j|P5mFLT6H*jX6;c*b7g88f8B!Wjo2@Ah >zsm|7vht!7@h*XG_h}4J_iByS{iPVV{id2e}iqwh}i&SfC%0=q6H3cITBPAm>BSqtg >Snf?D;b!n%mJ>&}nOMd|b>ln%a > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi >new file mode 100644 >index 0000000000000000000000000000000000000000..b7dcaab8f2068adbf69cae0b1cd80f98e7a2da13 >GIT binary patch >literal 417 >zcmWHE%1kq2zyNGO5fBCe9v}v>WgCD*XWgGAXQmphxKtuE<L-(FE13LO8`!LO-C#Rk >zV}Xa`0s~KO_XVC$?izT#sa9ZMWMX7yWdTD52D>{z?F_yV3@i)`(HV?f3=D1o3<3-c >zAqk8kV78=>ZwQ07fvK?pkTe66rVIhz!685*1f&-ZLP&7*52&vHKmc+)hz5B8M1wp5 >qqCp-3DFb;1M1wp8qCuVl(IAh3XprZ?G|+<}nx>xQ0{U9llnVgqLRHiN > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar >new file mode 100644 >index 0000000000000000000000000000000000000000..b44a1e19e9b1212585e55bd65be77665f4ecf6b9 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(hJU+K>i_@$&%nsYzz`$@6k!NSU|{j_4PnqW >jFavQJLP#+32UrIK1JK0(AfrKC0>*RM04=i9HRA#R5AqyS > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu >new file mode 100644 >index 0000000000000000000000000000000000000000..0cbd2952bb480dd403bc567bdc412c5d92813af1 >GIT binary patch >literal 238 >zcmWHE%1kq2zyQoZ5fBCe79a+(1sZ_F!cVm=auNnB>i_@$&%nsU#K7SH2Pn+o8v#-m >zaEF1*$2WvQ+rZS=07ROYf+T?;gamtjK(sIbt@sbJ55xu838G20m&*q13Oij>D-%;L >E05l&Z<p2Nx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu >new file mode 100644 >index 0000000000000000000000000000000000000000..0cbd2952bb480dd403bc567bdc412c5d92813af1 >GIT binary patch >literal 238 >zcmWHE%1kq2zyQoZ5fBCe79a+(1sZ_F!cVm=auNnB>i_@$&%nsU#K7SH2Pn+o8v#-m >zaEF1*$2WvQ+rZS=07ROYf+T?;gamtjK(sIbt@sbJ55xu838G20m&*q13Oij>D-%;L >E05l&Z<p2Nx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga >new file mode 100644 >index 0000000000000000000000000000000000000000..918369539a5b7d587be3ec826019c7bfa0a13f09 >GIT binary patch >literal 1311 >zcmdVZPe_wt9KiAC)y+RM<2htnX0F^?HZ@%(E}ctl$=r;nosvN4uN5((LqX^R{jr0@ >za|i<QP?U9%@K7C=xAag*P<gTrf;$v}iF7C;*7JRBFzD2=-^=@c-}l}74mLhd;^@Gs >zfcR@l%^h|oVs_5gDRa30A^qjqgBelgJCa;qF}zS-baT1<$BX`o&#B~w`K5)8v*Bdr >zR9tVG2<fV^2EBQtT326{+I`;ATl!Y?*4U!1X`Ry^|BUulKG)ky9&4ZDz4U#XmfO=W >z-L;p`xohVh$sN;orT^(IS@-aYtiN+sHeBzMJ1@m$<B5=LI(9|}E_Uf%p&q^auvhP? >zs?*JZLf!mpt!}CG$d-@GI{33d?wxw4TjxK?w(+krlzJ`OZ@iV^(Fqw|NhkN692Xte >zQmQjDEV_=5sr}vo5$PIK2b?j{UDL0+mrko_ey57QiK?DOkBU9<tN3h(=)GO44qnJR >zl!(0&LzzrQSowLYo5Pv26%^)N<bL3ExQdE%w~}IqLx`a=^WTc366Sp5o>e5opcZSg >z$Lt-;+*y5QbkdSMDa@0r$I(e)?(kN;HzE9uEyCZ_Xc{za;>(3)kBNPiJtY1C!1q5d >znctlO0tEvD2nq@c47&yg1qcNR1quZV1q=lZ1r7xd1rP-h1rh}l1r!Ap1r`ODT?34Q >zi~`NB!A1c`K}Uf{!AAi|K}dl}!AJo~K}ms0!ASvX*C3@pwQI0az*5js;8O5X08<cC >zAlo&VDWDlpQ(!aTrT}L^PJzyV-L3&oL2uW<r{Je70Lmg@SO}EGKv@vXkTLP!FA7(i >KSvc+WLDz4A0uDX^ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata >new file mode 100644 >index 0000000000000000000000000000000000000000..b57972dd8ab55785d8cb21b90b5277d8fc850fdc >GIT binary patch >literal 312 >zcmWHE%1kq2zyK^j5fBCeHXsJEg&KfF``kUdPTlU&IKx^fab~K~ic2LzGZ>kefslbA >z=mJmygSQ(<wQmFi2LnTN1|yG$ZwP}g5PJrPFlZZ?85@8Ufk6m%yIFyfAPfRPGr(-I >zA7Cy6!+#)9+a;j^qMe_=HUQBeH-Tu7yFfI^ZD1PcJ`fFZBLmQpEI<f!<qeQgK(_*2 >h33Mya2B2Gcz-|@r0lE{ndl?wGfS%AbwK6u~0sv>)ONsyh > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk >new file mode 100644 >index 0000000000000000000000000000000000000000..faec35d30403b70fccff6de6a523af81467036b8 >GIT binary patch >literal 1243 >zcmdVZO-R#W9Ki8sIcqo*FQv6sOS7fZ`n76WQ=2U_opy*t*b7B3Vk9KJP=~-lRuB=3 >z>JnW-i4GAzsV?EEB05MxL>(kbvY<m2(IJUg&-cFuQm2kR<N1G{J^OF4J>Mm_9q0<1 >zzlPWDFd1<>Sr@15<@)5zulEMV0<(gL(z8nkO^IiqxMcEGs`TT_^qf(znLDyQ?Hlga >zdAB;%f2~dDpO5N-lhqpN@$14JMOv1~XnFLDE((olh3~m8_CD00`?CbUy_F^7Z(@}v >z&c-TVJdmnKcO-OoP^t&7NX_Llvb6uWEIZmQvaeH?@9fv`;a$3-p-We8Zqil$jT#A; >zYvgB@*7;&m_qtG5|0t6+!xI`EbxZvXuQc5MAdRO#$=a(=B)0#VG@TmPb<IN(-}_kC >zS6q_j_)XoAe@t4+&uPoVMQzRN(blI&wC&v{P2Aq1?IQ=J<3g<_6Ym3knM}sG@}^}U >z?))i_=`*H0nfk(?YmeJ)%+@0Ni<;zaW7oYYm&cery{0gC&F#4CPVOFK@5$|(!uF1& >z2}#7xIy-CmFyqP&XPvzy|KW(g|9+qSh8d0;Ic~N&a^%<<9KEAGek1`T0|qG|IUq?O >zSs-a3c_4`(nINekxgg0P*&yj4`8e8ykc^O&9BocWQb<-vT1Z|<Vn}94YDjKKa!7Va >zdPsgqf{r#rBt=J?Ba$SNC6XqRCz2?VDUvFZE0QddEs`#hFOo2lF_N;Q%^6AB(PoXL >cjpU6aj%1Fcj(xU)|0wr@diz&stf?*d1<Lsg1ONa4 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur >new file mode 100644 >index 0000000000000000000000000000000000000000..5c95ebcdc377086c8c646e251569792fe3602c4d >GIT binary patch >literal 424 >zcmWHE%1kq2zyKUT5fBCeP9O%c6&ip<TXXB;UFm)k4sbn5IJNm{!s&_e9G5(DKZs5I >z%2EIS|9?g%W)@a9R(5s<hWId`dWOVU1{MZ}qymr;=?aWIAd&${W>zo=F)-9kV31&7 >zC}?1i@$n5|2nJ$p19K2IG60drAkq?uEkH)0fDpnC=K^W~JNyS!C(wQW>&!w|foPCN >tKs3lRAR6Q$5DoGahz5BKM1wpB(hl+<h^_~UG0@GITsA<z+v!?x0RVnQVY>hT > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching >new file mode 100644 >index 0000000000000000000000000000000000000000..62b5389229af5216670b89966a2ddebe56695154 >GIT binary patch >literal 521 >zcmWHE%1kq2zyNGO5fBCe5g-P!B^rRl+Ag*UyVBh|_E)Pn?Efqsa4>dF!@;Wy0uI|f >zU^u+(@`a-c!VO1fum>DxbZ0nTX?5Ym<1-8=qxWApb>x4;X`9ahrzb`*T=K~MQ2+n` >ze+EWoCKSlR%*?=$UI4U)A+v&kg@K{efRT%Vp`d|5fPtZI0>~vGwvTTJgSLUWu>p{@ >zFanc6mL*6V9E6bIuOCodKqvhN`42>c{0O2!{shxNzk+Cxf59}+&mbD)Z!it?JBSAP >zA4~(o07Qer0ZaqK0z`wt14M(u1Vn?v1w@0w222CP2SkIy2;{7KAe)xq#AO2vLpxmy >FE&yxUwsimi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait >new file mode 100644 >index 0000000000000000000000000000000000000000..e71bc4e802cbdfd9f90598029e0fda04c4074ab3 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(RcW&=_5c6>XJBMxV9-7T6k*UZU|{j_4PnqW >jFa~iMLP#+32UrIK1JK0(AfrKC0>*RM04=i9HRb{Uf07!( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao >new file mode 100644 >index 0000000000000000000000000000000000000000..2c20a32651d9da10d1d6f63495c3cf1fd55c7f16 >GIT binary patch >literal 771 >zcmcJMKP&@L9Dv_dTUGV1#HJAvUL;M#;^I$&N-WBti9|vrL@-n*7HMu02@x@1GKn06 >zfs&hym?RdXO^u48^{?JnqlLlm^4|AymmA*qg@&dkn#7N>t2ZpBK`qW6Lv3pbpSYX5 >zw323@ydONY9u^zrWAnI?n)J%2>I40`CnaCRm`K-eCo_&wJ@XWhuQy%#+jZD{zZkJT >zPCCuc{SGU;Rcnfs8cT~gOk2cm<qhAO_TZ7>Xy1%F{ToJpT|DWkjEe&2xh!}-)7^<Z >zS$MUpdrp^S(eaXAyc3Zn>usWR!IvzX^$G7xYqUJvVpQ~3MMa)w``shN^t`&1h^=bs >zhEYSfzW3f>NCdjo8VK=OV}<@;D$QSNvT85}u?8^*u?H~-u?R5<u?aB>u?jH@v74hZ >z46zI`4Y3U|4s+HyV4hL-0R<oxASEC*AVnZmAY~wR7z*X6DnUv?YC(!YszJ&@>M<0A >SRAeX#sR{qDs9WXr>+UaoVev)) > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau >new file mode 100644 >index 0000000000000000000000000000000000000000..2c20a32651d9da10d1d6f63495c3cf1fd55c7f16 >GIT binary patch >literal 771 >zcmcJMKP&@L9Dv_dTUGV1#HJAvUL;M#;^I$&N-WBti9|vrL@-n*7HMu02@x@1GKn06 >zfs&hym?RdXO^u48^{?JnqlLlm^4|AymmA*qg@&dkn#7N>t2ZpBK`qW6Lv3pbpSYX5 >zw323@ydONY9u^zrWAnI?n)J%2>I40`CnaCRm`K-eCo_&wJ@XWhuQy%#+jZD{zZkJT >zPCCuc{SGU;Rcnfs8cT~gOk2cm<qhAO_TZ7>Xy1%F{ToJpT|DWkjEe&2xh!}-)7^<Z >zS$MUpdrp^S(eaXAyc3Zn>usWR!IvzX^$G7xYqUJvVpQ~3MMa)w``shN^t`&1h^=bs >zhEYSfzW3f>NCdjo8VK=OV}<@;D$QSNvT85}u?8^*u?H~-u?R5<u?aB>u?jH@v74hZ >z46zI`4Y3U|4s+HyV4hL-0R<oxASEC*AVnZmAY~wR7z*X6DnUv?YC(!YszJ&@>M<0A >SRAeX#sR{qDs9WXr>+UaoVev)) > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan >new file mode 100644 >index 0000000000000000000000000000000000000000..2db063560c48c67f0280212a320b183d49d8cffd >GIT binary patch >literal 1258 >zcmdVZPe_wt9Ki8sZMLNzB*;Ilm1eeVsoSz;Z7xeqY#R+3L{<>=2Wpoe(Lw59P#q$z >zOLQ1gLWLG9I+#Rw*dgeUM2K{d4nlR1ARfX)MX;Xly9T399ec*}ex5yhH`t!<QiEqs >z2i0Gr!t5{^J!Z15x@0bo>O$ks?oBSP@$O7k*QRqduCs4zzTfStUAmL3TbRqOoo!6I >zXZ*4*+aR8?)v|uXE*mZ`OMUv2G#q&+8)L7eG5lOM`5sD>J0qJbu8Y?(t-Z?=ddtTN >z)jV`iHP2tuTVGz#zNxg{cK@huxs}kZSE9P@e4F;4tk;2KaS5LD%J$AyX&+c6J3Lhq >z3VfE(&#%(qcIuAz^Rny5lHNTtE#ZaNI`UvncfNS6qgSW&p3F_%b?Ua>dpRrndWUrP >zi5t?>G^l&KMfR6PbYJ6u^nE!j{q}b0e-oAiAF3tx#3S+9piYeDB^Apq9&(SV;e0-? >zZ1xp}hoh|IvC>)cr1XV9*Dj~Sq15Pc^Rudvab?z%Ih#wV%u`iaycTzCW~X?MGWQhs >zRb@PpQoexS%%GV8K1|sP!&(<Esed@<Z@=GXzG9y9M$VjV&K)^><oqp714su*3rG)0 >z6G#_G8%Q5WBS<GmD@ZR$Ge|c`J4ioBLzbo^q$LJDS(>Jhu8_8nzL3U{&XCrS-jL>y >z?vVD7{*VTd4lPZKNRO7LNu*1pO{7nxQKVC(Risy>S)^N}U8G;6VWeZEWu#|I(=^hx >jrD+@K8)+Qr9BCct9ci91Y+CrAx-XBI|3tJU5Gelz??EM8 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar >new file mode 100644 >index 0000000000000000000000000000000000000000..3a5dcb27007e1a2ffa67bbf3a30095303b5d67a2 >GIT binary patch >literal 288 >zcmWHE%1kq2zyPd35fBCe7+bUf$XWO)cET>Ps}oLl$TnOGdso1~$i&RTz>xm|q!LI1 >z*#!*@91IL~6Bu~FYyltN5C&f$);6#JVoQc_&k#qDYA6UH!395{dj10e$R!{e<QfnS >RauJB8j;pvpuGF>Q0szU5Jx2fl > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila >new file mode 100644 >index 0000000000000000000000000000000000000000..06859a70d9b6a7a10abe85b38775b97319409608 >GIT binary patch >literal 367 >zcmWHE%1kq2zyPd35fBCeE+7W6c^ZJk!8u<V4v85Qoc{Ej;lfJQf=4-)43DlZ`oLf6 >z)*z5p^`ZX%|Nl&kOw2&c$i&3JP*?!e#85YZk%fVwpn-t{#Abl9eSAY0v<)nQ*aD;o >z3PP~Ehz%$W!XUr{#2_}$4-gLsfR_Fjd3Z+vL|4n(PXN&%mx5@JYe6)~#UL8wY7h-_ >yIhY2z9%Kf{2Ot{c3lLoolw@FJW@2UmVkTzh|NrH|;-vcs7=$)JKicV9Z~*`$(PRh! > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat >new file mode 100644 >index 0000000000000000000000000000000000000000..c12f31a141db7e6e02f7274e114c1cd6be2ff1e6 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(!cQ|-)c^ngpMjB)fx-9&P=vw4fq})xH-tgk >jzy!o)2qD49A7C8}3_uhAgNz1o2^i011GLCa*MtiIP}?0H > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia >new file mode 100644 >index 0000000000000000000000000000000000000000..3e663b215327d8899a4b3fbe4623f066630b97b2 >GIT binary patch >literal 2016 >zcmdVaeN0t#9LMoP$d(r$zG#Sgc`(Toy1)g*#K4CL@PVtxxEZO$QQ?9`lqdwI;wG}@ >znER@1&Q)7YVy!vU%^o&;nC6^rj?PxDwZ=MWtLB8YnX`1ve($sOSAV(nPv`8O*V)~@ >z|NY*d==!a(0_$H_g87CI*Ix7CeIhUKzn=c-_>q%dVEC|`c(>l0@Wn-YVt=tS>A+9! >z<nEv&ZEM`5Eo07<YR{e;nc+QBc-~IVJm*ZC+Ha@CA9qr2_1M#|?{{W=(`3*5s?iC4 >z*6pUA*yp9a9dpxr8@!BN%iUScmENNpv)$QMSzczz1oyE}qBkcv>OP)0;>}G+wCCOq >zIP-oUv9rFt>11E{+J559kQ3@ZZRhlza&o(m*m*k+JK_2^JHK|&D~KF&3rp3TpR?U9 >zN^A8N6m-afu`XE{?9+wAo22+&yDs{?OrH9oMoR|jwDjyEUEH%wm%Np#OJkY3th-pA >zu1L_b`k*{B=T|K+8<UEJ%UYTFqg0OmA}iw0$%>&%vhw<ISvB~fR9*Q}BL{nB^@;a% >zO-qZ|z58_S^9S_V<_4{PvRR{5mHJ%DYF!t~(sg&jT9aHMHQ!Cq7jDm!^&kJC8?FXq >z<GV>xd*-IR*mX<l`i8`*yDFP@-_XrVK9Mc8SF}Fkm^73QYV6^Uv@uP!@wcPeG}fwH >zFLmlm!%=<tgALkzahtsIW~sIeRLiSP8TwjJk!)LABCW9$*`A*+JIeo(wj@j1^OCjw >z_iNHI>5g`|7o>Cad);|zK;9TStGkY!*WH8f=$_7g?K;?{)<ba*cE^wVPjAc0SZ<D> >zl^u>7XIZJUtnvRm`KBrowaUw@c|`eDT%7-iKEMJ0lmD6PzPUK)ymQ!*1CJbf<lrNR >z9|-`700{w!0SN+$0to|&0|^9)#Mgv^#DWBaM1zEb#DfHcM1+Kd#DoNeM1_Qf#DxTg >zM23XsYhpu!L!v{%L*hdML?T2&L}EmOM508(MB+pOMIuE)^);~~!TOqLk#LcCk${ni >zk&uy?k)V;Nk+6}tk-(A2k<gLYk>Gtz^ho%=CVpf9kP$$J02u>h5Rg$oh5;D|WFU}{ >zK!ySt3uG{S&1fLQ;cLbN84zSdkRd_F1Q`@$RFGjo#swJ|WMq(`LB<9d9AtEm;qf)& >zgA5QdLdXyyV}uM6GD^rWA>)J$6f#oCP$6T53>Gq4$Z+|Z@j?d7*Nhl4WXPBygNBS6 >kGHl4W;s18v0%q@W3Ru2Sq%gNAH=I`(isXm=xA}p;0b|0?X8-^I > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk >new file mode 100644 >index 0000000000000000000000000000000000000000..ed4b248276dbabd6b9424bd5f7252729419570f0 >GIT binary patch >literal 1197 >zcmd7QPe_wt9Ki8sIm?`cmvXgM%VkTa^=s8!O>Jt+{1+7KV1Fq3BL+g!A1VkOWCani >zs4me>iHL|_RG08DDx!lFMASi|BndiX9Xb>d>-oMWEIM`T8Sndf_q^{0+wYs&cAz_A >z{#rBb4hO5r9$c5E?dhgBki9=R7MLA6n3>}pGG#@BrDfk=r@bFvW#*20%)F898Q*Y^ >z&cD^A{%dWz;Cx&co~+hDuU{AKn5E_IISt0Y=;H90R`_1%63-(Ixj#$j>pNLG{x(s0 >z{A{A~<wL1@d{@HvhNODviqu>_Bg+Pk$?_vTBKx{z#m)hZ9NMKT>$`Q;mPTFe->A_@ >zP@_MqH0Dc4>`jTT`B5%whbJ^X>Xy3e9;tuuK^jhfl66;~N@D+WX*@NqP02gby!VN& >zuec=1<{P@9@Tjx|&uPoVMQttU)z)W+we9^TZNI%$J4Q|<Ixi%%{kdGuxC*9CzTAa* >zujw=L-sIo-^V&Y<HfD3y{+TAV+t};Aw5!ONJ$<HR>O8gMvOAN{aJQo~Wx^7*N6a3z >ze1UPXoGVVLf0*XC-=DHSD92Qh$+FFKkqNVyvZI|eGHqnyET)c39+^H;08#-`0#XA~ >z1X2Z322ux72vP}BileOsDF&&=(UybMgA{~Rgp`ETgcOBTg_MQVg%pNVhLncX=4gvU >zs&lmEA@v~zA{8PfA~hmKB2^+~B6T8#B9$VgBDEsLBGo$Da*=u+ZNW&zNXbaeNYU7D >RXaE0JU0i2tZ>Xs){sqhn1EK%` > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk >new file mode 100644 >index 0000000000000000000000000000000000000000..a5d39dffc110700f3f423b7ddd2f525dc09b50bc >GIT binary patch >literal 1255 >zcmdVZPe{{I0KoCLoNmkr2}<W$S!!m}`nhVZruNE~=$t`}qB02WFBFZCs0dt`bcq<{ >zAtDIb=oImwKZg){RL9XF#12DB>e8j6JQP;zeSand9in6J$NPQX9={E?_gP}^vBN>} >z$MBdPCL?Ml>#~%&jpn^I4>D6#i|S6M7guCOxjR!<{`F<5;@w2rn=ciWxqWHh*ip6Q >z&K~8z*`=0Vj;Lkl8&uVCzgphAK&^-sRCVN|stHV~THgz`vh=B{bAGVure9mD-oBFc >zXD-S5@h8^mXZNhY{j3%E(IXnN8QC~8BG+6TmTL!2OY7hf*|h(v4xT!p*R>Al^*eXy >z4gOs^6l~I=?_nMG^~msKrQSGW$xUP5bR@q}w%qp0)<@H_ZFoj*zA+)?p-H)A=#$<W >zeJtDi$Mv?_Q5kK2sJ9mn$&Tvly5s#V-C1-_cRs(MyWaHb*xi2JojWVzSE4!*`)uvL >zmeYfULP0o+=FMKt;@_?k7cbndlD}R~m(wXke9Zi|B5^>Nbu#5}3(=Pp^XKk!I}Wom >z`%GVwHP3X%6Cz-R%nX~^%*P0a8Ny*N?OWm>4*AQkx0&x&;IJtN&NhcmId}$#Z`S~z >zAfP~CfPn&nf`S5rf`bBtf`kHvf`tNxf`$Tzf`<agu0ceBM8Ra&fTEzHz_M#_F#twE >zMuA4bMgd1bM}bGdM*&DdNP%eAV5ESwYfw^PQgBj$Qjk)hQm|6MQqWT1Qt(m$QxH=i >rQ!rCN+cl^uu<aV$6yOx(6zCM}6z~-EbkLaiFW`Gx%wM9dvDxzz1GyQD > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk >new file mode 100644 >index 0000000000000000000000000000000000000000..5e0d9b67a3ee9bf444359b006b2da687604ef190 >GIT binary patch >literal 1243 >zcmdVZUr19?9Ki9joHf)yg3>uH%WT=QrsXpK^(&pSoFy?L!XUB|p&&w}qOdUEA|ebT >zf+j{!5oGB@2>pVdLZU!=5h2JPdPt#sD9qOR-ZdEY)MNK@?&s|6Zm^y2jUDbjS!w<{ >zvh50kqtOoLxtHx_=!uMt4$lQw`Y**-<&Wg%c^((%egAkP|I<v|JLSzSnCOoC#(TB! >zVV4%&J*2CzMRd)@8ZAB*(6t?fx-Pn0OKN}W`oNr)`rhk??6>N7FN%MDRyNLjZZA7` >ztG#UUjcj`PLIO`mWb^%DDIXk^EmsF*YfrBPk9SGMk(*k1_Ox!R@6qiC_G?wqK@C+_ >zXlSuot9|>Vdb&V&E(E1!{D;;~t&qA0Ua5aJFAW0=vg^(}krUIhyZ?*s2|t&{&Pi=5 >z9g=Y4m^NqjOH0XZZJE8Nk&Fu(d3{Cqe(2EFN1Ym-I4^D2!y0S-8th9X62_IWBzd|s >z)6S*K(q5#$@#oy*b{o_5%KoFKx!u_Lu`@1@F|ng2Cv{D&xa>;m9%JuGt(%-^Tg(K4 >zRd(#KBgB^(SMqS?$xG}Xw)orc&)Hv?V5^bsW|=KVwjJ4eN4xz<0!Ri(3P=t}5=a(E >z8b}^UB1k4kDo8F!GDtQ^I!Hc_HX$S<Bqc|i6Ot5?6_OT`7m^r~8Il^38<HH79g-fB >zACjP>%@9e^(dLLGiDZeSiR6hSie!qUisXtUi)4$Wi{y(WjAV?Y>}YdFl6JINBWWXf >ZBZ(uKBdKGbZQwu3J*&<>3Jv9<tY1XR7FqxR > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral >new file mode 100644 >index 0000000000000000000000000000000000000000..b8eb58d135f62054868473914994d242e1b8be07 >GIT binary patch >literal 1039 >zcmd6lJ!n%=7(j2@J`HJ+4%Q^bYSh};#MYShg;dj8m*S8@kOzgL@C~)#&r}p0gbD^h >zbP#nC2gTwbA`x^_(ZNyV4sNw_2NwsIieRZFe&?lwpi4LJ<$mXJ9|<Jq1XHJG3g)jB >z(;E)U*TeJX%Q_w>Z-06*-(Ky?T(56QyiLcW&(iVb@Ang5m+HxdOnU443-#2in%(x~ >zyzRa>W4GU!v^y>xwdu3NcIWY|-Bn51-Q^D3lUucWQomep`!|>Il9Krmlf7S7r0?QG >z>HGM(ntit@x#u5b-~1ctzf+fi+5_2t?v~`IugHNDPhDa5nj0Ls>4uJ-aenu#D;6eP >zaW!zI)M+U#7TxelMGn4BxI+sAQhwyi$jeR{y&9Lpcb8=B<gy&8ZE|ysM#Dr}TH9J% >zbbA}t_QojNYvLc%^Nh*&=zn3ddDCXhc-2IW2_(|NG&=vh8Lvk4ZE4JOHt#DFfyw0u >z_4s;<dWQHaV<N2PBQscsn4fDO)8ErT5JVE!h=Rz12n(swAmSkMAOay0AtE6%AwnTi >zAz~qNA%Y>2A)+C&A;KZjL#lX)d`JKxH3CQokQg9AK%#(z0f_?=h{6yFBos(2kYFIu >vK*9;B@jwC!sS!a!g2V&~3KA70EJ$3Cz#x%9LW6Va<iCwAR@NLx`~BE&jKSbH > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh >new file mode 100644 >index 0000000000000000000000000000000000000000..8db5e8a61ee9e63164ce7f07969557fafa982dde >GIT binary patch >literal 220 >zcmWHE%1kq2zyQoZ5fBCe7@Ma7$XS$?ex&~Y|No3kObiThHXwN*$-=;pRKURD;~T=@ >z1jO0~<{$|m2qA1dP%qdDo*!Tx3=BZi|A%dBJp!UZ)`5iUfoujM?c}ln+Ha?8&IJIu >C{UtE~ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak >new file mode 100644 >index 0000000000000000000000000000000000000000..ec98c62bab86bc3afbe58caef094734022600c82 >GIT binary patch >literal 395 >zcmWHE%1kq2zyRz(5fBCeP9O%c<r{!R_y0bIU1IkcPFF7BxD@uT;JVE*j$8lL7`|-X >z*P(c;q=A8viJ6IoiIt6kAq}J+M6xh2WL7Y6Ffi0jVBlk5C}?010+V743`qqH(muW+ >z3;{r_ZD4L}03<De*n%P4GsF={IDyPS0wE;0_Xkwpe;@$48$^TL4x&Ns2hkuufM}3E >XKs3lNAR6Q!kal|bi3{jWU2`q~jo)5v > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang >new file mode 100644 >index 0000000000000000000000000000000000000000..dc24926e80f24b564669b5979736a191114a998d >GIT binary patch >literal 267 >zcmWHE%1kq2zyK^j5fBCeHXsJEc^ZI3_w|o+COs4TaY;Y1AoLtlLDZX?3I;|dW=3WP >zhSDcM1q|gKAk}pf7&yQri;r&zgLiNUgBK9PKnMx8{(x%w4+J3FK{Ut(AR6QfkTl38 >PAeubaZ~>jCYsm!wM71|t > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar >new file mode 100644 >index 0000000000000000000000000000000000000000..a0c5f669628d8ecd61c398bc475cf2405d20000b >GIT binary patch >literal 225 >zcmWHE%1kq2zyQoZ5fBCe79a+(c^ZJk!cTJzSh^-1sQ>@}KLaBZ69a=m08p60!U3dC >y%YcEy$2WvQ+rR{fjX@GX5JG|-KOkBdfX4p^*#+W)>;uuH*vVxBwBJtGm<s@Gqaf1& > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda >new file mode 100644 >index 0000000000000000000000000000000000000000..0fc7fada699081c12e65301b7daa240ab530ab79 >GIT binary patch >literal 1047 >zcmd6lJ!n%=7(j2*rZ!0jm)h1?ef96Pjnx{PkZO{~B{)?0kbod9WT*wfNh}Hq6$xE* >zQx|avDh}e1f=()Qa4h%@Zbe+Wh~UsVC^f|IymUx$a`Qg!JvaBg7f8-2U%E1%a(|7u >zoiG_`o9uVrvE}8!Qti#NMzPnwSKrgW;`Mbedwst)YyDq0>H}-Ow|DhMJ@Kxp`(7>R >z;FEdXfB&K$xP4B&tCKo3GpYxt6M87uqlc3XJ(BpYN8?}AkHp3Q@mq%1w<;qyAIZok >zEslQpD9P6=a_srCj6HlR$Ey$I#PzC-&n?Kw*_x)V-O^L}yE<`UR?~xXnn_J*rcu&t >zVn(u`hjntRAgABQ^vs$kxfj0V--e~I6qTvR>r%Y@P0m)GE;gG@7YcWDc7*MUbhTZ( >zBGLAbJND72bNPz>7cN_Loz9iSbvswCgnC$=t?efz3EAD&ldZcvIeotDlH(IL(>61F >znRB6FwD!ST{s%cfx8Jkh)I<_Q6vxPd2!luqXyPF9AOay0AtE6%AwnTiAz~qNA%Y>2 >zA)+C&A;KZjA>sp?d`JM02m)FNkQg9AK%#(z0f_?=2qY3nD3Dkn!9b#cgae5upalep >pD4>M|i3t)EBq~T)khma$K_Y{M28j(Wnv?%JxLD3&ER1Dhe*khm-6H@1 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon >new file mode 100644 >index 0000000000000000000000000000000000000000..3cc2aafac4e27bcbb2de4b08c6451c1a56452808 >GIT binary patch >literal 297 >zcmWHE%1kq2zyPd35fBCe7+a_T$XWQQIPmnRKN1&brGKdZ|NlQD6EhPN14EQPNF|VD >zVPJ^PVBlb2sGGpR2Vwj8hA;#Hv9^Jku>p{@1Sy4r5W?280hNNBAoK&O2Wad6ux*_e >kK{UuYAR6Q(5Djt`NLf9Q%|M~sxNN{Kw$nAUGB)4>0I_91JOBUy > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh >new file mode 100644 >index 0000000000000000000000000000000000000000..e71bc4e802cbdfd9f90598029e0fda04c4074ab3 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(RcW&=_5c6>XJBMxV9-7T6k*UZU|{j_4PnqW >jFa~iMLP#+32UrIK1JK0(AfrKC0>*RM04=i9HRb{Uf07!( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon >new file mode 100644 >index 0000000000000000000000000000000000000000..92642679c8f9e68c125a8c6fa740ebf61df82417 >GIT binary patch >literal 389 >zcmWHE%1kq2zyNGO5fBCeZXgD+MH_%bM~`#E#KqcNXHB0qT#P(daLL;4!&Rf*0#CL* >zX?UwYgMrKTI79va|Nj{nnV4Can1PUqfguH`k%1xk8v_diLs9_)Cj&!40|PGuL)`=h >zL5PTtZwNyGh|o4L2Vx5#wghW}5g{bF^9NKD&>8<h?gh~xH-l)9yFoO_?I0TDeh>}v >g1BeFs14M)T0s<iafIvM^jM{$UvH|+mPS>0Z0QvW1Z2$lO > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin >new file mode 100644 >index 0000000000000000000000000000000000000000..8d6b4dfe21720eb32abd17fcd627ee9567f93836 >GIT binary patch >literal 1234 >zcmd7ROGs2v7{Kvwn(>hpM3h>Srj0h)q|TknG#~j)Y-UJeXwd_LUYMIhw1@&dP!^Fy >zi&leJi^PJ6kO+}k3@FsXA|zT!n_i1HaTXF9#B~1Ggd$qB>$}|hzaCJS`F<u2_neN% >zAG6$^a5L@p=6$WUkE`az_)K`rtPAe$&M)ju7v!FORj_cUx$yIF_xjnH^oHp`w?7qD >z8y}XcqM<dac+jghU7AxRy`NO+kvD2{^qC6OkE^oK16A%%sx2#SsG#qu3C@k0tsh6F >z;=%!`czxY$o4RO1PkPPvdq+*>?YODB(qyX7SDWz365||;smQsY+R<30b{;IyyNZf+ >zjkBO@zKgE)=S%I|_qy)eyzEI$>H67OX&8AYjT0$p8km&5$zf?eH6ksSCv<DaHEBCB >zq}$7Tq@%4*@5_oxXW+Q*{BlNjd0TbY%PzhDLz#{~3hCH%i^OlP(uwGVIrMc*`ZJk~ >zc)ZINFJIO#S9Z>CKV;|p?egXLd?EwS?bj-Ox5U2RPkVAjl8<HO(sSv=V^0R}%Id}Q >zSUe%2aGivlh`k+qhxsGoVca(!iGSGb{LkOAA1lL-DSPIaT~qc=*|}T0cgpT5`==P7 >zIG|Xdc%Yb|xS-ge_@Ee}IH6dfc%hh~xN&RkQ2a0$a%&w?EKxjBOi^4>Y*Bnsj8U9X >ztWmsC%u(D??76l6C<fhHhZKtp9w{anTr${X@X275!6}1PidP1+6t@g^DSjCYyS0uf >kmfc#<6w?&f6x$5GDaI+znSN{Gf4833VE+%ADjg^92NM?%(f|Me > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand >new file mode 100644 >index 0000000000000000000000000000000000000000..10c7af7fed8b1118aeb50229697655055a02d5d5 >GIT binary patch >literal 619 >zcmci8y-UMD7=ZCNX{)8};G%7fAMrD45sFwppp;JHP$5G=5Qk0$!Bt#@I_RW-f`i~D >z4s~!7aTOeHcW`lW&_Nv(Eb)D+AmZd=j=Luu9Nhham9^TG{QBB;hso#Y<iBHEm*ed2 >z?AcMX-0AH#x-yq;I)3V=-<}UM_fL)Njpue>Z#JCs9n*8NVR{d0rf+}Q^lvR1cYWRr >ztWKE0ierX~DKngFni1#Gj3#f57fbry%ey~z_u!9LFY@&;48^h|(TJ@h*7jrAwn*tp >zZz6MLiHa=v5*G=oR*F@0{obi81(M58>n!M;;gE=BeO7`$JpJ|SjNUASfWp8w6ci2$ >zNvq02p`q|lh$u`HDhd~cjKW5tqwrA(DU1|K3MYk>!rH3RQg|uEw61UX2j)ak`Ad_9 >F#0R(bef0nU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul >new file mode 100644 >index 0000000000000000000000000000000000000000..312ec40a112d5ab54ea2d92d735735be4b27a44d >GIT binary patch >literal 531 >zcmWHE%1kq2zyNGO5fBCeF(3x91sZ@v_w^4Ilb(tFxa6$<;gP@QhbP(Fe>@eI$at2- >zT=87c=fw;Cf{GW<zhu1P52|=|{94BA_a+r@mhZ@TdtR*KUHhzz52l3`3X2maDCVV4 >zP-=FXpzP;4fq{{UnUMtvGP43914B6n&_agt4h9wmhPnw1Kpv0;vRh{`@-Q&;EMVmE >z@eN_{4h~`P0%C8M5Rh^>2qD2|KcKq)0|Cf~AR6RL5DoGvhz9u<M1y<`qCvg}(IB6L >zXprwgG$;hXG%yrEG$<s%G%z$kG$=$sG$>R+G$>?1G$?dHG$@2X&H;rIhz5lehz5lg >Ph^AeLaRGx;*OChWrb4=L > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai >new file mode 100644 >index 0000000000000000000000000000000000000000..dbd132f2b0bcc8beab08e04b182751795c853127 >GIT binary patch >literal 414 >zcma)%y$%6E6ov01AsdnK0RGwCh(;k=S&0xTQ;84_wi_?7<`F!PCs;~}D7?f(B^vIT >zl7ch2`)zh+C+8E>VAZ0p#Q6&b$@1Vmt@shmEEPQ+dAwxQ={D8*Lz@c0P8P$BDh-yh >zJRhox=gVq;O|{%Y*PQ{??_KRC8|0oVI%a(=qV1LMrEqU0h@_&_Xe`L@@k|6ZIO2E7 >z93L|!ALb9D7bk4{9*EM0TpUDs5CS+32?Qb_WIzakkOCnFLJol-2uVX01tDw5!t~*5 >M#r`q2S-#n^-;pX<T>t<8 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore >new file mode 100644 >index 0000000000000000000000000000000000000000..78583666698a0332b822c0cd15daa58abf60eb27 >GIT binary patch >literal 424 >zcmWHE%1kq2zyKUT5fBCeP9O%c6&ip<TXXB;UFm)k4sbn5IJNm{!s&_e9G5(DKZs5I >z%2EIS|9?g%W)@a9R(5s<hQwH)dJxINz>rh`G9q1pkq1OF0Ljb>1|bH9x(N&t3=9Pg >z3^G2xAq>GltZiTp!bS!l(ilWq0<i_iC=?Jv*x_724Pb}=fa(Og?|+?H@L~`R@(73q >qc?Lv-JOrXao&wPzkAY~A=Rn#)9t6?#Krsfo`I5^9=yy9^3oZbMHDSa6 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk >new file mode 100644 >index 0000000000000000000000000000000000000000..16b1cd8f9757d845a7966ae83543750bdfc79e63 >GIT binary patch >literal 1244 >zcmdVZPe_wt9Ki8sZRS!B66BxeN?W#Use7lHwYjWiV%uoQE?J%W1GUSK=pc14s1A|+ >zIYfsM6;x<p(ZM9b!wx}*BtoQvbP%$G1o03aDuVTV-!&L@>ew@$_w(%8yTSH+mmWHK >zBBcHrm1c*@h?&W{`n<V3uJ2fUet&#njemQprY@7Kb)R}y`~7Zj-O`;@{rqfh?Tjzw >znGQ<BM3Z=Lua<SAPFa6$SsF8+r0LLm*${s%zVHj#7<eSjo~&%Dydr+rl=d%=>CKB{ >zs%7|qYMHyNx4b&51CtrO^}%7?dNZlpE=G0xnRXpK)~Kx`2??F{OGi(ebPlePZQg3> >zvOY`K&#%($Dc9W}=48i@CB1WcO2YGRbmZZz?s@q{M=wq4UD@lp_xLTn`@)3m=^NIu >zqt|3_^N{X~iR>$j=ziaz^nW=h1I|tvcpH}eA8RE3)GLXZkWOCBOFBNWFp|&bmBYEB >z@NkutJXV&MJSlzQ&$Zj-QtC#7`9;;}J!RJ8Ifq-R>@!tWycTyHW~X?MGWQhsRaGLH >zRskz$X2?v74^xi9u-Ao4`X7$?+wb?8Z<yz(k>h5YBS(%MIeJ@j{73>w21p7>4oDJ6 >z7DyUM9!MfcCP*qsE=V#+Hb^>1KDH(yBqIhX*_xb?q>!wTw2-`z#E{I8)R5ee<dE!; >z^pO0J1Z_=*NQ$;5M<hukOC(JsPb5(!QzTU+S0q^^TO?g1UnF59V<cr;lQWXEt;rfm >c8_63<9LXF>9Y;(9|55H05%X7wwpv!jFFREuFaQ7m > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei >new file mode 100644 >index 0000000000000000000000000000000000000000..748873bed9a167d0226bad2246556c45432880d6 >GIT binary patch >literal 790 >zcmcK1Jt)L+9LMqRd3J8VWKkFtB{CUAc^K$S{uE`Cvi&@iMEWfTEG7@5Vo^r2=mwM$ >z1CBfAJagyy7XyRh_dYfQi{JJCzpj7(8}9RVT01*R<;O|1Pq;V*_TqcGwzt)$I=$nx >z=-sgay;rqh{Iz+q@Aa93a-Rf}I#e+GSqCH2=I|q5LK|D^=(I(L=fxa%_sGd&yE+{l >zma~aTbKbVBFZwpsWyQT*mE@@F+%Ab^&Z%hJtd70}%*{nWZv7s0x1Of&mnzM}>$^No >zt(m7_u{Qm0D*3%xQXWQCYIsDuw^vL?Xhvr`VdaW*#sBFe(iOG;N0gQXk)d%(;qLN$ >zJ@Ga;Qr+lCy}hby9A5lB&hLX2+E-(Py?y`Y!=B!4lZ6b3jED@0jEM}2jEW44jEf8$ >z(~gV`jf{;9j*N~BkBpB5Kq4R^kQhi1BnlD+iGu`+X(J(_kXT4CBpMP9iH8J4A~Fvl >XImASQB2kgBNL=~%x^5f2sLcHdVF6z% > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent >new file mode 100644 >index 0000000000000000000000000000000000000000..6f7dea4abca3b703de677eba9a88fe02436b1ad5 >GIT binary patch >literal 635 >zcmci9Jxjwt9DwnQMy*w$i?%UU>uZ!C1fdEll1UIMbjTp$P#lzkLnkMtf~$icz#-r! >zE(&fU_W@j-T^#D*pj`xY(D;9%1;NS13wKXA61e;ltd=*X)UT0{9VWw;$$e^1mJ@5g >z{o=UpbvwIZPv$(8PMqb^Z}*3phgxXeTB+Xaa%f*}>+I>K?mJr1{Rc~WU}sk6wp=~9 >zmeoUrE<HT=p-0@h9<}fESjUZa%y-{;e)7j_kHv}7l~;|TNEyvdUzgeP<7#a)45j=R >zIf+^<DpRTTiXn#!N~*K5Hg*iz;hDm6pj<C6b4KPguPQ@Ed?QQn2ZGn{m*j*I6ci4& >zA)&BPXyOVFg^0pLp`vh6$S7<SItm|!kitlzq;OJ5DXbJ)3U6E?rZ7{eX;r@AAGwqB >K@-r4D^T|&sXn$D% > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi >new file mode 100644 >index 0000000000000000000000000000000000000000..4b2d2e296e7626c26b8ee570b59d171a8f2f72a9 >GIT binary patch >literal 1080 >zcmdUtKWI}y9DwiDRP#p%huS7-{nM&3{iA1_#HXh9T2Pk?4+#N9A%iUl4jqb<P{C$% >zDlQf$6$f#6gE*89PY`raC#ROkEh-9viy*f0{CzJ82oBEP<L*1|T>{DXRW4qg9aVpg >zl$<abC7JBIZp!jFz3hBi+wOJc?gqPh-s<l78`J&M@q50gAiZAHnb-9oySik1pWL#2 >z_vY>H+cS30jjG*y?X2B*$+i8{c{@<f*!{yPdmy`M52n7_TxYtL`<|>F`jD8**VerJ >zyZ7GUi|1zOY2Xb%d|*cI-1iPI*3FUm>qcL>ppRZ&3dY7~{lfW4zt~p|N}~gQ>6aV0 >zS)<)XCOE#)uTQLQ1}E2Jy8I|@##cV-iTZ{)wfst(nT9cqm;U5p@3*PbpXV0BFmyU% >zTbfVj)<2$Y@s0!!uUhZh_Y(0~OsRY*e+aAW2enElb;fgcDCHWpv%R)Y964#;aSeO! >zOrNW$%9JcadQ4_fW`S>1%8}9BwbshNH64?yk)|K5&&V$etIt*(h&G5iUZW495TY@n >zsD$W*D1~T+sD<c-D28Z;sD|i<D2Hf=sE6o>Bml_(l0rnu0g?nHi-?j2Bo9a;kW3({ >zKyra31IY%G4kRB)LXeCgDMgf=AW21(tRQJY@`5A=$qbSjBsWNMknAE#dXW4e3Bm<& >QqyB>qlVxdiVx*A#4Y(KMMF0Q* > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran >new file mode 100644 >index 0000000000000000000000000000000000000000..3157f806b7d7fe650ec6726f31398824caf82cec >GIT binary patch >literal 1718 >zcmdVaOKeP00EhA02NkKd+7c0ohIsaMJJZKe+Kvj2=~GQx+IqB@K4{Sw>eVg~LKnnB >z<DFE}s0ATTBNYphBS=b0NJ+5Kg@y!)AQ|TyHezLA;ZE-T&D^AmCjakv%4)q1>yInM >zyy52Znw#%a+RdYD^B(<pC{l;rydcAy<6RM*E<0i*-8H_rT1PH+tEjYhIy!!WnjO=s >zXAhlLbMBwgb8k&kvAqK_?re#O?+nrj?T1w2mNaQs_KT##I_=2*pq!5PI(bHmN{OB> >zQ%CoR)Xyb4?d=OCo*tI-?nQ|7zHmAJ(h0GkD_dtA(JFIStIVqZE?gBodSOAL%FasA >zi;}LXrEl&@`J_NByPGfFHwHz{#SWc&GDPJaye{+G=8J-wVO?0>pqA&<>!OU0YDL_6 >z>6to96ptI!C03a#c|S&$zU~w&A03se?nH^QtG9J|_Yzfc{F7XLpiQi4nWfiOUsmf% >zdv>p{m3yxjxn_HcXDv8$(a3jo+3^@5n<@{qljV87LC9w|u(p%6_%!oKtQ-)+g#a >zyt<+3o!U~>CASvGh;56f%Eq*A(KNG2H&1$|T0#!Uman0rb+}J&AIefY?q}+q{dZJb >zZ=>9G=8M>Uv|I0Kk5zjcp38leYsEgF&u0Y$1_uQPj{2vcK+Cd)834~<%SsZ~7|U8x >z7!YPz!evETR+bEy`15^kp2zZ-JJxnOZSzbqcQUv6_50=di}ii^^{3_^_OU`_iM(cw >z$Rd$d`Zdc$)`=_>St+tqWUYS9Vv*G%%SG0UEEriavSeh<$fA)|Bg;nCjVv5lIkI%W >zX6?x0k<}y1N7j!NfK-5#fYg8#fmDH%fz*K%f>eT(g4BW(gH(f*gVci*gj9r-gw%u- >zg;a%<h17)<=GRn)l!nxX6o*uYl!w%Z6o^!al!(-b6p2)cl!?@d6zbPhij<1fiWG}f >zi<FDhixiAhjFgPjj1-Mjjg*bljTDYl?$?x#)Q%L7RF9O8)Q_A1$SHuF1juQCoCtnR >l8~^XAFm{3e<j9P7raNu(-JBblac*HJ+Hr12YI34I_6L+)nlb<Y > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv >new file mode 100644 >index 0000000000000000000000000000000000000000..df5119935c5b01676e63d1fb1efd7273b8b4b452 >GIT binary patch >literal 2265 >zcmdtie@s<n9LMp8WDL=qEV0%QuuMboa)Ap{Ng4_Qf!yN86a$VCn5p!b#55tF?1vc^ >z&SkCnbIaK1heO4-<|1p;*+y_umZ_LeKft>LcU*$tru4i|t=jsdKim4U!|Uu0{$YIH >zfs*A_DdHa&W<KHJ8qLFdlrrCTd$V3UvG|~F@A<<2^+z{F$MLInXJeJNo7dUjylm-{ >zuYV;^Rko<E71};sGQm21A@=BZiHGHxm~4G^e9$?2>5x9x>J#0c#_99=4e@<zhq|!u >zbEO+<#Sg{x;>Wf;>!&oI{qxRiqG#enySL_)z8HB@1*eUOV6e~*uWQiZH(Kn`gTGi2 >zO(}MC+mN2L`HCIWK4QgM@A~659<V0o9=7i)+pX`8EA>w)@mlwYIsU0*`t{Urd+lkL >zI`zFrNBQHs`mE{AvG$B3l{#T_h&^-10_`bp_9w27*WR3Cc2dsUI(c@rKPBmq<-7By >zof^5_O1;wLpA{OeW_5<h^ucm<U-z)S-|m+W>|bKdes8bL*n7}=@THA%PTd|ocTJjn >z$iL6Z%x@I)ath`Agw-M|X3)tVTO_jkDx3v<sUqj%fXr>bUF5axbRPb2SmbXR?G$W} >zQVTcjkcBnZl)o&~c_eT~J-RYi7Ws~-K>iH**o0lGIN?@Ve076b6cz6*>RPH64~%h2 >zTIZ=HUH#7EyDU-K+Ub<lXNvN-4mein6tT3vLq3raCMrr><de}sQJJw#R)vMCWs_>; >zvYuY`)Qw`f{MZTg^!aqT;{6ZQ%HsiN)hk<6byJ%2Ol7r_uioLTUf3X>t-S86@vIUx >zS>4Wa;|fKsXIR!=P7-U!os(-jZWHS+e<q**ctEW0*dy!SiB$FbUz9J@{;D>-Ss_D4 >z-SX#G=wGk@)teBL-GA@6ArUIXbZ<zw5YcgBtPtsQL&pF9Nq#{<<e4XTzIlq!y!`zF >z|Gu5A=I7n*4E^zoBj$=f`SLolC1g*?rjT7B+d}q*Yz)~MvNdFH$mWpUxti@E`$IN} >z?9kP05!oZMNo1GEHj#ZI8%1`CY!%rnvRP!e$aazaA{%x!JLb>9mR-%Bkxe7JMz)RY >z8`(Irb7bqt-jU5CyGOQ<>>p`>tLXsJ0;C5>6Ob+-Z9w{fGy>@a(h8&(NHdUbAnic< >zfi%R`bOdRMtLX{S6r?LiTadmWjX^qtv<B%7(j25aNP9T?gEWYvLr9BUO^=W!adZi3 >z6GxwrMsaisX%*5dq*+L}kai*cLK=p23~3qCGgs3zq-(CGZAjmc#vz?UTF22lq<I|O >zL)ypDKcs;i9Yk8l(L<z(NEcmA8<9RDjYK+$v=Zqh(oCeANIQ{!A`Ru}DAH1no+3@< >z=&Gw}D@R{lO=CGai?o)bw@7o5?jr3)`YZmA0gf<Po|$a=oKTSB@p*iS$!Q4%NnTH? >H#~bk*I^)#B > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu >new file mode 100644 >index 0000000000000000000000000000000000000000..a8bddb9fa333da5c60c48132507687b2da74470a >GIT binary patch >literal 229 >zcmWHE%1kq2zyQoZ5fBCe79a+(`5J)4)n}q5iiy4}>i_@$&%nsU#J~{30~BWPjR2_& >zNnqge@eN_nHZV0d0Fq`PDIf?T!ImEoEet>l{)21-aX~hMXwq!uvH`llPS=bJ0M+&( >Aa{vGU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu >new file mode 100644 >index 0000000000000000000000000000000000000000..a8bddb9fa333da5c60c48132507687b2da74470a >GIT binary patch >literal 229 >zcmWHE%1kq2zyQoZ5fBCe79a+(`5J)4)n}q5iiy4}>i_@$&%nsU#J~{30~BWPjR2_& >zNnqge@eN_nHZV0d0Fq`PDIf?T!ImEoEet>l{)21-aX~hMXwq!uvH`llPS=bJ0M+&( >Aa{vGU > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo >new file mode 100644 >index 0000000000000000000000000000000000000000..8ad44ba981a2d97d40d3de2c8bf29606be50aa4b >GIT binary patch >literal 318 >zcmWHE%1kq2zyK^j5fBCeP9O%cc^ZJkbvvel>u<du-1zaU;O1G~2e;W7KHOf*|KQHE >zM<4F?e0;#n$OM5549(0y^$a}=7=fDWCNOY7NFU!21}_&N4h{iHGlFmkVMlNQ)qx%H >z1EdQG{sTekp(O<%8ssQ24RjcY200EygB%E=L5>8|K!<{8kYhnK$iWO`xtI&+d|gW} >E0KK7P_y7O^ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk >new file mode 100644 >index 0000000000000000000000000000000000000000..919b0031d1cc782d9789984e00f074fb6f17c4e1 >GIT binary patch >literal 1255 >zcmdVZT}V?=0KoCHyt=VT_)=Q7GM6o#)@jvTZQ3<kHm3zK2+Jt6#2{!y&<BAFtzIJb >zP!JJ>IO-+hKpzhwbg3T2hY%w~N~#B6EXoH%Vx9jrVboKPoy)oZv$GG_&Tq*>Cwqe8 >zui@4^Oh!yk)+K3u8~nWQ-P56|ie>)OndN0!QR*5hDgE&_T{b<QSux=eD@P7z%7=T^ >zs)rrQd$(1sz8+C)F4d}vQ(m>UbE&FK<diS+Rjmt5sjBifYQ5)`@*7{IfA)ji@aer- >zeg2wRJ@!)8ynZYLPqMN$drQ{cyec;ioRgc*_DXrYLvB7Ypn_+Psx1vYYU_a}wavR% >zg@Qg6`dOpG<)#cz7OU;^m2$`MjEYPcGJ4-5qodQR;rXoDcxB$)d1u@-PfVIk{okxz >zu@`1@_n5W2YS4@|KeP4}_M0uf+g8iWJu6;t(Ta~=wpu@ST8T&9R@=x0v;9WQN+!O` >zgYh}5FPF;+N5PVX%P7pdikx{5@}6)xi~hI_r(p=O|AGE(Me>-?>r~p|5~3?5iWl#T >zI}W|G@S3g^YhKgVo)iHY(le}QJs%?+dI*QTv~S6OIOMtCZ`0o`$6-?roNW%Ba_|fe >z->wEgK|q1P00RXC1qB5L1qTHP1qlTT1q%fX1q}rb1rG&~U5$tWiGs<l21P+dfknYZ >z0Y*Vafkweb0Y^bcfk(kd0Z2h;S3{&=w5vf<P*Px0a8iKU)krB&DOf3BDQGEhDR?P> >vDTpbMDVQms?P}B%*mgB;3UCT?3Umr~3U~^7+NVwY7x3Lt{g-I0t9Snb_fHt= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang >new file mode 100644 >index 0000000000000000000000000000000000000000..3a5dcb27007e1a2ffa67bbf3a30095303b5d67a2 >GIT binary patch >literal 288 >zcmWHE%1kq2zyPd35fBCe7+bUf$XWO)cET>Ps}oLl$TnOGdso1~$i&RTz>xm|q!LI1 >z*#!*@91IL~6Bu~FYyltN5C&f$);6#JVoQc_&k#qDYA6UH!395{dj10e$R!{e<QfnS >RauJB8j;pvpuGF>Q0szU5Jx2fl > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar >new file mode 100644 >index 0000000000000000000000000000000000000000..94ddfea5f2df592be9967734c16563c72e63b021 >GIT binary patch >literal 921 >zcmciAJ1m1y7=YnZDiN2sBoepQT~Vc|dt3L34x~t22GU5x;0z{&Gl&WK2LodG2OAr~ >zU^EzPE`t~uEb=Ev43au;V>4Nt=JaWsHfg^13y;mt)Qexou0P>&eERY_UFoOwo7aJ~ >z<VPd><x1r|d|A2IA(eOGmH9`t%CVm*of{ddVCh{J&b_Ik@q1a^f2T^?&t<9mOqJ#B >z$@1h~<+7hzuJ=<>@w8)A-tLI1%SFq5vM8z#CM?hPgs52yTD1#7;f)kpb(3SNJ`|7* >z0l)Hj3S^_hshU!4vhC&AY(F_N{0E0-V0+65u5Fqf3)1L}%$r@|A)~u@(CqQ~jNZ}) >zv(GV@KAg2@jwDRUk&k6_^tnf_Mx#+-i;w%`BVLFI^AOXLnXDMLL?NUSDFdOfaC@8e >zZPmAhuf$IH5A*%}`HlW-QRd8BW{u1nnK?3dWcJAXkp@Tyqy^FgX@Yb?+8}+9Mo1^5 >zRZQKBLo=ishjvIm4h@lx99kkhIW$GOB5jerNMock(i-WFG)KB4?UDY-4j_Ag>;ke6 >g$W9=8f$RpdAIOfx)O&*L3jWu=B>DCB1U)TD-}#Kg!vFvP > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator >new file mode 100644 >index 0000000000000000000000000000000000000000..94ddfea5f2df592be9967734c16563c72e63b021 >GIT binary patch >literal 921 >zcmciAJ1m1y7=YnZDiN2sBoepQT~Vc|dt3L34x~t22GU5x;0z{&Gl&WK2LodG2OAr~ >zU^EzPE`t~uEb=Ev43au;V>4Nt=JaWsHfg^13y;mt)Qexou0P>&eERY_UFoOwo7aJ~ >z<VPd><x1r|d|A2IA(eOGmH9`t%CVm*of{ddVCh{J&b_Ik@q1a^f2T^?&t<9mOqJ#B >z$@1h~<+7hzuJ=<>@w8)A-tLI1%SFq5vM8z#CM?hPgs52yTD1#7;f)kpb(3SNJ`|7* >z0l)Hj3S^_hshU!4vhC&AY(F_N{0E0-V0+65u5Fqf3)1L}%$r@|A)~u@(CqQ~jNZ}) >zv(GV@KAg2@jwDRUk&k6_^tnf_Mx#+-i;w%`BVLFI^AOXLnXDMLL?NUSDFdOfaC@8e >zZPmAhuf$IH5A*%}`HlW-QRd8BW{u1nnK?3dWcJAXkp@Tyqy^FgX@Yb?+8}+9Mo1^5 >zRZQKBLo=ishjvIm4h@lx99kkhIW$GOB5jerNMock(i-WFG)KB4?UDY-4j_Ag>;ke6 >g$W9=8f$RpdAIOfx)O&*L3jWu=B>DCB1U)TD-}#Kg!vFvP > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi >new file mode 100644 >index 0000000000000000000000000000000000000000..b44a1e19e9b1212585e55bd65be77665f4ecf6b9 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(hJU+K>i_@$&%nsYzz`$@6k!NSU|{j_4PnqW >jFavQJLP#+32UrIK1JK0(AfrKC0>*RM04=i9HRA#R5AqyS > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera >new file mode 100644 >index 0000000000000000000000000000000000000000..7431eb97fc4eaae4d8b4bd9449821d4d11a4b183 >GIT binary patch >literal 1290 >zcmdVZJ7`l;9Dwl?li0L66w$UCqph{Z8rvqZmei!N+7~s6mYT(?lMm1!{1JzuU<*D# >ztdBt)g7`qC3RN6xk<cN7;$RUe#i8n?4n>fIWKa>}`EDFSog6)vbH97fO#-?1casB0 >z4hPj=W3gFbGCIxVxN6w!?!5bud3yJSTISs?6;-KhrR(UM${)AdtLAR@EuWpvu9&Lr >zb5HtZ<yeh)ZY+^iBX(JRDks&c&r-AZt*nW?l-lq!S?hZ!b?&sRTXa#pjtT9}jq3HE >zMpgabE>%BsL2r0|Qv1eJdgHx)y5U+vH=d2^rV~xtf3R8y_Qxf7+$)>f8l}0vR5p9c >zr6ur1T7G?#kh?^O-p@$u&pEwiazethuXN=8v~J5h($RC{dTaWMZa;KgZ#y$4+q(vJ >z$AQbzSvR1&Iz+mi5#3YUFFjxPNUyzFdS8cS$HxkZJ@!a^DyS2e^0M<-u00vc=%IW* >zuWSn(c58DkEZRz3MJL4<<{y_jT`r~0cbnU)WLP<rI(=1{mGl$t_k*mheEzY`tdHDQ >zOS!7d)xu|3i6@fE=MS0Ls(gWfnL#uC{IpWG!YG^+_Q`*E?%)4>(fs8+&!1v|fdh&K >ziU+I41jPl#2E_-(2*nA-3dIY>48;w_4#f|}5XBM262%k6lvU%3VvB(<tHv0`8O0jK >z8^s*O9mO8SAH^WWA;luaBgG`erB!2-;?t@zN^wfDO7TiDOL0rFOYuuFOmR%HOz})H >vO>s@JP4R8j7^gV5YOGVdQ_NG`Q|wdxQ{DkOWGwv8??G9_yd}|wfWPcF#)vJ@ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane >new file mode 100644 >index 0000000000000000000000000000000000000000..8db5e8a61ee9e63164ce7f07969557fafa982dde >GIT binary patch >literal 220 >zcmWHE%1kq2zyQoZ5fBCe7@Ma7$XS$?ex&~Y|No3kObiThHXwN*$-=;pRKURD;~T=@ >z1jO0~<{$|m2qA1dP%qdDo*!Tx3=BZi|A%dBJp!UZ)`5iUfoujM?c}ln+Ha?8&IJIu >C{UtE~ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok >new file mode 100644 >index 0000000000000000000000000000000000000000..80b170bca4100c8915a0eab6602589e22bce9ee3 >GIT binary patch >literal 1244 >zcmdVZPe_w-9LMqRbk<OVb;wyuv(%O?+a62NoGV>6)*M9ak~J9g5AhZq><{{diU=e+ >zbSRMsOzL3KAq~cEStkh(br~J3ymSen4jRPzy`ME0b?Vq>Z12a%Dd_LD<lxY`Hu-B+ >z<_=F5F;A}DYF-|nh^A(z=2kZO`qMSFmli#)ktNUC(_^(?X40E;ON(0;th6^9)~z!E >zt($Dn`tgmr?P{4e41d$@Czo|c{Jl1IztJZDOKtW((VbQI)#rRIzVCCgYkAh)GLmw) >zyt^m6=WmJs#bw#^XjoeBo|3)S6B4)>mf)FySgAp6yU?!tdP2JYxJTRT>b1jK(~h5_ >zo!%Ph{P0P;eyqxY?7Vj8auS;UC_S01gm1i(gA)(r(AjC}y_V6w{+kjxJ*kJAhonC; >zsz)l~5^YRt^y_(zmG^1vZA_1TZqoQOzYZ+)O5*kgO~x}TWBGhu9OY$&hqI#Ov2K0I >z7p33$^V;Qfid>m8|4|veBj$SIxx*zg{!prmuf;nKbEo(oG4Cnfm+FB;QvAU#@mrR8 >z2Ki;;D9pYtyd?kOh*y9AocRm$95v;*xy_MNj-7J!cFplq2v8VMC{Q?1NKjZ%Xi#`i >zh)|eNs8G02$WYi&=ur6BHG~+9D3t6PP7G2ERt#DUUJPOkW(;Z!ZWMA9b`*LPeiVXs >z4MPe=yM`l$B!eY|CW9w~D1#}3DuXM7EQKwDE`=|HFoiLLvR%WOLfWojO`%QUO(D); >WPN7c6jDi1%du7Oc6vC}mu<{o<5B_}s > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk >new file mode 100644 >index 0000000000000000000000000000000000000000..220ad3db5fe8c36d1c32b88fd789ff9c71d3e94e >GIT binary patch >literal 1243 >zcmdVZO-R#W9Ki8sIbTqT-=(ycxze?4YIBur>9krVx=B%kC@F$o=#3arln^QOdXV@X >ziXb}l9)xu1<zU`YsF0xYWE})MR0osjP(-Zf`(J}mr;a^;{{PRjXa5bh=lf4?-M1%X >z{u(8Ag_9ApCv)kum+NmoZGUug#LV(<O3f}mH&Iq}cDn5QlO5$B2UBy#rzYl(wx&Eo >z37t0()rzb2I={bCD^G}e54v<g_ZM9lpVX?RF|7`asL%6Q7nR&qzx$2&zYfdd_fNew >z#}9aG#_q_H;mZ<ucwTC6^+?^t{ZfCrTb3S4NN`tF8n*4#(BYUai+1YrjXqsbQLBxi >zLT&sxQ^THW3BQ}x$d3Y9IrLha#y?2&?avY&d?77oUP<ef0a>;Cfvi6DOxLtslGx6B >zy4H70+G72>E`N)(R~^#!siWGFw?R8zZr0ApkjC#vG%>nfx-NJ$8Gmki)9JKv<;}<( >z?);pipfKk}?i+v3i`;HwdT!W%)TH{1o%dgJ6&Z6<O=<R;U2)l!>^;WblU+BZiLRsx >z1j8oK5VS`4GULh&XP&tv|6z;2{r;T&g=w}L*=`0~j%+)!^^SJ?kpz$okQ9&{kR*^S >zkTj4ykVKG7kW`RdkYtc-kaUoI9Bo2KMo3DIHYX%0Br7B>BrhZ}Br_y6BsU~EBs(NM >zBtIlUN1Gv%qNB|bNfOBtNfXHvNfgNxNfpTzNfyZ#Nf*f%Nf^l(N!iinj3n)7vqsWJ >b@<tLzGDlKp^x6jgquh&|?W53A7b*S)6q5sF > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon >new file mode 100644 >index 0000000000000000000000000000000000000000..3cc2aafac4e27bcbb2de4b08c6451c1a56452808 >GIT binary patch >literal 297 >zcmWHE%1kq2zyPd35fBCe7+a_T$XWQQIPmnRKN1&brGKdZ|NlQD6EhPN14EQPNF|VD >zVPJ^PVBlb2sGGpR2Vwj8hA;#Hv9^Jku>p{@1Sy4r5W?280hNNBAoK&O2Wad6ux*_e >kK{UuYAR6Q(5Djt`NLf9Q%|M~sxNN{Kw$nAUGB)4>0I_91JOBUy > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg >new file mode 100644 >index 0000000000000000000000000000000000000000..c1abb935c655ad4a8288bc3bd9445847e832f270 >GIT binary patch >literal 1281 >zcmdVZPe_wt9Ki8s>S~)FBr2_Ct<0t_Yprd}nscSjtO*Y_2tsL)2}PG8DJU>vR8SOA >zr|MuCp87K(PZb$>wE7*ogj7&oBJfZh3LESBzH2b*)UoH~dB5-byxU;!`*~CQ4h;s> >zU!%&bFd3a@a=iGA+1=dl^xj@Ho}U=a#g}+5W|!7ZdTJcc{53zmj?{kol3h0A^(>!0 >zk##@G$clSIQg>@mR$kgGt4{9_&yiMH-PbH@l5VMwR>@jlP8!^Evaa&Ic<q(i`|YQ0 >zoSjcMog7U!y?&>gr(S8_qe;E~?znEben)S}T+<tmXS9D{NN?&Nk-)K2vbpW71b6pK >zsBS>Qfp!V!5)yIu>B!qgX`PShEl*vtb;hHkV_x0%xJ<{+Id%JuSsg$4S#QfI+1~X+ >zcO3X2oed9lSI3kj>{oSn{g`ym-It#73)1uQitPM&Sav-)D#_{dy7%%PNhNLZ;e0-? >zY-JVYh0VU8WLxMcIVrvH=dsgnS1R(x+*TEQt}4uNTsf3VrETVZC$y?A?u#onvr_yF >z&!o7ns*}AbrOovDgJy=!4Dqu{*$Sg@QrM^d;hBH`{YCS4^E`XX^Jidy%Q&D|pm?xq >zOi)}<Y*2hqj8L3VtWdmA%uw7=>`?qr3{f0WEKxjBOj$LqD7GlRtQun!XB2A`ZxnMB >zcNBXRe-wihhZKtxj}(&>msX8UichP?D8(toD#a_sEX6IwF2yg!FvT&&GQ~5+G{rT= >oHpRD9W1QmLs<BS-PBBk$Pq9z&Plt_x|MeYkMa>%$YYDl20dKP)N&o-= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan >new file mode 100644 >index 0000000000000000000000000000000000000000..4c4e045bd3a47ef74883c0ec74261e8c6a41dc1a >GIT binary patch >literal 1213 >zcmd7QPe_wt9Ki8sZ7Z7+UTT|5`(w7|zh34xR!v=+E^7;k(IGlKQ3m}vyo6APU_sU? >zqN0MNsDpF}sSX|jGj`}AsE6p(3Vsj~6h#C<S+Sn)n}XP>Tkp&Bejc9vf$jIr?>~AZ >zs{Xos=7h!7WfuGDv*vL>IK1=S%c}mB;hV)(ff>tRF`f3$x*i4It75Pew`!)&7ei03 >z%IeW`QhRGq>Mjn*nlt-k?TL)6JCKz1*@)DqYGgxmr8I<o%Ero%67~jl_^VHEdb`|? >zyqL8cpM9{K#$MUYBhz-vwWoIL&_jFk;9c7~e8rAV+Qqi^%M#mrT;jDSB@xX@;#Xdh >zp<_DvIw4zrWcAjGfNU$Z>eRisZXd7K9T)t%bNGu+4}90#hgL{ePf2$l`YbydCUj5t >zbLsWo(V6-&$$T1@KKBjjo4GB!-kg@*4+@f<x~_9|iFEGLLD@5UN*BuIvU0hX{JA~e >z1^3crbGOI6@Obgwyy#IX^4R>Ds?kzr-`nr1P%4>LRrAmJ6PGzz{GMzsubQkjv*KpO >z_!{MME@$gJ^8YZ^Z*w0rKdj7jkqL9ml#xjz({?lyN2ZQU9+^H;08#-`0#XA~1X2Z3 >z22ux72vP}B3Q`MFjH9UrDF>+sDF~?uDG8|wDGI3yDGR9!DGaF$DGjO3(G-VN=V;19 >z>O%@dDnv>|YD9`eszk~}>O=}fDn&{~YDJ1gs&zEwBK10&f{}`ml98H`q8&}uNZD90 >Qv;Y6=_N7es9W626Z&TF~XaE2J > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores >new file mode 100644 >index 0000000000000000000000000000000000000000..1895e1b1e19120123e67367e55de3f2a5dac99cb >GIT binary patch >literal 3493 >zcmeI!XKYn<7{~Eb8B&HmjLInEN@Y|Ebg*sVFbX0R1d3FKDAZDhj0%Jywm}?dgO3Jh >zfgXlnDwH7zN}&fCQd$avRgq2EAVWYvg4h4|5EBv;<%Pbp&Ap#;b8pg+^!I(@`wvfw >zwEpr{!MwtQuS4d+&(+e*)4M0LoQ!TWHRJbUXU^O}otu}b^HOJNX4YPD29MSG>7{i+ >z`)j&z^jo?pBvd}>nJZbP%W2lt&tzHN7Rg>>%W`L=u6Vt!tep9VtQy-^KTlbttDp4g >z+Q?*G_uz3|=P%MPFK*ME?cd3Ubz5a)=2Xr7aEZ7X6=c(-neuh=6xp0GQns{vShu!{ >zlWlE2mv0ib>o@yuX<k4#&AS|}JC3DF{+cn8f8MnU(vq!$1G%#Ey<W0&^RTqSlw7ND >z>weueAxd^Fonh_nJ>S~>$p-zlZ;*VOo@DKbe8t-HYNqae`lx)@b&nLa{@MOM^pO2S >z^<DOlfv)}I&6W1PGYjkkUrw+Ou5#Q%3*K=LzdPMMGW|vOXiB1cY)D_XxOZpwc!!qm >ziO7cT$-33uQ^B$J>2fXX)3+MfXU<i#&+ZSj&+YilKL6D@`{%3!_Jxmk+85v4XkVJL >z+`c@*v40tw?_TMX<6iB!%)J&h&;2#zZTEWRH1|e{aqf*PL);1(q4L06HRQn=u`1(R >zXvM?^S}DH1Q@K;1R%uqo2@1LCJXHCtQ?<l?r|Ojgr&@9Tit2l_of?}no#32&U(KaC >zzFKpZ`D&-n^VNCjZJ%#cn(yI(<9v0y5AlUW_whXv*2!0|W^-Tt^7VZUO7(IYT<hR8 >zJQ3xD7CquTx;4mYwEBjIEjpu(XaA&4X5?$r@i`ivxJ)Ak?UTrq)e;r6UYhlOUz*pN >zD=i`?NsHU5(kghiwmSHnw7xY_+id74kL^#;=*5FIW_=rN`&xT#mr+ygq!4XCqqTJC >zTuM7821}=Ur!=<XZRuPpPrHO1mM#}gO4kybq-)`Jd7^lsbj!|??ghCTH!EFwES;}C >zM~{{#(_hhE{od5xqn_73Ek|j5_b%GEY7c!XEL5Mm9<B*Noh9LiO8WG*hSL9wt2&^l >ztPFH2%AnQf<(bqgGI(~OJUh5Zo||@7hqPNOLkAUTVx5oV`Iu}?Dziq1)lwaH`U6eA >zoub3HPu39!<8|bx19a53aq_|&F*<s29~qNeN5{U_T*mc^mXxHb@?u1786SI7CRDU! >zV$&d<c<Go-df>WF+Py_4U)ZNpRxFmOh3oaDkG|Gv*>m;f$%`~~R;s4@{r-T`_mwDF >z>K?!EH}AXqaZjHMyuZxfewQs*{=fPz@Asd&WLbXyiH255zyI>3fHHo6@e#|se)rG3 >zV&=yR5MH;;dwAv*s|rtlzTQ19-g?|T8iz-iN2Jv#JlyIR8_!#;0KRzk{$+Ut1jPUI >z0v<LW@D}jKollzI*6)8NCRmY0L{`z$EF-dx$U-73i7X|umdIivtBEWpvYyC-A}i`? >zmK0f2WKoe-MV1v=S7c$4l|_~oSzBarJ<aMO%ZscpvcSj+BTI~|F|x?WDkIB`tTVFE >z$Vwwi?P=B;S!_?U+Q@Pv>+NY499eNsv*gH{dzwYZLbK|gX4#Q-_cRNSth}dLdSvZA >z&Eg}g?`f7FS%0JeNCl7*AT>aW;AyIWlmV#&QV66HNGXt7AjLqcfs_NO2T~BEB1lP) >zns}O`AXP!ig46{m3{n}SG)Qfb;vm&Q%7fGgDG*X2q(n%KkRo}SD)Hw*nUFdmg+eNY >zlnSX8QY@reNV$-DAqDd^6+=pf)C?&aQZ=M(NZpXaA(cZ)htv)!9#TD|d`SI}0wNXk >zG$ll8h!hd2B2q@Ajz}SqN+P91YKasRsU}iRq@GAYk&1enk|H(rG(|<Kij)<pD^ggb >zvPfx>+9Jh8s*98tsV`Dsq{2vvks5oNA|qAyG-XEWj1(HFG*W7$)=06DY9r-F>Wvf} >zsW?({q~@Nc=t$K)P1%vUBZWsQkCYy%JyLw6`bhba`Xd(ras?ol0CEi=7Xfk=c$&)q >zxekyE0l5;8O98nSkc$Di8j#BYxgL-U0=XiPO9Htjkc$GjDm=|)fm|1!=E6X(4CK;4 >zt_|ekK&}qt@<6T+PxHrZ{eOboIZF5s`SaBH_fC+q(dJxf8xd`em9}AVQB9gR32z!6 >M78eoj{S;C54<V{N`~Uy| > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda >new file mode 100644 >index 0000000000000000000000000000000000000000..548d979bd1ece82ce76c18fff8a4d9a919ba531c >GIT binary patch >literal 2004 >zcmdVaT};(=9LMoPG)E^fDoGPCu?NK92nSCgXlP+)7$?5U!8j`Ttsn#~k^~`%%7>CG >z+X^jnY%Z7UqO4)gYGW9gH$D8!hw0kz=Nw$L+)Ov;rt<gq{&(3`SFJz$^MbR%)%X30 >zuV{WL9QenR>^|Y;+3a3^p7@sgc5parEM>-k-jTLbf`L8_Uh0%P?M9t=_5+hTl+a1v >zbeOw7Yqx11)tb9|pR@OLm6&^*=h?}LOp{)bVecy*H&bTav{Pqh$o(nj?6jntGVQM$ >znsNS|WF8;UtRqKc`d35xz}`<}M*C%({q{DQS##1p*s|9=6ggxcUb4kJlK!F1ncZk| >z#=q9wVASM}?9$nP<eEnZyEN~_(~{r6QbPl?WKPclEqFgDg-r<?Zu?V;qNR53vR@>U >zlVu+Ze<_bo@N99$Po{Y6yq$Ob3sdsrur2-lJv0A+)dk<RnJ0F9uVo*{&BE4wx@hZq >zd9vyqeX5~a%IB=n#pMxMd}X(d<}WqT6Wz8Vwa8Qq)Y~N&)6Fw`HfiPQu*ACS^w~p` >zrD|1~O5askIzL;NwV#pd%w&z%d@J$mqq;n@N0yH!+1lxcP3;dCY+`)3S+Vb^T{+Ti >zR&CvH>jvvheM7HZ-M`Ri>{EUI-8y+8f4jceR3;6nE!r5(md1;f+LV(lO+SaUdBUhP >zf1ai-W5;Ce&OE#B*9+$5j!E{F14m73%_aNlj{RnR<Tu;a+G}1*KWH~ptu-6Qk84Nq >zcIg-y(9WqX(mB|tUDqn*_5O{z=}btvdlLG_;WX)~FV#19U6w%7ZU6C?=M9$x0-kql >zC~&*yoia%&m9cnWQMG%^<L*j%;{W2Zul@Ze?mv1S7tXI-IdbX9wfnk@N3I^ZeB}C( >z0+0%j5|A2@B9JPOGLSluLXb+3Qjl7ZVtidSNI6J7NI^(NNJ&UdNKr^tNLff-NMT52 >zNNK*VHl#RTR~=FwQXf(vQXx_zQX^6%QYBI*QYTU<QYlg@QY%udud5a*7pWI17^xU3 >z8L1g58mSs78>t&99H|^B-PhHQ6z}V*N6Png^&<;_tN^kE$QmGvfUE+t49Gel3xTWz >zvJ}2<Es(|Vb*q6ahp$@?WI>P>L6!tr6J$}4RY8^oSr=qskd;A}23Z?qaeUqCAj{+H >z)(2T2U$;WY5+Q4ZEE2Lx$TA`8ge(-YQpi#vYlSS9uUjo-xqRJvAq(c~Rt#A(WX+I8 >lLsku0He}uK|FdvGH+Xa1;N``NLg7$BUaYV%R2V7<-U7n(2}A$@ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary >new file mode 100644 >index 0000000000000000000000000000000000000000..544f443a096dc1edb447ff85e71d0f17e40a227e >GIT binary patch >literal 1911 >zcmdVaT}ah;9LMqhnYuzEzE)<Nnk_SXIO#c>u9~hnQ>i?y@>H&Lu4Pus+;Yvd)m$th >zLgEuh5fv2+8Bwkas|$Nzk2ER?nvAx^V6oa0;b>vo5chlkcQfc}H-r7<oY&z9dh>mM >zqRZFS<#>-gkGpSp@oaW4J}126-a2Bd`o1XYA2%|R?~Tg+Ly74>YxKx(loWGKN%t>m >z%<T{K#EqkR^5eZqK7YYdPIg-Ap(8f7O_sKGyN#=Fw5O_8+4%CPr5BXggkZj9q-5H} >zVPh;au2`85rfbso8JgTXT2nq9qN!aE6+Hf<rnP^itQ}XBz3IF{wWk!WzG*p)U6xze >zZPOR;v%J*9mY>sX`2(#sBe`8OZmqPLe>Q2>g<^Z=>q-@L)Tpp~mY&^Nq}c~k^juxK >zigwJj=S$;MT$^ljGVZFRc)&{IK37@#w^nxVj?Inv(B}4Bwt2VTv-zDTto-UFMfSAW >zf|JMeLPLWsY<pLWmhIN!`qip<x?a)pGA&73prygdTG}5{Wn!sSemO!fKA2?7&;F(r >zz42CcG{LI7ezBKY?^{iKkG)*eYb&??q*rF2vsKksRhxFeRu^`vZs-}UNtM?8uwQEj >z8ny0ni(b7I)%y2WsQ$B!wqaMH8agWMwY6z_eP^C+TvT9<bxHO{c&u$I`Q6@3@T@62 >zQB8f{S@ZCIHDCY4TJGJ{meU>fR!_IK9{5PxIuGmZmg8#O(<(3USWIl(fBrK#_^Uk6 >zz4v*s?z%j0sOJs0z_5RQE{{aLX`!&UtR(7Q6;XZ{2n7Bn`Y-PHq5oI;cY}l6F>=d% >z%{}vQ)5u*Tw~gGlue)*N&XHS3?j5;#<nEE%NA4eK0O<f}0qFs00_g&21L*^4#MgC# >zw1V`4G=p@5w1f16G=y}7w1o78G=+49w1xDAH0J9%Lt687y&=sZ-68EE{UHq^9U?6v >zJt9paT_SBFeIkt_og%IJx?YiHeO<RmyGXxC!$`+S%Sg{i(@57y+eqI?<4EU7>%Ojc >zq<LT0J<>kXKe7SH4j@~A>;bX~$Sxq;fb0XZ5y(y;TY>BavKhW^H<0Z>_5;}vWJi!K >zLG}dM6l7PBZ9(=0*%)MJkgY-X2H6~6w>!x8_`3Z;HVD}vWQ&kJLN*E6CHy~cQ@mTO >W5Q`Oz<Ywh%g|frJNI1l&_`d*S?6GSA > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde >new file mode 100644 >index 0000000000000000000000000000000000000000..6bda6db7604c316edf78226eed2f785ee5f8aecd >GIT binary patch >literal 284 >zcmWHE%1kq2zyPd35fBCeHXsJEc^ZJkq-U!ZoS8aD;ZjMB0Jr#ehx-5j|1&T$F|)Az >z|Nrs}1H=FSj~_4q*&jbJav<0Y96r7w47vtJKy1jszz8%5OoWhN`wx&NAOKqUALI%U >d4RQ&H2Dt_#2XYaJt_O;d?<y`EpeyYRxd34xR0041 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe >new file mode 100644 >index 0000000000000000000000000000000000000000..c4865186b035081c6f216f75486310e78f03c716 >GIT binary patch >literal 1829 >zcmdVaTTISz9LMn|X<Ea+v4l=Y5|4UHg_I=KP)<FPLvl!pL`f@3jG58e*VdTPFs+#- >zF2Y4(j$>#xYv#~w%-NbPEoLph_ur)}H#YzF@AdRtboG6IoXhibBW!;>{mnPLJSFDk >z^Pt`4*P+eznO=dPb=c6C>h1bSy}PdI@HZE9#FJAx^44MXx!NkejZNZr;-vUjs{~Z+ >zkx>Q3GJ54Y8I$Uiz}O@iYmb&7-(VRxaJU4!C2DYYq>g_Zq#^CYbi$nhI<fh?+Uq~+ >zq}t~iy6=I8m0VRv&Up>bdL|LY%`!QzMIsj;ktn}9iH<0f=-w)s>Qk#zJJ!gwpQRep >znkds>WNK_fw#K!@=#2dd8h_kZXXXZK!oF!TE7?sGb9`iW(0ffv?3HA<`<fE?N>V!C >z$sE@kGN<jH%zbl4<~5y@)Q8tKt)^P$H=fo7g@v-Pdao{8dQcY^tk?7@1?o&q(IwvV >zHNzgF89ffo^h%b@r$cmE_jp-;`J1k2_mGvRJSD67i>#{ZlI+?xS)JW3YbrnK+W0H7 >zF6*J@1RRs~aZQ@*en~g@sc!giRP%a^HUD0@ZtQUCrn4)w;BJv@J`ksc4e7EaFF?2M >zkCLKAu~MAtE!)EVr6lQxZ1=QDX_%Lmetj)vgL|~>@og#Ze5N}tHptGl7OgmTQ!AV5 >zbXR%3R@GFg&845~zy9g#`*GHs5s$g4!Q$fn`*UiV)3!8;H{EHzadF{w{>5>AxBidK >z)@L4$ls`FC<XDk|wKPYI94>Oa$N?iqj2tp@%*a6_M~xgda@@#)BS(%LI&$pD!6Qd+ >zX$~Jbek1@S0we?^1|$e13M3394kQpH5+oEP79<!X8cP!n5|5<`2#E*@35f{_3W*8{ >z3yBK}42cX04T%j24v7v44~fsx1c*dvX+lI|M1n-3M8ZVkL;^)3MM6blMS?}5MZ!hm >zwKM@E5nGy&k(iO7k*JZdk+_k-k;swIk=T*ok?4`|k@%4TKt{mQ3;{9*$RHr2fD8jN >z4#+?tBY_MBG8V{SAftf{2QnVWfFL7cX@&$D6H7BF$fzL0f{Y6?Fv!RtLxcat*m#)v >XaWFsjw8^1Sp^mU{ds?`IPaeMj0dSc= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe >new file mode 100644 >index 0000000000000000000000000000000000000000..c4865186b035081c6f216f75486310e78f03c716 >GIT binary patch >literal 1829 >zcmdVaTTISz9LMn|X<Ea+v4l=Y5|4UHg_I=KP)<FPLvl!pL`f@3jG58e*VdTPFs+#- >zF2Y4(j$>#xYv#~w%-NbPEoLph_ur)}H#YzF@AdRtboG6IoXhibBW!;>{mnPLJSFDk >z^Pt`4*P+eznO=dPb=c6C>h1bSy}PdI@HZE9#FJAx^44MXx!NkejZNZr;-vUjs{~Z+ >zkx>Q3GJ54Y8I$Uiz}O@iYmb&7-(VRxaJU4!C2DYYq>g_Zq#^CYbi$nhI<fh?+Uq~+ >zq}t~iy6=I8m0VRv&Up>bdL|LY%`!QzMIsj;ktn}9iH<0f=-w)s>Qk#zJJ!gwpQRep >znkds>WNK_fw#K!@=#2dd8h_kZXXXZK!oF!TE7?sGb9`iW(0ffv?3HA<`<fE?N>V!C >z$sE@kGN<jH%zbl4<~5y@)Q8tKt)^P$H=fo7g@v-Pdao{8dQcY^tk?7@1?o&q(IwvV >zHNzgF89ffo^h%b@r$cmE_jp-;`J1k2_mGvRJSD67i>#{ZlI+?xS)JW3YbrnK+W0H7 >zF6*J@1RRs~aZQ@*en~g@sc!giRP%a^HUD0@ZtQUCrn4)w;BJv@J`ksc4e7EaFF?2M >zkCLKAu~MAtE!)EVr6lQxZ1=QDX_%Lmetj)vgL|~>@og#Ze5N}tHptGl7OgmTQ!AV5 >zbXR%3R@GFg&845~zy9g#`*GHs5s$g4!Q$fn`*UiV)3!8;H{EHzadF{w{>5>AxBidK >z)@L4$ls`FC<XDk|wKPYI94>Oa$N?iqj2tp@%*a6_M~xgda@@#)BS(%LI&$pD!6Qd+ >zX$~Jbek1@S0we?^1|$e13M3394kQpH5+oEP79<!X8cP!n5|5<`2#E*@35f{_3W*8{ >z3yBK}42cX04T%j24v7v44~fsx1c*dvX+lI|M1n-3M8ZVkL;^)3MM6blMS?}5MZ!hm >zwKM@E5nGy&k(iO7k*JZdk+_k-k;swIk=T*ok?4`|k@%4TKt{mQ3;{9*$RHr2fD8jN >z4#+?tBY_MBG8V{SAftf{2QnVWfFL7cX@&$D6H7BF$fzL0f{Y6?Fv!RtLxcat*m#)v >XaWFsjw8^1Sp^mU{ds?`IPaeMj0dSc= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen >new file mode 100644 >index 0000000000000000000000000000000000000000..239c0174d361ff520c0c39431f2158837b82c6e0 >GIT binary patch >literal 2251 >zcmdtie@xVM9LMqRfk?4(Z-2m9fRIS1cJdqi5tq^l%)GOd(?~^75wR}H%NV3anRBi& >zeCt@|$f@O+HN*a(`~$6(+GyeBFXpUVTdb@!x<tZitUk|gYyDAM|Mf@T@9z8f?z{W` >zaofF~fu-wea;(1{vE~UMju!Lb{`Tk0rOnl6wO!a))qT`o)pKROoPOP@;a9!#$*w#( >zvn5^5h7#o5s#v*tBvr2+^2zrvd!&DRhWyZwB9U5=AIlwbz4W>aOz)E$t_w2gJS9I# >zM29j*%24E-jtTFMjP=izak;-}eA-n_82h<8qfe`I;9VWxcSP?vzhCb>u~QR|9haoT >z9g_UYKAF(0lCtS}NezbNuH~y`qAwt6g~c+-T_EX6F1h=*@#2c{s%tP$Cx4Z$Q+gA0 >z>Zw@0r}L(|4}PoDT0hl{tsiUVhGUvl{ibGDT#}qnr{sFNByZ76lApX+3UV5xV7N(U >zB(~~|%PVE(uk||XxL5A|tXvD*E7j9AOYhrOq_f+SbWTm07Hyp=_m{+|w>nYgreD!w >z@354_e59pmUr1^H*D^2qeVG^TmIwM?lldKQh_B~8^|v(3g2M;&!MZwmsQCq5`0$Im >zD7Z$;rUy0PE7ir$1-isNMVAa^X?c8!lwTa9j|@(hrSII(Wxa8-eE(>v=)5K?ng*n@ >zH7r$?y|Qxice-l!QCVHlqtz*UWR0goYi@a4*Cwm3{bsk;4u^DIccVUfIiQanTBgAd >z*URJEJzCdZCQsC+=#$&>W&OfJ3Dr2|sq6`|q4;NcdbB0=nekd5`BEB24Qa!flhW9K >zNuPPET{echbkm*>baTgEeYWwSHnlWqlq1R!J>nnEsF;!e{b^Zo<IEq~N=kK%u&hyH >z-TLSCk0*aU_xS^sx44W;fHxfGKywrL_u1?)U$kd)(|*UYeltg?e^L;ck*%2$GACqG >z$gGfQA@f2ehRh6^8ZtLza>(qE=^^t&CWy=snIbYrWRl1%k!d3Hv^5ju=P*-bs>ocC >z$s)5wrfX~Fi%b}qF*0Rj&d8*ZStHX%=8a4onK?3bWbVl1k=Y~DN9J#95`bg?Ndb}r >zBne0skTf89KoWsu0!amu3nUpxHjs26`LHz!K{8@%Qi9|JNeYq`BrQl@ki;OFK~jU{ >z21yQ*9V9(Sevkwq8L~AgLULqll7wUlNfVMMBvDAFkW?YLLXw4K3rQD}FC<||#%xW> >zkeu0?q#;>D(uU*>NgR?nBy~vckmMoRL(+%j4@n@BK_rDp4sA^mkt`x<MDmCv63HZz >zN+g#^GLdW|=|u90BoxUgl2Rn6wkD}aR&7mMk-Q>_MKX(|7RfD=TqL{J|FFApCdJdT >UiL%?Dn~|T9<@RT1VP<aJ?<;p%>i_@% > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira >new file mode 100644 >index 0000000000000000000000000000000000000000..e25f8a599622cb45cd2afd7bf739e4d1ed5ed589 >GIT binary patch >literal 3484 >zcmeI!X;9Tw7{~E*Gt$uXD4HTJ6`5G5e{eU+jKs09MQ@4=nY$U95;`s!r!?D~=8>Vr >z(8OG77^A;tE-9M1;(}XLnrLb6+ch;Q#^`)cHDl9@dQ-2uckcb*l{@1bf8QtA=gFb* >z>MxI*>?gc<l-L(P*EjYp>)0&Gd2o`+`K4H9%_=jq3ul;jGmV*(w^8NxA86*jR%+hs >zbll7vHQCIMj#3LAUaa!MuA00{v(<-%%T)gR@#>@8RO7!?Q!RdFqFOTAGaskFX_h`x >z!z_>QV^&oA(yS=oY*wCMVODS1qzYCnS8L{sG;80UsXlwBT&){FNqs&%O|4H!RU0}+ >zn2l{as!i<|sLd&#n$7#pn!-SWDZJ3kY&|?iZTn<^+ID7fXuIhh+J0cM+VMuB+OfX( >z=%RE#RJ3u2**Uh6+PP?KXjk{F(5?j^nca_7RJ*753hjx{2<>@shS}SDull0v236ed >zkoRSiUEWub>%6aTT;hHG(>!nA$!zby%3)r~k}Ut=dsF;FSsDJfFAVX&OYi9)9@xb{ >z(!H(!{e4aRqw#h9W4BfIk4LrfPE?NZPLxG@Cr^iar}me5r?;N*&U{+poy{xq&b_nN >zJO8Thg(lARE{w?Xei&5XU+j_ZUrL<gUv44(kI~QjS0d8=(h7t8(u+a=rkp5M^|dOh >z+SE2iXT+H5gCk9iU>%7_EHgD*{4BMiPs_~_2c&j|9a8(^8mV)nAUASvuGC#WL!wp} >z=z5Ftb^Td$bc5-l8$SEIz9lVP-`a1GzAZVZqdRogx5u{Djp{YlcT}mP8;2!I<I622 >z=4c~nQhc-Axv`?$wX{@X=bx0O+54s0)NRr{W3_mLKa{xCeL6mUscw<5O1JF(rfyY# >zwr(9iUbnuQsoO?nOWTqGx?R~gX<v}2@BSu5IxOrj39H)6J<~c#$DDd{@6c%JG_{?+ >zFDXnC2S@4q8y%O<iC1+}SfO-@KBT*xJEpr<Sf{%dZP5=LnWrDj&(q1<*Gjk7r|X9n >z&6S5ojna=ypCXU;dR4lo4Uryg(j=JNMINjDko1ggB0aBol2R*4r+igIdS8yweU@F4 >zzQy6XUv71sy7Y{GJoBRNpIxM%=wGY{Og<$8J1*CQQn$<ChBNh$gnSuV=@S`NUu4*c >zw`BO$ba`^i1Q}5hl&3!ED`}g?=#eic$f$)q^wYx|%IImW^q5CG==7nr^)qn|bVlc& >z^w{c3k855_#)S^+@l~(L_+1<Hgme33qQ6j2Dq1Da&iq^^=g*esCd`-2*E1z>!*vy| >z5BrDDiuU)eef^{Fg;%=qnrG!I|KYQ|JQSmpd%xapiwaaKFTW5{Rj&Q{k58)VfL6-B >z*W_<i<e%U9Jh@v?CE3?qo~N36an?B1t8<T_eG9tZ4!DO31l*sLBM=Dw{Q@4eUvLXp >z`r9|{Ke@d8@q~yJWD${7blPP^))84qWF?WMMAi~nOk_2Y<wVvKSx{s}opwo)HANN` >zSyg0Nk#$8D7Fk(jX_2)>7T0N47g=6peUSx5Rv1}gWQ~zUMphYFW@Md_g+^8yS!$<U >zYh<yVcD0e^M%LSD7aUn}r(JSn&7F49kyUrvWk=TCX%`+@d8b`^WbK`H@sZVc+T};q >zA1MG*0i*;-4Ui%@Z55C*Aay_rfm8x11yT#77)Ujcav=3U3W8JwDG5>&r!5Ln6{IXk >zU68^cl|f2_)CMUIQXQl`NPUn3Ar(SOgwzNrlG9d+{~nZy2X*2>p^!=;r9x_j6bq>q >zQZA%kNWq-8Vo1r5nju9)s)m#esT)!_q;g2<klG=|L#l_A52+tgK%|0BTSBCUND+}L >zB4tGCh!hg3BvMMGmPj#?Y9i%C>WLH-si@PI6sf7x78R)~QdXp{NMVu6BBe!Yixd~B >zE>d2kzDR+Q3L_;(YV5Q{Myl+zWk%|Z6dI{CQfj2uNU@P>BjrZwjT9WII8t(?=1yC5 >zr0PyvcBJk|;gQNCrAKOy6d$QRQhucV$OV900mvnQTm#5OfLsMmdl?|t0dgTAR|0Y= >zAlCwNF(6k1aycN^19CwiR|IlNAlC$PQ6N`^(_R+Hb>XxZ26AN}mj-feAQuO6bs(1q >na($@(&yU{^l7H>|2)EaX$C(n_twpm|&AjGuvEAZ4ehU8;Pr47v > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik >new file mode 100644 >index 0000000000000000000000000000000000000000..dc49c32470906fb2ff94fc599c73141597443f98 >GIT binary patch >literal 1188 >zcmd7QPe_w-9LMqBnvSrDL7-$%-zYVZVEsW5ifFMq)DE#h)Ws1MBn2r&w;GlZ{UJTn >zY1KFJ6#auhFm?!nL``d%wwBpnb83Gy%Vt^Y_kMQh(5X&64|`q@&$C_jd55>}*}cO2 >zad_+#J{$r2;ocjymy?mB8f#o&&L@sHT&Ud=z1ZvaYN*~^YN=>wUR@S#Zav_=8!R?$ >zYs#c8Rdl1hbiKCUDV0u7iFRJ`>%IOi={mJUyW`j8{$7thh&4)LQ(7O^U)7%S4t=!i >zjP_P0q%TmTkLTT#WJySqQ)eYLXTPML9FnJlMcUuGO`dhHl7Xg!`utj<yr|o%FHdLW >z)s9Miy)Pwi{PT4%7?-z;e&|p|Qq!}FWw`K`4v$RB$Ye}MI|k%k-(h`!`L=v$iRi}@ >zO)_@QujAFn<kOKVnFy(Vu39HwR@Uj{+Qss9?oQ1t%$Ll>2A%pjB;R_L>i4u;r{e)J >zGhDw<ciump`PuAf#QwMTaOGvQ<6~xK?wWhzyqLW?7&hfTpIPQxZZ_I`zU*>2?@ahF >zM$F`XVzTyNOk_}GRAg9WTx4KmWMpVZJ2o;nGP<K39vR=!27pB1XhT3^K!QM`K*B)c >zKmtJ`K|(=dL4rY|LBc`eakK#;5jonBkeHC5kf@NbkhqY*kjRkGkl2vmkm!)`kob@Q >zkq8}ah)9e`kVuqBm`I#Rph%=hs7S0xut>B>xJbN6z(~Z7He@7bBxodR{BOc8u%-J7 >FegQpVSd{<( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia >new file mode 100644 >index 0000000000000000000000000000000000000000..56b383b16db1ec8394d33e31863e468ed4bbc9db >GIT binary patch >literal 181 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34$+|NnOnFfjc8|M&p|i;r&zgRTL@j1a=6 >jF+)w{_yJ^q0MNkynQea$fY>0@8E_lVWdpRx&WH;D2q-0^ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd1af32daec193239ab6b472526fd3d6bdb2f76 >GIT binary patch >literal 170 >zcmWHE%1kq2zyM4@5fBCe7@MO3$eHwPk_Q9h|Nnn1KvF=!;^P~_;10wf5JG}!KfpQ| >Q82$qRep9)C#v5<}0M)@5+W-In > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley >new file mode 100644 >index 0000000000000000000000000000000000000000..3649415bd14a3356419efd7340b430e645509e0c >GIT binary patch >literal 1251 >zcmd7RK}ge49KiAa(qUPL1_e%2XQilVKAp~V)1EnWEyGn_v_mr@G>E8Mr&&Qs5M<pu >zR7h0Nt4oK5{K@Ikl2#FvMU13FK~Og{==HvT2&4{m?EQKF&*NSGjNf;C1H*?KtUp$s >zxnZ-q&E~vr#Jnzt4}>Or2kcZJM@-d)?CJF%M7p3~rnO5wS`5mWcMEFvRk3_LF{Pf| >z*K#g!N_ag#r1wQq6@E?mif$ef8=j5(iqCh6k{kO~>5+i+jkc+>Xo1`~RH`;rEy>Lh >zmnvWNR#w!Ph>DLBveILT%IEWT)tC38`d-rBl1Yi0OIPe#H7>TE7_sXvjta5&pk06R >zx@rg}q`&{HYAhO*O)W#J>3gSa_C{6nn{v7BTa9XYkSAMTS7(A_v)RzY?pWLL+u8Q3 >zRk7^@GjVx(b*!WHR(!|c=U8Xqg?PB*X)L^SEZ$XiH`X=3CmzY4%S0xRW_NzNlZjsI >z&F-2V%k-S7&nC3iuACLi9(S&JmS6na+3nVPCS_U9J6G$M8P`g!)3&un>xHaqEjO0A >z;l5{gpS92ITH!al(d^&H*!TC*Mt+TU(HvOjm+0Yho+L7AWZcNek+CDAN5=1H5<oIQ >zQb2M*l0dRR(%_rq;b;;;GC@*7azT<ovO&^8@<9?pGD1>9azc_qvT`(OA$d8P#E{I8 >z)R5ee<dE!;^pO0J1d$Ap6p<W}B#|r~O`1rajwVqgQzTU+S0q^^TO?g1UnF59V<crH >sXC!GPYe$ndlDDHt9Le0#q>ki{B#&f|q>l+ROY1-EKR;yt8}0u5pBDRd_W%F@ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT >new file mode 100644 >index 0000000000000000000000000000000000000000..aaed12ca284d69e3a8ba25891701790bde7f6743 >GIT binary patch >literal 2223 >zcmds%TTGU99LK+J!U*z^<v1##W`ZFH6@x<a00=3D@^UPV08#AV3#4Kt{ya2lOG&$s >z88f6AT~rvYX^urKH&zI&E;^9r=%!(9)J@6E?EiVzMOzo$wm#3E|L57e=Y6l<@5f(W >zTeC?2AlQAv4M*I~^Hg(3+xj=#+Ir%C9`L`ff&P-f#k0jW*qIR+YH!eRb4*}TAj5*D >z%v5kej0OLiZXwAxEab~*3!QewLO=N3!p8gTw%4OH`RngArRln+p8HtSHec55tsR=a >zyjOQL9@3q$r!=FqMl=36sPOb$MNEFlB4<}yWdDAP_T^Y~XO+c_#@o#1Y@5{=X0dzP >z?5^Y8iYsff**0WzR=uXVwLj|aIeRrPZ&35buWEimm*x*&R6^)cC3L;31!E1mxAiki >z{G!DcHok31-F22+dc;zW6<X@1a$8iNW{a0)+LDbCmNqNamZnbF(i^h$m~f?E`ra}+ >z$L#)|3--Xsh%!%)YT5Z7Eq~z?J$T}zR%|(~l?Tt;s_bU1u4=Qaq&F;kb(7@;uhp8l >z6}INL4(0yvs`9=%q=))<YVFw?t?MjN{_$L`Z_d!eyBDY+P-Gh_a%^M4eO9<4-ux+1 >zRumUz#nY}^@y(yCWc;#~UKz5o;a)56J!6lYyQD|o8q}uNkF@#4E<M)Ru8M6(^?2z4 >zRpvIRD!p3O@kQDanWLKNb+*-4X<L6Ov~8nVR{MFHZST9so_H_9o;-D{J@v|jJ#ANQ >zN8novY!6Xg*)`SYjj17HM9(A)XlGQ9c7?v9T@xp@d#pu`-<bA%TBm0}tkiSehwb@} >zCfj>#hcz9juzmF#>=xf&*QB8Tz$G2N;Qq)uamE)Uz1*(Qzdx_b_iJT#7Du6<*L*%s >z`Tu<<E$%gMC)d1hNH-k~;rlW%yYcL{gV~Q~w;{}qFk8ax39~7Fj$L841?<bS+ZbkN >zp54|kd-LozhuIxwd%*sH4FWp^wg~JI*d(w^V4J``J-dwpI|a6i*{f%_S<G%dyX|83 >zi`g({$Cxc+_6%$qvun(@fqerT2X^k+Z5`OVXSaD^_nzJMf&Bvwz;po90!$AuO~7;k >z(*{f*Fpa=;0@DgiFFd<uV7lSiwFA=+OhYgo0a^m|1ZWD-6`(CZUoedUI)iBqrZ<@8 >z0NwHI+5_|lXb{jLphZBBfF=Q50@?)h3DYP{r!cL;^a|4~Ot(C{c47L3X&9zsn3iFB >z1~d)m8qhYNZ$RUK&H=3hdIvNQ=pN8MO#eK)24XshX(6VEm?mPnh-o9HkC;YcItjEA >z=q1ohpqoHDfqr^+4Fx(1v=rzm&{UwSn6_g2ifJsSv-&@THjMBtOidxeiTSB1NvTOG >MiTO)V^5U>R0gAQ*YybcN > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide >new file mode 100644 >index 0000000000000000000000000000000000000000..4f331a87df4ed78be0d00b1a82b5c66c773069c9 >GIT binary patch >literal 2238 >zcmd7S|4&tQ9LMo<x!ibPN)Tg=G>9)5Qhd39IWWYFS5lHIgf{~M(p2z56rtf2P3g-W >z?_zUiP4Aprr4iWbhg<`7ZjHI5qGFo%ZEcORjIGVAt*ou+^E|UHSAT%#?A*t>=WciR >zhx>X48iFl_)_)F{dBVl9%Us;Y_L`RiE8l$ez=^EO<ALKcKGq!iaHL5;8uW%fez`{` >z`Z7Y!POnDK$P`yihPr-TtTCQwjrlZP-SOY6d)TS57vIzCUrLi3KL1W;?2MAQqhk`^ >zd|qZo4ogDWDVY`Omm5=uB(bhT690Nml8UP(>B4K8oZha<W2&<qew{torgJ9q_2#}R >zO&Lwl)UAi~mVL)0tv;;jz2`Jz$wA2s{w%j<JR@@}&&q94Es~WzELjtuNVYp7+2iZ= >z_NgAZBXU}E&g|9P{&|{rB&7M9E5x&>K?|DJYGGHY7A^AW{MuB#Gi9zWD719JpD|iI >zCq;_Cn$nU#re)!YalPxyNhuxpK^7f9DP`dgWbyt1@osoS%AX$9B^A5Gx9*TG&3j!d >zd||!YRV&LfTXorQhh_PN{Zjc^zuYsnT~>^ANY!Ao`1e)I%091DZz+(P&PKg=jbCeP >z%5;@CUjv>ry)P|6SI>;n)ziP|{TI(`-Ph-|e&UoiyfdN?9Q{@rht5h<<XvgjVR<k# >zC~G!GWNqEE^3d`gSy$XH>*qDfhGf6AB!slp5!BX84Z3l1g$7TTYTIb8w!f9C55E$x >z9nV|(Nbe<mwDTM7Y>Sh}>Zhfv@+a9;GAWz0&&cC9os@3(+tU5}fNYuCE1@s?Wb6AO >z={XjZZAV_z?FYm9#GY>5@l>ns?5fi!$Cc9=eGQzJwPUyWBU>*FIn2L09J%_w+_x%V >zmHU<kc<gZSY6bp(BiEUaxH$Mm?&B`=&K%R`*p$?th}&j4JCW_!n*AUfvNbzGwuI~n >z*%Y!XzLRYs`$9HmYj%cg&DQJ<*_^G}9kM-Sf5--r9U@yq_K0i}*(I_~WS_`JZOu-R >zt=gKsBAc}}yG6EZYxaw57}+thWn|CDrjcDE+eY?{Y#iA+vUOzd$mVU$?vd@=n*AdU >zKstc50O<kJ1f&Z{8<0LAjX*kqv;ye`(hOVE4Wu2mrXNT{kd7cNL3)BT1?dXX7Njpo >zW01}utwDN&GzaMp(jHsWAEZG@hmaN_Jwlp<bO~t_(kG-*NT-liA-zJHg>(yPm#yg+ >z(lDfBNXw9(Ax%TNhO`ao8`3zWb4cru-XYCHx`(t6=^xTSThl?Lg-8#PCL&!#+KBWK >zX(ZA~q?Jf7k!B*@MB0h;6KSZe=_t}tq^C$zk**?bMf!>~7U?X~TFc>#x^hOlu7T6C >zp8V1Njk~RAySZ+=xmVp+`AP1-y8BOftymuCmMkptkmMYHfhVsZ&y(Yy5BWv0e*=T+ >B3P1n= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane >new file mode 100644 >index 0000000000000000000000000000000000000000..a327d83b7696f39c01a9b5cdff1d4f0fd4b1f94d >GIT binary patch >literal 452 >zcmWHE%1kq2zyPd35fBCeK_CXP`5J)49KU6A=Il}Ua5`i&!|CJU1!uO0HJn{;S#WMa >zF~j+G=>p~g%LW!+83t9)vka>5Uoog_u4hm`e}+Mmb0UN0`gIIUj8MqT0)Y$+{S`oS >z8D?!@WMN?FS-`-F%=YmOVQ_SH0TIC=AZ3h<Ad(@3u(O4L%D~S40oK95@E-_@-p=O$ >z(I9VtX`oj?G{`$(8t5eu4e}O<26+ucgS-c#L0$wI2l6I}26+_(K;8w@Kre#;$lG8V >Y=yebPc^^yzgMeCLzy%5uT|)yd0M{6F@c;k- > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill >new file mode 100644 >index 0000000000000000000000000000000000000000..768b167857dd82807b5ef912be31518086c77141 >GIT binary patch >literal 2274 >zcmbW%eN0t#9LMo<d5ABhBI=AZh=&+aJY2vW7$S(IBv%M;1_Y$}fPfTX;T26;$@rG7 >zj7skuTc$Cv)m&Df&aE+*R8&mUves6VJ@6M%TUlGt@BLeIx%i87cJAxk%MQDL+|S!v >zS+^;}`QH(2KH=hc&RpDwwV9W$Rd2l7bvp6NkoS}f4c7QR>aW(1d-8mr9BP%}jyPXn >zQ=SG*kC))mI1T=7iH5j?G~}~b4GsT6L;C_XZ0vo#{^b~%cIkVWzB@o>oEVhwn#(fN >ze^erJ&&n*{UYQ-;D|5;lWzOGE%iOFIxnbHqjf`#3$U)V4E|1RZsn_`<X?jyfu|^F< >zX!Q0Ydh>yk5>wHxv27PMZs}o(ulq%AiQ6LyMHeJtY+MqP`Xq7qQ%MT-OVY7-<hIdP >zx!r$Glh5zh6yIB#dfcaJ<u9qbvr^Nm*J(y`j%F?{&;@1DdPh`(F3fOr;a?$|H9tzS >zwj8^Z_0_0m|2ZLxP7mpwUyevl_fN9;)EUWb|4^13?3TQZuS@=u1G=>ESt(e5M3<$$ >zriBIVdRK6nERV0%<-Z@56+a%7qR;or-Ge)2Wq+d-_tc2zK#8pC$di(7=~CKMrT47$ >zXjy5luFgwSuRBKXjfv1TGXr$Z#IJha*kvvM`l410pVi8D`}O`4-$_;P1*!JGCpFq9 >z5BPdy?PkBMD}PEJT+u4)vl?W>tyQuy(j%K9d|K<O)7tS$-8`~V>(1q9{XmK~ycw-q >zUJ2L6=N)~hZCoF2`c|9jXUHQJ6VhDtvuw>Ckw=rx%VRg5k(SW6rR9%q**3agd|!0P >z_78m0da_P-9Dh-F9&XpiJ6m+u6Sca#xm*KW|DJ(CQ#@T$eQ>hp9B0=)^J{iq=yjQ& >zcDw)D`}~5{UMIg`nU{}UE?yn)<U<KDf8yfkG#B@?ukg+s6Xw`DS2tiwQ1>^uV^&}j >zG9;@R6EY~P85J@tWL(I=kdg7f85%M+WN=n9I%IfOGd^U1Rx?6mh{za`K_a6>hKY<5 >z87MMRWT?nkk-=KcXp!L}<3$E+H6uobY&By>291mw88$L*WZ=lik)b1FM+T3K9vQyX >zj2{Vr)kFXZfz`wS2?7!YBn(I#kU$`jKth4U0tp5Z4I~^$Jdl7`O+=88SWQf<CMZZ$ >zkgy<eK>~wB1_=!k8zeYLbdc~M@j(KFL<k8H5+kb#5)vgOOh}xNKp~MrLWRT%2^JD9 >zBwR?mkbof(Lqdkc%xZ#$L=6cW5;r7pNaT>vA+bY(heQtv9}+(#fJg+95F#-|f`~-X >zYQl)b5eXy`NhFj=ERkR$(L}<D#1jc95>X_iNKBESB2l%Pup)6q0*gcz2`v&^B)CX) >zk?<n%bzA{gBN%+$6wkn^J~-KPj<ctWZ}-e0C&;!q)V6qrZSght#U7L5Lfhm2MEPo# >dO~|NqO7@~mH^ol&q`OnoQ{Bm)1(22*_78DE8g>8x > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra >new file mode 100644 >index 0000000000000000000000000000000000000000..aaed12ca284d69e3a8ba25891701790bde7f6743 >GIT binary patch >literal 2223 >zcmds%TTGU99LK+J!U*z^<v1##W`ZFH6@x<a00=3D@^UPV08#AV3#4Kt{ya2lOG&$s >z88f6AT~rvYX^urKH&zI&E;^9r=%!(9)J@6E?EiVzMOzo$wm#3E|L57e=Y6l<@5f(W >zTeC?2AlQAv4M*I~^Hg(3+xj=#+Ir%C9`L`ff&P-f#k0jW*qIR+YH!eRb4*}TAj5*D >z%v5kej0OLiZXwAxEab~*3!QewLO=N3!p8gTw%4OH`RngArRln+p8HtSHec55tsR=a >zyjOQL9@3q$r!=FqMl=36sPOb$MNEFlB4<}yWdDAP_T^Y~XO+c_#@o#1Y@5{=X0dzP >z?5^Y8iYsff**0WzR=uXVwLj|aIeRrPZ&35buWEimm*x*&R6^)cC3L;31!E1mxAiki >z{G!DcHok31-F22+dc;zW6<X@1a$8iNW{a0)+LDbCmNqNamZnbF(i^h$m~f?E`ra}+ >z$L#)|3--Xsh%!%)YT5Z7Eq~z?J$T}zR%|(~l?Tt;s_bU1u4=Qaq&F;kb(7@;uhp8l >z6}INL4(0yvs`9=%q=))<YVFw?t?MjN{_$L`Z_d!eyBDY+P-Gh_a%^M4eO9<4-ux+1 >zRumUz#nY}^@y(yCWc;#~UKz5o;a)56J!6lYyQD|o8q}uNkF@#4E<M)Ru8M6(^?2z4 >zRpvIRD!p3O@kQDanWLKNb+*-4X<L6Ov~8nVR{MFHZST9so_H_9o;-D{J@v|jJ#ANQ >zN8novY!6Xg*)`SYjj17HM9(A)XlGQ9c7?v9T@xp@d#pu`-<bA%TBm0}tkiSehwb@} >zCfj>#hcz9juzmF#>=xf&*QB8Tz$G2N;Qq)uamE)Uz1*(Qzdx_b_iJT#7Du6<*L*%s >z`Tu<<E$%gMC)d1hNH-k~;rlW%yYcL{gV~Q~w;{}qFk8ax39~7Fj$L841?<bS+ZbkN >zp54|kd-LozhuIxwd%*sH4FWp^wg~JI*d(w^V4J``J-dwpI|a6i*{f%_S<G%dyX|83 >zi`g({$Cxc+_6%$qvun(@fqerT2X^k+Z5`OVXSaD^_nzJMf&Bvwz;po90!$AuO~7;k >z(*{f*Fpa=;0@DgiFFd<uV7lSiwFA=+OhYgo0a^m|1ZWD-6`(CZUoedUI)iBqrZ<@8 >z0NwHI+5_|lXb{jLphZBBfF=Q50@?)h3DYP{r!cL;^a|4~Ot(C{c47L3X&9zsn3iFB >z1~d)m8qhYNZ$RUK&H=3hdIvNQ=pN8MO#eK)24XshX(6VEm?mPnh-o9HkC;YcItjEA >z=q1ohpqoHDfqr^+4Fx(1v=rzm&{UwSn6_g2ifJsSv-&@THjMBtOidxeiTSB1NvTOG >MiTO)V^5U>R0gAQ*YybcN > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie >new file mode 100644 >index 0000000000000000000000000000000000000000..a3f6f29a49617167750848c71e463faf6f3974fc >GIT binary patch >literal 2223 >zcmds%YfP1O9LK*$V8lr!%PAKnw317B058ZXB{e`$NsPlaMMC6anFm27%hPXWo?c{j >zag$|Bq%nHqRJv#zi<oV$5m;OIG^1WLx>;K@otZtKXZ5NVy={G-J^#<yv*(;w=lcoN >zv^37qKZtUkaKqEi&F6{c90xz@uowH2e;x|Fs-e@B!S_y7*l@2uIMUUoGvUNwM9^=M >z6Q(JuG|{3i=2~>-Rg3;O!D3?1Tg>afoA<(?U4JNE<3IgU6GB%s@#Ncztv#n3I=eL~ >zZ$LM8?AA?5hc&sXQIr38TvKw3G&N$C;$}2h+&9@u@Dy4??|MrdO|@y^0-HYQwWOvL >zyZJz$lB+{D!$xf8(u2CC<$K*abEj@A9@eaJ>y(mqR4Ko{q0}EoE$zcjr4OI7+h5zE >zj3YfZd;c2w_J%F9Jx^JiS}c2Qjm@dpqq&O~+Ps`*&7YoRIa8J^=c;VM#SG=1{o4G! >zV|GXXJ9g(lx-IM()uKb=E$@j_x-0aPE#A<hCAII{(t@z=&g-*$-^*5zwBHJ&R%luD >zaV`6;TSebKui{U3Yx(J|T5+OLD|;(da-c}}g#B8zJzb^2a$8+jX!n*bu(HLe7RZXX >z@?@`7#9pzAYd=`!g>zPQe#ENJ3|P&;F}v^NS*>|xSZh1qQtgvRwXUN}b<NM}{;FN7 >zFKW~J+y*tImTN;?p&BQ(T9c>Vntmy>=Fxm>`Cz_n9Gqnj9G_|r9=^^tJ#*O}vhQqj >z@CyrWj8<#)C2c7lQ=9*DwWkefYka@9#T?PL%P(pB*gkc9W_tMDR_%DRUXS$cwMV-{ >zw)45o7TQ&3k8N3Po^gL&5t09aOWO05^GDWGU5b=mIOd7@`{c>Wl7N;JlyT$-c+KPC >zRN&utvd?+V-N_~Q8`3q0c3)&NW;dAaVD{tM*$`$&m@Q%UgxM57$F4Bj0`}$F*%)SL >zuAQx6_U78z9A<Zz?E(7(HVEtx*dnk;V3WWufo%f&bnR>u*eS48V6U#7%>ui1?Q9pb >zU(ALvJH~7ovu9w_m|bJG4eT4(IIweI>%iV!JDUe~kJ&!3e@p{_4q#dU^Z?TYpbMBb >zVEO<w0@Deg6_{SQcAA0d2G9;nKQIl!bOh59peLB70A0bf1?UT=F+gW9t-<sL(;T2X >zuATM({Q(*TbO>k>&?BHpK$n0v0e!+W3ezb}t1!L7Gz-%$*G{`I{lYX1(=klTFg*jB >z26PQ*8_+kPaX{yQ)&ac(ng?_bXdkA3uAK&AI*4f@riYj&V!DWFBc_j-Mq)Y%v=Zng >z&`hA4Ks$kcx^@~0bQEYQ&{LqPKvyws#q<@^SWIX2e+aFY`p(YIqQ4m>*;&49UsguR >JJd`=t`zK#J`gs5V > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin >new file mode 100644 >index 0000000000000000000000000000000000000000..c6ae9a7ba253089d4fcdb9668b70aaad20dc94ad >GIT binary patch >literal 323 >zcmWHE%1kq2zyQoZ5fBCeP9O%cxf+1P9KW?o=Il}baXMrd$LZs76=$}`cAQ=AP;qWS >z703B@r3xlSC}d!$n*dbLFnI+dD+5F83<d^A=im?^;SvH827(amR<i)5Ko|tLff&T* >z`vKws!G9nq7Mm0SqN|0N3qUl;Nnjf2ED#NH8khz;4@85U2%<sG1koU;f@qL)85o(F >pppb!~Y6Zv&ptFHi0-X)?H_+KEKE5DVqdFZJ7$6~CODkgoE&%?nVk!Ut > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla >new file mode 100644 >index 0000000000000000000000000000000000000000..99f07a9fe53bfa85ef4c41f90dfbae413aaf12e4 >GIT binary patch >literal 503 >zcmWHE%1kq2zyPd35fBCe5g-P!1sZ_F9KRg~bM_duoDMlM<@E7PmNVNkM9wbvX5r-j >zD8jjoPeh6_LPTnLsfea(kcj5`{Zm{Ew@h(kjhW)ETqNTDu2RI4IYh+sT(n62|NsA) >z7{QR41p!$Y7%DCRtzqbtVFa?Pc^J5m**?A@4B7^kCZ<5r0!RV@BO{1p2qEkbQJ^xg >zKYoC9Ffag}@V{gk*9H&`@)wu}`VB;b{0F9iegx4Ve}ZU`UqRYI{sq%OKZ9tHzri%n >z?;slFe=rRU0}u@g2M`Sk3lI$o4=@c36A%pw7cdPB8xUO&w2Oh70mNkk4l+Ak3o8>- >FE&u@na1;Ol > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart >new file mode 100644 >index 0000000000000000000000000000000000000000..07784ce5d751f040ba7ab43713f32cb92ce9afb1 >GIT binary patch >literal 2335 >zcmds%YfM&k9LK*8ml5P8%PAm`S_v2;ctJ?TOMsw~7>@{~NQhi4^Fa{F^659Vp4MWO >zxnS86ZH(SHkS^NhBC?G&0&DA@=BTztH*0IAL!|RLt5?0~ZR>M({-3k6^Spb$A8%=G >z)ja)!Q0EOdyx`nCPcY{=@=24ubY}Xm{odEq-?!2C!Koq}=*aL5w$<xgV482_-DX|u >z_G`4SMAsX;Y^-CkRCLHZfmj7C>r}8W!$QW#D70Xjg<ej#u(_ia_Gz?*PrPX1Z(Os8 >zOTBjE(I}1k{A-Q(k7&Z_cQmo=f^KR(u1T3ay1D6~Zizdl$;DNgeEoo?q~~gC@H$1# >zsI<s$Qx)yWvFMJiHf<=uVglI~+Z$nV)$w*~OSh(%_-%#_+RT+lbX)C@x_#z8-H|t- >zSwUMApV+DR-``Zi&qJ2@ajRwzoV7b&->ak(?KbD|CM7oqY;HrQQg+l@>gH0LSM-GD >zFI{2_(rUCYHqO$ftXA5nY|-T;rJw)CGCGFst~2l1;-1;Iq<u(BkB+m<$Ioh+{})@n >ztz9e1KD3qD0o|S1ZCS~$Sa#fD%L!ehRbeN!>W|~f{r-97eRfc*`*v&1sVc4Q*r@!L >zT-_7M(7HXdRp8rT>&tWO-hxF|xIDqUDN(jzdW02C9I>LYpKRl$3s!t_&`QqrSZPm} >z-FN!DHoZEa&8=^%?8#1TX=+n>&2zfHc)u!g>$Nq#Qk4lCv@J46Rg>zh+EZcGzZF`| >zP?ptxw9vNq&awwiPPGS*-C#SOy=o8H54O|ymHD=ZsjlRTcI6GLKI2O@B=&1})EPB~ >zpHSn~m$hg388v-jdiec1?R~34k90TNqsRTW@6b;3?=QE<cC9y0&|g<@$baaPo{Dk) >z@OrvUA<~Oop76g<-mJ~{YDIP-N0yh*JRVMY|9wv_&S&nPuDHLD#vB@w^&Mtkn2lj} >z=GxgBW^b6yVRnbv9%g@-4PthP-7WIK9>LipVwb=+fqh~&3hdOivsKJqT|1k_?AEoj >zUCe$l8wPd^Y#G=yuxVh|z_x*X0~-f+?%LTpuy<hd!0uf;+XwdV+Gzl$1DF<IdVpyH >zrVBtDFnz!@0_X(L3ZNH2Gk|WmcG>~-1Je+oBbb%|J;5{u=nAGSKwmJ8!E^>_4W>6h >zb1>a;?X(BeAD}^)4q;k^=@F($K$kFW0{Vn$6woP5tAJi%nuX~Wrd>e4TssW|ItH{1 >z=o!#7pld+efW85Z13HIk9j14f=3%;rX&<J4uAK&AI*4f@riYj&V!8;l5$Ge(NT8EI >zD}i1D%>=p$v=itj&`?ZAT{|ts^c2%nOjj{&#q<@^SWIUzt;O^fXfDuQpuIqUfd&H| >zcI~tn=rPb_pvyp;fj(mzjp;O|)tFxE{}k*9Dn2JQg^nlXr=}#QCZ{CjFF<qWNBjwi >Cm?|a! > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI >new file mode 100644 >index 0000000000000000000000000000000000000000..57597b0b9743475c547021ff8cdaa0049729d0e0 >GIT binary patch >literal 1889 >zcmdVaT}ah;9LMqhnRQ_o>wzXdtjr!Tm!19pS#fM?R<p9HH9a$}td?cx*u#EV=C`LM >z#byt(MPW%7TLobZ#>z=q)K<ih5fPJE^gv}@gmlp_3Hk-Gv)}uVcU^QBbPk@^IpVnx >zzVA<XQM6`~^TuPK{S7}nHrXHECpFra;s4b<ObF$hgeUtViD^}m*tIs29GEW2Z6%SE >zo;3Nm$&HM-5+@_K{Gd{g{9;B`DwWpQC8K9H>oL*CX6)$odR*aOX56#8Iz6M!q~Ext >zGvfD}jNg9NpY*OV6Iw5-%<erhQGQav_FDP0qEWdAi^QucQj_X}l9d}&lS_xllo3PJ >zRIg8_zV1_@ln+hl-c6O=_DH5(JgYvt(`|B2cI(^=9VYL)4n6(oVUxe=u%5B|cbQor >zdRBFdd>(931+yAt_P`uHXH2Ecd3i|BeX`#a-m2I0y4IO5&MnkMZSzg>k!)Sk<eB*m >zDSCk_kuR5rROtd&%JP#{*c~QcrM_0>gI`E_?7mv~>|d#Pa9LH}=#)i&o=}TBZ<-~i >z{?JveXU)<*$MiC3HOnKr^w$+z&5F4zb#-WoSvh{TUX_?<YKB&;)q%yb`gwth^yEtP >zpLA7wB~{j(iC1fn2V~uWr)quUWBEp1S1KAa8!CHsU15*en0-xe%D8IklYZ5k<4>B+ >zuYS}Gy-h}LZ_r!*j+(9K%k;MP?`8W5rFI;Q$hW&n)y}$kvNINo1>!#Fe-4OyN6!I{ >z(=yhck<)z4vG0#}2I3v(&?#rI;~YI5_^7Bj?93=A3p*1$FUz&BuK()sjs8dY?FU<L >z|I|NN)Bhd&zs5EuG~DAO2aFuCuRUbsn0@U*BS-CP4;wjd<iL?5M-Cl1cI4oZqel)O >zIesJnBm!R>0uqC-4FZY6*M@<_fdqm?f`o#^f&_y^gM@>`g9L;`goK2|<ZFXMqVlz2 >zA#ovrA(0`WA+aIBA<-e>A@LyrA`v1XA~7OCB2oI<Fp)TsK#@q1P?1=XV3BB%aFKYC >zfRTuikdc^?ppmG3ZP-ZMNZ?51Na#rHNbpGXNcc$n$N(TCfD8dL2FM^Fqks$pG7i3W >zAdrzjh5{K2WH6A?K!yVu4`e`)5kZCo853kskWoQ~1sNA#J21$|AVY(U4Kg^$=pe&` >tj1MwE$O!q`Hl6o!i3a8P`;<4)bEjpw_Je2NdYQ$Z8}x#1X7OYg^gr4}_uv2k > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman >new file mode 100644 >index 0000000000000000000000000000000000000000..71ca143f29f2e5799b865478d05a0e88465d92f2 >GIT binary patch >literal 522 >zcmWHE%1kq2zyPd35fBCeF(3x9`5J)49KU6A=Il}Ua5`i&!|CJU1!uO0HJn{;S#WMa >zF~j+G=>p~g%LW!+83t9)vka>5Uoog_u4hm`e}+Mmb0UN0`gIIi0T~apUKTTG&p6ef >zbE&^Uw_;5L6C)Hdvp^sdh+<&qUIVm{Vb%slAiHM)11B=u$2Ww*(bWY+1c!i>F*1Tk >zh7iL35eF&*`{xH(2Lr=@ASimf=n9Ai`43D3{RpB#{shxNzk+Cxe?c_J&mbD)Zx9Xg >zJIFYY|3Ne;3_t)B4qzG>79ao$4=@c36A%D}3z!Cm4G4h32TTLQ2n0ak1foG<1)@RW >Q#X!vf;{pYsuAu=J0Hh0uumAu6 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe >new file mode 100644 >index 0000000000000000000000000000000000000000..57597b0b9743475c547021ff8cdaa0049729d0e0 >GIT binary patch >literal 1889 >zcmdVaT}ah;9LMqhnRQ_o>wzXdtjr!Tm!19pS#fM?R<p9HH9a$}td?cx*u#EV=C`LM >z#byt(MPW%7TLobZ#>z=q)K<ih5fPJE^gv}@gmlp_3Hk-Gv)}uVcU^QBbPk@^IpVnx >zzVA<XQM6`~^TuPK{S7}nHrXHECpFra;s4b<ObF$hgeUtViD^}m*tIs29GEW2Z6%SE >zo;3Nm$&HM-5+@_K{Gd{g{9;B`DwWpQC8K9H>oL*CX6)$odR*aOX56#8Iz6M!q~Ext >zGvfD}jNg9NpY*OV6Iw5-%<erhQGQav_FDP0qEWdAi^QucQj_X}l9d}&lS_xllo3PJ >zRIg8_zV1_@ln+hl-c6O=_DH5(JgYvt(`|B2cI(^=9VYL)4n6(oVUxe=u%5B|cbQor >zdRBFdd>(931+yAt_P`uHXH2Ecd3i|BeX`#a-m2I0y4IO5&MnkMZSzg>k!)Sk<eB*m >zDSCk_kuR5rROtd&%JP#{*c~QcrM_0>gI`E_?7mv~>|d#Pa9LH}=#)i&o=}TBZ<-~i >z{?JveXU)<*$MiC3HOnKr^w$+z&5F4zb#-WoSvh{TUX_?<YKB&;)q%yb`gwth^yEtP >zpLA7wB~{j(iC1fn2V~uWr)quUWBEp1S1KAa8!CHsU15*en0-xe%D8IklYZ5k<4>B+ >zuYS}Gy-h}LZ_r!*j+(9K%k;MP?`8W5rFI;Q$hW&n)y}$kvNINo1>!#Fe-4OyN6!I{ >z(=yhck<)z4vG0#}2I3v(&?#rI;~YI5_^7Bj?93=A3p*1$FUz&BuK()sjs8dY?FU<L >z|I|NN)Bhd&zs5EuG~DAO2aFuCuRUbsn0@U*BS-CP4;wjd<iL?5M-Cl1cI4oZqel)O >zIesJnBm!R>0uqC-4FZY6*M@<_fdqm?f`o#^f&_y^gM@>`g9L;`goK2|<ZFXMqVlz2 >zA#ovrA(0`WA+aIBA<-e>A@LyrA`v1XA~7OCB2oI<Fp)TsK#@q1P?1=XV3BB%aFKYC >zfRTuikdc^?ppmG3ZP-ZMNZ?51Na#rHNbpGXNcc$n$N(TCfD8dL2FM^Fqks$pG7i3W >zAdrzjh5{K2WH6A?K!yVu4`e`)5kZCo853kskWoQ~1sNA#J21$|AVY(U4Kg^$=pe&` >tj1MwE$O!q`Hl6o!i3a8P`;<4)bEjpw_Je2NdYQ$Z8}x#1X7OYg^gr4}_uv2k > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne >new file mode 100644 >index 0000000000000000000000000000000000000000..ec8dfe038c2d10aed29763ef8f664c8f0cd35c8c >GIT binary patch >literal 2223 >zcmds%TTGU99LK+}!U#&qa>zjmwG<3Fs2G%z2S7+Ml$T?v1c+h>UqA&b>6eGmMM_$m >z%$Oq0=%T`CO>-<_wXs5Eb<u$|M>j^bSvMs!v;XH=7j0d1+xk3v{-0;>p7*_azaM{j >zZOsDxgJAawHym;|&y&p^?Q36eZ|{x!dC>o^1_w$4=g$<|P*+CaLPvv!TVete0~r=H >zX}W?7Vl4RAbPGwoVIf~cTWI)Y3w`f*3%lBHx1Na7ZC`z>NzK<a`Rs=Z-*`#4w{>bt >zW}oh8+OIofPiksuji&ywPZ8<4inwyZB4<`x<iPV5?aQ&~t}2TejkoD7**2p;%wl)9 >z+g(R{6j#=4GaFygtQD_ncI}V4d)6M^lQ*O}6E<mXLbv7)pI1WYVI_3Gt$AY&y0`69 >zOZ>dm<~O}*Nj-IzydzU7M+z-<L%A)ePqT$fm)N59(=2U9tSwF*x5YPP=`j&XzxbVH >zbdA~ly&u~HBO_XJYE(<l^(yngM|$wsaV^_?O3U}1vlZDbT3OX@SxK*1_R40<30|#L >zvny=XZ=K4$^0M;2+^>fQc53yR8m;LnQU1|ft!>HB!;SM)5Gb;B6*;!P;65u{7H|HP >zC@YE!v*PgUR($g(E4g~fN-tlqvf(}}?>lXeoV}<=-x$({why%Ng>G$X>QKej!+NZA >zuPSpJRFz(>>i8mUj?7WblsenutF$e@6x!C&EUW!2&9?Q=vB%$;W>1{F#h!d=+@7)@ >zY<u7v3v3HfUD-9&=Z&c$V?;X=2DLM)SGz*r(ysC2Y8-1-)7PfmpVaB;_bc^G&p~^( >zv)T3>*>25yE9|-YbvD8G*EKQdKX6Gc-@8Auj-B=eNiTLN^zYAW^8H$#oyAe;=QW>? >zQ~rP7NvnI!+sQTW8`4cjL&Skd%x*lp?O^uf*=-23Bg~dCd%|prpJP{;Z2|l8>^6qk >znP;~(%-%e^&0%(j*&eVzV1vL8fh_`i1U3om64)lNPtR_nz)n58tz!1-*=-iHThDI0 >znEhfljM*_}%a}a_o5t)K*fy|lVB^5ffvp33_v|(g?B286KCpkF0hkV8T7c;RrU^h7 >zFm1r}0n-RfCorwR^un`i2BsUHT{|%Sz%&HY5uhbNPk^QXT>;tx^aaxxpfi}(V0wdT >z4$vLXu0241fCd2_0$K$02xt<}C7?|}pD>NWbPCfdOs_D_!gR~CYZs<pn1*3GhG`k5 >zXF$_{t^sWW`UW%(=p4{Gpm#v?fbIe9!}QOyYaphBm=<Dsh-o6Gi<mZI`iN;HrjtM` >zfnEa51iA^d6X>UB*HECNKudw10!;<FifJpRub9SSI;;OfXu}Ba{L~a8oS2`Ql9Za1 >Ml9;~;B`*y76Gy`Te*gdg > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW >new file mode 100644 >index 0000000000000000000000000000000000000000..aaed12ca284d69e3a8ba25891701790bde7f6743 >GIT binary patch >literal 2223 >zcmds%TTGU99LK+J!U*z^<v1##W`ZFH6@x<a00=3D@^UPV08#AV3#4Kt{ya2lOG&$s >z88f6AT~rvYX^urKH&zI&E;^9r=%!(9)J@6E?EiVzMOzo$wm#3E|L57e=Y6l<@5f(W >zTeC?2AlQAv4M*I~^Hg(3+xj=#+Ir%C9`L`ff&P-f#k0jW*qIR+YH!eRb4*}TAj5*D >z%v5kej0OLiZXwAxEab~*3!QewLO=N3!p8gTw%4OH`RngArRln+p8HtSHec55tsR=a >zyjOQL9@3q$r!=FqMl=36sPOb$MNEFlB4<}yWdDAP_T^Y~XO+c_#@o#1Y@5{=X0dzP >z?5^Y8iYsff**0WzR=uXVwLj|aIeRrPZ&35buWEimm*x*&R6^)cC3L;31!E1mxAiki >z{G!DcHok31-F22+dc;zW6<X@1a$8iNW{a0)+LDbCmNqNamZnbF(i^h$m~f?E`ra}+ >z$L#)|3--Xsh%!%)YT5Z7Eq~z?J$T}zR%|(~l?Tt;s_bU1u4=Qaq&F;kb(7@;uhp8l >z6}INL4(0yvs`9=%q=))<YVFw?t?MjN{_$L`Z_d!eyBDY+P-Gh_a%^M4eO9<4-ux+1 >zRumUz#nY}^@y(yCWc;#~UKz5o;a)56J!6lYyQD|o8q}uNkF@#4E<M)Ru8M6(^?2z4 >zRpvIRD!p3O@kQDanWLKNb+*-4X<L6Ov~8nVR{MFHZST9so_H_9o;-D{J@v|jJ#ANQ >zN8novY!6Xg*)`SYjj17HM9(A)XlGQ9c7?v9T@xp@d#pu`-<bA%TBm0}tkiSehwb@} >zCfj>#hcz9juzmF#>=xf&*QB8Tz$G2N;Qq)uamE)Uz1*(Qzdx_b_iJT#7Du6<*L*%s >z`Tu<<E$%gMC)d1hNH-k~;rlW%yYcL{gV~Q~w;{}qFk8ax39~7Fj$L841?<bS+ZbkN >zp54|kd-LozhuIxwd%*sH4FWp^wg~JI*d(w^V4J``J-dwpI|a6i*{f%_S<G%dyX|83 >zi`g({$Cxc+_6%$qvun(@fqerT2X^k+Z5`OVXSaD^_nzJMf&Bvwz;po90!$AuO~7;k >z(*{f*Fpa=;0@DgiFFd<uV7lSiwFA=+OhYgo0a^m|1ZWD-6`(CZUoedUI)iBqrZ<@8 >z0NwHI+5_|lXb{jLphZBBfF=Q50@?)h3DYP{r!cL;^a|4~Ot(C{c47L3X&9zsn3iFB >z1~d)m8qhYNZ$RUK&H=3hdIvNQ=pN8MO#eK)24XshX(6VEm?mPnh-o9HkC;YcItjEA >z=q1ohpqoHDfqr^+4Fx(1v=rzm&{UwSn6_g2ifJsSv-&@THjMBtOidxeiTSB1NvTOG >MiTO)V^5U>R0gAQ*YybcN > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/North b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/North >new file mode 100644 >index 0000000000000000000000000000000000000000..c6ae9a7ba253089d4fcdb9668b70aaad20dc94ad >GIT binary patch >literal 323 >zcmWHE%1kq2zyQoZ5fBCeP9O%cxf+1P9KW?o=Il}baXMrd$LZs76=$}`cAQ=AP;qWS >z703B@r3xlSC}d!$n*dbLFnI+dD+5F83<d^A=im?^;SvH827(amR<i)5Ko|tLff&T* >z`vKws!G9nq7Mm0SqN|0N3qUl;Nnjf2ED#NH8khz;4@85U2%<sG1koU;f@qL)85o(F >pppb!~Y6Zv&ptFHi0-X)?H_+KEKE5DVqdFZJ7$6~CODkgoE&%?nVk!Ut > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth >new file mode 100644 >index 0000000000000000000000000000000000000000..85c26d509a81d77ebfd6525b4777ed32cd6c9e1a >GIT binary patch >literal 479 >zcmWHE%1kq2zyPd35fBCeVIT&v`5J)49KS<*=IpT*I303c;q>w131_w!EjYV8bOI;; >z?**LOBo;_9CM}R!UcW$7HD-b4`cn$7h5HrUSko2Um1`EbziVFL$sD)9^IYlzCPpx1 >zW<fv(hMYM-8yM;)FtRW(6f`h!BC~ybLl_*xT|h)|2uK+tBZy=OA?yJWpfa!ret>l_ >zF#HFCl4W8~Ks3lhU>fKt5DoGem<D<dM1wpCqCuVnX$N@}Oana&qCp-8(?CyyXpqOj >qG|=-P8WaE^8Wad18Wa#<8W<QL8WbR48W<=HR0|a@P$=nIZ~*{&uy;lP > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland >new file mode 100644 >index 0000000000000000000000000000000000000000..a327d83b7696f39c01a9b5cdff1d4f0fd4b1f94d >GIT binary patch >literal 452 >zcmWHE%1kq2zyPd35fBCeK_CXP`5J)49KU6A=Il}Ua5`i&!|CJU1!uO0HJn{;S#WMa >zF~j+G=>p~g%LW!+83t9)vka>5Uoog_u4hm`e}+Mmb0UN0`gIIUj8MqT0)Y$+{S`oS >z8D?!@WMN?FS-`-F%=YmOVQ_SH0TIC=AZ3h<Ad(@3u(O4L%D~S40oK95@E-_@-p=O$ >z(I9VtX`oj?G{`$(8t5eu4e}O<26+ucgS-c#L0$wI2l6I}26+_(K;8w@Kre#;$lG8V >Y=yebPc^^yzgMeCLzy%5uT|)yd0M{6F@c;k- > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/South b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/South >new file mode 100644 >index 0000000000000000000000000000000000000000..4f331a87df4ed78be0d00b1a82b5c66c773069c9 >GIT binary patch >literal 2238 >zcmd7S|4&tQ9LMo<x!ibPN)Tg=G>9)5Qhd39IWWYFS5lHIgf{~M(p2z56rtf2P3g-W >z?_zUiP4Aprr4iWbhg<`7ZjHI5qGFo%ZEcORjIGVAt*ou+^E|UHSAT%#?A*t>=WciR >zhx>X48iFl_)_)F{dBVl9%Us;Y_L`RiE8l$ez=^EO<ALKcKGq!iaHL5;8uW%fez`{` >z`Z7Y!POnDK$P`yihPr-TtTCQwjrlZP-SOY6d)TS57vIzCUrLi3KL1W;?2MAQqhk`^ >zd|qZo4ogDWDVY`Omm5=uB(bhT690Nml8UP(>B4K8oZha<W2&<qew{torgJ9q_2#}R >zO&Lwl)UAi~mVL)0tv;;jz2`Jz$wA2s{w%j<JR@@}&&q94Es~WzELjtuNVYp7+2iZ= >z_NgAZBXU}E&g|9P{&|{rB&7M9E5x&>K?|DJYGGHY7A^AW{MuB#Gi9zWD719JpD|iI >zCq;_Cn$nU#re)!YalPxyNhuxpK^7f9DP`dgWbyt1@osoS%AX$9B^A5Gx9*TG&3j!d >zd||!YRV&LfTXorQhh_PN{Zjc^zuYsnT~>^ANY!Ao`1e)I%091DZz+(P&PKg=jbCeP >z%5;@CUjv>ry)P|6SI>;n)ziP|{TI(`-Ph-|e&UoiyfdN?9Q{@rht5h<<XvgjVR<k# >zC~G!GWNqEE^3d`gSy$XH>*qDfhGf6AB!slp5!BX84Z3l1g$7TTYTIb8w!f9C55E$x >z9nV|(Nbe<mwDTM7Y>Sh}>Zhfv@+a9;GAWz0&&cC9os@3(+tU5}fNYuCE1@s?Wb6AO >z={XjZZAV_z?FYm9#GY>5@l>ns?5fi!$Cc9=eGQzJwPUyWBU>*FIn2L09J%_w+_x%V >zmHU<kc<gZSY6bp(BiEUaxH$Mm?&B`=&K%R`*p$?th}&j4JCW_!n*AUfvNbzGwuI~n >z*%Y!XzLRYs`$9HmYj%cg&DQJ<*_^G}9kM-Sf5--r9U@yq_K0i}*(I_~WS_`JZOu-R >zt=gKsBAc}}yG6EZYxaw57}+thWn|CDrjcDE+eY?{Y#iA+vUOzd$mVU$?vd@=n*AdU >zKstc50O<kJ1f&Z{8<0LAjX*kqv;ye`(hOVE4Wu2mrXNT{kd7cNL3)BT1?dXX7Njpo >zW01}utwDN&GzaMp(jHsWAEZG@hmaN_Jwlp<bO~t_(kG-*NT-liA-zJHg>(yPm#yg+ >z(lDfBNXw9(Ax%TNhO`ao8`3zWb4cru-XYCHx`(t6=^xTSThl?Lg-8#PCL&!#+KBWK >zX(ZA~q?Jf7k!B*@MB0h;6KSZe=_t}tq^C$zk**?bMf!>~7U?X~TFc>#x^hOlu7T6C >zp8V1Njk~RAySZ+=xmVp+`AP1-y8BOftymuCmMkptkmMYHfhVsZ&y(Yy5BWv0e*=T+ >B3P1n= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney >new file mode 100644 >index 0000000000000000000000000000000000000000..aaed12ca284d69e3a8ba25891701790bde7f6743 >GIT binary patch >literal 2223 >zcmds%TTGU99LK+J!U*z^<v1##W`ZFH6@x<a00=3D@^UPV08#AV3#4Kt{ya2lOG&$s >z88f6AT~rvYX^urKH&zI&E;^9r=%!(9)J@6E?EiVzMOzo$wm#3E|L57e=Y6l<@5f(W >zTeC?2AlQAv4M*I~^Hg(3+xj=#+Ir%C9`L`ff&P-f#k0jW*qIR+YH!eRb4*}TAj5*D >z%v5kej0OLiZXwAxEab~*3!QewLO=N3!p8gTw%4OH`RngArRln+p8HtSHec55tsR=a >zyjOQL9@3q$r!=FqMl=36sPOb$MNEFlB4<}yWdDAP_T^Y~XO+c_#@o#1Y@5{=X0dzP >z?5^Y8iYsff**0WzR=uXVwLj|aIeRrPZ&35buWEimm*x*&R6^)cC3L;31!E1mxAiki >z{G!DcHok31-F22+dc;zW6<X@1a$8iNW{a0)+LDbCmNqNamZnbF(i^h$m~f?E`ra}+ >z$L#)|3--Xsh%!%)YT5Z7Eq~z?J$T}zR%|(~l?Tt;s_bU1u4=Qaq&F;kb(7@;uhp8l >z6}INL4(0yvs`9=%q=))<YVFw?t?MjN{_$L`Z_d!eyBDY+P-Gh_a%^M4eO9<4-ux+1 >zRumUz#nY}^@y(yCWc;#~UKz5o;a)56J!6lYyQD|o8q}uNkF@#4E<M)Ru8M6(^?2z4 >zRpvIRD!p3O@kQDanWLKNb+*-4X<L6Ov~8nVR{MFHZST9so_H_9o;-D{J@v|jJ#ANQ >zN8novY!6Xg*)`SYjj17HM9(A)XlGQ9c7?v9T@xp@d#pu`-<bA%TBm0}tkiSehwb@} >zCfj>#hcz9juzmF#>=xf&*QB8Tz$G2N;Qq)uamE)Uz1*(Qzdx_b_iJT#7Du6<*L*%s >z`Tu<<E$%gMC)d1hNH-k~;rlW%yYcL{gV~Q~w;{}qFk8ax39~7Fj$L841?<bS+ZbkN >zp54|kd-LozhuIxwd%*sH4FWp^wg~JI*d(w^V4J``J-dwpI|a6i*{f%_S<G%dyX|83 >zi`g({$Cxc+_6%$qvun(@fqerT2X^k+Z5`OVXSaD^_nzJMf&Bvwz;po90!$AuO~7;k >z(*{f*Fpa=;0@DgiFFd<uV7lSiwFA=+OhYgo0a^m|1ZWD-6`(CZUoedUI)iBqrZ<@8 >z0NwHI+5_|lXb{jLphZBBfF=Q50@?)h3DYP{r!cL;^a|4~Ot(C{c47L3X&9zsn3iFB >z1~d)m8qhYNZ$RUK&H=3hdIvNQ=pN8MO#eK)24XshX(6VEm?mPnh-o9HkC;YcItjEA >z=q1ohpqoHDfqr^+4Fx(1v=rzm&{UwSn6_g2ifJsSv-&@THjMBtOidxeiTSB1NvTOG >MiTO)V^5U>R0gAQ*YybcN > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania >new file mode 100644 >index 0000000000000000000000000000000000000000..07784ce5d751f040ba7ab43713f32cb92ce9afb1 >GIT binary patch >literal 2335 >zcmds%YfM&k9LK*8ml5P8%PAm`S_v2;ctJ?TOMsw~7>@{~NQhi4^Fa{F^659Vp4MWO >zxnS86ZH(SHkS^NhBC?G&0&DA@=BTztH*0IAL!|RLt5?0~ZR>M({-3k6^Spb$A8%=G >z)ja)!Q0EOdyx`nCPcY{=@=24ubY}Xm{odEq-?!2C!Koq}=*aL5w$<xgV482_-DX|u >z_G`4SMAsX;Y^-CkRCLHZfmj7C>r}8W!$QW#D70Xjg<ej#u(_ia_Gz?*PrPX1Z(Os8 >zOTBjE(I}1k{A-Q(k7&Z_cQmo=f^KR(u1T3ay1D6~Zizdl$;DNgeEoo?q~~gC@H$1# >zsI<s$Qx)yWvFMJiHf<=uVglI~+Z$nV)$w*~OSh(%_-%#_+RT+lbX)C@x_#z8-H|t- >zSwUMApV+DR-``Zi&qJ2@ajRwzoV7b&->ak(?KbD|CM7oqY;HrQQg+l@>gH0LSM-GD >zFI{2_(rUCYHqO$ftXA5nY|-T;rJw)CGCGFst~2l1;-1;Iq<u(BkB+m<$Ioh+{})@n >ztz9e1KD3qD0o|S1ZCS~$Sa#fD%L!ehRbeN!>W|~f{r-97eRfc*`*v&1sVc4Q*r@!L >zT-_7M(7HXdRp8rT>&tWO-hxF|xIDqUDN(jzdW02C9I>LYpKRl$3s!t_&`QqrSZPm} >z-FN!DHoZEa&8=^%?8#1TX=+n>&2zfHc)u!g>$Nq#Qk4lCv@J46Rg>zh+EZcGzZF`| >zP?ptxw9vNq&awwiPPGS*-C#SOy=o8H54O|ymHD=ZsjlRTcI6GLKI2O@B=&1})EPB~ >zpHSn~m$hg388v-jdiec1?R~34k90TNqsRTW@6b;3?=QE<cC9y0&|g<@$baaPo{Dk) >z@OrvUA<~Oop76g<-mJ~{YDIP-N0yh*JRVMY|9wv_&S&nPuDHLD#vB@w^&Mtkn2lj} >z=GxgBW^b6yVRnbv9%g@-4PthP-7WIK9>LipVwb=+fqh~&3hdOivsKJqT|1k_?AEoj >zUCe$l8wPd^Y#G=yuxVh|z_x*X0~-f+?%LTpuy<hd!0uf;+XwdV+Gzl$1DF<IdVpyH >zrVBtDFnz!@0_X(L3ZNH2Gk|WmcG>~-1Je+oBbb%|J;5{u=nAGSKwmJ8!E^>_4W>6h >zb1>a;?X(BeAD}^)4q;k^=@F($K$kFW0{Vn$6woP5tAJi%nuX~Wrd>e4TssW|ItH{1 >z=o!#7pld+efW85Z13HIk9j14f=3%;rX&<J4uAK&AI*4f@riYj&V!8;l5$Ge(NT8EI >zD}i1D%>=p$v=itj&`?ZAT{|ts^c2%nOjj{&#q<@^SWIUzt;O^fXfDuQpuIqUfd&H| >zcI~tn=rPb_pvyp;fj(mzjp;O|)tFxE{}k*9Dn2JQg^nlXr=}#QCZ{CjFF<qWNBjwi >Cm?|a! > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria >new file mode 100644 >index 0000000000000000000000000000000000000000..ec8dfe038c2d10aed29763ef8f664c8f0cd35c8c >GIT binary patch >literal 2223 >zcmds%TTGU99LK+}!U#&qa>zjmwG<3Fs2G%z2S7+Ml$T?v1c+h>UqA&b>6eGmMM_$m >z%$Oq0=%T`CO>-<_wXs5Eb<u$|M>j^bSvMs!v;XH=7j0d1+xk3v{-0;>p7*_azaM{j >zZOsDxgJAawHym;|&y&p^?Q36eZ|{x!dC>o^1_w$4=g$<|P*+CaLPvv!TVete0~r=H >zX}W?7Vl4RAbPGwoVIf~cTWI)Y3w`f*3%lBHx1Na7ZC`z>NzK<a`Rs=Z-*`#4w{>bt >zW}oh8+OIofPiksuji&ywPZ8<4inwyZB4<`x<iPV5?aQ&~t}2TejkoD7**2p;%wl)9 >z+g(R{6j#=4GaFygtQD_ncI}V4d)6M^lQ*O}6E<mXLbv7)pI1WYVI_3Gt$AY&y0`69 >zOZ>dm<~O}*Nj-IzydzU7M+z-<L%A)ePqT$fm)N59(=2U9tSwF*x5YPP=`j&XzxbVH >zbdA~ly&u~HBO_XJYE(<l^(yngM|$wsaV^_?O3U}1vlZDbT3OX@SxK*1_R40<30|#L >zvny=XZ=K4$^0M;2+^>fQc53yR8m;LnQU1|ft!>HB!;SM)5Gb;B6*;!P;65u{7H|HP >zC@YE!v*PgUR($g(E4g~fN-tlqvf(}}?>lXeoV}<=-x$({why%Ng>G$X>QKej!+NZA >zuPSpJRFz(>>i8mUj?7WblsenutF$e@6x!C&EUW!2&9?Q=vB%$;W>1{F#h!d=+@7)@ >zY<u7v3v3HfUD-9&=Z&c$V?;X=2DLM)SGz*r(ysC2Y8-1-)7PfmpVaB;_bc^G&p~^( >zv)T3>*>25yE9|-YbvD8G*EKQdKX6Gc-@8Auj-B=eNiTLN^zYAW^8H$#oyAe;=QW>? >zQ~rP7NvnI!+sQTW8`4cjL&Skd%x*lp?O^uf*=-23Bg~dCd%|prpJP{;Z2|l8>^6qk >znP;~(%-%e^&0%(j*&eVzV1vL8fh_`i1U3om64)lNPtR_nz)n58tz!1-*=-iHThDI0 >znEhfljM*_}%a}a_o5t)K*fy|lVB^5ffvp33_v|(g?B286KCpkF0hkV8T7c;RrU^h7 >zFm1r}0n-RfCorwR^un`i2BsUHT{|%Sz%&HY5uhbNPk^QXT>;tx^aaxxpfi}(V0wdT >z4$vLXu0241fCd2_0$K$02xt<}C7?|}pD>NWbPCfdOs_D_!gR~CYZs<pn1*3GhG`k5 >zXF$_{t^sWW`UW%(=p4{Gpm#v?fbIe9!}QOyYaphBm=<Dsh-o6Gi<mZI`iN;HrjtM` >zfnEa51iA^d6X>UB*HECNKudw10!;<FifJpRub9SSI;;OfXu}Ba{L~a8oS2`Ql9Za1 >Ml9;~;B`*y76Gy`Te*gdg > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/West b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/West >new file mode 100644 >index 0000000000000000000000000000000000000000..85c26d509a81d77ebfd6525b4777ed32cd6c9e1a >GIT binary patch >literal 479 >zcmWHE%1kq2zyPd35fBCeVIT&v`5J)49KS<*=IpT*I303c;q>w131_w!EjYV8bOI;; >z?**LOBo;_9CM}R!UcW$7HD-b4`cn$7h5HrUSko2Um1`EbziVFL$sD)9^IYlzCPpx1 >zW<fv(hMYM-8yM;)FtRW(6f`h!BC~ybLl_*xT|h)|2uK+tBZy=OA?yJWpfa!ret>l_ >zF#HFCl4W8~Ks3lhU>fKt5DoGem<D<dM1wpCqCuVnX$N@}Oana&qCp-8(?CyyXpqOj >qG|=-P8WaE^8Wad18Wa#<8W<QL8WbR48W<=HR0|a@P$=nIZ~*{&uy;lP > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna >new file mode 100644 >index 0000000000000000000000000000000000000000..768b167857dd82807b5ef912be31518086c77141 >GIT binary patch >literal 2274 >zcmbW%eN0t#9LMo<d5ABhBI=AZh=&+aJY2vW7$S(IBv%M;1_Y$}fPfTX;T26;$@rG7 >zj7skuTc$Cv)m&Df&aE+*R8&mUves6VJ@6M%TUlGt@BLeIx%i87cJAxk%MQDL+|S!v >zS+^;}`QH(2KH=hc&RpDwwV9W$Rd2l7bvp6NkoS}f4c7QR>aW(1d-8mr9BP%}jyPXn >zQ=SG*kC))mI1T=7iH5j?G~}~b4GsT6L;C_XZ0vo#{^b~%cIkVWzB@o>oEVhwn#(fN >ze^erJ&&n*{UYQ-;D|5;lWzOGE%iOFIxnbHqjf`#3$U)V4E|1RZsn_`<X?jyfu|^F< >zX!Q0Ydh>yk5>wHxv27PMZs}o(ulq%AiQ6LyMHeJtY+MqP`Xq7qQ%MT-OVY7-<hIdP >zx!r$Glh5zh6yIB#dfcaJ<u9qbvr^Nm*J(y`j%F?{&;@1DdPh`(F3fOr;a?$|H9tzS >zwj8^Z_0_0m|2ZLxP7mpwUyevl_fN9;)EUWb|4^13?3TQZuS@=u1G=>ESt(e5M3<$$ >zriBIVdRK6nERV0%<-Z@56+a%7qR;or-Ge)2Wq+d-_tc2zK#8pC$di(7=~CKMrT47$ >zXjy5luFgwSuRBKXjfv1TGXr$Z#IJha*kvvM`l410pVi8D`}O`4-$_;P1*!JGCpFq9 >z5BPdy?PkBMD}PEJT+u4)vl?W>tyQuy(j%K9d|K<O)7tS$-8`~V>(1q9{XmK~ycw-q >zUJ2L6=N)~hZCoF2`c|9jXUHQJ6VhDtvuw>Ckw=rx%VRg5k(SW6rR9%q**3agd|!0P >z_78m0da_P-9Dh-F9&XpiJ6m+u6Sca#xm*KW|DJ(CQ#@T$eQ>hp9B0=)^J{iq=yjQ& >zcDw)D`}~5{UMIg`nU{}UE?yn)<U<KDf8yfkG#B@?ukg+s6Xw`DS2tiwQ1>^uV^&}j >zG9;@R6EY~P85J@tWL(I=kdg7f85%M+WN=n9I%IfOGd^U1Rx?6mh{za`K_a6>hKY<5 >z87MMRWT?nkk-=KcXp!L}<3$E+H6uobY&By>291mw88$L*WZ=lik)b1FM+T3K9vQyX >zj2{Vr)kFXZfz`wS2?7!YBn(I#kU$`jKth4U0tp5Z4I~^$Jdl7`O+=88SWQf<CMZZ$ >zkgy<eK>~wB1_=!k8zeYLbdc~M@j(KFL<k8H5+kb#5)vgOOh}xNKp~MrLWRT%2^JD9 >zBwR?mkbof(Lqdkc%xZ#$L=6cW5;r7pNaT>vA+bY(heQtv9}+(#fJg+95F#-|f`~-X >zYQl)b5eXy`NhFj=ERkR$(L}<D#1jc95>X_iNKBESB2l%Pup)6q0*gcz2`v&^B)CX) >zk?<n%bzA{gBN%+$6wkn^J~-KPj<ctWZ}-e0C&;!q)V6qrZSght#U7L5Lfhm2MEPo# >dO~|NqO7@~mH^ol&q`OnoQ{Bm)1(22*_78DE8g>8x > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre >new file mode 100644 >index 0000000000000000000000000000000000000000..b612ac23562126db6b0aa3ce26dea6760c15be24 >GIT binary patch >literal 662 >zcmcK1J4nMo9Dwm_Z9%H&B7%sIb{BjVL_{)nP`pYead0ZQxd`HtI_TokNfZ}XJ2^?~ >zbX(CWb7`xBn?(>`rL~;@FVsm89K3M(jzGfYckbF|W?KCiQF+2-#AUMX&C2a4e~>Hm >zXH=oRZi>%ZU)6F>dG1D+>w~&7)b=aIZKv9r(zVm3b6dUCckYVwdOYmEMR%Qdlhq%6 >z^QMtb=|<_^X~v%X=J|kW)f4*j@WhN<=k@5$iy1ph`{Of@Ccd|?6Fm<mwc+ViFJe4v >ztqO;Jxw^t(Yt5EY)|N~tVr}t4b+cBT_0qDdCMIWPCgo?ohx-SFM&~8jiv@!M5>!wq >zFccgLP*6dlKm`>n3K#{A0!P8408$VskQ7V`Xi!0=zy=ju3NQtk?E_80rhrq>Dex40 >W$^lRgfqL?-e>sTQf*j0ZGWG?L1Q>+? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha >new file mode 100644 >index 0000000000000000000000000000000000000000..6d91f91452d0c8474f917c41add3395838504ac6 >GIT binary patch >literal 742 >zcmb`^y)T170LSsCMMw#^8gMiv1_?FLRQv--NS=tW2@+FBw${vW69dDI;vdkONF>-K >zSj0=cEY#phs7A@T?<FP+iEFN(rqkv7^C#!$;@*!_VgKQBI_>3mUB-T`Zq3eQ8<NM_ >z&$!A3?Q-X8PMr5^d0u#u7mX+SA~z&1%hmE~{a9RIuE@L}6EACleyti6#oclFRxea( >ztXY;0w#9p7U%ziYs&b(uKbBLf=_n(c7mrkn?$EM#Pqi*h$+p@Z6`cs{=<T$K_1){( >zX-@PNv${XKAQIPSGVu^n$-_Voq&$^2#(3e-uRdX8ZZ<s6nBX~7Y0O>Ts~H~gy{_&a >zd%uJDe~44EaX9u3hDb;#r;UXKL!u$!oHia3&}kzgA(5C!P$Vi67Kw`lMj|7joi;WS >z+-ajD;gR^fodJ*$kRgyUkU@}9kYSv59AqG;9SIo<84DTAX-7kbL&n3jeapWN7#Xl* >H4#p#2M|K~x > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East >new file mode 100644 >index 0000000000000000000000000000000000000000..308a545ce5931939fb6353fa4273aedf00b49372 >GIT binary patch >literal 2016 >zcmc)KZ%h<)9LMp~k|maZ+FDstzedK$6Tf#ydYX~S5J(OpZ-!JxA|U<=Wn^esN0zy< >z$*hcxw)UG3n&p<iwwmasBWEFNjdb>p=}EHn&s^C|uhY7I?_UplP|rMe_qws;&x7y# >z6R&A%2nYW4xXyitCy#db<o%5a_wvTOEg$rZD;w(hbG|unp+FBNTV*i%o(`T%>#2#~ >z+EWLX$>}S%X!6aZoH^aCL-B}QtQoDpk6JF5dROY@v6D@zDyXTxk0qUb!lw76%$1+B >z^lHZzGpT=vPHy|kOfmObi42&j?M-^;m}4fVdc4g!yI!Wv{>@H1*(bSE$7$}NVUriQ >zpn0!%$UQ&ZWT&qQn_%yUI-}vJ<eM&?x#(@t#3l_*ika{uVk23rr63yDg49PcOQz_o >zfmLSqrB7_M=Vh65W?1KT2F-oPGIn0`Sabi;omyD&t9fAOUphbkgjujHr3-KUMT)A9 >zXwl{4QXE@ii-*pek_p?iWdANHP4Bj4UC+pagD=^|iPuc|!3G<vecDuXm)gp*SLLCt >z^;#u!%)@mhx+HLii5KN*{Ku#)%^9Oh`)`-(k>|B~&sAA=c0g;kC*{#(t$l1&uRMNu >zp<Q0OTb_99E?XNqY@U2&fv%WfOkHD+)};?geaR@TKfcm5-u=BczQ4#cW%X-Qcb%;M >zZm+J{Tr6t``s})zTzP8WJGOc5Xj$LcVK+=XCoRqEY|9^?No!@LZT)7SY>ckejYmE; >zZMRiu+uk2!Q%ZI7i=F1#uW#1pR%|d^_FvTJ7w?c4y1vxF$Pw4}E0Z}{9tdPI!$Tvk >z&t$&%Ja9vKEFPGlVfT!<1LYC_@1x%8KIV@)<$r?Tn8|S5$boy^kt2tW96NIGUU&4! >z;d|ZjBLN^0AR!<zAVDBeAYmYJAc1&YBuFS;7Yh;$5)J=8;UMuK0U;3~At5m#L3v$N >zNLXGM7ZRA)MTUgtb+IAAA<-e>A@LyrA`v1XA~7OCB2gk?dR?4Ipk5a#5-Jia5-bue >z5-t)i5-<`m5;77q5;PJu61LaHjRfv>kt3mdUF=BkNc2efNc_kEAR~Yb0Wt>2ARwcF >z3<EL_$Uu1ANFYPubz^}HhS!Y-G91WwAOnJo2r?wdm>`3Kj0!R=$haT_<8>p042{=~ >z4Kg@hH#*4hc-{CQ1B8qaGDOH2A%ldB5;9E4I3WY&bt8ogmDi0GGFV<WTF7vD-FP7b >zhKv|8WXPBygNBS6`eAb>rvKAJd&2c_ZD)?Z{(q(}d!C!U!iakf7Y1XYP<|+1XKFAO >J&X4dW`){q=QK$d_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West >new file mode 100644 >index 0000000000000000000000000000000000000000..855cb02c4082719f3a51c8401288c013efefe683 >GIT binary patch >literal 630 >zcmb`^IZFdU7=YnTJP7e>Y%DyYZ32TyAtEv!r3%7=;17rhRyNv2ZPSaOg{4|enMjHO >zi(n^;79ojg>;fuyghUy?cP#}$aF*G3SlD6bS$}msJ?{M&ZSsW4h{<H#y(72%v&?+1 >zZ{;cXxn%Osv--Tcr%DqAU8+ZPdEn8O^J}Wo8q?Loy1K8N=$b#HUJiQfYsZFqvzz+8 >zH*Olsle$s7QO#)0HcvZEtKP3avRN~Dd8CK7AI$LaoE=G4Ol)^ck9OUexV_Mc^tH-3 >z=e%&}*DLH?vEX^m-Cl*-Wo^C4!lLgbR8nS24#4pLaOlSOE3%_=9G(IYR1hc-6buST >zP(h)<1Qi?#5Cw?>MZuzgQP3!G6g&!GP(h?X1{F*SC<T?z2bO|M0j3~RpefiCa0)uj >Q$X@>fADxn)FrA8i0o?5eRR910 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/CET b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/CET >new file mode 100644 >index 0000000000000000000000000000000000000000..4c4f8ef9aed8bf567ce727c33ba1b97da6f6ee7d >GIT binary patch >literal 2102 >zcmdVaUrd#C9LMoP#8PJTMTJ8GViBQr<UgbasT~hY1yVT~se}fi7EzptL20aF&KYx` >z8p}DvKgC!zJ9>e&hSvH!T1Zx74a>FV%Kpu{nX^A*^?N^8ZC!O&zq4nrXXm+jE}qXj >zylz`lf$tyZYWEKpXP3LUpV~Lgzp-!p%*Fi^QS}cT*MT>sgWY>IGPPBs=U3XPSNs}# >zF=(GWUu37B&azJ<$@W?G5?wpcpoC{<*>&9^SzCz`8?!Y%oT3?3%WP)h?@G%2Ny#(5 >zl0Wv8{FmNR%DJPu{_{hc_1<$zJ#o^~jzlee|3RDGBg@$Sl+9_5*bN&R?8eHlWtN8Q >zra*~hrDfaA(^4!uE~xCwMVk9<mgbEo>y{6$(XB(jDlqVa=J%daPWQ*kZ9Ad7#@Ccz >zH(>>lAuB8!wxTsJSaEv4l@xSX$z+!;NbS{vvzu(;AMILnGHADdS*y~)dX)_?(j7aO >zYH?qhmNaE*Y4<|Avpi10##CFDbzY(1q?N~gq>9Y1t>VIWwmkM7TRt{oE6%-SE2FPk >z<>=e0+S6mzM-J<*mKIyp^Nd#Cvs-JLH>>8hW`!#&bhp1+YXkGN_DY^=lgh33i|M-e >z@?2Z@`Y&2P9&Z~CC0gCk&vsweC9CfpvyJuRwrR(Yx_|K-)=)R9#*BToxh$%tDaW-X >zUE1>fUTvL>Xxm7q9ylA;gD<aF^M|eW(5^DI4A$7gTQl^?&SGm_U22ggzdf2i+uB0E >z*<*=5YtKzm`^9gpBjJiVPQP!R7bf)hu|a!cY*^d(y{jG3em&Vapsqb#^2J;g`(OC^ >zd}(uH+y|RrzPP{N2SYVsUoaGQk79W43;&Cc|4(-qfTtS)G6ZA{$RLnWAj3e$feZv0 >z2{II9EXZJx(eQo@2N@4CAY??ykdQGUgF;4y3=0_-GB8g!GGu7T*pR^?qeF&=j1L(g >zGD2jC$QY49BBMlxiHs8&C^Aw{H&kS-$Y7DtBEv<-iwqbUF*0Oi%*ddTQ6s}f#*GXd >z8M&t$Ix==oH+W?9$ncTzBLP4nfP?^v0TKix3P>1`I3R&QB7uYgiG`;N1`-WV7Y-yI >zNI;N?AR$3wf&>ML3KAA1E=XXI$RMFXV&mz8gG9&Eg$Icb5+Ec(NQjUaAwfc-goFu+ >z6A~ySQb?$fSRuheqUGtrg~SU97!olgWJt`ApdnF1!iK~R2^<nRBy>pZkl-QF^K{`u >v;^*lCh(r(xAreC*h)5KXFyj9*j`6OP^YdwDpsFyZI43Vqm7j;Xh4Fs@!4?eK > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT >new file mode 100644 >index 0000000000000000000000000000000000000000..5c8a1d9a3ea46457985198597d90f95462a70168 >GIT binary patch >literal 2294 >zcmdtiUrg0y9LMqJAjKa!NEU@iP+BtNfPkTBQWh|FC<OJ0AY`E!Vi{i(P}JygV^A07 >zCTUm=rO4IFsj&=ek^Nok&kSkKW-+bhoEz~}UYO81J@4nXtL|D~_MF#m+<)GIRSl2k >zsDE6z{SS}ZYaicnJ%@byz<Ynn!H!tn`{FtI>Y1QEJ@bm3u8lI+uGXvZOMWwP*028h >zBHaWB(pBhnuTkAz<>?$VVOz%3q)jmrUOQP|SN^M9zj#zfWPK|UyHa&j+}jd$_*E5c >zo|nnzyL8O=M~(MnvyMHn$4q%+kBZyhWNvu2Nlk67FgG?-sGF+tOuRo&-Mk>t+>(~4 >z5@yVoX^|5uF>IP7{+^(xUl^C9p=<iqkA9ToV?XGW-Vf!rmMQA?oxL(+#cyinh7Zgg >zxx?ztk^^Q|{5vXj_D+);9MWmgYfainzn*=$$fOVM)xP01lF_q8XZ9D$oVF^R)iq19 >z>swUL=17@aT&eC_c3E;$7pi$VU(5W6B$YS)lF7RmR13zxGz&jJukJqgmRWRULg&B# >zoVjQBh`#qFF^d~d>igPv$^B)o=z_XNDV)=;iwc)Y(I4-s;*5=^czD0^d&`W!f4eFf >z%{C9b{DOY)%n~Wx(W;jm&yup5YF)l>sw`cUua`Ank>yD#I<Vr51SUMXB6mP4eo0o9 >z$={jE&y=bP9yhD{ep1yV-KM7fQ}xi`HnY0!kb1bM#ynE`v99fGl{FcCdTo8R)OkDf >zy5f9UH@aTer>02#Hzm3u!XpibeR{*ipXITAe)agNklEOhuAVq@!8BHQmF)h+Y|0%| >zPd2`0HpdUCrm{}c6dctpd419{a!PMa=#Z_0$8_t}^|Gy}OK(40B0Jie^-}{rX<NNg >zKiwTG%A-7ClkCrb=`R#Ianz$ip*IhzaQ7YQeq#y>1FB%TeJkxN4=@f7FYqr$6tc&V >zkTD^HLPmuQ3mKQw4h$I?GBjjt$l%b8jt_>%+3|4<5E&uI5Row=gG5G&4AW`Hi44?f >zN6Il&WUR<wk<lW<MaIi9U}VG`Lq^8TF=%Ae9K%M&%`tFf<QzkH+OZ>pM@Ekf9~nOq >z03-q&AwXil5d<U(9AQA>z!3<ijRX=3r;P;?3?v#zIFNWC0YM^yganBRM^KQcaD)Yk >z3rAp($Z&+lX=B3?93(m%;X&eq1PF-`5+Wo<NRW^yAz?z|gapcIBgGLar;Qayu$(qp >z9N|LZg#-+V7!oohW=PPGs3BoP;)VpyX(NY(&S_)E5j>}j9!L0)_;Cafi6BP^kr;9W >z5s4xaMkJ0%AdyHSp>*0<BEfXpXd>Zs+IS)XMIy=(QY5AvK}Dj<5mqFw9Dzk5%Mn_q >zjV%&fr;RQWUZ;&O5@004NQjXbBSA)@jQ^W3N84J@v(@&M&dtop%<`3HXJ=+-W<~!E >D%injH > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic >new file mode 100644 >index 0000000000000000000000000000000000000000..f86ece4c4032634b3526187c5f86364077b9a9b1 >GIT binary patch >literal 3438 >zcmeI!X;76_9LMpCm=UE?iki4l7HWtOD27Y%SQ?{(oMcf_@MM~SrDWogggR--OsP$o >zWk!pJOQn}ELruKyj%FPo4NLK;p=MfQ8*bdr_q^>z<4iBR%yU0?81C@y_x-0nmi=Um >z=O3?|%x`#j)tZOTE$5iGIdvbuzwE~v-#dp}I7Mai<$Ifti4Wgx?XGZ2oR!a~yB~#h >zbc$2n_Z43o?p@t~tGoJWFYnrR@40Ia_H{nKHrM@R+iT9Jzf`;HUTJXFe>uqY&Q5bm >z)-88G8=C7aU0C35=)A@Ge3EoGhWfl;4135e3u^7%)cGghrZbnlTN)qmZK-JGZ1rTi >zTi=cLmS5W7Zd?4l<EuL3+n$x+?09vdyHgZ7yPnB)cRO>OJyZI-dqc)L`+86E?Ymsy >z-QP<1_8*bn0}D>d%DaEht&|s3Ro-F!t^18Slvbt>cPdfe#V*s;p4Zip(0qMF=c%JL >zv*fWgQ$<aAraWGlE_6}6JdqtIP8NjAQ-j-z(+M5*nLFC3vk?LMY~2-guE{BVuHvZr >z`SfmmzNB2$Eh?6mW*3UzCNGe`kC`a`NY0Ue#wUrtdL+vFF4^jG^C)>GXsEhUKSW<W >z+g)9&j?~xpHCGK~&9r}2o$@Tbr~_WEQjMlp>cHHKqOtr{-XtnT6SqR%>}(K0ol4~` >zA#aLc&k`AYafY~6PnWkHc|$ezWyofmrm5y@@^r}CBh~GNBlI0J`>Gb%eRRu=b}Dpm >zm~Iu<pjvmiuG`!dChiP6uG<D&7j5gV$*>d0MZ1a`*?#+W(V@gAJASZ2bjrJ=!{^Qy >zccp!+@6P!^b&lPr?-}x<x;OMK9no#PifH&;b`4HYU2B%gZs)qH`^sm^$f`#~_o7iU >zs<eyfQSg9tUJn-06Ebwnl=GrzLO<PW_}3yfqP^}N;}!Qe@$0y-uT<RW6S~jUb*k^4 >zox0x-i&g*iT0XF4ih6L-4jKPWs&Xf<lmq5HD;`RINj^L-MGWlmlpHiLRt)-WnNH~b >zs7k2H*Mpn(RD(;i^pFdoYUuJ=GVySXNXpNY!#1`Q$)n??Sn{WMw12o9o>whW+6Btg >zw9O**YOPF<T`tmV1N6uaWoqQEQ#zwznR;yHZau0dUyYu(N@td5sjP8@dQ6e4WKyww >z{N+qBw)+D4#DsV;u4#@OpAas_Ur3Y_A_B#PgHbZONv+8KG(_f{-YX`)8L6NC=9GG7 >zS~ERq{cbfm?V`?Iv`Rf2TdAi^E>zEjZqQScC#tCp6>?hK0x_+oRL*FVBW9E@ku&QP >z#q&ke<*e!`kzbG@UnmO^1zG*%?4_54r%}KS{scC@!7tqCKltze-tXTfJs!XRkP2w* >z_wV(2g6!wp?0ZOJQmSXbK=Y)SXM}k~su?PeC&0d?-oU`s+wbw8{C<WG89QX~kkLbi >z4;epX0Fe<yh7cJ;s~JRO6s=|$k#V$|fkZ|U8A@a<k-<bp6B$lqJdpuKMid!RWK5Ak >zMMf1FR%BeQW?+$#wVI(t#@1>E7a3h-c#-i%1{fJ(WQdV5Mg|!fWn`F<akiR)Mn>9d >zh8h`bWU#Gfw2|RP#v2)MWW<pnN5&i(bgLP4WZ02$M+P1ld1UC3u}20U8GU5<k?}_Y >zU^NjyLSQv9K!Sio0SN;V2P6<kB#=-bu|R@>L<0#25)Z2h2oez_BuGrq289nqg_j8n >z5EmpcNMw-EAhAJ$gG2`j4-y|FKvokWBt%GzkRTyZLc)Z^2?-PuDI`=#tdL+K(L%z7 >z#0v=+5;3a@84@!jXh_tMupx0n0*6En2^|tUBzQ>lknkb#vzh=R5ww~RA~8gQh(r+y >zBN9g>kVqtvP$IEJf{8>E2`3UyB%nw{ttO;MOp%}>QANUv#1#oF5?Lg)NNkbdBGE;{ >zi^SJz0*pl1YC?>}*lL1|L>UP)5@#gPNTiWaBe6z;jYJy>Hxh5F2{;mQs|h(0bE^qD >z5_Kf(NZgUYBauf!kHj7cJ`#N-{7C$f0{}S!tmY6vjsdGV2#}+|Y7PVBI6w{r<VZjc >z1>{&j4hH0CKn@4wct8#a<cP4ELjpM_tmdFVjtZ+eERf>@IWUkT135I1V*@!j@c*NO >gGvr^6j$m_(^fEU|WKz$lm?$SQDLOhTI?4(D8&gR`p#T5? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central >new file mode 100644 >index 0000000000000000000000000000000000000000..2ffe3d8d8e012445aa961fc53b38934681dd2a2c >GIT binary patch >literal 2891 >zcmeH|YfP1O9LImh8;GK2VuS>y6+;mL#qdH|>KG(~dPEd5H4L$g#~X?l{56@ES8A4* >zQKXJqt`$0$;$>uN&aIq7lq8K1m7GdGsavST>HqoH3%A^S)62eR|L61Y49+=k_<X!m >z^WKV+f6dQ4;jlyIaNk4CrNr}~zU0`!^wNqQ`pLn2&e83|^;lZ5`~BKhJ=6EDb7n?I >zw|ebtIXiK>dv4M>sp);n{V{&OoR@O9HfWpF)^Bt#n76xdGTXgaw?%*6wZW;YEYx4t >z&3Eccv-DD)*J&t9)XT|3oGa79^=f3W)0i|ue(gTky%rHB*KYT8ubXdky{g&0(byn2 >zYmU23CyvW+8xOm8^2_vY>`eDw*A%_)Um*9JbLGLcOldivEPtLHCao3y#rJur$kssd >ztZ9`ti*HHWc_G?vMkj5b-l82wHmP4so%;7atsT1^(E!<_0q#!iRKH0(*M1{`M;2+9 >z13RSauJ@(ewpH@Px`oocaF#rommxi-BuP+mg7h33DNjX)NN}Gq`m}$GgtUp!klVr9 >ztD&QYR^8WUzP+JgdoF7Dj#JvZpsPIlUb*&}^t<$(^MgDWUoFq4d?hageJv6FHb_Kk >zl|}~4m&m%k+V8qo`d5CaQPqwPC|#`4dnf3?qA41)X|TrT7D(KJo;oNgQwC3H*7%5F >zG9>ONebFye5_<h135~5X^g*o*J5evgFC3B)<t>_c=wo?leVx8svQkFoAJJEeOZ3&W >zojNLKg^t>vUq5<av5px%-WhXeza$Nq>n2riljOiOH+k<eNok68U;Ai_j;$Hzq%JSi >zar<JNwCpTR-`w39KO#{lEV}DV3=LQBq#DQD;?a!w3Mb=gm}G{Xbu+&cnbNw?om$o) >zS#?|8?Be6{dgW4gTFz(kMrpP?J@u&0SX1cC98jij=4LrLfva^^Qlc}fX}0D@ggd#X >zQZ&!c<K%rArE?lDJ8y4JmUmA3+_?q)<=yg2Zhl6fIO~tO^WtyG{QOVd1wmD^Fl~*y >zu(e4G63U!{y3@KOc(t>na*q}^&vurUZqjAvQ=H{Ri*!Xrlv6Zqvaa0P#cAWQueR;} >zx%vCYM_t=@_-|j2{lG_kiHD#0d}TL9e7*y_J?(tHFSd)nz3*(V-5!2EHq|SmMw>Iy >zoXO^-d(FSNh{xlx5b-`<4~NaKT0J!LH)cMwoGZIOfat=~C<CGmh&mwpfG7l_5r|4G >zjZPp+foKJy7KmOTih*bbq8dx18;Ei&jdmdFf#?UKAc%$_DuU<;q9llxAZmi>38E;7 >zrXZ@aG`fN)%hG5IqArNOAPR$M45BiK&LB#IXwA~74Wc)Q;vkxXR(0H<J7$!}&>lm5 >z4E;eA2+<%!g%BM=lnBuxM2(h4j}S#dG|5mUM3)R@GPKE1CqthMg)%hCP$@&F45c!( >z3Q;RVua-u!5Y0kV3(+k^xe)C_)XUH>M8OOVGgQpbF+<4=En6BjL-cHE6b;cdL)8#n >zLzE5CHbmVJeM1z^&^Scp44p%i&d@qU?F_wJ8pSg-&rm%>_YCDjw9imKME{HgKr#SH >z0VD^OCJB%%K+<4o^1w)hrO5;%6_zF!jATHv0Z9iWACQDVG6G2nBqxxhK(Yc!i>1j6 >zBr%pIGmO+&n%ppw1IZ2}J&^n`5(LQ*BSnxLL6QW?5+qHKJV6p=X)*;#m8HoQBw3aw >zTaa`?^2JCPBx8(}L2|}O8YF9sv_bO5NSvj~93*v?CU=nJS(@xY(g(>OB!Q3&LQ)9H >kAtZ_Ne-n*Bjr&Y4hnQ?er4EXYi;js(jg5_tjgATU3t;rI(f|Me > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern >new file mode 100644 >index 0000000000000000000000000000000000000000..7b4682a39e2fc97450c99eed4576d2a4614bf294 >GIT binary patch >literal 3503 >zcmd_sX;76_9LMpiA{wHIikTw0q=>RgxKd&+gnGpVOmRCJdIvQ*xgZo`3u-tuOrt@i >zgSl@RqGFJSpr$rWiQ=B((UcTH5AL~eJKyJRFB;!9)8jn%bH};7{eAy2aS7AA+y3#? >zH~+)SbHluRZ}EZo$SGJZSO0KRe6uw0=$fzdBG#^O)$3xnM66#jQE%vyEH+N>r#HC| >zSDOd7*PE+?)mHDH<<?VnvF+(L`E7oX*nZ(N`P~<uB6nY++>sWb@>Y$MI~_yBuGCPu >zJJMg|Pw<j^e4B{x`#zKfu38j!YOV__PKdoO_x0Xmx75C?XY`M`rK;#qq28alQx&gY >zsY?=9r~~N>^}*;Qbtrza{wZjzI&4psM?CtdqXCoTFP~_6qT@YzLOfAr^RMcY5f{~| >z*sZ0f+pQ};6ZUE8S=-{`b6&Gc&xa;OoUh#^FEpPgE|h1;i(5Vt<wY~)rHpu?a_sVQ >z!eDVFElB<m)kR#L<SDQDxrvI%0R3mP&g#0ahrZGBj;eI6(UlKQs+$#My6W^ERed;L >z-`Za$Zs(qmdUd|2$=ogPEXo#l6SL&K$tmJ~bh3QVZ@hRI6ek~bS)l&%2$zo=j#G~x >zjnz-C_f=2N_R-IdwpFzS-rBjzschM`y3W$es_p`%>&aT-BA&_mBb0EBxFj0{9}o@O >zmB<&Gt`}~$b<#~Q5slPh>3(jlYFzA)O$yVM$Ci(E)32s0&x~ohS<0KLc|xRaF|Mof >zit^Jfd%LR_{Tk_39sI;g4XbtQx{XBZJ8rVg<!a%5yh^q$IVODaev>b+$rJ68Y`Xo2 >z%SDISE4t&1T=h!WA>C=n=c=>UM(x{muJWxtDE-`Gm0$S=*|oB#>Q=N=`j^FsfSd#w >zxT}W<N*gMJm$woj4u|eO=dlQljMA@;x*)=QyXhX?i$u=`jdia!=T)zY+q(CYeX7sl >z<GSzfIVwE&mV9mR2kQ0AQrU0iR27l9Q}$0^B;JT#AqT`y5d(vg<e-5A#Gt#Ib!5O~ >z6<M}SM>X!RqIS*FL#jKfp{p|Fu+tI3o;p(w-_t=vPq51oSuSE^c#s@5ze0@m_LMQP >zM@7t&yK+p}Rx#$9haT&5SdBeYqsP^5R&ndg^!V~+YC?Lxo>(+XO^VOflXHeEVc#vM >zES)K)24u;%9d;4lI9X1M3=-3-<D|paQ#gJNmkF+SMZ$I;Iiuo~n3>f_&pKA4-bwP- >zvvbQ-Vr;FJnfdD7Fs0`tW~;eg2lTw?6g98*l1%EAC6dZZWOA!ykzBM+raX!h@8v9( >z@1G49sc8<mu)s&8O^T9>zO;$Db)M&6J(uVC^?&NOPG|lKo6YGwQe4Ny=`7q~YiNCU >zw?3N=v&Yy54K(j)^S))?5iw@GY_>YqN6f#EUZwe=HF}Tu3-dV5Gv`)v6*7Xz5F%rU >z3?ed$$S@+~hzuk$lE_dZV`*sy6B$iQGn~kHA_IzyC^DqTm?DFUj4Cp$$haZ{i;OHX >zw8+>ZgNux=r5Rpid@aoYBO{CqF*3%;AS0uU3^Ov$$Uq|_jSMw1*2rKZqm2wVGTxSE >zz>yJ0h8!7lWYCdOM}{34cVyr#&B!A|Z)wIJ8GK~)k>N+i9|-^w0VD)S43HooQ9#0g >z!~qEe5(!Ha3M3XtFpy{<;XvYn1O$l)5)vdPNKlZdAYnn`f&>PM3=$ek6B{HrNOX|! >zpcNm!5Fj2CAs|FZjF2E9Q9{Cm#0d!$5-B89NUSVPu#jjW;X>kt1PqB75;7!aNYId| >zAz?$}h6E0Y91=Ptc1Z9nP4tlPA@M^3h(r(xAreC*h)5KXFd}h80*OQt38kfpB@#?a >z6HO$XNIa2%A`wMGio_HNDiT#BtVmpuz#@@FLW{%}39hAyE)rfOzDR(P2qPgzVvGbC >zi82yqB+f{nkw_z<wluLuf^BJ{jfC6M#2X1X5^*HtNX(I-BT+}fj>H`aJQ8^%^p+;} >zNboI9^pWsen)o9J0CEH%hX8U6AO`_*6d;EIavUHB0&*lEhXQgeAP0k`IU10|!O|QL >z$N^z#jtJzCK#mFIpg@ia<gh@F3*^8+jtu0`K#mRM;IK4D2Xc5=n&SgGKrGD>f*c~q >xF@hW<$WekECdhGu94NNuyCVLl7mAxXT*Ax&<8KcQ>>e2GZx0Cx3<(T&`x_HwlD7Z= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain >new file mode 100644 >index 0000000000000000000000000000000000000000..d02fbcd47f845bd101a7ec97150df7821b826357 >GIT binary patch >literal 2402 >zcmdtiZ%oxy9LMnkp}>tlrxHU!BP|I6<c~Lj%%~tjyg_h5G{Pv5U92FrJ1xXh;E0}h >zDq}X1KqY9cFm;W_2AadIKRS0^E-TTp(pfh8v&F)=o%eaf)}tP^^<}^N`T=7+`n=t1 >zJnPcMKW>Kk2@lt49^Pju^YP-?iSu291NzOOVAZ|rW!>%DuJ*iiN$+i)DfZQWqI;c3 >z)mx<(WnWaU>d*LC_D_8zK5Y-vzJ<Rx`l_SF=Vce<>A0`OpA*l>$x9VtYA{Rs`(s5= >z^&CB;_^O(jGpU19$5cq%Ssf}5D~A}-j`2O}+Ved+?97M=Kir}tKI{>ZZ+A=idW*QO >z{RMgbmRfOxr$)|NoiCya?w7N(62y%Ox5?-Qd1_9mL(UD1S95<|q+`AfRk6MhJ@3em >zYX19|^-Vp;Rh)O8y!rV7wV=!|7uJ6!ZgGAiZ(Z@8SQK?s#wThKKXpzgI5vocu_HS1 >zvRm9fyjLfkYE;Qx+jYvp61BLwPN%-QM5WcW%Jhx1RYv|gxuj%5IpZIYccg!*mIf!v >z%$Pq!=EX3XHF-v4ANyI}`PGnEw%?)e8rm(E@AygI-MLNVG@Q`)w05d{i}vgLYPPD} >z#johR+_ft2w^5m&+$8c(^~r+pDp7E-U9Py2BMRT>)hka|DpymRe(;0ks;JVVi#y`f >zL(2+vi8oM{#wKfb*>}o)HBy&5kE!zSlVrvG3!-8)Lav?~6>Ij5%ZJDML}jZ_J~G@c >zs%j3&wO#AQqpp*>x~)w;mV7`zUguFY;X8G0exa(p;?;HW$*S&nh4utTD$l#wy8ee> >z)cTH9@`;lX;z@6od}?4^G?d54#vMNKwDT{yq2Z9&7<Eo=D(VoMrY5yF^MLY>oz<J8 >zcdE_9BYMk(S3TR+qo4btLNztF=&gg<s=2CGZ`&2CL}0+QuWN#)eKY+R|HZrC|5~>Y >ze*Zh&0YQHMZY@IWdzk%{D_w5k$~8}^c~+UH*llJbM1cKp|BJaz*uUdH`TfienI1Af >zWP(;RLu87`9Fa*PvqYwe%oCZY)yx!`Dl%8AnJh9}WV*<FkqM)nF)wDy9CJn{jm#RE >zHZpHy;>gUcX6ne?k;!w+9+^JJ{E-B3WB^G4M-GrAaAW~V14kZ^L?D?!Qeic@K$3xE >z14##x4<sQ-Mv#;sIYE-bkrgB@9C<+!V>OvUQe!o_L6XCf9V9(Sevkwq8A4Ko<OoR; >zk|iWfNS=^HA(=u_Wi`1%lEslNBwZZ&LK4Q2F(hRiIYW|$WDQ9hk~buAR+Bj-bykx* >zBzaboJtTb``9l(jWDrRql0zhkNEVSaB6&m-X*HQdQfW20M3QMW*+kOGkxwL{92rGY >z%8^qfsT^5F(u(92Ni33CB(+wPTO_$wlU*deR+C>O!AORY6m#SlNis*4ku-DU8A&up >zrjb-zO|Fq-TTQl+bX!fnk%S`|M^cXD97#Hob^ITv-C>Hq)RaHTm64L3lA7d7OG`;h >HNp<`UV`q_f > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland >new file mode 100644 >index 0000000000000000000000000000000000000000..a1d14854af6b82bfe814f2c64aac01bc053d5fcb >GIT binary patch >literal 3664 >zcmeI!YfzL`9LMp+3%4}yh1kVX0ZWmK)@oU%AV*uo4Cz>#89ZrJ2Gyfx8HM9?nNnve >zyG#aDR*(`ArK`qfH+xddQPYm&Mz@U+Ei@N1B)9WD_Qsl~rkUQg%=&p))Ny?A|Ne5X >zEu5X^`qL{$f5MwrtA6v`{{j8W%I*2xo?q3}QRXXotbD_sMHOow4!qzFdtO}8-}};% >z4$mt4xc6nN(euj8GXt+?Z1Pl&{UuN}_(jiaXYUKF?y|(Q`q%ovn&50t^%v!V*S9Th >zsHravyisj6)V@;YeRJu=hPnqI@V+%Ssp0L}`QEkJu?_1cW_W$W4mPY$NbqhrBgV6_ >z$N0d;wgaAbS_cQ}cW?9f%d&6tZ;z~e_wAavO}<q3dkb4D-+!i$`-2%fDnDG%=Kg4O >zUFGH*d-*=@zoOC^cf|Ker#F+f4BYM8^39V;4X$;*or6NfJ7+aHyB^L^pH1#8cHf+! >z_6+?_d@iDuiuqXVO>9wn_g9I1y`tp4ogX=YMq7SSHCHtH^W>M0<cP1z-16(fRPjwo >zy!>`j9}&F1Lw=XkCYrM1)c3u6In4>}s`>B{rzJ9=T6XMq4mA1I!P<4s51T90kMH_L >zYfZg8R9+ztFE5ur-M?5IDJqqr8!XY5Qy`CCK2iKUB2ykq%6ES0kto}vGo1Eg6V&nM >z1gAp{QNKFT&Iw<X3cuRoxSrmxA|7gRIxX0$Iv4L3U1l}Qu2Z*)$Z=a_R7$mo9=Jxv >z^jt1tUCU(bp*zHBUlq%4dzU)hH%*hLuP<_XRNbz6K6{nZ>yfFd_ri3iPhpzsJENb| >zZ&F`%hWlsd%%r0#?)<)@zy5EDk2osg54XtyUn_Cej?d-U?`;t0)UKE3zOYgZoVPu6 >zUTMB{{`A_=pj(PR8$9ZX(2&Wqf(iZRg%U3qA51*)xIHv>aByg&ZC}t58NAS+XAj#o >z$QoYewv+3+S|dv0?UcvAw^HX^6iU1E6DvI{E;Mr5YHL(Nd+4IHrPjrffslJZRnXn! >z4~;(lXmHHtiqIwd<_0gVskg^&%n4q$yxhM0xzymeqEh>cB~z^NIR*9vE5*tfk!fdU >z^tLjOEC^){PY!17nh~1Ry=QPz-6f&P2Y(7)xl-DmJw2@KMPuwKYrBgauUk%C(JHRG >zG+s`dw?kY#phM<PuM@e)8)e?86(TR#uH-qjj{Gp7W}JA!xptLbUDr6z@h+)Q*ZZ$= >zW?GBY4P~R9S=r_C#)tAm{_s*+Fvl&d?gjFutax$L51DdKLWh{MEm0OmHj2XP7<o(6 >zCUNUiL)2~C1J2y}QR?;@zf&}Qzbal{;oLE5tGcsjv2$0yYGvnGj(uW_obN6b^BdR5 >zyW<MP-Tq~A;jv6{Pg$|NS0#!?CDY`6z8Fz5bELfg=>wuu#6S4z()pCH$gZb+d+HDW >z{dZCS$=`bFzb732^huX191g6C=whCu^|Lb1j_c%eH}gr)aJZ#8qVLI{da`p}Q!@1X >zYW<$7-`DWH{=mE<PU3R$ko)&{^N{{+=58MQ{SSuqYv$OI2a!99+*0J8A~zMetH^Cd >z?kjR*kvogrTIAj$Hy63P$n8b$FLHy8`VJ$v7`eyDO-AlAa+{I+jNEACP9wJ(x!1_e >zM(#FpyOH~i+;HTM8}%(m?m2SPk-Kixw;j3f$c;ztJaX%idym|F<nAN4AG!ZX1CS0N >zEimdHAWcBJVAO3u`hYY7=>*aWq!&mtkZu@tJCJ@DbwiMjAT2?9f;0u`3epy&FGypM >z&LFKpdV@3v>5fsi2kDPdHwftv(jufsNRyB*A#FnXgft526w)fBS4gvvZXxYL`h_&i >zs5^$V4CxutG&Eh~fwu9|eFGYYbPj19(mSMiNcWKTA^k%dh;-1XTZr@!X(G}^q>V@) >zkwzk&L|TdT5@{yVO{ASjKaqwa9YtDd)ICL-igXoeE7Dh_u}Ei;)*`({nu~N7X)n@W >zq`^krVWh=I-D9N5NSBc|BYj31jdU7mHPUOO*+{pMb|d{p8jf@vX}MAN9BDezb)@Y` >z-;u^6okv=a^d4zG(tV`;NdJ)yVAMMR*#btr2aru*)Vl!L2FN}@HUhE}kgb611!OZI >zy8+n_$bLXJgi-GZWJ?(Jo<KH*QSS<5TOj)a*%-*qK(+?5H;~PN><(mmAo~N^Ajl3u >zwun*h5oD7X^)5lSiBazpWTPNE1=%XdUO_esvRjbtg6tP$!yr2b*)m4GXOK-})Vl`R >zHb%W~kd1@v9AxVtdk5J($nHV5kLw>ypNLL>SSA0DpT8bIv3ek-k4aC_TWMH!dU9HF >P%CPLz)a2CUl-S<@u$syt > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific >new file mode 100644 >index 0000000000000000000000000000000000000000..9b5d924173e6e71c2c0a73cf2aca368d3af002e6 >GIT binary patch >literal 2901 >zcmd_rT~L%&9LMnmUl4>mnJ5w3NlgS50YOnT({xr$L}ev0!<PgG(@?QhOVK8pvNsNy >zFHJ@N$cvmxbQl{OlhB!*nxYcSL~SEWWl&Pl5|ws4-{-cAuA9!zc|OnVESG$Lp7})u >z$*zB#ZuT24r`BHH`)sz4$^(bw-Gh<l>n+jJFzEWqhQ&ivqqmnnp1o21F!!oHp<C6D >zsg3%i>l@V+xnDOm?@_1x$K-UKQD=NL^3(2*jIVZ^{JiBg(_Fb$ekodM&X(rNuNia9 >zZ+Yo*E-uBKchA!ode2rZvEy`0`zX~K5~EuiBGtw7etl`*4b^tES^r+qq%K!?%9T|I >z)zxyJv~N0Wt`*nG^@Z=7KeDRi&xy~Q8zal4V`!DS*{eWq^(a%fI-b+FTMAU?$$b6S >zm(!I0fLjMXh*z$iaXRS5a233+r|z<9sOh>mR=Uj&Gu<bJN=V`*(?egBQ1z_|bJa`O >zmA$5CbG3vw)vJiQ3c2IcYSnA^9<AQ2P<L)Iy7&4Lbyv}9-6wahip=onzGKIzesQC9 >z)WB?WcW9K34o)@E?J084*?uObp|A8meA5ir*CF@5ciL$0Fn!;%hs?m72t8=oDK$9t >zvc7-%XKF~~F&!IUsbc+Y5*M~v#reLI_|_$ASnWO;-dJizRBn}onnh-0=~I%pb+Sn+ >zd|fA(3^t?OYjjF>cas{MqemyVm@y$~IxVJ~O1luP$KJl6#vSd{>8HO^<M&3%go7Wd >z2g+~B#J65m4;G)1NoBju<g8kGXz9yl%1Du^Q&yO%*BZ5Z#7oNExL;>PELRydJM{Fn >znd;%UYh=cWWhQgOHktX!43o8Bt<2h<U}lfcl{sEzvSZT4Gq>G%I{Qmb>T#2EZk(Ps >z;HsMUMU2k%H>&x&{Q6Pfezl;iSwB|0L**?!q8C=KSBo-zviOB<X32;;dAx9~SsGC# >z`R-hk-&Q7tvFWC;zCemX`kSJUr^&MO0rSN6e7*ep7`4Ld)=yUZRdG(7URmC(R*mkd >zR~H{qC6R4<P1Y{8CJ-v#v^wMUU6gfERc2jny{zvjGf!7m%QGhn%!bkm*?3@@Da|X9 >zO*`XFa8PiUuJ-ZY`~(88yy0>M0`Hihu7N=LW>*jAJ=}S!8JQl}tSR<p+xv*Uvpn{{ >z+~o>#9-e=%!{_#gP8~Y<3wr|g<W2BiLTZ5&1E~g54o6!Lq##H|kdh!ZL5hM@1u2W8 >ztqW2Zq%ufpklG-{L8^n42dNKIAf!S_iI5s0MMA2Cl*!T72`QALtrSu!q*h3=kZK|2 >zLh6MS45=7WGNfim(U7VkWkc$Q6b`AJqb(g$JEV9>_0TCFFVv4?3kXyYDIrorq=-lr >zkuoB6L<)&i5-FvlttC=Sq?$-Mk$NHpMJkGv6sajvRHUj%S&_OTg+(fhloqM2qb)8{ >zU8KB7eUSnq6-G*o)EFr;Qe~vfNS%>FBb9cvrABJ)Xp4<h8!0zZZ=~Qz#gURDHAjk$ >zR2?ZhQg@{ANac~zBei$5#Yd`-lpm=-vH-{mAWML(0kR0lDj>^%tOK$T$Vxccr9jrg >z(JltE8jf~3ko7<o1X&SeNsu)`76n-qWLc1PK^6vC8ArP`$l5sC#X(lb(Jl|NKF9(g >zD}*c&vPQ@vA*+Ne6S7XoLLn=KEETd=j&`w-)pE4Ug{+sOT`*+DkR?Ob3|TZ})sSUF >z)(u%WWaW^hL)OmGE*`Raj&}Kw^>effh^!#8gvc5qi-@cuvW&<&y8gfO7-m;9&93M0 >U%uxx+35mlqladmW5)#Ay2A}k~%K!iX > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan >new file mode 100644 >index 0000000000000000000000000000000000000000..5fe8d6b618e34c4c87a7eac43f7a27af41161d02 >GIT binary patch >literal 994 >zcmc)I%S%*Y9Eb7Wl%-5VyqJMViy|}(1r3t+8kQv%jsz`aOcZA2p+6uFEegTK3$7jA >zL`0A)FT<2XUdjsyW0`kP-ZCvYM2iUO_&%@gbmPi1yytT`%rJ}R8@(TIz9RdsljaSF >ztIQmpb6s<L^0)n5qQ6^rrZU~0rW(Ju<c8OGz0~hlm%U{E89(VqywvFuCpEd_z23=o >z-Xu@O-aX9n2OGA%p}SlD@U`~XNa=+C{zA9+A@7?r8lH%a{uy`1wqC`?TO&Gs@t2cs >z$d#$aHubT#MLyN7s_F9!^7-npnvnsSJ^NhEdR;R2Z&1&_eJl%0&-CJpgu68GR4=!> >zu9t}GFYyQN%A;F)^=5^;R$r{w3k%$h$}06WyIeLe6{*di`Ley?tMAiO@?#{e<XGsy >z&+&`{U+;bSL=beWi3GvRu26<~){<qPBlfPiOU~`;s8m;&Q)|vWbM8c?+&puI{@<gA >zDDd0<hJOtLN+30mB1jda3{nRvgjBMcQb;YUDTY)-$|3cTf=ETABvKP8id03)T1{P~ >zFj5&QZ8f!#;z)I*JW?N70I~vP30AWPWD&?JkYyn2Ko)|m1X&8Q7GyEVYLMk1>p>QT >XtO!|>)vO6w6tXHj`elX9)XKuUTnF}q > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon >new file mode 100644 >index 0000000000000000000000000000000000000000..6b62e2d3c39a8406cdc087b387fbdac0709f9141 >GIT binary patch >literal 2093 >zcmdtie`wTo9LMq7Qm4zo2XZ>soqcrX+}v(I+~(=*mrc&u&MkLdo|(Ve54N-|w@xjc >zCyXK^_AXI_?EE<VM<kpKMX-hm1tF4c5s@(@D5Dsn1+A2Q`#eAOUw`yx(D(R$AD{cO >z-G8rVbVFN9x$hs>RQraTYrnlY&rRA#>cW+Q;}`Rcxi)>^ME`K|${Py@hVy>y9Nt=? >ze=AAI_`-g5H?Ubf(6&?0h_6%GwNX8D=@K=opi1Y=Yn0j3a&&HbrR3hJFb{q=OZ>w# >zP2l6-WzN}g^U#Uwq7#es+yfuUyjYgbYyU>gue_xnUj3n3ko|?uFHEWYi7``<nN$U% >zpPRy;wy8x!XHC&aj})g4nc(0SDd~CHlpb0kWv%b%@~-)^INYr(8mCBQeoR-D|0qi` >zLOSH1tU@<)_0qdH)v{0T>FVpBspSJX=8=o1)uVlXn8)6GOFiE4t$CvNl&q*9GEX+W >zDK#a=tgP7~D}Nc$;o^fTJaSIgW^GrsgGcr1u{G+cV}qvdt9FU(J#5yTuao+XyG+B8 >zpgg@iZq_E0H2SMebln|^-V2ym<(CrsewkiB=eAn^iC@PjM%0Fr6Z+ZFb82Jn4gK8E >zQMIY*vfiB9qqamw&DPfs%eLZ6=K0oL(v;P2n!|Bv9_ux&`PI^TwZ*h$1f=bQRi^z1 >zPhL3EthZnDs~w53e(}tN>WCHS&b}M!rK<b&&W_8fD|<|L*Pm3~-ZYa4U6RD;&t`W{ >zzw92mYW9rx$}6ce=GCuTWN**gX5WQX(zB_{?0>gV($nnczDenm)2C$o2OrNn(B$)Z >zUSBe8l0A3&rn>WV_f($uzNF3I?3?Y*fx1Z47q78*qrIQ8cLU$;iw66m!OE59o_`tr >z_Z=kdpSvB5|NVcSz4pC!@EEcSWE;pnkc}WaLAK(wdqFmX>;~BmKhJ)U4Iw*1wuI~n >z*%Y!XWLr+VFJxoL&XBDkdqXyd><-x;vOi>l$PSS$B6~zO>9o5<w&}F{L^g`-6xk}W >zS7fuuZjtRG`$aa4>=@ZHvS(z|$gYuXJMF%ajUzipwvOx_**vm)Wc$eekp>_gKw5zG >z0BM5Lb^&RF)Aj*rgwu8cX$8^?q!~yzkai&bKpKK{1ZfG<6Qn6l+ZCiOPTLoxF;3eV >zq%}xykmexWLE3}#2Wb$}A*4k}kB}xIT|(OAw0%Mv<+PnbTIIC8LYjqi3uzb9FQj2e >z$B>pGJwuv?bPZ{n)AkK%oYQs=X`R#d4rw0JJ*0g||BwbE9Yk8_`@hF9(^fKMD_Im- >S94rr(7DdX+f@Q(d%s&C-P%%gV > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental >new file mode 100644 >index 0000000000000000000000000000000000000000..ab766a41bc06db2956154da6e2fb0dfc3e9c1b2a >GIT binary patch >literal 2538 >zcmd_rZ%kHI0LStB00M!esHvbPS&|0A;g13acq9-=!KZ}$hlb<`%m6`P1SR<*skKOE >zBWFdn*330MU<EdqXRV<Y6|4wdI$JYat;Nhr%=C7?XYr~Ry>070yZ3YV>|x{0?|TY1 >zl$Rzr|F{CpH{4vWo16D(&F0Z6vR51^`p(<Y^lkq^XNOjs>-#(F(`46jXYkm%D*f)f >zMDKekZ_4+5A06xtAJN?x4|scS6zSt9BfJB%E9AiT?+3p)*Q&pqby^K46zbu+HhE(x >zRo-m-L%9Q=YNz^~^3-~@kIYrRh4I=iB1%n2UoHKe5ET&ID+4Z!s=%95<t-<MRM7d~ >zWbmP%#l*f58PYN+ZhiH*oK)5&CO<Q*Lv!|tDW%<d>Vi5kZN+|lTWFh_9@(g;U*4%^ >z`ft)RhaOU4mzL@9&SW*~^CCHWZ@8LsG+o|a^{1NK8X+Tg`HDL#edN59>*CJ*i}J3p >z^J0Foqvu~cAtHYn(|4aeC>C7(NH6@bPu(-}mX3O(Lq&JD=taAqRx$0{bZp5ZN;L10 >zaT!@EzPMZ_q>YF~xl%3;&J;^RdSsISuu66&$>dK0MamCRdg<XG#l5FPbn0^hBJI$q >zPTzJ!ENdCka?QtTdD$_Yk?@YXFXttlIrRmV71t%Ru2iY)(0wv{)JNo8u9LaFmE!)P >zb#i5oqgHh;m3jREBHz1PuYTo-@@AaX4>Y}~9*p{3t|_Wk1;J<J+N4Wj?a`m~`WdIh >z`qt0%hO39g#!97&MxGa&R=4TR-4){D*qyq#-7B`t+$&3(x2uw|8o9MNUu`{8C`+YK >zr9DZqEMkf(dpS&&yT7V!_1EQN7rs*4x6IIwpSmI{<TYJ+XjoK5e64r1bc<@IPuG;~ >z7d78>=-Qk{QG2>q*2lH0`nO+`4WSLH;n`;S#N~~uvAje!4W+3kb2H^ropaT$g^_ZX >z>$)BvkFUqiXZ+*q<2%9J{sI4ykH72oec(9u>F2t~l@sW?C$%$?r^h^p2R)O=pM1Y6 >zufSPj?nPp;xf9JjzC@45OwC*#Pr<+M^Pu^m-RGG78~y{=E#EVzAK5FiS!B1!c9H!e >z8%B1FY#G@zvT0=3$hNI!-^j+1og-Vfn!O{NM|O{F-)i=cGyrV}c%cPcrUyV1kS-u? >zK>C0*0_g<O3ajY_(hQ^<NIQ^zAPqq}g0uwb3DOj#D@a?Az95Z3I)k*vYI=h-$7;HR >zv<K-A(jcTmNQ;mjAx%QMgtQ6i6VfQ8Q%I|<rdLR_kZvLELi&X?4CxrsGNfln(~zzq >zZA1EoG!E$;(mJGfNb`{HA?>r8{vi!SI*7Co=^@fYq>D%!kv<}gL^_GI66qz<OsnZ8 >z(oU=CC(=-)qex4Uo+3>}x{9<F=_}G$q_aqCk=`QBMY?M>?M3=)H4R2OjI<c(G16qD >z%SfA%J|m4rI&C$rMtW^E%|^OyHSI?FZ8Z%?I*zm)={eGLr0YoAk-j61M>>zR9_hW+ >zG#}}{)wCb!ztx-p$T?s&X902^AZG${E+A(Eay}qugw>?O`9B^ML8;~lNl!G-g!JgV >T<e2!FC9&~|(Rqviehc~wJPiO4 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland >new file mode 100644 >index 0000000000000000000000000000000000000000..060bef81898b9b45492ce2e2e35fb218f5cc213a >GIT binary patch >literal 2242 >zcmdtiUrg0y9LMqB0R#d`5mT@~(jQ3!;Q`{02KbF2A>~hrnTmzv7?25pNQ5PMk<=`e >z*@!LEx@e?LAM66yU_NWDwCvBhAav#IqPf*tjI6{ge?9M~x@xVvF8ZDG{9eDEjh&61 >z&%0_}LtUo#w=2Sa!r|I&56`o^>}~i1>HaO4Cs%uZ(f;X=jo0#}4zyL85GmE6t20bk >zVzQoAP$A)7jE;yNk%;pXI`V3qTyr9*qt5*#(f!}6>7(Nk)BTyc_Q0^rs6Vb|J~w7! >zOZKZ-b%Q2u;Wjn<-ad0(Y>%Fk)M@5SZq@PO8%%ugL7i}6nVC0`tFQmGT5i}kPv3Z~ >zKyGUORnOm(D2Y2l)y+*Ia?6q{>elkF<+g-#YC*1N7F<4|l75&nx1W7oExh!eS@iCx >zzGM7Nll;a(oif;M7Vmskr}j3QwAx3t>e?mgg~d9fra?0E$JL#(Lb9TZRCdge<b;pu >zTyKWteiW&ee3NXJ9{yI{bt=Z>y>MFP_fMFD#-nOkchJbH5B1&k@0h~OxAi?GFPoyc >zmvnLZaVfsote3~`m*o>7s$_DTl#Vp1`+^V2iXl(099Sx4??<Te%AKa-)uXzy@T|Fi >z`(FJ(^3SrWx<yw-pOG~=7u1?#-<h>@PpY+hJ~8Vq9aig`w5cB7tu|Ejn1=_qs7KPa >znws89wK0C5)OKywwNtIKsis_SI<s2pMCrPr9H~#7rR!fwkOu!p-PnFb9y|ZJ-n?<H >zdHm!>wM8zQrv5S2ocM)#qI*!ac%!DZzE8D&b<nhxbgH&fBhsGUtJ~jtO*&#bbjR~u >z^3>#d-Puqp+k^S~>Cz&3W?;VFu_#G)_`V+q3km(l*R=5e@)hp;eNTFxyNCJykwbw< >z-#@U|oBr4R$RW>uGOPnLSC&<I#r7;#+4khvlVyMRfdKD6sQUNKylDT#ZDz_oaM^!{ >z->|FDeuw=QyCGyp=(fZId*ZU20(OOL3)vU4F=S`R){wn9?dFi(A=^XthinkpA+kke >zkH{vGT_W2=_K9p1*(tJBWUo%US!B0PyIo|z$cB*}BU?uHjBFa&HL`7F-^j+1og-UE >z_U^QsM|O{FAK5?B0Hgy*3y>ZlO+dPUv;pY@(g>szNGp(DAk9F!fwTkZhtoC$=?Kyi >zq$fyIkggzYLHdF;2I&ma8l*Q!bCB*hZF`XZIBkQF4k0Z<dW19y=@QZ=q)$krkWL}3 >zLVATX3+WcpE~o7m(lDp(7}7GNXGqhKt|4th`i3+P=^WBJr|limJg4m*(mto{AJRal >z?I6-Zq=!fokuD-_MEZy{66qw;N~D)aGo7}ZNIRXjpGZTUwxdW(owlb)Q<1JBZAJQu >pG#2Ts)274wzs5Ey&xW`l+upMZQp$2uGg7nDGBQ%ivi^LE`W?cWOo9La > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Cuba b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Cuba >new file mode 100644 >index 0000000000000000000000000000000000000000..1a58fcdc988ea6ec1bb660ceabe85ea19e5b0774 >GIT binary patch >literal 2437 >zcmdtjZ%kEn9LMp)-yCXL{y`%Nlf+6;u<Ixk&n5~6SHHy76okkSycl6dLZaqcNwzk6 >zP?AYJsEoN)8ri^Vbe8yMj^;PWVWTkv<3XES%NZKU?f3q*wzeMhpdNM3&Uu~P-Mjnf >z^FD#XV0oJJw<Fqo!o|^SE}kdtF}L?Oe!1tP-q)n9rr14GRIX=w^WC!<IePZ<Dz7_n >zlXN$)_P*{KFFhGoz20{&%Qta--biVbj)Zo(*Oz4J^`Qdq*ZvG0ZQbkscJi>^XxQwI >zbvPPo9rB!}K@Dp->4n#JX~fn+H?s75iSkYHqTLg6)3h9ST*4t4H&XA#I1Li>Q>8op >zVo)Z0yVslO<;u;+H+#3Vy)Bb=9dvKa|50x%Z}%prcI%WC2fV38&+D`~^<Hd7nNE)` >z_GZMb&>6!^z1v6UYTUUE?j8LxI`c@T8^5DK?rcnO6AFDYt2*4hYgxX|UUkV$oV`%* >zPC4bynfkIO#SVH&W34iGq(|==*eCb)9n<?dx5&Kq{hHk3mz1VDoxgj&ET}Ei)QVh9 >zdt|XL%ud$(-Sy&|d0rN!9hF5l+9f@%ThoVo^?}h3^}$o0Xh#35y7)+sEctAkW;Py^ >zr3VA*mKW*rET1gD@``3B#!B{ghh=5Nby@kb=tD#OlG|J*dEF!Ge{r9#`eK!?uDz)8 >z`Y)2dc(OeF%mpckyDEV-pGsh~PuBXHW$mRax-Py$*L9uO^<!^p;k)fxG_X@Qyl_B^ >zJ4>{rtX>~&akbR{hCJ3#EE|(|$m11DrEKB`*_1s?HeJq?ilhjs_$ony(LYG=gK()F >zJ}q1J$Lka4hO}zCqfZ_=snu%+b!%g*KIQAuZPokq>8bB&&FU>$Gj>9@r@tiI2M$Ty >z^h&AgY>;QK<;jkgpwwSTk)6A9Wmm@}*<F$>&o%ulVG-f~_KXbw%NZ5<-<_dQ+Zo3( >zch89og-&~6<3ge1N1X|O-uWcYA8>NawJghA1p%`j#|aCwIDvoO-CO3Hc6ZnQ_=)+q >zP$<|iw*%QBvPEQ%$R@33m&i7)W}nDLt!AglR*}6Tn?-huY}ab`i)`3xc8qKp*)y_f >zWY=i7%>(=9FdGMUj%*#-JF<CX_sI5<{UZ&qnhqc>u$mqqO+dPUv;pY@(g>szNGp(D >zAk9F!fwTkZ2htFvBS=fErYA^KkggzYLHdF;2I&ma8l*Q!bCB*J?Lqp3GzjUC)wBrd >z5z-{2OGulLJ|T@lI)$_f=@rr}q+3Y4kbWTzLpo+PEkk-{HBCdhhO`ao8`3zWb4cru >z-XYCHx@R@*L;7bm4MaL<H7!JXh%^!DBGN{rk4PhtP9m*DdWkd>>891R6X~bbG!*Hm >z)wC4pDbiG=t4Ldsz9Nl9I*YUx=`GS+q`OFak^WjugOLtfO^cBpTTPRZE+cJ5`iwLh >z=`_-6q}NEZk!~aHM*3|v4M#d|H7!SaZZ%Cux{kCR={wSRr1MDYk={H1=itYfH-OK) >Z3Fi41rlh4Tn7?42KQ%Qa)jXxf{0?B7_b&hd > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/EET b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/EET >new file mode 100644 >index 0000000000000000000000000000000000000000..beb273a24838c96e81f0469e3827bea20ff930c3 >GIT binary patch >literal 1876 >zcmd7ST};(=9LMoPj+LzFi-wRqS%fGa;qaIcM1}{Za#Y}Gq#_xJQba+-z$DgU&J}Z? >zHdb@x)XA80dh!D60;%~pTgKcRYgW!JSK7l|n>wGy=I{N#?W(K#pPjw_JKMSYzCYo$ >ztu1-Je>@MlU-<HDbzk16KQ`Q?*pFu0;{!oiSCQhHGc_ZesF|T9_C)?Y#i#$NSu=lD >z!nE&|aN}zwUim^#Uf8SICqGuwv2ja26tR@g_gLznEN$ESHm9xAo?72zPgjR6y)<ag >z_=_wfIn(AonrNBP70SF-pn1P$X#V6ZWu1Ol3r6qAKm5BE4*jU?f$x;lbxeWg!^&;A >zXnCEZmR~kz1+|}8VajeR%ImSBseW6OG^9nBHd^uhZk3Ez*mFPCt8}DMWn(3Je*0pT >zf0nElTGF+6px9olj8;W+k}b)&s$j*GRYrfSs`SfNb^SM6I_<bEoj7aDuI#tvk%Lx! >z?i+=64%&)C`?RvX-Bt~LpqiIHRBhWP)jiv$aCMbdC#=vK|9q{v9Z-FIrPcp1LoeT& >zXKTN_sdbYvwtjD%HH`jc8~Sfp<Ise?(l}`w`~J|Y<zHD-!#Opl?Xpc}5w$#WRGU+z >z&DTEFmZ?s)p6%6Zm%@7ez&f>^>999;l&O8B&feUTrnj~iT1QQ(b+#nf+qtRM6})Tj >z#QCf{Ctlru|6)C{x7Bn0l=WV}sI5mv?A?hmZQFH1eUaUIuXkAeJNxB}`p-VTtU#1I >zwd6Uz=wPre><b3Nz9{#E|HYZQ|NA&q<Xn-HMa~vEUF3X`6GqM$Ic4OWk(2gxXN{aT >za^A>^BWI4BI&$vF$s=cvoIY~?NCHR(ND4>}ND@dEo-Pd}4<r#J6C@QR7bF=Z8zdbh >zA0#0pBP1mxCnPB(D^Hgel9#7T49N^h4ap5j4#^Hl56KTn5Xlfp5y=rr63G%t6Uo!l >zC5mL~=~6{<MUq9bMbbs`MG{6bMp8y{Mv_LdM$$&|_H>COnR~j_k=&8wk?fK5k^GSf >zKxP1$0%Q)5NkC=+nFeGYkcmKM!qZI!G8f2XAhUr?2QnYXgdj75ObIe4$fO{%f=mlC >zFUZ6oGvn!|2ALaAH#x}cAk%})4>Cc>3?Wm5|I;~&al5oIkA?Dw^0N!G13CHrP;S6` >HD~Ndj&PSQE > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/EST b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/EST >new file mode 100644 >index 0000000000000000000000000000000000000000..ae346633c1690d49530e760f8506218bfa9feef1 >GIT binary patch >literal 127 >zcmWHE%1kq2zyORu5fFv}5S!)y|D78c7+ixxfSeG*`e0_T{D7H)YycO~98)d;2yPBR > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT >new file mode 100644 >index 0000000000000000000000000000000000000000..54541fc271644e44973989a27f3846a16800caf5 >GIT binary patch >literal 2294 >zcmdtiZ%oxy9LMnslIR5zDhd^;pkg5Z?J6P_CXB9jh4f-bre6)bLnuyaHz>oJDCyQ* >z)1ZH&EHi6!WM<Q9OwE~FGgDTxKf_~NtX0%8df+7Q?Yz&^9`&qs?#}OZcAtOV!G`A5 >zC7yqrIQtKm^Mbv+ll%5$sMkLFMPA?HQM+C~C7(ZQ)Y+^*)ma(SmoL?uv7hGXzs{AJ >zD<`Mv$f0x-eLJc>y%7`BeL=@QuFW_VkvO@cuBz2CzT&)!FFGdi&rMbnlXuI+eLIcU >zY>@=LStWk+hE6&XQdb}D(v#lVWRhQ6ty8u(nQJ=k(bqOto9mY5>QsM@xqfz{z9A>U >zq-EyF<Ow5YN^F8m`NONGUKo+|Gry{7M^8(}{x8&xyY|aXVUM}_nH`c@_k+n=)30yw >z9XGeme_r2~y2oVauG86(PgRb$PUj50rE-6srKb;ctGvOW<o7kJf&(+9uycVb+L0#3 >zp^zzAds${w`_1i(z87EibThMLKxV}!nbN7>>eAug&FryHblHhBX3lqgy1f54b;rj~ >z>pQo9sqT7Zm9A)eU(M~>D0kQFRP!2FN@ZbKRaMTDs?oisI)8<(9^7X9NprRTK&zQQ >zlBE~Cx>eo#b%g{rw5Ww2W=hSnfU50@ll#gG)uP9SWpR3n3f7&J;Mk~I;(J$?{5Z+f >zXPnUW$1j?tk-fTM_n>)TXq#Tvb<jLG(5ja=_L>!a3$+A3P%FDzWL18TdMFf-#-w)D >zR9z@dBMmB)og$%A<*Ir7s5I}(P-}+2l9rw_(|Y=%emI<N9_b&{ZFLc&wjb1w`m|Zw >z)~na09y9A}I`sO;c@-}0k?_z_)t=Ta?E`PBj!O;lMBirh<hgR$&>2!s9m<f-<$ksC >zMUQx5JTbB3?B~Dqi$*^?661+R55MP$bMFc6n^;vD^i(aj_kMe8gN!4F8~hg|irT}F >zkTD^HLPmuQ3mKQw4h$I?GBjjt$l%b8jt9fz*zo}aL`H}V5g8*gNMw}AFr9Xs$UvQT >zq{vW_u_A*-MvDv=880$mWW>mjkuf8KMn;Vc8yPn;aAf4j(4BVd$l#IDBg03=j|2dT >z01^Tu21pQ)C?H`#;(!FgX(NGz!f9iH1Otf%5)LFDNI;N?AR$3wf&>ML3KAA1E=XXI >z$RMF{+Snk$L860%2Z;|7AS6Oah>#c|K|-R0gb9fg5-6vQ6cQ?@jTI6sr;Qd8E+k$^ >zz>tU`Awyz@1PzHA5;i1mNZ_0{a!BZ$Hg-txoHlw$_>lM^0YoB*gb;}#5=115NEneg >zB7sCAiG<Q=V~GUQX`_jR(`n<01QdxV5>h0lNKlceB4I`1iUbykED~C$jV%&fr;RQW >uUZ;&O5@004NQjXbBSA)@jQ^W3du^?Kw%U1t83iQ;MR|eZ;)3FWBJbZZQm>H! > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Egypt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Egypt >new file mode 100644 >index 0000000000000000000000000000000000000000..ba097504459673e254831edea689c2f8143990df >GIT binary patch >literal 1972 >zcmcK4Z%oxy9LMo<K@qQ5UbPhS8X6>Gl#oH>O)9+(4cD*T%Sy-Uhc#Wb+-c;NQsd0E >znq_Oo16^(DGFzoqW?3|K%eF$aIN8Wew>-3#WQHdMjhjU0ee79Vt_OY@_r?4(o}Bk5 >zz4Vdg<>FsA%>4=9T(kS;=h4c2w6%O>+A>Z0;Ds}${i|+$=+JxN;S)3T*E_n*H(&PY >zj+d7k{myFr?X#gd^1{xbyW*j+yRS4jHL5i{)fwtvPiO4uj~^Gmbu`<ajlJT`2fL+R >zU8H{B@U!h*x<s69oFx0^tXKVYo8`GFF?GJ;h&?})6ay1;<Um)u$P853KMxG53&;1{ >z!EI~RUweDy&~tl)c)iF*R{Wx}nwQAzg>f;g;RiW<<{KhsUd)cj>r}agNtxR-QbdP8 >zWuqMlHR|M`&D-_48hx-#Uhzu5xboeH?U*NvRqVx0a%^3_7`HMm$5(cVtL_Qx)%oMq >zge@(0LZ(LK%dIy5c$1pcm$29D7iw~+l=028#gsi;?X_x!D%f~bPHlKiOj}bgubW>W >z3YSfnMMWufec}r_J?D8*96x7^PkyFKM3XIPuU0d=-j_FQZxp2mezZ5Pe@or8Wt^Gy >zSe`Cx?l<L&di2c?9yPN|w7#Xf)l@`3)Ro2Ghm~hLf~wq4!>aFg1-Es-8qV3>5+vH5 >z4sUN+70iA6fv~#qzTl1xYs{VXjry)9>dm}Fot}U1T$3C-7%V6&FbmA1K}{^n)O-@t >z3++#4(Mzqt-NzzfZNolYyY7Bd`(`Fct-95ucC6E>V|&AN;o2Z8a+$uev;O<*;_nqA >zUgut)D47*;PjPaA7<uvM+Qn&+Os4oq^Y;-x(wBbI%KbC{rvKnSxEpf!%)Z6jkvHyj >z?;LsS$a_cLJo4_5w~xGkqyeM@qy?l0qzSL<0%^nR`al{%Izd`NdO?~&x<T4O`av2( >zIzn1PdP17=x~`D6ysj^#F{Cr3HKaH6&G7@>ajrd}KcqpVLyi`a9yyvsx<uOax;{A? >z^}0@xR*_zjW|3|=+C}<B8b&(iXc_65qiLjTq;0S3o1<~B>l|qv=^bev>7Ju~q<>@s >zkR9OI0%Q+3HUZfMWE+ru;MfSS+X-YVylyX$%|Ld8V>^)jKsE%~5oAk{JwY}F*%f44 >zkbOZm#_M(l*&46g8)S2k-9feo*&k$skR3v{2-zcKlaO6Pwh7rMWTU)pr;x4ky1ha+ >x3)wAXyO90zx()NX9YeOv>-Nm+HVxS|ahYZ<a*0{X{^$4puVIV2l`Ace{tf(fqG134 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Eire b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Eire >new file mode 100644 >index 0000000000000000000000000000000000000000..655daf37889fd12380c7f055f2cdd85dd4665e03 >GIT binary patch >literal 3531 >zcmeI!Sy0tw7{~FyAqu#?np>js8g3Zk0hiPyat}pvIVov|mZByZk};qeIhCd3IFAiw >zrsnHTF1X=}<{Ii`E-5a!Yc9C2i3{5M{nvEUMK@k_(K&O@=XmCD>F@h^dk;y7aQ^WK >zu;1|Fan8Q@T=5h8Hnr}GNmCD&DnD(H$4sBI)qFo~x|uP#nlYcR(=$^ZnOOs;>Di-p >zm^ra)%-pDldTvIPGp|lRJ-=SA&TJ5>GcOmK1<ro6Ag_{MSa3rx+McKv@BCF~&5zYf >zOqyBxg-0*@YOh(I6k}E-FE`m;!_3O)-g=csnbi>~W=*+UW^IKyv-bJ{v#!9=IfrlR >z^+$W@4Qux6AD2Bg8^2wtH%$%Hn^Pz2EhCHc*0?mit=k;)Q}aGLx8-KNJ?@~{p6_oC >zM4!@mHEWrJv5WMf(E9pt*hGE!{?|IcY?98ud_^BUSH&FrdAB~k?Y=pYeaW26s;p0C >z>@ug5Uo~fjj?ibjH!#0>#hi;MZO%t7))xXp^u>x^bMav*T~IV!U&_C#FCXurudLgn >zudaAtu6?&mUmr8b+?X+1-|Qc4Zl%ZT+no~ho%q)JZmlxr_o!ff&$(_2gM4-2seR`D >z;|u!1rWNMlMIZBM)Iw9VJtxU0DOVQ{iPOGaGj$37mb#>8ye?T#UHhv<?Z4x(4!9Ak >zOD(TvO7HdPGLs&evP&!Ia>Gv;H6_fH@3zTQNK@w7@L8r}+$~cn__9=Po-0*+evztG >zGo|X;CGuS1c&WB^k_4Wfuc|M~QZ+V@Q#B`u3Ys}o>BMAJYfKmQe2iBG_iv<Xhc;7n >zI(3%1rK_rX4H`<lyG<k{pqzx{Rh9+?H|2%wLJ8fuUm9lQOV|%9rO}A>;u$wt!uuXk >z5y{!Aab%8a()}CNw8nJREFx7kD@s?*12d%g@&2mC!xU+`p{;u9Xq>c~7cY@HE#>90 >zttDz|b$KNrSXzJ9Lbd7OD{Th^s&;iQNc*-$s)O%N=@@)cb-Z?7Mf+@4(Ytr3PG@JU >z&RGjo%&v{nW#R-CyJ)7oHf)&cI^k34)@!_UPaG&cUQ85kOh<XWO04t@4UwMrJQ7!_ >zgNi#;LEgAqU-e#fNBZOis5eb{)i?W!dMo|5iqF`s`o-s|{-ZC++fl34JAHS_fS@UA >zU}Tmg_^p&dHADtooGgQjl4Zz_G<o;9SB7Txk;L5L>b)-`W!StP>ixk%k~Frd8s4py >zN=~SvJ_xU=Mzp`LJ}mF3ltz^#<;EG6TK1l#?%k%+t{st)OXsOkyL05DDO+T8)^zze >zZH}Z*OqXKM6!-c2S;DvYQ-1oF^!pDypFDX`+i~oBIj6Ye_yra7bDXlOSZTXQj-%Yq >z_M1OHJ5Dk88^`^P;}_G#>$J14=pJ6DjeT{rpY3n#!@jwH<o?s~{`(M~x4(3Uu<)<H >zdtx8G_5~b6hSAlIBQlW4NFqatj3qLd$Y>(NiHs*QpvZ{2+95^86d6=xR9)?`BID|6 >z2NoGwWN4AGMFtlcU1WHX@kIt08DV6IkugRF85w0{n2~XIwF8ZeG&0o4SR;dtj5add >z$ao_Ij*K`m<j9yKgN}?kGVHE)+>wDtMjjb@WbBc_ceSIB48N-#e<T1%1dtFQF+hTV >zL;(o{5(gv@NF<O@AhAG#fkeaAh69NQ5)dRJNJx;FAVEQ*f`kQ$3lbP4GDv8U*dW0{ >zqJxCT)y4-25E3CIL`aN~Ao1UTC?R1&;)DbWiIl4i6%s2~8!RMRNVt%AApt`ohJ*}> >z84@%kYDn0SxFLZ<B8P+yiJhwr9uhqyd`SF|03s1YLWsl=2_h0jB#cNLkw7AmL_&$g >z($xkNiKeR!ClXI2ph!fKkRmZff{H{H2`ds;B(O+ik<cQsb+y4oqU&nIi^LZRFcM)T >z#7K;hAR|#m!i>Zj2{aOEB-BW(kzgaycD3O~;_Ye!jzk;@ITCXu=t$I&up@Ct0*^!< >z2|W^fB=|`5U2XW0_`BKz067AXLjXAjkb?j@3XsD9IS!Bm0XY(oLjgG!kb?m^8j!;Q >zIUZc?0f8J5$RU9o6Uae<92Ll6fgBgefq@(u$f1E88_2<d939BvfgB&M_5eYS5LbJM >zAjb%DkRV41a+n~;338wyM~d_Rm7<=`l@egjn1<o@hVg`U3HO9G4YM|eM&SW}06*^b >Ai~s-t > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT >new file mode 100644 >index 0000000000000000000000000000000000000000..c05e45fddbba6a96807d30915e25a16c100257e5 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<UarX@YGC~OJgPFnd17-@c0bD?H47dQeKL=s} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 >new file mode 100644 >index 0000000000000000000000000000000000000000..c05e45fddbba6a96807d30915e25a16c100257e5 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<UarX@YGC~OJgPFnd17-@c0bD?H47dQeKL=s} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 >new file mode 100644 >index 0000000000000000000000000000000000000000..082986e76d623d5b0d47e7b690cbabd9cf9a0dee >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWm|M-D{LD#?#C=x<~2|s}9VF1%4 >LE*qeUc7|L4a%mO_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 >new file mode 100644 >index 0000000000000000000000000000000000000000..23276cd13aa7a8fe46d109e6a9a2f33372d271a8 >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWmFHT@!&^0swiiD70!VjQ&7{D}% >M%LZtoouL62029g-8~^|S > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 >new file mode 100644 >index 0000000000000000000000000000000000000000..28c579dcab62c958f1766847fb316f64e8854123 >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWmPYqyT&^0s!iiD70!VjQ&7{D}% >M%LZtoouMHY00%V_<NyEw > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 >new file mode 100644 >index 0000000000000000000000000000000000000000..c740603969f103c523c13b04b57ed2eed427d908 >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWm4|iZ-&@}|<3?adUA3*gmfN2t! >L4bVh8LnAH#`jHc? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 >new file mode 100644 >index 0000000000000000000000000000000000000000..721cde2f3896162d84430f832fc5426bf2edb9ad >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWmfBb-fLDvAJGlT>aegM_O0H#S? >KHb4{YjJN=14HeJ; > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 >new file mode 100644 >index 0000000000000000000000000000000000000000..ae06bcb654b641b86c40254dd0adce48af80c5bf >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWmzj}dzLD#?-C=x<~2|s}9VF1%4 >LE*qeUcE(%)S+NzE > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 >new file mode 100644 >index 0000000000000000000000000000000000000000..5a7f878c98d53b58dfa59738c26f0689a1b6c6da >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWmKYoCLLD#?pC=x<~2|s}9VF1%4 >LE*qeUb|zc^O;r_O > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 >new file mode 100644 >index 0000000000000000000000000000000000000000..18cbf1fe2bb028343e36285553af105cd1ed15cf >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWm-?@Q-LD#?(C=x<~2|s}9VF1%4 >LE*qeUcBWhaK=~CY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 >new file mode 100644 >index 0000000000000000000000000000000000000000..1aa4be88302308a9a764d0dd632b74b3325592f5 >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWmU%h~VLD#?xC=x<~2|s}9VF1%4 >LE*qeUc4k}vG@TUi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 >new file mode 100644 >index 0000000000000000000000000000000000000000..cd8ed49af3204f76cf25844942015205fe7e360b >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWmpF4qpLD#?>C=x<~2|s}9VF1%4 >LE*qeUcII3FC_xms > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 >new file mode 100644 >index 0000000000000000000000000000000000000000..e0ba6b8897028777fa930ce4a832307f716df241 >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWm?+0>p4J?2nAtada1E?MbFiqmJ >K0h(xM!36*t<rIJb > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 >new file mode 100644 >index 0000000000000000000000000000000000000000..eee1bcb70e8f59e5a4fdcd04fbbd9acec88fa04b >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}85sWmZ!BP7&^53GiiD70!VjQ&7{D}% >L%LZtooh26l4~Y~= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 >new file mode 100644 >index 0000000000000000000000000000000000000000..c05e45fddbba6a96807d30915e25a16c100257e5 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<UarX@YGC~OJgPFnd17-@c0bD?H47dQeKL=s} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 >new file mode 100644 >index 0000000000000000000000000000000000000000..4ff8701406074eaf82aa119ad75049e7d41b0c6e >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffNIu00V=zfgz9;LV^iDKw6;y(<Ck% >Kpow<6hFk#O7Y?le > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 >new file mode 100644 >index 0000000000000000000000000000000000000000..e12e461d50a0a48872d7a6d814936abaaa406782 >GIT binary patch >literal 150 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffPf}0tN<cLjxcygai|QfV4sZrb%2j >LKojkB4Gp*eWk?YD > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 >new file mode 100644 >index 0000000000000000000000000000000000000000..37f273974d5ab91321e2d236121f27e957a0d9ab >GIT binary patch >literal 150 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffU264Gaw0hK4{^2ni<q0BMB+Op~~5 >MfF|1M8X9r|0CMsXIRF3v > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 >new file mode 100644 >index 0000000000000000000000000000000000000000..09297f1bc24ec1d8c42eb6129d3a4641286f5a99 >GIT binary patch >literal 150 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffU1v0}Kq>h9I3GB$)66q!kJ<P2#cv >LnrNqMXv75ofSeI| > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 >new file mode 100644 >index 0000000000000000000000000000000000000000..97ae1e140a4db63082e006a9efff0ceeeb25aee8 >GIT binary patch >literal 150 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffU2G3k(d}hQ>fv2ni<q0BMB+Op~~5 >MfF|1M8X9u}0FFixxc~qF > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 >new file mode 100644 >index 0000000000000000000000000000000000000000..58d6d1b2adcec0a790f8266afc78e02e653befe7 >GIT binary patch >literal 150 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffU1$2Mi3_h9*E(2ni<q0BMB+Op~~5 >MfF|1M8k%qc0Gsd;`2YX_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 >new file mode 100644 >index 0000000000000000000000000000000000000000..f0dc70625cf4e9dd2fdef1ed8d3c91827199be5d >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffR#`0t17#0Z3;E2`2miX@vqzlelbv >KCfey5aRC7Af)4Ef > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 >new file mode 100644 >index 0000000000000000000000000000000000000000..a0790fe9cd25455191d6e49e9557897e926d0d46 >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffR$50Rw}!fiaL3LV^iDKw6;y(<Ck% >Kpow<6##{jT?GG&g > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 >new file mode 100644 >index 0000000000000000000000000000000000000000..a75a173dc6414570ed2a5da2de82f8500714207d >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffR#<0|SG$feDZmLV^iDKw6;y(<Ck% >Kpow<6CR_jqXAf-v > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 >new file mode 100644 >index 0000000000000000000000000000000000000000..85ebf22e8f941954a5b58e4a26071a5ae6135897 >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffR#V00V=zfhmv`LV^iDKw6;y(<Ck% >Kpow<6rd$9N(hscw > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 >new file mode 100644 >index 0000000000000000000000000000000000000000..95def1f9eaf83160e6dcd3d3e883fa8d4f6b0d31 >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffPeX0t17#ff<NJf(buBTA={bBrY4E >JiFUeXTmT|H5A6T| > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 >new file mode 100644 >index 0000000000000000000000000000000000000000..c6a776e95bda241701c82f9ee62e2c12f1f7c360 >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffPeh0Rw}!fjN*BLV^iDKw6;y(<Ck% >Kpow<6=3D?Ts1Pjx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 >new file mode 100644 >index 0000000000000000000000000000000000000000..f74a16f98a8710c8ef291b73e1c3e66e368a6203 >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffPdlkfUv20c3@cV8RcORw%$UiOU9P >JqMfb<7XUpI5N!Ye > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 >new file mode 100644 >index 0000000000000000000000000000000000000000..9b647c0fa95c3838ab9a1fd7caa888468c53d654 >GIT binary patch >literal 149 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffPgC1O^6e14|$)gai|QfV4sZrb%2j >KKojkBEx7<neh{qy > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 >new file mode 100644 >index 0000000000000000000000000000000000000000..c05e45fddbba6a96807d30915e25a16c100257e5 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<UarX@YGC~OJgPFnd17-@c0bD?H47dQeKL=s} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich >new file mode 100644 >index 0000000000000000000000000000000000000000..c05e45fddbba6a96807d30915e25a16c100257e5 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<UarX@YGC~OJgPFnd17-@c0bD?H47dQeKL=s} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT >new file mode 100644 >index 0000000000000000000000000000000000000000..40147b9e8349c50b9b5459d34a8bf683c91b182f >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<U33UzuGC~OJgPFnd17-@c0bD?H47dQf)dy|> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC >new file mode 100644 >index 0000000000000000000000000000000000000000..c3b97f1a199421d6d9625b280316d99b85a4a4e8 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<U2@P=uGC~OJgPFnd17-@c0bD?H47dQg2nTKe > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal >new file mode 100644 >index 0000000000000000000000000000000000000000..c3b97f1a199421d6d9625b280316d99b85a4a4e8 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<U2@P=uGC~OJgPFnd17-@c0bD?H47dQg2nTKe > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu >new file mode 100644 >index 0000000000000000000000000000000000000000..c3b97f1a199421d6d9625b280316d99b85a4a4e8 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<U2@P=uGC~OJgPFnd17-@c0bD?H47dQg2nTKe > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam >new file mode 100644 >index 0000000000000000000000000000000000000000..6dae5e4702f5b87a85a9f099e2aaef7ea2f0c6a4 >GIT binary patch >literal 2949 >zcmeIzdrXye9LMp4LK;2dS4<$qTSRz4Jb;p#q=aZD5bB9Y!Al})ks%Vp(&(br>Noez >zvCOG?Lr{l^hPMIUZ%rkuQEIw2UD?IR&74|e^?N_nmg|q&`lEk(9-iOpoWssvjQ7Vk >zVOCz8=Py@~{e*{Whkbb6^JROiaAK~kX!<mJ<=NfNs`7o#dzF#S>SZC$8ci~5i*GvX >z3L?z<%yUk8Mu6FnQ14VkPBfKK2h7Gvm&~R%>&>R-3C`xri%eD2MW^c64726?Jg2&H >zwAtFY+|<0@*KFI?&1^4t#Cd<|IHxwFkF#U$BD2%$IJ<m%oZao4ojt=#%$^@kJ9S}m >zOx>9)rvBCjr(t)a*?aDc+4pXZ+24?34wNi42P;pQgXeRy4`me<94<XvaAZ(s!O<x< >zt{&@Ic=h;*?HMO8kC9WGLbY*SvV6F7fSi6cQa&mSk&n}dYr8%z1?|eGY0z7prTxMb >zm7)agkQ=4JzA){WHbU->|4BPVe5WBD&ueJwQyO}0uZCUPs`q@dMmryRTf5XZNO)DX >zbX~bxx*3)3^Iwr3`GwLmdz##v>XV3}DRN(Qf<%T#$^A~4L<J;k)b#<{>&r;(-4vpI >zj<nIfwKp}o{2T38c1~j!p3we9_3F*tqOmz=C9bem;uGs+z_@p0VAoZW5LY4zEu}K3 >zOPLP3FjWTsT&zPHlI6kAvvg?1WKFCaq7N-j(qSvYb$DKcCM_H+504Dc<lHVYBJ#4P >zB)7=OfDd$3#1}HE`70US`hbjXJT8x3S}$X&H%scteVVq!NP5*;eQfq@$uO_!*eBl9 >zarx7A`~&&wOC6<;ho)<0bZ^bP;nl28BPHvzV14p>FPX6ON1fOdDA{W|NKWk)nN)gB >zCYLqJl*vspb-}m#)UaJLE$5`>c3&>j6RS0^?GByMRdvSK%XDT-q0Tx!PoKWv(`PnL >z)cm7!<k>e8b#}#gd2VKREm%BI=8PRGg?XVeH@2G;rQDL|J9wnHe<v-zdQnP(ZfMEr >z!!ob=tiDiFAul%8>HOsfbwTwieQ92~mM$sPR(`Eo`~SncO~4)Y4s3g;d$+sG`LAw| >z$G^<}FM5K@{ruh6ZEt_=U*mD?C;R<^|2Tuh6Xx-R_wWn9{rv57&eSxYCw;unlVt7d >z^~QPa8Eenv6rX+UFYM)KFMIIwr^~+c{e4At+HbfOx%vB7f3a7q;Ia8gRa|XZkh&m+ >zK`Mik2B{5F9Hcr(d64=b1wtx>lnAL2QY2SfC8SJ9om_39kV+w?LTZH+3#k@TE~H*a >z!H|j}B|~b46b-4Gt1TN+H&<IYq;g2<klG=|L#l_A52>H4Eg(`sq=ZNfks=~hM9PTN >z5h)~6Nu-oWEs<g()#T4gIbCf%k%A%>MM{d)6e%iFRivy)U6H~fm36hHMQV!_7pX2% >zUZlQAfsqO$B}QtD6d9>9Qf8#iNTHERBc*n=wML4KR2wNbQg5W-NX3zoBQ-~gj#M2f >zJ5qO~@JQv6(!1K)BgJ>M)kn&Y)E`*@WCf5VK-K_R1Y{MEWkA*eSqNk$kflJ@0$B`K >zyBf%HxZ3qV76e%lWJ!=UK^6sB6=YeEbwL&eSs7$$khMV;$JMS5vOKPKeUJr0RtQ-l >zWQ~wTLRJY`CS;wEg+f*eSt?|$ki|k)3t28#yI#nGAuEO~8M0=`q9Ln>EE}?J$ig8j >zhb$ekcF5u(tA{L~t6e{20bT71B1?#@A+m_bDk95>tRu3Jp8qG(PG``+oyb5tr2S%9 >U(&)7Kn1M0g=(Jcb_Ky$z6}+vK{{R30 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra >new file mode 100644 >index 0000000000000000000000000000000000000000..b06de7a5904dd87bc1c43c023418bf2829c01df0 >GIT binary patch >literal 1751 >zcmdVaT};h!9LMqhQB7-R-)v;l1Cqkgb5TlioLUsBKjk5b9>ftPtvtn;nYH%4Xv{E7 >zYi4OS;UZ=XW30K*3^N<^I5Qg-v&QfJcj>~N&A*-VI&0_LecoStd2Mx~^~V!n{=<vM >zXI^{`-fi9<W<Rw;yL%+;*a-=5Q;FEIN5=aaWWvg|GBMwl$PBMca;HjEXtYcoF;=1j >zJR1EqSz}&B>6C#nI`!6Yo!0wJ-JS1rddCxu-FHvp8n0-4<vC3#dn}0!y^@sKC&@*J >zBqi*)q$V~?>QJl99M_>UpH)cOk0wpO>XBJbOEsgbTr>O9b@u*j%{m&YbE+dXdtaK& >z%?VIX<v5ua^+vs(A;}52tGSWSCHLcN$@9A|dHr`}{>#&{py#aQ-@m2>?QOEK`;;!K >ztCPiTd$q9SpceV6w0MS3?fhI_60%U2x~J&U!FVklog<}>M(MJzF|z#97hN$BBr8t_ >zOIhy+S=IVk$~*dHb@_l)?0m0lvM$Tovin*YaYU*zd$c<6qSl0|*1SEe>xLS%_D+kg >ze`f23Gb_}0yIwXP$ke*7V%fAVLO1VEk@~_6X{Zj7EeYY$=>0BRgDq)_8?8;BUP$xE >zL2Z6;Q(8Vg)@|pzWP5*~?l^KoclI3DT`is3+TN<JVSfJq>d&%V?1abPvPOy(Xj!4- >zT_b*f&M&a760dD}oL8~U*IX{=&HnoUH<~Xx1N_GC%=6PcyHYQ7AcN##l*llVaUugn >zMv4p-87neaWVFa|k?|q}b~GbKhK!6E88k9#WZ1~Kk%1#4M~04!9T_|_dSv*>_>lk{ >zO$0~?jwS{q2qX$53?vRD5F`>L6eJcT7$h1b93&njAS5CrBu5hy5|pEf3JD8|3keK~ >z3<(X14G9j34hav54+#*75DC%I#E1mxXre^IMB+pOMIuE)MPfyQMWRK*MdC#QMj}Q+ >zMq);Sb~I5VVIy%Pfg_P4p(C*)!6VTl;Un=Q2LL$&$RR+E0df!=%~3!OgQGbP$bmqP >s1ac^lV}TqD<Y*v=!}>2SN07ND(-S=2V%uGi6q^zo?=DD)$GD`RU#;eS#{d8T > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan >new file mode 100644 >index 0000000000000000000000000000000000000000..90d7c2a810846febe4c2a6c60e8c0156505d4d91 >GIT binary patch >literal 1197 >zcmd7QJ7`l;7{Kupn>00Xa8MiDq&{jI`iNfBq(n_?Y?_8@3PnPPs!)6s1i=r<pdhqh >z?WBSth$tc$9DENtStUppvF+qmg$qtTkh6$l(Rlthb#f3l@8z7|<!}>7zJFol=vYks >zaV<9|EUsR&cwRYSwmX4r@kz-)v^sLNye2Sj)z{6X>%Y4m1wN?q+J%JGFnhM#IDN?u >z-aBK5t{3g5b4ToTr-$wJ$8z?D{YiUczSV9{HQ1Xv{B}6#(=Gl*9q~jY@+BaxuRo2p >z&3u&h$8V&gG$+x^&t>!EL)lWiDc0eOvh~2Uj-9xoJG*b__})`G5t`6lv3<Jh$3dNJ >zJSoYyeR|vCh-`n>qIWE$By~F@-A|jOXDTc^uPI57d1cpRQ1@ovOXko|-4}i(*^I6G >zJ@+No{6gnGztjUYB|R{ISMPo|rT08Iuk*9FWbndqUC4(<hrh0p@k*tlTs6z8x7)LH >z*LrKcZnnSQZm-*|RCI;;GgX_V%ya*ct4^t8TA8!z{`<sbPO9&4o*yizcB|8@gjsRE >zK)JY_C$_>rO!M2)r_2wkFjZu-95Y>H!pM{z&7_fOBNIoaj!YhzK2iWu0a5}|15yN1 >z1yTl52T}-92~vuqsRbzpsRk(rsRt<tsR$_vsR=0xsR}6zsS7C#sm#%ohScV0ibJYH >z%0ucy3PdVIN<?ZzibSeJ%0%i!3PmbKN=0gQG{qv-I+}8kdXa*Wijk6$nvtS$+|2&} >Nt=g9|wf98hzF%%35ugA7 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens >new file mode 100644 >index 0000000000000000000000000000000000000000..0001602fdccd0bbb1849adf237c93aa93ea80a73 >GIT binary patch >literal 2271 >zcmd_qZ%kEn9LMo<g`0R){37uu0nvz1yYe6W6GV8uFcS>nYNR3<h+;%a#2_(l#auJy >zzAaWcGp!hN%&tA4oI`3^IV~W!#+sFb<;pDQSn9MDtKa+N)>;pG){}mB=e!PQm+^$p >z+qbT+Hr@KiahW$<oIU2^d6wVY_WS4hkGEYKJAUfu*)u;^k9{hKO9n5ll%d|D@!>b4 >z$3B0lZu@BX>s6!2TqRR3Z>*XceXVNhP{5itaL}6Gy~ZEfS>d12vB)pmev`18o#Qi0 >zd&k2Io~^n)<77!h!cQ6*{*6Wj4QbTX_ci*$QN81fLptlD7d7U@fW#gNNZe}&Wp<}Z >zeA_cJr@m3<Zm5<!i+qxh<CVMI*^(HWBzI4XmL#V~ldfm#yzdfq{z#-Q_++x)(|1$d >z-IsJ>*H@a{@tLMHozT>pw>7QeoTNAQNk(qJWR|`xS#bv>JH17+C)#CkOqVV`ze$$- >z+N?_lJaX^X<(kt|sk!}2^}gNtnzuhz@2^eJ{Ej8EtiY+BniyH0cu~Ec2`O-%(ZYmL >zDZKK%tO)v0Rt%q(2QIuND+9e!H28rQ@9mUTN8Zo}8ycjf^EqAp&>k(V->hYe>eW|N >zsB5BD>00-EU3(){%OeV;{L7j8@b!7J?!9Zee#9jk4uwfY-(}g@epM>FhNY@<L^kdE >zQ6I@WCe;;#S`)udHs=PkHsoF15~sT5hgWp#M5ET7Zq;q)efsF(^;&;whdlOtt~T_P >z$>Uq&b^Got*|9oD8f&BEiL}|$<o!jS46~#;B|@9Wzm=BI8`^UAV`;r|PM><GM|KYP >zYumn)x+`!%pKk5e_Py=u2$~c$$r<bnHr_Vb{_rL!WXga2v8>1(^H0k?*s>O+IzlWf >zc8)dOvO>iQ<Jl4M_xFE&r>NLx<(tdvE#v01JoaUN`13f-x%Fr{9KL_w(F^9=_Kt4e >z`nBK9Y07(bIkGEcTefCj$i|SJAzMTChHMVm9kM-Jvp@a}8$@<!YqrQ?j~q6M>=M}~ >zvQK2A$WD>1B6~$Pi|iKJuC3WGvSDP$$d-{kBb!Ecjcgm)H?nbL=g8KPy(61Pc8_cy >z*}tu60MY@Z1xOE&CLmov+JN){X#~;<q!mankY*s=K-z)y!`3te>4>dq3DOg!DM(k4 >zwjg~$8iRBOX${gFq&Y};koF+`K^lZ~$kwz7>5;8z64E84O-P@RMj@R-T7~oqX%^Bg >zq+LkAkcJ^0vo$S4dS+{yhI9>S8`3wVaY*No)*-z^nul}`X&=%*q=85WkrpC7v^7mc >zx`?z9=_Areq?1T1kzOLrM7oKz6X_??P^6<sOOc-1nx-OMwKZ);`ie9b=`7M(q_;?O >ik?vam$MCvLnir-MX?Jl(a#nI`N`|{QE!BR?bo~Kn113@c > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast >new file mode 100644 >index 0000000000000000000000000000000000000000..4527515ca3f249a44599be855b3e12800ebe480d >GIT binary patch >literal 3687 >zcmeI!dvwor9LMqBn$hO=nHU-N(OjC={5BD438AqqmtXotj4)(rmX?v0Q>h%sdF!Yp >z<U?Y)%x%kMU5MsB*GZFmE_1(T%%;!t>o})#oKr`C_xqiB{Lb&^cR0@Re!e`th9*Y2 >z?s+_D-{FVH75l^M!1wGg(;6)@)Asu5>D%3A#+-HLtLZb$%#7N`e7IWAO1))f51OvO >z9<$NRiC<~HX;Y%-HteV8HO|wSO~Q5NnPM~FwcE@usG%1WUDOLVB<V$)cIm8n@p`dI >zGfO^l>!qLWFw2r-&GM9GCcA5d$%*NuzjG_IA}ZCata{n3s^>F6=R@i(EQ)-zEM1 >z{+IL*D|hQ3mzJ5IzR1yQrUmP@qcZf*qf7NVZ<=1;ZI1b+WpAC=dad5z-D@@!`kT!` >zjbwAi%d%x>J=yy9Q?hNTOY-}9)pj{5JBIg_ohd<TXGxUWHMC6c9uQ{s#2nTI_3E2~ >zcBN8q=&;%wzfkWj^ELY-Ch2`QKGTI&l6B#kvwHvWn&$T{`TD^68|Gm4X>%wmNFScE >z)f`EA-W(k^QXlKy#QfnAb3Ce&IT5``p9~Jur>c9*sgjDisC0xrU3gBPInYC&UA<kO >zTYl4=|8l9mFmAB9ICHGN)IY{tPEXKRIw$I@32pVY`jyR}Z9?^R*9B7?;-`xb?=&~c >zPU@R$mYb4OzUJ1L1*UXEZnAH3o-P;W)qY(wb$S2Rx`KOxu257*`>Q1Fzp+dQT#VNh >zm(@0vcDQxr$+t|ECDnA*5eJQ$8esyvtufWolzAv}wyEyDY-)s_k)W1&Qqy;v)T)&! >zwT>;8hl?jj?RAqS_{cm}XJMAAyY>@RZ=$G>S;Lf0N>TO4#i>VPJu0++Q`I26g=*Nj >zi!`cKOEqrtxHP`@goFiDm9T;!X;O4a9?LG4@J+kr@hOE8@okPY9r?YuKgkgH$p)^- >zKEJ7`lx)>3I#)f>{d3j4?hMr;YLseGnyy*~Pmz`f`m0tYsnYs~_UftqUU_<Mf<))G >zmS@Jdl{VAr$g_!|()NQ^s$EAvX+JPnJ=gH0bZB3yI{IyrPN9cXr}HONjPF_%lfO}Q >zKK8Zhk~Lq&Zv9E(CQVfF3unm-!-uP`6W^C^FHMl{NrR-vlS$%<?IbVOjF+C_Vbb%u >zTf8+oD(|n=<mGFRs$Sn+mEHvb>J<~H`edI~ebcX~gem!|UqXTEKlZe|+Gd3s&}XX* >z44JA1MQ2IkgE=y|uE^k188W0aMTTxnlh+P-WLRczNy;0cUjH~+hR^Mx-WU=h$>W== >z5#63vDTy`Jo00X@$PPEuTY)Z>+O&qGUOcKsRk<#scC1%v=YNyYOXjLE`ML7W)SqQ+ >z)(m+!ZH}Z*N|y(G?)T~IbN9(NeedJ@<;vgtoBhiF)3d@qefVELyM6n1j=f;6D$1uE >za@6W*pGv&rvhV!;eLjti^SIje@VGkRbM}SH$H&M1INwFjzu(TQcm5bxVDX)Ax$Ix! >zcI`g?Taa7oXzwX<Q<1xh+*ahiA~zPfv&gMQ?k#e2k-LlBUgZ8FH`vkMVdNG&+Ix)L >zWaKU*w;8$5$c;wsG;*tvdyU*|<ZdIk8@b=e4M*-ca?2g<Jx6Xja@UdDj@)<T#v^wg >zx%J4sM{YiH_mSI=+<&A2NCzBk3y>Z-+9n`fK-z%x0cix%38WQBFC1+%kZvIDK>C3+ >z#L;%d(Y6HXiKA@_(iKPB7NjqZwlPR&kk%l*L7Ibf2Wbz|AEZG@hmaN_Jwlp<bO~vb >zqwN#YD5O(JtB_tH%|g0`v<vAM(lDfBNXw9(Ax%TNhO`aoo1<+U(mAAcNbiv5A>HG@ >z8|_2-hcpoBAksod+e4&@j<$<P8<9RDjYK+$v=Zqh(oCeANIQ{!A`L}4inJ8zDbiF& >z+f}5kNMDi0BArEAi}V(0F4A43y-0tN1|uCtT8#7<X|kj3GSX&8+h?TFNT-ojBfUnN >zjdUAnx1;Sh4;qei9BDbybEN4=*Bx!!k-j_H#v`3aT95P|X+F|@r2R<$kqv<C0Avdw >zdjQ!4$Sy#(0kRJq?M6U$f}`CE$X-A;1F{>C?SSkDWJ4f30@)JCo<KGQvMZ2nf$R%M >zyD^ZR;b^x8vNw>;f$R=sdm#G**&xUcLAD68N03c|>=I;~Ao~Q_D9BE6v|9z)E68R+ >zb_=pyko|&e7-YvFTL#%P$fiMd4YF;JeS>TqWal{At%K|xN4t5D-Ggi&Wd9%=2-!i% >u7DD!r>wf1D6X@>q|3PH`740Ajuv5uxCsTM_vxw#q?xvC9aglCb1^fkK<6HXx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade >new file mode 100644 >index 0000000000000000000000000000000000000000..79c25d70ef09aaeec21f0a10a029650967172a80 >GIT binary patch >literal 1957 >zcmdVaYfQ~?9LMqhL0H4S7)2!{xg6a~D7WL3s9ZY8CAlQGB%zgCF3rrEeOY4-b6vxT >z2jM}?T<4O6HN%WC*O}Qcw>5t6|7Np!;F-<;od5sTPMse8-XG7D`8ko+A6E<W2{%`< >zx%s*ETJyNxB<4x&%h7W4u#eX5cgd}7(Ne!YSn9ty@^9}elRIfc)z_Vs@B8eycDlP) >zJ73(YerL{#|IsQ5*tJKxl&J)+S|?p|3#8k$+0s45BSG<Q>EVo(VE+*5*~(W!yj&Xc >zDO!6y57yod9ktKp7TUM^i#iX!)_&y=G_>@FhAlgz;n~MDBJ;jP7F0`ALXAX^-!3r$ >zyCpWVNMajHB+jo~;~veF0pAOC;8~XpdYGZ{m06llGf)R_9Hv8d`s>h~ARSgZK!zuJ >zsVm!0Mg+f9x2sVSy{>6e&|^t@_d=4Jo|ojht1{}@0U2F&L{e(cY3i0TNjthv$K>V7 >z*s={eZqjBQpF2m>`{$}BB}pgvr0GOwZ=Lu#Tr)Z(O2)l*I{8yCnR4o*PHpg(X?xpB >zX7yW{Uh+Y*%IjoCR)fr3{YGaEIW4m@Yc)HtLgpk?X-><NIyXRd?yDU-udzVqUoF-J >zk372Y&{WO6vP2ebO3=K@bXhzvQ1ds&$dYmKQjp^#OC!3-GWS<m-qw=Bunt=I{;3qT >z`K(3tm!$aJeO+;)QdZX0=&Fhfy1Ht&t|>mKC0k0=(X2^R^KzKCSMz`QvaI%T=6qRg >z#A^2I>EG4S(z1Sk^4pYDkL7Z6r+ds791h-G4u|LOr+J0>L;Ey;vA<(kKg=~f{{2Yg >zbR#DmIpxSnM@~C(;%&{TM@~L+`uVpMU~4KsN<eBria@GB%0TKs3PCDCN<nHtib1MD >z%0cQu3bHj7AtfO-Aw?loA!Q+TA%!88A*CU;A;lrpA>|?UAqCo+3Xu|RO^ryANR>#L >zNS#QbNTo=rNUcb*NVQ10NWDnGNX1CWwx(vJXj@Y?QZ`aIQaDmMQaVyQQan;UQa(~Y >zvH-{mAWL9t)&N-qTeAwtG9c@KECjL=$WkC{fh-2H8pv`W>wzo?vLeWmAZvmwimh1{ >zWLc1PK^6vC8DwdYwLumKSsi3~ko7?p2w5RyiI6oy7RlDE60%ITW}T3QLRJb{DrBvY >k#X?pKSuX4Uo-S`QY5gMDG-qm5XiR9hGc_U{!=k)@0!L5Jf&c&j > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin >new file mode 100644 >index 0000000000000000000000000000000000000000..b4f2a2af6de4526f909f743425c0858d32cd14ad >GIT binary patch >literal 2335 >zcmd_qZ%kEn9LMo<`IExPeZ}CKfKWF=><X8^i9u#pU<PQ)%}6CA5VQ#6Y79!lk~!Cy >z`|23XA^9i9tQqwHZ4I^AztKVx>}F`LEmveU$7W8dvHHDFTebC|XFciMd(P|JGk9>f >z`+57;Y^q7O{&9qvC!8F6&B=Y_4s+>>aIWtPT%0&C)~DS)$MuzWR1dax>R?!d4viPd >z+1H#pe8elC?#q;OFD1%|KUzjkbXcQhr+17VULm8GGAGVg#pq{6E)C?2Bm`>5HE?u` >z^?7o?TyW2kFTy%xEa;4mU2T%c;m(O!B}?VDj9)a$^@B#w`cj?2XVrQAw9dZrrrv)3 >zkj{C3ug07_C9%i)B<{dLncJokzwJdysPoGm>#F3=VxPEj^W`pgwj{<T$=wmNB`MUa >zNjEZe-ZzPw9EjHWA5PPI`X|-hb5$3#U(}S=Pc(JwN%d5}p=sq~lJ4)9jJyHKT-702 >zaov)g-Xz&mEwV7CT^C-il$>81b<ruW+;^!=b9*Z^Z(xz$ziWvu?uyk1YFxUcHAfyS >z2vu)&j4VwY*L?4k6oh`Pg|4rp@Y=VsEclEp8y=L0uDmKmeXmRL(7Rf)r%je0JFF|} >z>*e9Lox1YTmvvR$1}(j}PJP9N`iOJ6u68Hu>YE-diz<+^3z7QRjd`->#80|55H9Nu >z&6M)~ALa3u>r&A^EbA)*Qn~$mePZ$3QdK^r)$#jfLtdZOOh2x*ajLc7b?U|`zit|A >z)+aCf^r@q3weF(^d3txA*7ugm=8f_C%&shHSeYyS8mDYYn=4!Mf0k!wTGE&rrHvC` >zOVf;-+H~#%X}&h5&%M<v&kqmiw*Bwv_P%a?p}9v}_Oxh_BPclJ&sV4;gpap4>_<V< >zrvLXZ%Zk`-e%DrPf+NJTW(Ys^zu(XIIBvD9Kdyg0FD~&}-uzN7oaU1`91in#aAyvO >z!}ssg+GqaIp4O!OKbG~IIW`}uoJ6K(YvzVb4w)S?J!F2!1d$mcQ$*&7OcI$TGEG}E >zPh_IDW~R1gs>ocC$s)70HPf{<^F=0%%ov$6GG|*eX}%`2My8F-8<{vVb7bnaX70%3 >zk=Y~DN9K<t0LcK70wf1W5|At)X+ZLTBm&6<k_sdjwk8=!Hjs26`9KnaWCTeGk`p8; >zNLG-vAbCL&gJcFt4U!vMlN=;FwkADDevkwq8A4Ko<OoR;k|iWfNS=^HA(=u_h2#oJ >z7LqMnlP)A*wkBan#*maDIYW|$WDQ9hk~buANam2#A-O}6hh)#zqz}oTtw|t~K_rDp >z4v{1xSwzx^<Pk|El1U_$NG_3NBH2XJiR9DPBoxUgl2Rn6NK%okB56hPiX;}vERtFz >zw@7l4>>}w!@@s1njAYo>q!`IDl4K;yNScv6BZ)>bZT*ir9c~)FAdQ;4OEOZjQatXG >KG!Ld`g#Qj|*MPME > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava >new file mode 100644 >index 0000000000000000000000000000000000000000..ba82f311b74838347de6dda464a22e95a16e0408 >GIT binary patch >literal 2338 >zcmc)MdrXye9LMqJfXHRazG!eru7!lukvoJ2nH_<lU@9jgl|V(*B7&1KC=E;ITx0I5 >zGMz)xjInA)ZDFmUwXUOucs&`GYs-~s<=o6kHCDg(6ERx;@AGiZ>&L@(Ha0%*;aRr6 >zCd2yQ6=a_9;@V+eoWnMow~k59st(_|tNVs}w6p85zWl!G{?<L(AKah=7Z=E}*PS|e >z&@IPzX32>c6Xm2gLQWohr|Q(IKsmiRTF(@pk~6z{<9&YKcwb4be3jfQXI<0e>)_oo >z<fxaSOHCrbR@aABC+QSVq)siJC%0w(q2UQXYsA!V)#-mso!36l$O~`j?WYguv`=<u >z)RChSeW*ub_U)J0HkG)IFGzf?SMFG`TJ9|INJ3tLOn2o-Vsw(+H7Qb(0^FK(Jxgc& >zkf_PN2)+BWK)t7TSY2J0bY}ZGO=<m7Q#TyZwCXoCy<$i*yuFf{-zQm1c1w0lr{rWb >zNzO=%<VLk??)jB6>(54=ebg=YeN(P^-Ibc(H(T%DI#=g(MC$`J2|BlRmONM(pzi7@ >znU{D`3)~}881RJ_C447ESALXY|Bs}2uwUk1cvTkkydfn6A8P6LHd%P+6@93#P8PLo >z(Z!Fvq)TeoXxY8B>M1GGhn)*`sViBR-bmB(@Iom+J4GM8K0}th`<pKJg~*BnVN%ii >zi#*nHO)A?5rK-{=D>q%%Rde2x)fEF;9k*B3<o9Sz&|zI0qq_E|J-TkhtLyul_3`r_ >zed4v{TKjo}Jh?4j>$=P2sdaH$zcpJL7Uzk##wkyy$I6C+-{qMwOBz$dwejlr(iD0_ >zn@)Tx%~yu>*|)ppxxqf&xc6h-)YGZYH+N~v_7?SX`1wy5yB+2jF#5o6V&JW~Eo<^N >z^LK4U$2%riR;XCP|2<olWAgYXi%LC~yP%9Wk5y#8F_*)^mwh=Lo|`Yqd@LVrU%N)n >z;lra3{xVl=@y=naJ$~7irSUy$Ll%du4p|<uK4gK&3XvruYeW`_tP)wKtyw3sP-LaZ >zQf<vzk;U4Y)gsG9){86{S+T8IGQS>cMiz~%8d)~7Ze-!e%8{kpnzbW~M^=w4A6Y+A >z0Hgv)36L5fML?>6lmV#&QV66HNGXt7*qUM>)j-OD)B`C9QW2yiNKKHUAXP!ig46{m >z3{n}SG)Qf1O>vOw*qZVn^+5`RR0t^%QX`~DNR^N>A$39ug;WYD6;dmtSV*;OO}UVI >z*_whO6+=pf)C?&aQZ=M(NZpXaA(cZ)htv)!9#TD9Q$D1Awx)nc1(6aWHAIStR1qm7 >zQb(kaNF|X{BDF+{iBuCQCsI#aQ&6O$NJ){JB1J{2ij)<pD^ggbvPfx>+9Jh8s*98t >zsjsamFj8S#Q(~mXNRg2$BV|VFj1(HFwB_(ORSp=t{mgOV=mY=2pj&bO+i6p4(`i#{ >y^DjxLSpT$n>}*;bHvXq2CeSx4_V{F*bBKxg%yhEuD$PvEPDyi>rl(<QX2{<symJ`< > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels >new file mode 100644 >index 0000000000000000000000000000000000000000..d8f19a6312a2c271e09103ca2674b33c6c33c439 >GIT binary patch >literal 2970 >zcmc)Ldu)w&9LMo<+8&ppzF1qT=4@S8ta@*U>0GJ=t!qc8u2aQSSDi^~C|P5S$k!r6 >z${bW(Mwzv4E#_VsosBX!k&rRlV$Wv6wlwy8KOz#g#D9LL&+|H`d7A#yzCURrCTGPs >zo;Z!nceptF%*FeFx#qT_SKqnCjYD&bYcE-=E|%%)k_!EFuj-nj<+`TkUX*9-25aq{ >z%G`Ak&8_t_Q>>EsdDe!}A-ScY@z%z$Vrx?er?t8MY-{taxZEu_##o<S7-Vfd(Zkwy >za-&tYF~r*L8JN4{LzngW!YS6y+!W6jc{@GjgCaZ?eMh)=MTuv3%nZ+-rhj<$+`s18 >z``bCszVnORmEZmDuByK3-oNLp`@ouoo`WkY++P;Ab|1=L?mj$ef%`~$f%|B;NYAlO >z8Sdj<4!KXHpZA=&)X-Diua*1Mjs9|abD-9&OOmfYj*~MP2gjbt8Li*s1<1Dpy6f4c >z-Q`^W5N*<-F1Ja^c=cNpBu$HwRi-Csv&=AUp4L)Zr1p~MV*ghEkY6;Q#Sa?jeOd!= >zAJCT9wri`i9t}FOR9jc=m*A~s(q`2fd491<+gbC(ot-Byj2tg7rld(o*JODqJV8Q( >z!{p`0EhWsAq+xgBwB3)P+P*eGI~=R8uaw`@@RFO_aoHt}DEdkxr&noI<~EHUbx~sS >z$|W|jQsRbuBJpijOF~S(B-9m3r`F4~)8%o}`JWluWq*>q_I<i`EghqYm0k4p`8~8- >zaj<sJ3eg@#ouy}QmnLPlmR_MZG&!kGdb>_)pO7ok=hk)U>wQT2)>KQsYwM+d*%nDT >zbx>26ES3RV*XqEW92vCu106j4BOQ`GL5IGYt!XKJ^o_s)IxM`s4!awr>HfVX{X%nn >z^G-V%vFlIGsP&bRo@O$t{8t%Wcw5FStC6u|YGvH)pY^S7yJh^SQ<~X!rA$aH)2s#+ >zI<bxF#GjVyq`EwvTwS1VUry60n=&-}_%xZiAW?HlhsryX+G_6nc$qf1tK?+`%Dd6e >z%k<>G<h^DNnGxx)GpwtU?{`=8&m5J4TNicaj#7EQrc!6EJgl?JR_mOC5-nU(s7^1J >zm$#3%PlI~(pZdk~-Y#xFUJZSp)yv`V2{Qkr93O|nPaF*#j$pU5@#F8E%^p7U;K@hN >z^h`~23{OsTB-z(cKA4+1PN(@Y$NoY4vor0#+hKm2gNsvTF5U;-<C8h}%^9}q%5|K2 >zGrJUN3epu@(-x#JNMn%BAg!@Ay+N9TbO&h<(jTNjNQaOXAw5ExgmlT)v<c}G(kP@; >zNUM-uA<aU%g|rLl7t%1KV@S)8o*_*`x@K$IhV%_-9MU<Ybx7}!<{{lf+K2QHX&}-; >zq=iTiktQNtv^8x+`iL|V=_Jxhq?brDZA~|kb|U>m8j5t3zX4imYkG<_73nI{R-~^; >zW0B4xtwnl^G#BZvt!XdPU!=iEhmjT|Jw}?0bQx(g(r2X6NT-ojBfUnNjdUAnx2@?n >z(r~2XNXwC)BTYxTj<g-=JJNWh^GNHF-XqONx{tKq*7P6Q09&&I$QB@bfNTP?3&=Jg >z`+#f&vJ=QwAbWvq2C^H-b|CwKY>2Jd5oAkj&7L5eg6s;iEy%tg8-wf&vNg!wAe)2i >z4zfMS{vaD<Yjz0PB3rXZ$R;7XglrSCPsm0gJB4f&vRBAvA-jca7qVZ-h9NtKY?-au >zGi1|{T|>4F**9e4kex%e4%s_o^N`&`wh!4qWCM{MM7Ge@>>;v=wq_TRZAA7F*+^t3 >zk*!4b64^|L)62V_w~x!m)v$hpr+)FgPd#ofZ{J4G>h*9n&32mAG{>x_pRikI7v=Hy >vPXC9`Jb3caGbv^}|93y17*OWa*UW6k=p-|-;i<6^@extssnJmw8SDEm0cgd8 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest >new file mode 100644 >index 0000000000000000000000000000000000000000..e0eac4ce33159ec614c51379c6c48935a114b470 >GIT binary patch >literal 2221 >zcmdtie@xVM9LMp`1y}6)u@4e~0ivRTcEACmXy7jbvN%OKja1}oA!41BsO(7eZt0v; >za_@|3mTtHlvu4B}lo=YSWVE@Hez?{e^Sf--nzJ@?)*P$P^IQKk*ZQZwdf)CIx8uk7 >zgV!^#d|gAny5-``Cp@{`=E?i`h<Q2D^I6=<*(27;pAK2?Uw+Z*ySU9dHTZ^o`n^}} >z5034z`(J6ZKisw6J`-AHpKV-ZpR1W`4?L1*e^fNlKA)9ff1Dg^$G`QdHKy9GO7Pz~ >zbZ^0sm6$Ocxi29aNs8%@B#rb$lCK<zjQxCH<o<KpBPpleR;kB3RobDK)VTH+RC?P+ >zH9lCcCahelCRUcKjN%z;k~d3DP93WrxXYt5-G!0NaIc+t-D72ad()co#Z_zSz_9gT >zZ`AT0?YFWgb=uh-Jyy<+m#cC&?X!IKo2&9_yY2kuEkgw*eR|rG{kkyiu%4bD($h!7 >zx+tYXiiTI~nKxTx*6C9H(APCm+*KzfeY0ft&UrHDwN#ngkRkJS%+&MC-BMbgq9308 >zy_A)X>T>rdQju|4S6ur}FNis#7eoj3qgP(nk9EJPD=+kme{Z{9c>IVgYHHF|?b~JX >z<GW=^aE(;Y2uh%`LY5{ilx5y2vh0RWY7)zJ&6i{3iR)Q<`MbZ!ic227vNK-S_FmPi >z!Xvt_BdV>sOM3OzALYq8C-hUb7o<M@pk7nbEe&z+$l5fKwLct?#?fY3H`ppq4+rF# >zV=E+heuG}Wt3;Z*s`ayt>GIspLcL*ev2Jci(i`)}=}l$7>CN#<x8x>D%g^8F&^<RK >zG&G=FuYD!Y_jKtk(LQNAcviM{AC_&cM<u*BEH3wLF@Jx=x?^wojPLmCL-SQ0x8Lz! >zKa@%inSWYdW0jifbD96+)bZ->e|lf(52*R(SyoofOThf7%k}4zU*mEG{(UZc%r`o7 >z`IR3r_q(~^MLQ0e4>BP~Gb3b5$efT#A+tiJh0F_?7&0?tYRKG>$sw~triaXrzljMV >zGeo9{%n_L+GD~Edj%J?7M3I>yQ$^;=F<Fk;a!i+Fz8n+gm@&tcIp)kUX^vTQOq*lg >zj%MPHX6DG$k+~z2M`n*qADO?SNdS@oBn3zgkR%{kK+=HZ0Z9as2}hF(Bo~e*8Avve >zbRhXa5`ts|NePk@Bq>N%khCCqK@x*x21yN)8%L8IBs-2KJxG3#1R)thQiS9PNfMGJ >zBuz-3kVGMwLQ;j~%F!eX$(Ex@7m_a|VMxZ1lp#4ol7?grNgI+kBymXQkklc$Lz0JN >z&(Wk0$sdwHB!fr_ksKmPM6!sa5y>NxNF<X;Dv?|w$wad0Xwr$~)6pap$taRiB&SGH >mk*p$VMe?ft$9?sf=w|1WU$4I)r!dEtTj2HQ`J8vtJbwUKI6@Er > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest >new file mode 100644 >index 0000000000000000000000000000000000000000..3ddf6a528983fc02f9ec0a534756e4d6c17e0e70 >GIT binary patch >literal 2405 >zcmdtiZ%kEn9LMp)zf5NCONLhigd#!;`FDZDAhR1V5=`V~Bodg2e<DI62BlHSTyxBQ >zYfOiTq7hj$Y76ZFS_##3ArVFf>M~Kl{xFK1W@GhxpC_&Lpl3bkoZa&}oO|z+J3eps >ziuJ{D)<2FZ<_Ry32J_<nrWehnahjvBv43!U_duIAwH(qtF}Y=X-i&D8Tf0-6clCwr >z`?yn2OmvlXk1UpxZ#lGQze~P&Ena$G4wK&N9%WxPRGshJ)=_wBX{&yf(I@>$UGjBA >zyPTf=hI})1hYWZg(}BxXGWb)po*B-Q3;Pd@4`u&ScyY_wvP;ge^TQS2jgR;pE*y3D >zS))I9>Wr*J>lWvA^$-0)XU;gQ4zH8ynD|g<4ZW+gPc`eUU9W1uk)slLuuXz?@0B@q >zD#4pxl8};exozcYxjoY@p~<OoM`WUe1%}I=(`HGyk4wX^#OvHkVH(jtQ}6n8ir(FR >zO(R<_>%96wjjH`zqbrVROwl_Un?E3N<?Z53>5%wkJ0u~fNfP6#ByqAv<_Fa4{Bx@$ >z>Gw)qaMUIDp2^kZ)&foGSfKZ9U8D;e1NHvmP+e4;BoCzdsH-SI9t<1NRM(`W`JB-7 >z&~GJuY*;e9j!8z(ad~Lyby?i@wq$mHq*>eRWXZvO`fzEfEUnw3*^h41WhHAg=bjRE >zXQt~TjwQN0GD4SMjnQ2HG|4@Evp#lZuB<rxtLF9l%F1Rx$#4Hr9<P~@g8CjQEa;b2 >zo4?m57JeYB^SiYuxIxyWv}y5;hjeX_>e|trx^A*u*B`Ie4d>kY<bgab`D~*+^-7AC >zw&uvw>w>jxYl3XdPL}dwhddKIM=DZ(lV|-bsf_m5%JB<QHT|kq^?oANV*~o!d#&<( >zPls-5=+w<^P5MH0i`HzfQBMy~FK=@(r?;0m?Z3I<v>)@9&kg_iX<2?3&Huj@7~<h= >zS<}Uu`uF?4o@8dZEmvv|7dPMVFbA3&_rI@gm-(Q*wrloxEb9+*Y#4h#5LutCSs=1P >zWQoWcZOtN)RU*qo)`=_>St+tqWUa_zk=5Fo<s$1v7L2SISu(O_WYNf~k!2(6wlxb! >zR*ozkSv#_LWcA4Mk@X`5Kq_EsO2E%W4LB$QQU#<8NF8iVA&^QSr9f(d6a%RSQVygZ >zNI{T_ASFR+f)oX*3Q`uNE=XZ)O=XbMAhkh?gH#784^khbKuCp<5+OB0iiA`NDHBpB >zq)@h|Qb?(6O|6h(A=N_4h13fv7*a8$WJt}Bq9Ij7%7)YpDI8Kcq;$5Xc1ZDTP4$rS >zA@xHFh*S_MAyPx6h)5NYG9q<E3W-z_DW$EcB~naVQ%$6tNIj8)A{9kSiqsS-DpFOX >ztVmsv!XlMLN{iGMDXy)lE>d2kzDR+Q3L_;(YK#;asWMV#q|Qj8kxC<_Mrw@|+tySY >zDYvbuH&Sq<;z-Gnnj=L=s*aT1vQtjI|Ced^HMO4?OZOwQoKXo;F_BrZF&ORi{S!K& >B&MW`` > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen >new file mode 100644 >index 0000000000000000000000000000000000000000..9c2b600b103dc4d1f49b5f087055e19d3e031129 >GIT binary patch >literal 1918 >zcmciCUrd#C9LMqB0S*~U_N9i$0t7oE{yFj=LW4|?z^DVIoRk#AKL~0>K}Mh$G#PV^ >zxvv|mxnj{|%sHYiP%rS$(sHK6+KM$S=cY5wnsZYI)>!@CPdBW(_IY-m*K>diE`IM% >zaQ%+zbn~CfZGXat>mB>yeP)||T=eWT7q8WuOA`Sze74j?dw<hePyDQ&&~Mdq@3hXo >z{<%K+eUCnM?x4n;JSDOH0}}V~Co-o~CBEf7NvLg*x#e5s=|E7tx%o2Bmo160NizSj >z*^=b;Ytne8F1V4X3rA<^qOTv(#e<XT>-|-ibY0fu_Dh<w>!hYueWqy@W0Kx5C>eP} >zlDXys$%^Zi?DQtdo@$kxm@dt^vRRh?*{I7-`Q_Q4$~3pHQuBtE>2n<`boocI`h2xl >zSF|scl?86~SH;Mx#G9J$pOOOiH(KbuDus7`k)qHqrD)`Wym0-nyf|=F0>fvt_&}$W >z^na=^)z!(%o%?k4y7zTW?KUlardET2LVd+kqHBE%b?ro|mPHpx*^iIwtK$n~{qg&{ >zVKhR@d!nRb@ORnRdQU35Mr2dvsBGSQTemDfAzLekwJQFQY|9(a>KVthCQh~H)`z-% >zszG;LXx5!qg8JH#4O)A?US8jyr*(a$^2YXfeX}D=>R0DVL$ycVN}D6Q@*l|CQAQe5 >zqP6kvHED{R(5COclIA;Oy8DYh*)uYvEr-tP-hpm?x4Bna5438C%if`35BoMI{11Do >zOl*QH%$P_qk4}GISsXO}{8Ao4{>tTY9>M=Vv*Grae7KtJhxe#SzS-+9d(FFhyAA7q >z2=747vZFoE$eBjYH5X?aIp4?`ceLjmIqS%IN6tKQ?vb;PoPVSNqywY{qz9x4qzj}C >zqz|MKq!UNm3epSG4AKqK4$=?O5YiFS64DdW6w(#a7Sb2e7}A-eZ4K$o(Kd&4hqQ<E >zhct+Eh_s0Gh%||GiL{CIi8P9IinNOK>S&uqx^=YeBK;x_BON0xBRwNcBV8kHBYh){ >zBb_6yBfUG?=8^6lZTm?7$Oa%gfNTM>2goKMyMSy1vJc2cAUlC<1+o{&W+1!aXtx8| >z4`f4-9YMAP*%M?_kX=Ex1=$y5W00Lewg%Z7WOI<+akSfm?2n_}AY_M-EkgDP*(79_ >zkZnTt$+$v8>>cKQ*tan=_#fCQyHIwg?AJ&!GpD}?>`wiAtNs})`;4&TwIq!h^A%?# >PXC<fliqldtB_rZ*zi7H} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau >new file mode 100644 >index 0000000000000000000000000000000000000000..2109b52a734c1eadbc8ffa4fbdd5e6a53fbbb60c >GIT binary patch >literal 2445 >zcmeIzeN0t#9LMo5@hBo)*NA5|OhCQzD2gRY;>8ruiy)E-o{|s+EmRB>@HgieO#>5a >zR;*ZSDw{G~j8f33Oj!|7W2=VN*_ve!)3eIyGFQL%Ay%zFT7UFkpSyG4c!y3mzc2FF >zY%EQZzs;dP;bD#X;p=Fn-(D_%CE$&YkNr+9_|Z6Zt;IO~#WP0tV4cy^*Jhr1^F{OQ >zv3=%ShilB<hRx>N)y3vJWh=~g3)9VW4<?%LrAC?OWA8FAgm{^KJ<Z1ZPu9Bozs_=e >z*cN<X;MEMr;KA9Bq2&jRpqQgWcZXa|5B3{z2mgF$Z^*ZSL!l!X>0$lNL*YHGR>bjV >zt;m)=)};O0tjRSc)|84>);()8t*Gp|*3|j2*1gV9Yg&ZA6+Qlz6`hf7#(1ZwnCsCh >z_HwYAZd@^@4}WjWI5+5?**Rc1UpwiZb*RIL+uQ7p-+s_YD5-KM7PXs6TXzj5r=5`5 >zD;p#wvPtG7ZIU^+D<w6&UZq~jlX<tw)O}}C<o=OmYW|U2mDcT43+j{A!j}S7dTEe) >zVDC&><hr3UN+!tSX`d-q#x=?G?p8~tek4n-ekw~nUzeo=r)Alf&q-E$i)8noR5^`x >zvix|nTCv3t_x>uCyShfLtXQq`<`%2`?0ITcaJnjRhO2@bQK~Q~RSG}xQV(4ZlQmsm >zsfUMuk+rR!Qq=jm6z{$)>kjpbvF?IAQhQN7y0A^w7oAllllRGEX|1Z%@2J`kxkqid >z^0X?uU7|Mjm8(scGFADp9940Cy=-oXS6hy_<ngkJ>WTUosmzU&t)=5+TcSg@yS|eu >z#}Be2-dF9ghNU|28&y5jB|EQvpq}bDEV~9ysG1i#Rc(8ds@wUz+TB>GJnr!J^!n?| >zXPmE}uitq8(O1BPKVCliJH37W!<R_7pZ<?5VLyqNNJzElU(HDH2oQ;wA`{2nM?VR4 >zND!ZRgpR$Zrh81{`z31Zee9F5KOs9OUo!NwNIx!D9&h>s`_aG1$y=<SEdBx>9;1)_ >z1t0u*`Tu;EP5S%oyS(}PZ~RrSpsVjD<xVNLO1W3N`erG2OSxUj{Zek2a>tZgrra~- >zrYUz#xoygQQ*NAc=agHg+&kswDR)n~eaih)44^o`KMM;e9#BlMt6iYjK=FZM1jPx8 >z6%;QhW>DOq*g^4wVhF_%iX{|JD5lueu25{Tt9_vuLvhBgwua&j#T<$|6niNCPz<6t >zM6rnC5yd2iOAMPBKH1eqF`TlitzvjZF^l0A#V(3p6vHTvQ7of)#xRZI8pAe<Zw%uo >z&e_%0F}$;@&11O7u#e#%#XyFG6bl(1QcR?{NU@RPBgIIHlXkV06ff;+GbwH|?4<a~ >zFqGja!%~K)3{x4dQfy`TN->t<EX7)iw|2F;6n821Qv9VDOmUcDF~wts$rP6vHZy!? >z7|n2+VKu{RyV`7q+jh0x48JLcGaRQ_PVt;#I>mMQANGF_yTAT%Fe`~449=Y7xRkgA >MXHH@QjZgOf4F;`^qyPW_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen >new file mode 100644 >index 0000000000000000000000000000000000000000..be87cf162e1a1a8470574ae2c62b92f61589b903 >GIT binary patch >literal 2160 >zcmciCdrXye9LMqJoWl_#WnVNn7B>qCts{5H3utx(W^%l7R8kR5L@6RUDT7ieGv*p| >zUmeRia#=Z6O{hPp{=mz$%W&b5vNLAobUL-$%*~uuWA%GKj^V1m{XKi0*Tciy{DaRs >zu&ky!+xpLmG+($mE#~HZ^vmYap47UkJ$$6U*SB;--<7#?@_mnn-toz)-MP}gEmgh_ >z#>qDmL{B%pCf~+)YItR*gwLIqfszwCaP+v03GKNy)<0YB%lT7dQ-0C7u|KHCby7Xo >zkLb9IAL{+5_v-_n?b7%|hb7@)mn6RVmL#>RByWC2#@7br!4+%dq0)e)6cot>Z@#1^ >zq{+jh#z~snr)f8Gb>gK|ofMAKN4|*EN4syS_rOm&x$Qem-~N?mY&@iyRh^nuaYnL( >z-I7z-Be{#-ki5iwlAqlu`Gd_eCB99koLwzb|7y@_hkY{r`*JPlsMNxqX*#22md<QX >z(8sG&bk_E%@<g#)eO2)?JN1ed`39xfeL_o8&PmDD%QDAxOy-1o<;jch%G|CGq_pp- >z`ggX<yn}D+{JJ_>(E6$_T>82$s$HvPkJW0Rv_uzs=IIjeBwcbdQ_EwErF>wFK6PWF >zEc@hlT^^2-75ihPqWf1_*?e6p+d{IcGAygN{H#yU{8ZLd^l4S{URhh%rPU)p)^&-h >z>wes$>j#5c)7zxaoDJx+?=9EbFYD#G9fexgQ6|r?Pu2}Bc~ZZyK!VjCc_AxFHWvLM >zn_?_!$cWX3YZs(3`ldGae=bc|&*+OEb;wJh9^Jh6xNhm%r(2s2X!Fiybvm35SHvBc >z(>>zuUzT-mpZNo|62?0sEGt^9dxoC3zYKr(`2&`(sEkK|f8j6(%}e0_=P=UzlAE)` >z+`Px!;wN+dHm9cLR5#X-`YjikiLIFmG8ber$ZU}5AoD>cgv<z;5;7-bQpl`q&9snt >z*_w&*e`03H)R4I$lS5{QOwZQL51Ak`Lu87`9Fa*PvqYwe%oCX?GE-!#$Xt=hBC|!N >zi_F*7Oc<FlGG%1W$fS{3BhyCajZ7SwIWl!*?#Sek*(1|O=5K2ffMmedqyWhQk_03R >zNE(nlAc;USfusV-1(FOT8%R2kd>{!yGGc2|g5<>3Bn8O|k`^Q{NMex8AgMuegCqyZ >z4w4=uKS+X*4B46#Avv-&NkX!OqzTCrk|-ooNUD%rA<06rg`^9~7m_d}V@S%7oY|VB >zAz4GxhU5)N9FjRCbx7`z<RRHZ(ud>^Ng$FzB!x&0ZA}u9EZUkhB6&m-iDVK<C6Y@d >znMgJ*hs)`5M!4^|Tq7dy{xuX%lTQ;)lSxyzXt72QJ#T**{$5Hx|CP|;hMKo1)78mY >U6xQp{NzY5q^!l?hF(W7HA9HUhBme*a > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin >new file mode 100644 >index 0000000000000000000000000000000000000000..655daf37889fd12380c7f055f2cdd85dd4665e03 >GIT binary patch >literal 3531 >zcmeI!Sy0tw7{~FyAqu#?np>js8g3Zk0hiPyat}pvIVov|mZByZk};qeIhCd3IFAiw >zrsnHTF1X=}<{Ii`E-5a!Yc9C2i3{5M{nvEUMK@k_(K&O@=XmCD>F@h^dk;y7aQ^WK >zu;1|Fan8Q@T=5h8Hnr}GNmCD&DnD(H$4sBI)qFo~x|uP#nlYcR(=$^ZnOOs;>Di-p >zm^ra)%-pDldTvIPGp|lRJ-=SA&TJ5>GcOmK1<ro6Ag_{MSa3rx+McKv@BCF~&5zYf >zOqyBxg-0*@YOh(I6k}E-FE`m;!_3O)-g=csnbi>~W=*+UW^IKyv-bJ{v#!9=IfrlR >z^+$W@4Qux6AD2Bg8^2wtH%$%Hn^Pz2EhCHc*0?mit=k;)Q}aGLx8-KNJ?@~{p6_oC >zM4!@mHEWrJv5WMf(E9pt*hGE!{?|IcY?98ud_^BUSH&FrdAB~k?Y=pYeaW26s;p0C >z>@ug5Uo~fjj?ibjH!#0>#hi;MZO%t7))xXp^u>x^bMav*T~IV!U&_C#FCXurudLgn >zudaAtu6?&mUmr8b+?X+1-|Qc4Zl%ZT+no~ho%q)JZmlxr_o!ff&$(_2gM4-2seR`D >z;|u!1rWNMlMIZBM)Iw9VJtxU0DOVQ{iPOGaGj$37mb#>8ye?T#UHhv<?Z4x(4!9Ak >zOD(TvO7HdPGLs&evP&!Ia>Gv;H6_fH@3zTQNK@w7@L8r}+$~cn__9=Po-0*+evztG >zGo|X;CGuS1c&WB^k_4Wfuc|M~QZ+V@Q#B`u3Ys}o>BMAJYfKmQe2iBG_iv<Xhc;7n >zI(3%1rK_rX4H`<lyG<k{pqzx{Rh9+?H|2%wLJ8fuUm9lQOV|%9rO}A>;u$wt!uuXk >z5y{!Aab%8a()}CNw8nJREFx7kD@s?*12d%g@&2mC!xU+`p{;u9Xq>c~7cY@HE#>90 >zttDz|b$KNrSXzJ9Lbd7OD{Th^s&;iQNc*-$s)O%N=@@)cb-Z?7Mf+@4(Ytr3PG@JU >z&RGjo%&v{nW#R-CyJ)7oHf)&cI^k34)@!_UPaG&cUQ85kOh<XWO04t@4UwMrJQ7!_ >zgNi#;LEgAqU-e#fNBZOis5eb{)i?W!dMo|5iqF`s`o-s|{-ZC++fl34JAHS_fS@UA >zU}Tmg_^p&dHADtooGgQjl4Zz_G<o;9SB7Txk;L5L>b)-`W!StP>ixk%k~Frd8s4py >zN=~SvJ_xU=Mzp`LJ}mF3ltz^#<;EG6TK1l#?%k%+t{st)OXsOkyL05DDO+T8)^zze >zZH}Z*OqXKM6!-c2S;DvYQ-1oF^!pDypFDX`+i~oBIj6Ye_yra7bDXlOSZTXQj-%Yq >z_M1OHJ5Dk88^`^P;}_G#>$J14=pJ6DjeT{rpY3n#!@jwH<o?s~{`(M~x4(3Uu<)<H >zdtx8G_5~b6hSAlIBQlW4NFqatj3qLd$Y>(NiHs*QpvZ{2+95^86d6=xR9)?`BID|6 >z2NoGwWN4AGMFtlcU1WHX@kIt08DV6IkugRF85w0{n2~XIwF8ZeG&0o4SR;dtj5add >z$ao_Ij*K`m<j9yKgN}?kGVHE)+>wDtMjjb@WbBc_ceSIB48N-#e<T1%1dtFQF+hTV >zL;(o{5(gv@NF<O@AhAG#fkeaAh69NQ5)dRJNJx;FAVEQ*f`kQ$3lbP4GDv8U*dW0{ >zqJxCT)y4-25E3CIL`aN~Ao1UTC?R1&;)DbWiIl4i6%s2~8!RMRNVt%AApt`ohJ*}> >z84@%kYDn0SxFLZ<B8P+yiJhwr9uhqyd`SF|03s1YLWsl=2_h0jB#cNLkw7AmL_&$g >z($xkNiKeR!ClXI2ph!fKkRmZff{H{H2`ds;B(O+ik<cQsb+y4oqU&nIi^LZRFcM)T >z#7K;hAR|#m!i>Zj2{aOEB-BW(kzgaycD3O~;_Ye!jzk;@ITCXu=t$I&up@Ct0*^!< >z2|W^fB=|`5U2XW0_`BKz067AXLjXAjkb?j@3XsD9IS!Bm0XY(oLjgG!kb?m^8j!;Q >zIUZc?0f8J5$RU9o6Uae<92Ll6fgBgefq@(u$f1E88_2<d939BvfgB&M_5eYS5LbJM >zAjb%DkRV41a+n~;338wyM~d_Rm7<=`l@egjn1<o@hVg`U3HO9G4YM|eM&SW}06*^b >Ai~s-t > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar >new file mode 100644 >index 0000000000000000000000000000000000000000..a7105faaeb14ccf0a5d3588e74be709fab224275 >GIT binary patch >literal 3061 >zcmdtjX;76_9LMo{L(&+>j!u9H>M=va5CNCm$P|$%AeWosuBoU=q+|pxQIlEIIL^O@ >zB1gz$5;_LBg!`5oxFCuMDQ24H?wDncnxdWW)A*`p8sGGy=b4AknL9l1?*0Be!zL$3 >zy8d?6x1aEEmD-1Mvv=*Eg>8z=!WwU#dobMO<?l3K=H{72In9juV544~e%E|8Ay+S% >zxyR%ut~X!zx}yt%#^|NNrFvPrP`&K(EwkKJWtLa_>TfPy(}iUzx@hlVUA#0=uP~Wr >z<%i*V)u)Hd>Z$SO+qBiDq<@%M6E{q+4OeDeWV%`Z_-|%IlO(g@mm_B5MVH=m^jE$4 >z_z=BieU;w2>Ymy5#TxzH!T`NJBS-I;QKxq%W$Il6^3Cq9!*yx*?Yb<f#+21QX7>5D >zk$pKsWq)N0DSx|%99ZR&iZMy*pq!RNsiUMa%}-U{iByLt-_up&Ld=o4Q@XlED^uO4 >zPO49yQZ<Q%y5^pjIT|)!AHDsVu5C0`*IvG&kDv87KkTp2CwAR7KbBlFCyV{`sqAv| >zQ`!sW^pxrP%)oZ$XOEb(kqyncs3LtnAVgny!ejis4v7Ett<v<&3VE{1NVA=vNWkVT >zDzLCvHP2n7TFevGa@KoFr=+P?BgUzx;ytQ$&lvS|XcrX}7_8bfY^s92qb2x8Cuw^& >zNJ6Upq}}fN@=VDs3C+JK?XznoY|eh^FnzOxk1vvlk;hbIT8ZiywMlgv__^xbJWq9r >z%urqGvQ*cAZ0UMptm<|rUAk|HRy~d<Nza1O61AzjJU6$u^ja7w&nLH*-gCOCKK;BU >zdVGND8+2Y`qU%&Y@4XV+`lO1zdQQc8ZC7y>d(?|(mZ+DCm#g^lZIUp5o=PlSEH9^~ >zs{ZrdmjOdQmVqe~WYDuI;)#!ySNs!YaA=4Oz8Nk_zWr3v_f2Hzjkapo+TUe(wT~KM >z8mo~dSJbGi>uPj%g&H%uT8*83NnY)>PK_H`F5_D+P!pnxCAq;Gnb=%p;)NWURF@`` >z_hiazCp<D`*>FiIou*#@C`wWb2B|kDwUnuIJF95}daAT!fAwZW3pG9FwtB0vOQm=4 >zmGo<;RYs$ml5uF4%Dj3^W~?kwGb=X9tOYw{c5$A(lbJ7B^Rwg;_ru;^?guw-di~S; >z^}HYbZ}0o}|F~;^;I2l>T@PIiT&_UvZpbID#?IOIuXB8Y$JJ+$#}$ix?IAjb#~xg6 >zx7$9>>u$H_-`i4V|J7;BE$1DV>%P5)RQl9ITH|PYgER-}4$>Z^KS+a+4k0Z<dW19y >z=@QZ=q)$kr9BrqNRyo>UA<aU%g|rLl7t%1KV@S)8o*_*`x`wn3=^N5Gq;p8?9BuEA >z<{{lf+K2QHX&}-;q=iTiktQNtMB0e-5osjSNk`jCq?eAinMgO0b|U>m8j5rjX(`fE >zN841St4Ldsz9Nlvw4HUdtwnn4Xq$_4*U`2Y>93=0Fw$Y9#Ym5lCL>)&+KluWX*AMl >zq}52Tk!B;^M%vBSmVP_hh9ezET8{J_X*$w%r0q!Gk;WsPM_P~c9%(+(eWd+J|B(%F >zv^#)o0kQ|kCLp_jYy+|n$VMPLfouh`7szHHyMb&6vLDEXINBXSw#3oy39>23t{~fj >z><h9n$j%^JgX|5mImqrH+k@;6vO&lWAzS2V_Xyb}N4rbNHX-|jY!tFn$W|eHg=`kG >zTgY}H`-N;6vSY}WIodr#HqFuQ8nSK3z9Acj>>RRn$lf8FhwL7*eaQYH8;I;6vW3VV >zBAe)FcM;h}WFL`@M0OI{N@OpQ%|vz+*-m6Xkqt$56xmW_PmxV^w7ZIItE1glWMh$? >xMYa~%TV!*Q-9@(7^{~^++&;Mf&*ST3N4b3js~nopF|2b~cxXaIICkjh^C#k8TKNC~ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey >new file mode 100644 >index 0000000000000000000000000000000000000000..4527515ca3f249a44599be855b3e12800ebe480d >GIT binary patch >literal 3687 >zcmeI!dvwor9LMqBn$hO=nHU-N(OjC={5BD438AqqmtXotj4)(rmX?v0Q>h%sdF!Yp >z<U?Y)%x%kMU5MsB*GZFmE_1(T%%;!t>o})#oKr`C_xqiB{Lb&^cR0@Re!e`th9*Y2 >z?s+_D-{FVH75l^M!1wGg(;6)@)Asu5>D%3A#+-HLtLZb$%#7N`e7IWAO1))f51OvO >z9<$NRiC<~HX;Y%-HteV8HO|wSO~Q5NnPM~FwcE@usG%1WUDOLVB<V$)cIm8n@p`dI >zGfO^l>!qLWFw2r-&GM9GCcA5d$%*NuzjG_IA}ZCata{n3s^>F6=R@i(EQ)-zEM1 >z{+IL*D|hQ3mzJ5IzR1yQrUmP@qcZf*qf7NVZ<=1;ZI1b+WpAC=dad5z-D@@!`kT!` >zjbwAi%d%x>J=yy9Q?hNTOY-}9)pj{5JBIg_ohd<TXGxUWHMC6c9uQ{s#2nTI_3E2~ >zcBN8q=&;%wzfkWj^ELY-Ch2`QKGTI&l6B#kvwHvWn&$T{`TD^68|Gm4X>%wmNFScE >z)f`EA-W(k^QXlKy#QfnAb3Ce&IT5``p9~Jur>c9*sgjDisC0xrU3gBPInYC&UA<kO >zTYl4=|8l9mFmAB9ICHGN)IY{tPEXKRIw$I@32pVY`jyR}Z9?^R*9B7?;-`xb?=&~c >zPU@R$mYb4OzUJ1L1*UXEZnAH3o-P;W)qY(wb$S2Rx`KOxu257*`>Q1Fzp+dQT#VNh >zm(@0vcDQxr$+t|ECDnA*5eJQ$8esyvtufWolzAv}wyEyDY-)s_k)W1&Qqy;v)T)&! >zwT>;8hl?jj?RAqS_{cm}XJMAAyY>@RZ=$G>S;Lf0N>TO4#i>VPJu0++Q`I26g=*Nj >zi!`cKOEqrtxHP`@goFiDm9T;!X;O4a9?LG4@J+kr@hOE8@okPY9r?YuKgkgH$p)^- >zKEJ7`lx)>3I#)f>{d3j4?hMr;YLseGnyy*~Pmz`f`m0tYsnYs~_UftqUU_<Mf<))G >zmS@Jdl{VAr$g_!|()NQ^s$EAvX+JPnJ=gH0bZB3yI{IyrPN9cXr}HONjPF_%lfO}Q >zKK8Zhk~Lq&Zv9E(CQVfF3unm-!-uP`6W^C^FHMl{NrR-vlS$%<?IbVOjF+C_Vbb%u >zTf8+oD(|n=<mGFRs$Sn+mEHvb>J<~H`edI~ebcX~gem!|UqXTEKlZe|+Gd3s&}XX* >z44JA1MQ2IkgE=y|uE^k188W0aMTTxnlh+P-WLRczNy;0cUjH~+hR^Mx-WU=h$>W== >z5#63vDTy`Jo00X@$PPEuTY)Z>+O&qGUOcKsRk<#scC1%v=YNyYOXjLE`ML7W)SqQ+ >z)(m+!ZH}Z*N|y(G?)T~IbN9(NeedJ@<;vgtoBhiF)3d@qefVELyM6n1j=f;6D$1uE >za@6W*pGv&rvhV!;eLjti^SIje@VGkRbM}SH$H&M1INwFjzu(TQcm5bxVDX)Ax$Ix! >zcI`g?Taa7oXzwX<Q<1xh+*ahiA~zPfv&gMQ?k#e2k-LlBUgZ8FH`vkMVdNG&+Ix)L >zWaKU*w;8$5$c;wsG;*tvdyU*|<ZdIk8@b=e4M*-ca?2g<Jx6Xja@UdDj@)<T#v^wg >zx%J4sM{YiH_mSI=+<&A2NCzBk3y>Z-+9n`fK-z%x0cix%38WQBFC1+%kZvIDK>C3+ >z#L;%d(Y6HXiKA@_(iKPB7NjqZwlPR&kk%l*L7Ibf2Wbz|AEZG@hmaN_Jwlp<bO~vb >zqwN#YD5O(JtB_tH%|g0`v<vAM(lDfBNXw9(Ax%TNhO`aoo1<+U(mAAcNbiv5A>HG@ >z8|_2-hcpoBAksod+e4&@j<$<P8<9RDjYK+$v=Zqh(oCeANIQ{!A`L}4inJ8zDbiF& >z+f}5kNMDi0BArEAi}V(0F4A43y-0tN1|uCtT8#7<X|kj3GSX&8+h?TFNT-ojBfUnN >zjdUAnx1;Sh4;qei9BDbybEN4=*Bx!!k-j_H#v`3aT95P|X+F|@r2R<$kqv<C0Avdw >zdjQ!4$Sy#(0kRJq?M6U$f}`CE$X-A;1F{>C?SSkDWJ4f30@)JCo<KGQvMZ2nf$R%M >zyD^ZR;b^x8vNw>;f$R=sdm#G**&xUcLAD68N03c|>=I;~Ao~Q_D9BE6v|9z)E68R+ >zb_=pyko|&e7-YvFTL#%P$fiMd4YF;JeS>TqWal{At%K|xN4t5D-Ggi&Wd9%=2-!i% >u7DD!r>wf1D6X@>q|3PH`740Ajuv5uxCsTM_vxw#q?xvC9aglCb1^fkK<6HXx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki >new file mode 100644 >index 0000000000000000000000000000000000000000..29b3c817f4637e98623c5f76a6078f18157b5cfe >GIT binary patch >literal 1909 >zcmdVaYfQ~?9LMp064tP9EC-b$$>pfi)vbh_aw(*PTvDjq5<<$YW15*Y``Q{a4AYt! >z@gQts?#8q;n>E9ljk(UuhGEwDz5kxrJn+osoSpycteu{H-yhGs<t6dfAFod4FMN1a >zm=E8Byyj8AZgt2#Uru4m)fa`qk!{{yJ$+t>{}r#}<5_R-=V!FfgQME_#$FA%bXh`A >zHA>i_Bhs%{C49?vi6||X{tK4KfGm$hrnqIGGg+cSqh(On-Vz;<uF;<pb?}QQ9n#uM >zhu-R}!<xRTv;K_^uY0U9HTN`j{Uvo3oz}SgM-pG&Bnhd_k~njpB!wN8<oHTSZm*V+ >zA$2;kZIO)nUZJBer^}cpd79EtpsCHHb?naZnszW$$CX6t_?l5NAtON3i$Y{#)GKwT >zw@XIAUCoSqDw*$J%4Gj*GTC=WraV6`QyWi8R?8L5-cu{nP94+fWo0s>c8BK7*{w56 >zi#2ydsd}<9b(UkA&UOyb*<W0m7n~t^4}0j`&x2*&`A<5(HBc5D4U+t(ce1ehqZHKn >zq_Ch>7Hxg2i_<R1lKd7e3O^vlsf}9F<(w`JQ(gLczb<Pp*X4JrbVZv-SDu)!rMK70 >zs$HpC){rZ!mxb$^ok_AbCq>Fj9I`I1pR9L(lMO+ZRKx~r#fN87+5L-F-oGhT?;q)= >zvkkJ@*Q{F(T-U9Qhjm+3y;kq3RzLp^_Pb-izkFMkqu3l2&yJQg)aBR3vO*)QZohxe >z%Jx{3%*XA{<>BG?mY?6Rr|0jdyV3m8KHabUi+TMpuiT4+4kD+FoHKIL{D!keP8&II >zTXW*bnIor;oI7&z$k`*OkDNb}0FnWc0+Iug1d;`k29gJoh^@&4Nd?ITNe0OVNe9UX >zNeIaZNeRgbNeamdNejsfNzB${hNNa|azm0svP05C@<S3tGDK2Dazv6uvP9BE@<b9v >zGDT9gHMt_m+L~;Ubdh|KgprJql#!f~q>-$Vw2{1##F5OA)NM`fNb<HOdnA1%e`ErX >z89=50nFC}JkXb;c0htG6B9NItrUID@WHM~cY#`Ht%m*?d$c!LUg3JjrDafoK(}K(k >zGBL=^AX9_P4Kg{lW_FP2u{HC9Ob{|d$P^)SgiI1LOUN`?|LHabnz0%l&ulrf6JnBL >PT(Jqx>^PVGEiv#Xi)pZk > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man >new file mode 100644 >index 0000000000000000000000000000000000000000..4527515ca3f249a44599be855b3e12800ebe480d >GIT binary patch >literal 3687 >zcmeI!dvwor9LMqBn$hO=nHU-N(OjC={5BD438AqqmtXotj4)(rmX?v0Q>h%sdF!Yp >z<U?Y)%x%kMU5MsB*GZFmE_1(T%%;!t>o})#oKr`C_xqiB{Lb&^cR0@Re!e`th9*Y2 >z?s+_D-{FVH75l^M!1wGg(;6)@)Asu5>D%3A#+-HLtLZb$%#7N`e7IWAO1))f51OvO >z9<$NRiC<~HX;Y%-HteV8HO|wSO~Q5NnPM~FwcE@usG%1WUDOLVB<V$)cIm8n@p`dI >zGfO^l>!qLWFw2r-&GM9GCcA5d$%*NuzjG_IA}ZCata{n3s^>F6=R@i(EQ)-zEM1 >z{+IL*D|hQ3mzJ5IzR1yQrUmP@qcZf*qf7NVZ<=1;ZI1b+WpAC=dad5z-D@@!`kT!` >zjbwAi%d%x>J=yy9Q?hNTOY-}9)pj{5JBIg_ohd<TXGxUWHMC6c9uQ{s#2nTI_3E2~ >zcBN8q=&;%wzfkWj^ELY-Ch2`QKGTI&l6B#kvwHvWn&$T{`TD^68|Gm4X>%wmNFScE >z)f`EA-W(k^QXlKy#QfnAb3Ce&IT5``p9~Jur>c9*sgjDisC0xrU3gBPInYC&UA<kO >zTYl4=|8l9mFmAB9ICHGN)IY{tPEXKRIw$I@32pVY`jyR}Z9?^R*9B7?;-`xb?=&~c >zPU@R$mYb4OzUJ1L1*UXEZnAH3o-P;W)qY(wb$S2Rx`KOxu257*`>Q1Fzp+dQT#VNh >zm(@0vcDQxr$+t|ECDnA*5eJQ$8esyvtufWolzAv}wyEyDY-)s_k)W1&Qqy;v)T)&! >zwT>;8hl?jj?RAqS_{cm}XJMAAyY>@RZ=$G>S;Lf0N>TO4#i>VPJu0++Q`I26g=*Nj >zi!`cKOEqrtxHP`@goFiDm9T;!X;O4a9?LG4@J+kr@hOE8@okPY9r?YuKgkgH$p)^- >zKEJ7`lx)>3I#)f>{d3j4?hMr;YLseGnyy*~Pmz`f`m0tYsnYs~_UftqUU_<Mf<))G >zmS@Jdl{VAr$g_!|()NQ^s$EAvX+JPnJ=gH0bZB3yI{IyrPN9cXr}HONjPF_%lfO}Q >zKK8Zhk~Lq&Zv9E(CQVfF3unm-!-uP`6W^C^FHMl{NrR-vlS$%<?IbVOjF+C_Vbb%u >zTf8+oD(|n=<mGFRs$Sn+mEHvb>J<~H`edI~ebcX~gem!|UqXTEKlZe|+Gd3s&}XX* >z44JA1MQ2IkgE=y|uE^k188W0aMTTxnlh+P-WLRczNy;0cUjH~+hR^Mx-WU=h$>W== >z5#63vDTy`Jo00X@$PPEuTY)Z>+O&qGUOcKsRk<#scC1%v=YNyYOXjLE`ML7W)SqQ+ >z)(m+!ZH}Z*N|y(G?)T~IbN9(NeedJ@<;vgtoBhiF)3d@qefVELyM6n1j=f;6D$1uE >za@6W*pGv&rvhV!;eLjti^SIje@VGkRbM}SH$H&M1INwFjzu(TQcm5bxVDX)Ax$Ix! >zcI`g?Taa7oXzwX<Q<1xh+*ahiA~zPfv&gMQ?k#e2k-LlBUgZ8FH`vkMVdNG&+Ix)L >zWaKU*w;8$5$c;wsG;*tvdyU*|<ZdIk8@b=e4M*-ca?2g<Jx6Xja@UdDj@)<T#v^wg >zx%J4sM{YiH_mSI=+<&A2NCzBk3y>Z-+9n`fK-z%x0cix%38WQBFC1+%kZvIDK>C3+ >z#L;%d(Y6HXiKA@_(iKPB7NjqZwlPR&kk%l*L7Ibf2Wbz|AEZG@hmaN_Jwlp<bO~vb >zqwN#YD5O(JtB_tH%|g0`v<vAM(lDfBNXw9(Ax%TNhO`aoo1<+U(mAAcNbiv5A>HG@ >z8|_2-hcpoBAksod+e4&@j<$<P8<9RDjYK+$v=Zqh(oCeANIQ{!A`L}4inJ8zDbiF& >z+f}5kNMDi0BArEAi}V(0F4A43y-0tN1|uCtT8#7<X|kj3GSX&8+h?TFNT-ojBfUnN >zjdUAnx1;Sh4;qei9BDbybEN4=*Bx!!k-j_H#v`3aT95P|X+F|@r2R<$kqv<C0Avdw >zdjQ!4$Sy#(0kRJq?M6U$f}`CE$X-A;1F{>C?SSkDWJ4f30@)JCo<KGQvMZ2nf$R%M >zyD^ZR;b^x8vNw>;f$R=sdm#G**&xUcLAD68N03c|>=I;~Ao~Q_D9BE6v|9z)E68R+ >zb_=pyko|&e7-YvFTL#%P$fiMd4YF;JeS>TqWal{At%K|xN4t5D-Ggi&Wd9%=2-!i% >u7DD!r>wf1D6X@>q|3PH`740Ajuv5uxCsTM_vxw#q?xvC9aglCb1^fkK<6HXx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul >new file mode 100644 >index 0000000000000000000000000000000000000000..9a53b3a39063e86859b12aa755b78cfb38a26709 >GIT binary patch >literal 2166 >zcmd_qe@v8h0LSs~aUAC%)b)e#2L33-Ls3H@It;<Wlc5Ja>4}@+_AJqKI`%DVt8C*I >z%*}N3aoJ>}IZ`4=&bD-ITIsP`!!UYMED2aoYqmKz{nnyi%&zbIskWMb)cUvYv*%vN >zaq!3OKJWOtEt^WkO=qfpg`3l^Z=Qz|`oY>g(b<)iYj#~cZ6DgW!8yF+1*4}iVZK&# >z!tN~$JFkb^?7pHRv+t`L_8UL%a*n>g$QWq5W)7tK?XxQ;%#Vf=#^B&F^W5cr<I^Xu >zI_I|rj0=Y<&EeWK<6<n^`E2eE`}5-K&ZWS5dnE0EIdY}O{^I%(bM$<(F*a<Q<Hz^f >z-+q76{I2DcJ+V2%{9$Iq7Tu>D&(`C1TH+PQyYgi_ealJHSN@if(fX3~R~||DC!ZF9 >zP;Yl&bg`4E{B~Aw$jlm<ZDjXUnz!`sGj8q3GlM&~8@E5+nY^Q+Lfl#RTr#I%JaJdJ >zIhpG{lbGhOPKI{vH$r3klldQBu%~zB7&G>4S2Le)QM0zKQFk{lSNFv3R|Qo?YWDn) >zD$LJRbEZzJurDmb6VqhT<$#<!{EM9T!Bts&Voc8O`B*O4-L4jPyeaQ}s#}({?30Vu >zzpF~0JfO;!98~42o>livPpFF0M^(j*$5bTm85tR0rYa}b$;I!@Q4fq($*SI3x#XQ0 >zvU+EstmzVR=_bE?up?hR6ulyAH~gxW6%NX1t)rryrOtBSS*xz#%V6ELZ-VvS{$Tyk >zKyby^hl4AR^#x<+&R7k5$F0VruUZecwg!zo?bah}U$j<j+i0zhoDRlgb=I2PMysj% >zpw;waiM95Vg+^N{mGXGg{>zo_`}0ckX88Z@<((3^>GJu6$Scy{NRhW$qzf^x#4|;R >z{8=Jfh{#gUZM-6K{{H%3-@|WX4RKMg?`U*24{=dkQm*eZ{;NJ7eSUxD{vhK2yp<09 >zPIoIm{qcwTqe?ZsJ#Y!x4zeFty&+^r$d-^jA)7*Wg=`Dim#f|wvNL3B$lhG_=8)YX >z+e7w;Y!KNYvPEQ%$R?3pBHKjviEI?vsjJ>9vR7oY$ZnDCBKt))jO-ZQE%UkQJp-FY >zc8zQs**CIrWar4%UG?5MY~EGx9@##!e^=cAqytC`kRBjSK)QgmfkPjVMj)L)T7mQe >zX@;xr2GS0sA4o%xjvy^TdV(|s=?c;oq%TNgkj}X3)*!t>nuBx)X%EsLq(MlBkQO05 >zLYjnh32773C!|qGr(AWbkY2g!W+B}|+J*EBX&BNmq-99YkftGBL)wP)4QU+GIal2} >zq<2X3Ty^)5_POf*Aq_-2h_n#tA<{&oi%1)hJ|c}oI*GIr=_S%kSKUpdo!F+o>*D_y >O(99|w*XjjjnZE%*@2d&` > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey >new file mode 100644 >index 0000000000000000000000000000000000000000..4527515ca3f249a44599be855b3e12800ebe480d >GIT binary patch >literal 3687 >zcmeI!dvwor9LMqBn$hO=nHU-N(OjC={5BD438AqqmtXotj4)(rmX?v0Q>h%sdF!Yp >z<U?Y)%x%kMU5MsB*GZFmE_1(T%%;!t>o})#oKr`C_xqiB{Lb&^cR0@Re!e`th9*Y2 >z?s+_D-{FVH75l^M!1wGg(;6)@)Asu5>D%3A#+-HLtLZb$%#7N`e7IWAO1))f51OvO >z9<$NRiC<~HX;Y%-HteV8HO|wSO~Q5NnPM~FwcE@usG%1WUDOLVB<V$)cIm8n@p`dI >zGfO^l>!qLWFw2r-&GM9GCcA5d$%*NuzjG_IA}ZCata{n3s^>F6=R@i(EQ)-zEM1 >z{+IL*D|hQ3mzJ5IzR1yQrUmP@qcZf*qf7NVZ<=1;ZI1b+WpAC=dad5z-D@@!`kT!` >zjbwAi%d%x>J=yy9Q?hNTOY-}9)pj{5JBIg_ohd<TXGxUWHMC6c9uQ{s#2nTI_3E2~ >zcBN8q=&;%wzfkWj^ELY-Ch2`QKGTI&l6B#kvwHvWn&$T{`TD^68|Gm4X>%wmNFScE >z)f`EA-W(k^QXlKy#QfnAb3Ce&IT5``p9~Jur>c9*sgjDisC0xrU3gBPInYC&UA<kO >zTYl4=|8l9mFmAB9ICHGN)IY{tPEXKRIw$I@32pVY`jyR}Z9?^R*9B7?;-`xb?=&~c >zPU@R$mYb4OzUJ1L1*UXEZnAH3o-P;W)qY(wb$S2Rx`KOxu257*`>Q1Fzp+dQT#VNh >zm(@0vcDQxr$+t|ECDnA*5eJQ$8esyvtufWolzAv}wyEyDY-)s_k)W1&Qqy;v)T)&! >zwT>;8hl?jj?RAqS_{cm}XJMAAyY>@RZ=$G>S;Lf0N>TO4#i>VPJu0++Q`I26g=*Nj >zi!`cKOEqrtxHP`@goFiDm9T;!X;O4a9?LG4@J+kr@hOE8@okPY9r?YuKgkgH$p)^- >zKEJ7`lx)>3I#)f>{d3j4?hMr;YLseGnyy*~Pmz`f`m0tYsnYs~_UftqUU_<Mf<))G >zmS@Jdl{VAr$g_!|()NQ^s$EAvX+JPnJ=gH0bZB3yI{IyrPN9cXr}HONjPF_%lfO}Q >zKK8Zhk~Lq&Zv9E(CQVfF3unm-!-uP`6W^C^FHMl{NrR-vlS$%<?IbVOjF+C_Vbb%u >zTf8+oD(|n=<mGFRs$Sn+mEHvb>J<~H`edI~ebcX~gem!|UqXTEKlZe|+Gd3s&}XX* >z44JA1MQ2IkgE=y|uE^k188W0aMTTxnlh+P-WLRczNy;0cUjH~+hR^Mx-WU=h$>W== >z5#63vDTy`Jo00X@$PPEuTY)Z>+O&qGUOcKsRk<#scC1%v=YNyYOXjLE`ML7W)SqQ+ >z)(m+!ZH}Z*N|y(G?)T~IbN9(NeedJ@<;vgtoBhiF)3d@qefVELyM6n1j=f;6D$1uE >za@6W*pGv&rvhV!;eLjti^SIje@VGkRbM}SH$H&M1INwFjzu(TQcm5bxVDX)Ax$Ix! >zcI`g?Taa7oXzwX<Q<1xh+*ahiA~zPfv&gMQ?k#e2k-LlBUgZ8FH`vkMVdNG&+Ix)L >zWaKU*w;8$5$c;wsG;*tvdyU*|<ZdIk8@b=e4M*-ca?2g<Jx6Xja@UdDj@)<T#v^wg >zx%J4sM{YiH_mSI=+<&A2NCzBk3y>Z-+9n`fK-z%x0cix%38WQBFC1+%kZvIDK>C3+ >z#L;%d(Y6HXiKA@_(iKPB7NjqZwlPR&kk%l*L7Ibf2Wbz|AEZG@hmaN_Jwlp<bO~vb >zqwN#YD5O(JtB_tH%|g0`v<vAM(lDfBNXw9(Ax%TNhO`aoo1<+U(mAAcNbiv5A>HG@ >z8|_2-hcpoBAksod+e4&@j<$<P8<9RDjYK+$v=Zqh(oCeANIQ{!A`L}4inJ8zDbiF& >z+f}5kNMDi0BArEAi}V(0F4A43y-0tN1|uCtT8#7<X|kj3GSX&8+h?TFNT-ojBfUnN >zjdUAnx1;Sh4;qei9BDbybEN4=*Bx!!k-j_H#v`3aT95P|X+F|@r2R<$kqv<C0Avdw >zdjQ!4$Sy#(0kRJq?M6U$f}`CE$X-A;1F{>C?SSkDWJ4f30@)JCo<KGQvMZ2nf$R%M >zyD^ZR;b^x8vNw>;f$R=sdm#G**&xUcLAD68N03c|>=I;~Ao~Q_D9BE6v|9z)E68R+ >zb_=pyko|&e7-YvFTL#%P$fiMd4YF;JeS>TqWal{At%K|xN4t5D-Ggi&Wd9%=2-!i% >u7DD!r>wf1D6X@>q|3PH`740Ajuv5uxCsTM_vxw#q?xvC9aglCb1^fkK<6HXx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad >new file mode 100644 >index 0000000000000000000000000000000000000000..37280d05f9a993b27468b028bcd8f0774a3ce017 >GIT binary patch >literal 1518 >zcmd^;OGs2<97q4-E45K4!p3)|`N&62<D;pxrpD3Kku0Z84{#w;5v0{J;zI_Bh?*YK >zLdy^_f)t`!lnE_b1euM3kWE1l5xA(kiOPuj&Q+mkQTu+Ed(Y)##DO`-zxPnPQ~p?z >zKH+9N_04;Z(vM!Ny|s7xrO`Jt61+NiFL>>KFxVfs5_}TZ861D#XnS_k9-J8P*q&c3 >zw}ra$Y@s<z$7D~Sb?VG;^HezhO>)7F(2A5-ZhLIF**=%_C}lP=lp6N9)5b4_(jQ(o >zGHzWkGW)uWth2|Bl_%Sb>?3=ORr_m=9Nz{bx2n)sU6N|#Wu!{JHC_s$D^$U!d{y|) >zuGUP)s-nkVRq@?fRWcY>rI*Lm+Q67vcVa|2+WOV{15d?yY)HzghoyY?X{pFOFO|;2 >zQu)18T<P7)^}0niemkf(jaA6zaD%EE+NG*TOVpO`GPSigQMucb)wV#fZ1;Xvp0)(3 >z$(vDL&qt|^9#wU@lT!ELh15shk@|@T((txN8b|uXH-1|+ojWCdUvWo-B_c9v@rsF# >ziCr>(#l<gNORfKYC0Iq4yY#Oi8QGR7kwlxs{r+C$;5;LnbC=taAX4OzWsA?n6HBuB >znKbh}YyREW<QI>(g@<37T59y&C|(Y{`k>fR#=o^#=ARZl-hP????N@}kDEe$S@^pj >zdPfKL?SKeoQcDIA4I&#vIEZu*@gVX+1cXQk5fLJzNi8HqN{E;ywVZq%1cgWn5!IxY >z6(TG|T8Ow1c_9KrB!-9#kr^U1L~4lG5V;|OLnLR2&XC=t79Ju!M0|++kN_YNKth1T >z00{yT1tbhc9E?C1kuXAG#9~qh!-&SD4u=sBBp^makdPoTL4txr1qllh7b7r8WQ@=t >mu`z;!L}yZm$B56Q4v-NcBSc1wkRTaR%70U3ypFfj8UGW?P;_7b > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev >new file mode 100644 >index 0000000000000000000000000000000000000000..b3e20a7e3946dd522e50db39a81c0e5f4f1bd619 >GIT binary patch >literal 2097 >zcmeIyZ%kEn9LMo<1d6UkUt4s&0YZ|Bc7+RwqCsNU3p2QSl`D}-T<eNjM2g11G+a8@ >z8o6(i)m*w+G5j-SwxK=1)}Ohu2Dkel*BrT8t!&P@vsJTltbXrf)Po-MsArwCb6$sY >zxjf?Yj;`L+Qeyq%xZS+r;^;CL&(n69+i~BK_~|}h?9-9L<nZNM89C<F#G64$j2zvZ >zIrB*J?kQhZdDBND-rw$cf6A4Nq;E7>b<gnrWY*ckPWFjcoScI%I8%GJI=MUIPG0LO >z=iar|&a}GuPJTs!bD!VmOwaZ>GbY|}X1tvDb-{PuU9&#F8k>FYv&j8}iI~6d?Z}+o >zQ?bH5`y)l$&T1fjQj41|N=f^mlvWPO+?B6NS<WGuSJEl-#=50Et5?e}t&;^eI&|T? >zL3v=bQ7ihJwQ^{oKDc+WE_yv%t6K7P@ty_pP<5IH<5{v~`eh9T$D}RpYrN@}is >zFH2KCkfn+9^6<BBN$tRKsT+Pz!~1$<*@-uFd0U%AdUorIM_$sEt?RXZeyc|7YIK!% >znKt-mX~Xq^HfB~!;}>`8qdynO>N7v-nhPFTdw8-m4PKSUx_^}B-h{-OFUY!`SM>2k >z@5mEP!y3;$AnPj!v?cwtZpcyH@WX4majac8o$t~oFGcmKqieMFqb>6Ei<R2eUoX#W >z%+<|%%Vf)n3Tbcg%GTnkvMuzhJUiKvj-pKMaK4ewjO*H&JSSb(F6#DE{qkI5NOv6g >zP<IX-(&xMSw0mE-+7nW4Nli;lx%K9me%s%tXTr^M;-vrLw5;rd=KqU(s=4P`>6SG+ >zU`?{D46%ea_Fd!m@+#Xm{^|I$ox>aMe77zfwQ9{33Pr7OeXSKV21E7yu*AGH4;;4b >zUhvmp+tGiY#CG%R?j(Ns^LxLWqv6cQabzOMOpvJ{b3rD9%*NGBhd;x7kO?6(ay3&z >z=7dZNnH4fEWM0U`keMM<L*|A|4w)S?J!F2!1d$oKnkgc4L?(&M5}774Ph_IVOp&P~ >zb44bL%odq0GGAoE$c$ahl#w~Rnn@$GMy8F-8<{vVb7bns+>yy6vqz?n%pXYrk^v+I >zNDf?05|AvonlvDJKoWsu0!amu3nUpxHjs26`9KnaWCTeGk`q^x6eKIICM`%_ki;OF >zK~jU{21yQ*9V9(Sevkwq8A4Ko<OoR;k|kG@CL~WtqL54>sX}svBn!zFk}f1)NWzee >zAt^(0h9nKinyX10k~deAI3#mO>X6(a$wRV-qz}oT^?(0tkBR1-5+dmjmll>428v4k >L;o^Y%G}rS7d^Gc? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov >new file mode 100644 >index 0000000000000000000000000000000000000000..40b558f82117925877dc9ad67522db00a7b169d4 >GIT binary patch >literal 1167 >zcmd7QJ7`l;9LMn!n=~bHaM8v#sgIh5KD{PQNj0shX&b636bTMhq4+2Wf`6ogg3y4q >zlM0HUqKIN}@j2*Zl^`x++sUm82b_E$XA#7r@qBOX<REU|n|nXuk_^f3TNphu9#?-H >zHTDS?N1wfTzp7|&w^VoWNhvt8I(D_ZCN%HV*34yUzk42qKC1HCg``tAd!}4Jb5V!y >zoz{`-6T0E-VZH9u9=-l(PH)(k(i`*5x-ng+H?;+IG#oHZ!9^4E#U%DMB+YL=kF~t~ >zB(0C%N?U18+Alqqj;V*TdE%xxhc3vL{WB(h{IW^(+%TQHPnu+;Xu9HiP1lbDCRKkz >zQt$dr_u{B*eb!{QEu<xVCo4Tq8>DwSD%-Cq$&CA@Zz^nd41AF6!Jno-`dS9E+6?;c >zORn*S$$fcchN?<tX#TF*`F`5$dT`F<XK%~!`D3P#kBm)LDi!6aTCsF`eZS9Yf3@Gs >z?eC}8?^mkhiv1r|i=(_s4UTy1Uz^IPmCN_#Cm#ER&*X;-s?|x@D`~Gzr9Ad!59BEP >z!+_tGzM|~!s4yflCXX2u85J4U)sBk{jEsy7jf{;9j*N~BkBpB5fJA_VfW&|Vfkc6X >zfyCiz13@A|LP26df<dA|!a?Fe0zx7}LPBCff<mG~!g957A%VHt$dJ&G*pT3m=#cP` >z_>cgR2$2wx7?B{6D3LIcIFUeIZKO!3t~ORASR`5`TqIs3V4Sp@|924w(l+tl_C(+p >DaEJ}W > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon >new file mode 100644 >index 0000000000000000000000000000000000000000..a85653044e0094363ea0f30d017a20ccdce2227d >GIT binary patch >literal 3469 >zcmeI!cXW++9LMpS5+i~iDnX2gREegttSD8|L{qVnix_E)h!yd;#tEglB~``A`BAi1 >zJz}0TV#O-4M`FaP5;an4#d<VUR8@cP#~;<xKdR@n|MkhqeO*`LKcDy4-fKvFpzSY@ >zyZVH0o{Q?6_g+r*GV5BZb3upU`hwpMIu|ayqc6&xtbdj4&=;p~GL2ZfzGQl#p4K*B >zUz#{VU*_#@F7KRXrn}zL(;uXot8-VHnJc}`HAZKB?WeBhy3dB0>-Bp22FFxAt4m3J >zb6|wNrDBf0<=Iw!>%DY+d(LJvd&??w$KqIh=a<vWUGq(IcT$46XK;+UH@cI#uZ^p| >zzlFbfpygciV04ClF#nRC>*A;9-q-X)m;0NCH%6L=Z!ax4;_Ogx<b0ZWbWRiV=-v)} >z^BidfdHZ+j$HsV=$1(;L9FI&XIKF&|e!^aCo|q9{a56By;N&Nh^;13fncs$QG*1Vg >z(7yB8qn)X~K|5P^nRfQ^94-Im6z%-hp4x@=DaOULF~+4?@kYU<9>x!j_l(Q^gN-YZ >zjf@}Lc^Ov&-HmH?pBmS_e6$<oYG^l}l+$h&{;Cz8yQAGYbWywg%`xpx`Y!G6{B_#B >zX=$1{{&VgA&=l>b0c(t+D8qOVGShe%G|BkcdzA60N}N$#qMK1%6lS=8-N;scftRhq >zbaz|Dl;%z`x}mdDTy<w<do@`l<cagupkHKF?_1KN%6aKo;;8g2+99i5$u_E=GGvXt >zGo{z|Y*8~KQ`B0xSk#^&MV$#B3oXGR>h>8R>P6UvcdJnGnr|~vzh(pRx_dRzz%@iR >zc-TZXyjoxSoc557_Lr7#WED%_WjE!Uv(L%KDTk%s=<U)!ZnX@E$rpi+ED_Xtn`ja_ >zS2V4)NHhyf63w0_ixyt9Ws3{_MDUZbvSoINc<cLU*=j|sY`v|ee0xe;*=9ja`A)pI >zY?~4++J(8wkT@^#ZvE>rG~}rWbIq0Qy)TLOcdv=?61zosUXFPG%2LrGGhIX+*(p1w >z&Jdk4mdMVDiK5Gl$+ByYX)-clpp0ssAng(DWjD`Gvb(R3?Ec7KMpq3J(Pt{lo(~&} >zUYj1s-lyF}AET0p$+|5*NG=kwv-3pX*wdol#6sD>&1Nwm=7@}|Gfxa`ohjqXY?Om) >zNjd1o7jp1Zha8eKP7b|bm%~=|mI((&is4gR%fuB?V#MG&QlHXPjO^M<IO09UsDRpH >zbm(I-rjkvJ^{Xn!nwLdVg-0^!_&zc2ZoVA9c7^ybZ=0MjZ;zaqxk!FAZkbF@O_sJ& >zF0Yg*`I29*>gQhkeyQIp{dfO<nX=ZGTd9Bl>)EqM1JtnCDhQX7Xe;~Y_cb+_@_&48 >ztIXf>sy_F4@h2lX+HE~Tqj=$4{V7Df3E>m<xTxp(i}i0ke{cT><5z6`p3U}5J&YhS >zgqCUykwHX85gA5g9Fc)UMiLoHWGs=vL`D-CPD?eO$bcdviVP_-rpTZoqlyeGGOozL >zA|q?5h87uHWN?wuMTQp{Uu1xh5k`g>8DnISkx@p585w6wHPFaNTdJW(#u^!HOEuca >za9gVJMh4tcjW{yomTJtALAO++jtsk{8h2#iE!D^)LvN|Z9vOUO^pW95#vcg)5&=sU >z0we}V5RfP!VL;-51OkZ!5(*?1NHCCSAmKpbfds@-MFa^65)&jSNK}xpAaOwggG2@i >z4H6q9I7oDm@F4L)0)#}!QiX{B7Q~2$An_0-9>Rpg2?-PuDI`=#tdL+K(L%yysp5qM >z42c*LG9+e5(2%GhVMF4E1P+ND5;`PyNbr#8A>l*fXQ={+L=Xuf5<?`2NEDGUB5_0l >zi9`|!B@#;{m`F5{a3b-vQ~^aIYN<ks#1siC5>+IuNL-P?B9TQxi^LWQE)rcNyhwbJ >z03#8$R3S!UY^j2bL>UP)5@#gPNTiWaBe6z;jYJy>Hxh3o;7G(RRmhQ;TdJTVQAfg# >z#2pDd5_u%_NbHf|Bhg2~kHjB20FWa9IRubnz)~Fq$WeeC2FP)M90<sffE)_Qv49*5 >z$kBit4#@F<91zG6fgBRZF=43=3goD;REGs}Tp$Mqa%3Qf26Aj52M7Ltbo_@$hnu=j >Y{5e#7I|emw+SuPOz_(+7KkwXr2Z!Vh=Kufz > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana >new file mode 100644 >index 0000000000000000000000000000000000000000..79c25d70ef09aaeec21f0a10a029650967172a80 >GIT binary patch >literal 1957 >zcmdVaYfQ~?9LMqhL0H4S7)2!{xg6a~D7WL3s9ZY8CAlQGB%zgCF3rrEeOY4-b6vxT >z2jM}?T<4O6HN%WC*O}Qcw>5t6|7Np!;F-<;od5sTPMse8-XG7D`8ko+A6E<W2{%`< >zx%s*ETJyNxB<4x&%h7W4u#eX5cgd}7(Ne!YSn9ty@^9}elRIfc)z_Vs@B8eycDlP) >zJ73(YerL{#|IsQ5*tJKxl&J)+S|?p|3#8k$+0s45BSG<Q>EVo(VE+*5*~(W!yj&Xc >zDO!6y57yod9ktKp7TUM^i#iX!)_&y=G_>@FhAlgz;n~MDBJ;jP7F0`ALXAX^-!3r$ >zyCpWVNMajHB+jo~;~veF0pAOC;8~XpdYGZ{m06llGf)R_9Hv8d`s>h~ARSgZK!zuJ >zsVm!0Mg+f9x2sVSy{>6e&|^t@_d=4Jo|ojht1{}@0U2F&L{e(cY3i0TNjthv$K>V7 >z*s={eZqjBQpF2m>`{$}BB}pgvr0GOwZ=Lu#Tr)Z(O2)l*I{8yCnR4o*PHpg(X?xpB >zX7yW{Uh+Y*%IjoCR)fr3{YGaEIW4m@Yc)HtLgpk?X-><NIyXRd?yDU-udzVqUoF-J >zk372Y&{WO6vP2ebO3=K@bXhzvQ1ds&$dYmKQjp^#OC!3-GWS<m-qw=Bunt=I{;3qT >z`K(3tm!$aJeO+;)QdZX0=&Fhfy1Ht&t|>mKC0k0=(X2^R^KzKCSMz`QvaI%T=6qRg >z#A^2I>EG4S(z1Sk^4pYDkL7Z6r+ds791h-G4u|LOr+J0>L;Ey;vA<(kKg=~f{{2Yg >zbR#DmIpxSnM@~C(;%&{TM@~L+`uVpMU~4KsN<eBria@GB%0TKs3PCDCN<nHtib1MD >z%0cQu3bHj7AtfO-Aw?loA!Q+TA%!88A*CU;A;lrpA>|?UAqCo+3Xu|RO^ryANR>#L >zNS#QbNTo=rNUcb*NVQ10NWDnGNX1CWwx(vJXj@Y?QZ`aIQaDmMQaVyQQan;UQa(~Y >zvH-{mAWL9t)&N-qTeAwtG9c@KECjL=$WkC{fh-2H8pv`W>wzo?vLeWmAZvmwimh1{ >zWLc1PK^6vC8DwdYwLumKSsi3~ko7?p2w5RyiI6oy7RlDE60%ITW}T3QLRJb{DrBvY >k#X?pKSuX4Uo-S`QY5gMDG-qm5XiR9hGc_U{!=k)@0!L5Jf&c&j > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/London b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/London >new file mode 100644 >index 0000000000000000000000000000000000000000..4527515ca3f249a44599be855b3e12800ebe480d >GIT binary patch >literal 3687 >zcmeI!dvwor9LMqBn$hO=nHU-N(OjC={5BD438AqqmtXotj4)(rmX?v0Q>h%sdF!Yp >z<U?Y)%x%kMU5MsB*GZFmE_1(T%%;!t>o})#oKr`C_xqiB{Lb&^cR0@Re!e`th9*Y2 >z?s+_D-{FVH75l^M!1wGg(;6)@)Asu5>D%3A#+-HLtLZb$%#7N`e7IWAO1))f51OvO >z9<$NRiC<~HX;Y%-HteV8HO|wSO~Q5NnPM~FwcE@usG%1WUDOLVB<V$)cIm8n@p`dI >zGfO^l>!qLWFw2r-&GM9GCcA5d$%*NuzjG_IA}ZCata{n3s^>F6=R@i(EQ)-zEM1 >z{+IL*D|hQ3mzJ5IzR1yQrUmP@qcZf*qf7NVZ<=1;ZI1b+WpAC=dad5z-D@@!`kT!` >zjbwAi%d%x>J=yy9Q?hNTOY-}9)pj{5JBIg_ohd<TXGxUWHMC6c9uQ{s#2nTI_3E2~ >zcBN8q=&;%wzfkWj^ELY-Ch2`QKGTI&l6B#kvwHvWn&$T{`TD^68|Gm4X>%wmNFScE >z)f`EA-W(k^QXlKy#QfnAb3Ce&IT5``p9~Jur>c9*sgjDisC0xrU3gBPInYC&UA<kO >zTYl4=|8l9mFmAB9ICHGN)IY{tPEXKRIw$I@32pVY`jyR}Z9?^R*9B7?;-`xb?=&~c >zPU@R$mYb4OzUJ1L1*UXEZnAH3o-P;W)qY(wb$S2Rx`KOxu257*`>Q1Fzp+dQT#VNh >zm(@0vcDQxr$+t|ECDnA*5eJQ$8esyvtufWolzAv}wyEyDY-)s_k)W1&Qqy;v)T)&! >zwT>;8hl?jj?RAqS_{cm}XJMAAyY>@RZ=$G>S;Lf0N>TO4#i>VPJu0++Q`I26g=*Nj >zi!`cKOEqrtxHP`@goFiDm9T;!X;O4a9?LG4@J+kr@hOE8@okPY9r?YuKgkgH$p)^- >zKEJ7`lx)>3I#)f>{d3j4?hMr;YLseGnyy*~Pmz`f`m0tYsnYs~_UftqUU_<Mf<))G >zmS@Jdl{VAr$g_!|()NQ^s$EAvX+JPnJ=gH0bZB3yI{IyrPN9cXr}HONjPF_%lfO}Q >zKK8Zhk~Lq&Zv9E(CQVfF3unm-!-uP`6W^C^FHMl{NrR-vlS$%<?IbVOjF+C_Vbb%u >zTf8+oD(|n=<mGFRs$Sn+mEHvb>J<~H`edI~ebcX~gem!|UqXTEKlZe|+Gd3s&}XX* >z44JA1MQ2IkgE=y|uE^k188W0aMTTxnlh+P-WLRczNy;0cUjH~+hR^Mx-WU=h$>W== >z5#63vDTy`Jo00X@$PPEuTY)Z>+O&qGUOcKsRk<#scC1%v=YNyYOXjLE`ML7W)SqQ+ >z)(m+!ZH}Z*N|y(G?)T~IbN9(NeedJ@<;vgtoBhiF)3d@qefVELyM6n1j=f;6D$1uE >za@6W*pGv&rvhV!;eLjti^SIje@VGkRbM}SH$H&M1INwFjzu(TQcm5bxVDX)Ax$Ix! >zcI`g?Taa7oXzwX<Q<1xh+*ahiA~zPfv&gMQ?k#e2k-LlBUgZ8FH`vkMVdNG&+Ix)L >zWaKU*w;8$5$c;wsG;*tvdyU*|<ZdIk8@b=e4M*-ca?2g<Jx6Xja@UdDj@)<T#v^wg >zx%J4sM{YiH_mSI=+<&A2NCzBk3y>Z-+9n`fK-z%x0cix%38WQBFC1+%kZvIDK>C3+ >z#L;%d(Y6HXiKA@_(iKPB7NjqZwlPR&kk%l*L7Ibf2Wbz|AEZG@hmaN_Jwlp<bO~vb >zqwN#YD5O(JtB_tH%|g0`v<vAM(lDfBNXw9(Ax%TNhO`aoo1<+U(mAAcNbiv5A>HG@ >z8|_2-hcpoBAksod+e4&@j<$<P8<9RDjYK+$v=Zqh(oCeANIQ{!A`L}4inJ8zDbiF& >z+f}5kNMDi0BArEAi}V(0F4A43y-0tN1|uCtT8#7<X|kj3GSX&8+h?TFNT-ojBfUnN >zjdUAnx1;Sh4;qei9BDbybEN4=*Bx!!k-j_H#v`3aT95P|X+F|@r2R<$kqv<C0Avdw >zdjQ!4$Sy#(0kRJq?M6U$f}`CE$X-A;1F{>C?SSkDWJ4f30@)JCo<KGQvMZ2nf$R%M >zyD^ZR;b^x8vNw>;f$R=sdm#G**&xUcLAD68N03c|>=I;~Ao~Q_D9BE6v|9z)E68R+ >zb_=pyko|&e7-YvFTL#%P$fiMd4YF;JeS>TqWal{At%K|xN4t5D-Ggi&Wd9%=2-!i% >u7DD!r>wf1D6X@>q|3PH`740Ajuv5uxCsTM_vxw#q?xvC9aglCb1^fkK<6HXx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg >new file mode 100644 >index 0000000000000000000000000000000000000000..6fae86c53176e605311e09823fee55d07d157405 >GIT binary patch >literal 2974 >zcmeIze{{`t9LMo{&0@>uZP;YPt+j?`zqb$#GmdP2-dKLi3|Vt6?QFt0?TG9+ZyhIT >zv}<NVjB0+hAq;b3DJGPY!;w-)x8zWr9etkPsME<m^-urw{hs@Me9yi2yMK1>^W_{f >zBQw_ax5MAO!;52&d2t`O&|C^jx7HMQESgl@aNe`#TE)e+Wvg9p?@=u&T%{!!YhCV1 >z8$9b4Tyd9126)!bogrlji#!`9Bx!kAf~O*Uvu$HnyJu6gw`9}xc-Q8u*|vAimb$ha >z9cJ5ltin@S5o_D#9_rfuY8%_TOJ{oCb44$FKWB-nYFMOu$DlEeozddn6`Skc-SS8G >z?mL&=d%i#I{@~0qNA=ks95r>99D8@4a_lQv>fZn64#$VZ!HxrYs~iWXFL4}7&v(=& >zMY#`mAL}^M^MK=M`Wg4p^FHpne$kHOR|m_9O+i{;nk*l`9xo?nZI@4S0_D>oee~3d >zK5}|+sQPtnborG{QU7J_rDb7?%A7=Pl@YE1&UV^5t-rL1`$gM^eyf44ztAAB6B=}5 >zpSHWaO&>bt*7k>1XmHJ53E5I99oCdc$0C(Z^A?FCD@Pt4H$@&vbxLTj6nQivQNlvP >z<*^p+B-}e$!*9lG=PO~_r6Ewe9&V<OSKZc#vTwB8%JUjo_>o4<snO_+tr|1_oW$l- >zNnG!0i68NXBy?CSiLrT-*jOOlgI8+z3zMbCuesWDZ?Zi3dAjy0pQyd7d+Jk*`)X2g >zi1x`0)xL#2q~8E<P0k3G{$W=&CAm=scpuY&p<l|t>tD$ruLCluzD}OLyj})ZZkE*J >z`!#KOkqp_gPKRb^%dnzXbol7kbVSxv9r;9-I#UPgGeJXiR74jYbt_ua+YXTQ&jR$> >zo1JCM&YyH_gRhKpx03Ny-^ql68!~Zay-b?eAd}}`)8~?Q$&~TOHKWsNncBNjGn?<w >zX&qFjeZ5MjH|FS!x_o{9f>UR19IIJJX3GmpdTVz1NSQUgle!is$n4?0BquXSUX1A| >zb5eemms;5*H>$1XdM-(x|1HfsSu6S1&*|Ll<??cUwa#08Q0G^!)dl%wTClu8ZB6Xv >z^lJKm_x;Xh&F^<U=;Q0-Yo76H+N6cwe|6ey-nHiUX$x`Ko0{LN*nIwa?=N;gKDPzj >zyZ-);`KEctJY_!p<9hcmq^3D-$tfebIBlc38EtONVYl-#S8o11>~`lr$jR-y58g2c >zSwYfbY4U<32FVPP8YDNCCOJrUkn|w=K@x;y2uTr=BP2;kmXI`Anmi$iLNbM<3dt3c >zEF@b<x{!P!2}3f5qzuU!k~Ac1NZKq--jKv0nL|>C<PJ$5l077SNdAxnA{j(dh~yAS >zB9cWUjg}^lNFtF;BB?}ji6j%rCX!AhpGZQHjPma$rIseANK%okB56hPiX;}vERtFz >zw@7l4>{^=iBKbuUjAR%|F_L2>$w-!wG$VON5{+aUNi~vdB-u!|k#t*{d?N`*GLEDi >z$vKjAB<o1pk-Q^`M>3D39?3nDd?fow`YlcVkqNLgGk{D1G6%>cAhUo>12PZDL?APP >zOa(F*$Ydb1flLQ7AIOAQni)Z+#L~<OGAYQcAk%`(3o<dt%pg;P%ndR*$m}4~gUk;y >zL6&BQkSVe>bA(J1GE2xbA@hVx6f#rDR3USPOcpX*$aEp|g-jSSW5|?QnmI!z4Vg7$ >z+K_oeCJvc7Wa^N)LnaTIJ!JZj`9mfUnL%U<EzKMvlW1vX5t&A09+8PeW)hi7WG?al >h$-Fn5|9Ucg&A4`pVP+%J;vy3wqa)H{qA@DY_cvO3s>=WX > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid >new file mode 100644 >index 0000000000000000000000000000000000000000..9b51a73bd52e9afe7d788f548213ef57415f65ee >GIT binary patch >literal 2637 >zcmeIzYfRO39LMoLDhjCh1x2XCMI%BB<t8L1p&^h7-Z&|V#8DBokd8zQui#{6j=68m >zYOGA0OdBa!VQ!(dR8pssrL0j|ELUc!ou*8?F#5g!^`I474|~%8?3~y6AK*M-`@KKT >z1uKdZtbbgC%_ls$cAF>f9o6RLwRhV*JL^-ddUbeqZ7iv7^#0M^c)8Tte`>F%X>Wqn >zTtCZw;Moz@o6oJW-g3uPzg@P)-7-6{`sk^vo@03h*71kaJjYi$y4q68T_;B8SD)zK >z<~iN{rR&U#t2}3q&2Y8Xcep>=J<fHm`jGqMO~YKDxa!>J7ysnCFlDW~Gd#1a^Gd$Q >zXXx23pPMhZeXlil`CTY?4{i<Z8uEt2GqfSa<-fJZGpr^<r94^XT9G@TC|U!ZAv!!~ >znv6*NMS~)L(2>Kx(BS@OHTcGR8gi*w?>JwtcOH9Q9fyxd=)NWidv<*Q!LU+bE+- >z%4GDyC307`Qz9p4$lWo?5)~RP_Y4V<Xzz55?w+7yzKPPY9V7MLwn2Jd%WaKmxT52> >zf2QMWPHSxWVT~)=uki()l2FzniK(qJVeU(k6t+W>6DlRSr%EO|w(G=;izMaO3Y~N$ >zT^{&6Pbcpw)YR5V`rziNn)XVlPAQJmsWmC`P^P!07dd2F)Md>`?~zRJQ<@d|m1JH2 >zR;Ks=K&H2!lt(V@mKjZrl6~fV&DmBfGxzP%S*4{iyLOY#nZH%%mMqoW`%BcBou!Wk >z&(wJ_V|CuGIL!;nl)O&^^|9_Tvf!PYn&06k3+n@<pyjGOUUfqXx3`O{utOHD|6UiT >z9g-ylXS67yPL`%NX|c~iT^6Rg?7NqBc~6<HIJsJ%xaia;U(eT)4_C>`EvZ_%Cs&?Y >z9-;2dNwR9rWGO2SmZ#&xr99(jc_zS;ir65n@O&+m{<pO9+;Lfby;Ij5*duG(TXkLC >zQC;7(LpQ8$(5h`!I>4*n-yZ$F`VI8%<1xr*ps(M5@#yXSt=60v%U`?(pyg{>p`*Np >z{^fljKedAG&--|vo#V9TXXNt2)7+(Vmu~JX%Zu;vGMD{*f803#{WLe2-?UHj?LYsn >z*IXNt4_e6SMou_#%8`?foOWAt;*nF2oP6Z;BLzSzfRq5K0a65{3P>4{I@p>*AeBH$ >zVQXrE6a%RSQVygZNI{T_ASFR+f)oX*3Q`tZQy2a%6voz61}P0v8>Bc$b&&EP^+5`R >zRLItp2&oZLB&146nUFdmg+eN2Yf6RG3Mm#+Eu>sXy^w+-6+=pf)C?&aQZ=M(NZpXa >zA(cZ)XKQMQ6c4E$Qa+@9NCA-wA|*s>h!hd2B2q@Ajz}SqN+PASHMK;FX=|#9loP2Z >zQc$F#NJ){JB1J{2ij)<pD^ggbvPfx>+9JiZHPuDRYisI@6d0*6QevdWNRg2$BV|VF >zj1(HFG*W7$)=05!O|_A7+nRbK1xG55lpLu!Qgo#1NZFCPBZWsQkCYy%JyLw6`bhb0 >zP5qGtKvn=*0%Q%4ML<>oSq5YskcB{20$B=VEs(`PRs&fMTeBX>g4miBL6!tr6J$}4 >pRY8^oSr=qstp6vbuZi(9>oYE%9g4|G9G^5kE+!{F4r3Gjeh1W6@Av=! > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta >new file mode 100644 >index 0000000000000000000000000000000000000000..c1208e2d2ec5e948a30dc3976edee6921d3d4aa7 >GIT binary patch >literal 2629 >zcmd_rZA_JQ7{~FOCwWNiLIq4gEF^qD1p%KD4GEkHmU1#uR8T}MqFXZ3QaPHrYR+9P >z#W^8Cjipm+in>y2nKqk9h+%5EoX)Ilc5i0r6z%`Lo%W&^z3WZ)8Rv66!prOX^Guyz >zG{pMH6KKBShi9Al;d3XidD}Sry1lWr@m%HMqfXU6EC2nsZ`+%yBhOXmf8f+C+nK*P >zZ<xI$t4IEk;uNRx(gZoSEkc_%r^`2bUYkp1=<(8UX~}AFPK-{}Z^yStYgC(kvfp~= >z<Ylj(3a*eFNqd|drw^UG8QEgr{G{Hwb*tWP-%#P)zS!*CS+U!;4)1b&X05Y*E2r9i >zV_&uX-z;+i2E6BV=#gXxhV-$6BEs#UGs$*vTQ?0k*vb3A$v?GY&F|h$drxWS<;T4b >zR(z^bu-hA2R;gXm)_J>TOp|W?cUfUEmo>cW4;tZjOe3y-rrj@mqz|2_)*fHJt33}i >zNaT(>iK^Try;iG4FIg_Vi%aF<yxH<dmPcYnWk{d+p%NPzCy#dQE^z_r8h0&O`(BLI >zey!o!|8SrVsK2i9TYu4kYtQJQl}B~(!ULL6xKk6SpOzt|^^%mjUy>(RNJ><d3>~sa >zhPIc>@SbaR_}Ky(akETEHl)jA-{<P6+L@ZVf259Hm8N4hM(X25F`Bk=gpAD$(DcHd >z@<i+<%}8&T%z&?TT+EL$?#fRx-tP+;-*iNtys$+k)NPln#?Li-&1#vrqeh=9DUqjF >zzoC<!eMcu3&(WM=#p=l#r_V%8)G6`(bV^%-=7wcT?sr}Exodr8>fS$eT5E{pRfo#- >z`rl+m`Bj;@wn_45wo1X$Uv<`)eKLD`qZUSQkU6P!S`@TL=SHc{{dv94YcJLLM;7bz >zXFdADhtst9s|E7nTd7)7n<FpHi&lG8iY%BkN=l0&<mJR(vM}R@yb@|j+2AlObI!}6 >z&TYD=`H(EWa#~;exK>_o+OJDC9Mq+CRl02PRxMvsu6{ng_g{Yg=H=tdyLsL7?!Vms >zx&NEK0UiG9m$|1(b5B-eZy$fl>MU09z4yD{{QZ4aw#Q1($l=YyU-*~@%?HoFU+;GF >zi|+MacmKw+?wH4JI8lgPv#Ysi<f@U&My?yVaOBF7OGmC9xp?I2k;_M}A1MG*0i*;- >z4Ui%rRY1ys)B!1ktEmK13ZxdUrWi;yTunKUdLRWsw<3I?Bs``jKv9sYAZ0=7f)oa+ >z3{o1THm;^PNOh3%AoW2Cgj5JA5mF<hNJy2CG9h(B3dKXEkWwMFay7+5s)dvbsTWc( >zq+&?PkeVSyL#l?94XGPaIHYn&>5$qX#d9^)L&}HL4=Es0L8OF84Ur-uRYb~&)DbBp >zQc0wgNG*|Kx|(Vt<#aXmL<)*j6e%fEQ>3U!RgtnHbwvt`R2C^MQd^|BNOh6&x|;eT >z1$H$RMoNs-7%4JRWu(kVosmK#l}1X9)EX%^Qf;K%uBP5d!Cg(ok&+`dM~aSA9Vt6f >zcck!0<&n}OwMUANR39lnQh#ItT+Ip~OMt8avIxj3Aj^QP1F{gvN+3&ttOc?d$Z8<V >zfvg9zAg*RbkR@?7Yl18avMR{3AnSrG46-uF(pdkmsR=RbGcb`IiqB3OlrktGK07f1 >I2PcL61)Kf$7XSbN > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn >new file mode 100644 >index 0000000000000000000000000000000000000000..29b3c817f4637e98623c5f76a6078f18157b5cfe >GIT binary patch >literal 1909 >zcmdVaYfQ~?9LMp064tP9EC-b$$>pfi)vbh_aw(*PTvDjq5<<$YW15*Y``Q{a4AYt! >z@gQts?#8q;n>E9ljk(UuhGEwDz5kxrJn+osoSpycteu{H-yhGs<t6dfAFod4FMN1a >zm=E8Byyj8AZgt2#Uru4m)fa`qk!{{yJ$+t>{}r#}<5_R-=V!FfgQME_#$FA%bXh`A >zHA>i_Bhs%{C49?vi6||X{tK4KfGm$hrnqIGGg+cSqh(On-Vz;<uF;<pb?}QQ9n#uM >zhu-R}!<xRTv;K_^uY0U9HTN`j{Uvo3oz}SgM-pG&Bnhd_k~njpB!wN8<oHTSZm*V+ >zA$2;kZIO)nUZJBer^}cpd79EtpsCHHb?naZnszW$$CX6t_?l5NAtON3i$Y{#)GKwT >zw@XIAUCoSqDw*$J%4Gj*GTC=WraV6`QyWi8R?8L5-cu{nP94+fWo0s>c8BK7*{w56 >zi#2ydsd}<9b(UkA&UOyb*<W0m7n~t^4}0j`&x2*&`A<5(HBc5D4U+t(ce1ehqZHKn >zq_Ch>7Hxg2i_<R1lKd7e3O^vlsf}9F<(w`JQ(gLczb<Pp*X4JrbVZv-SDu)!rMK70 >zs$HpC){rZ!mxb$^ok_AbCq>Fj9I`I1pR9L(lMO+ZRKx~r#fN87+5L-F-oGhT?;q)= >zvkkJ@*Q{F(T-U9Qhjm+3y;kq3RzLp^_Pb-izkFMkqu3l2&yJQg)aBR3vO*)QZohxe >z%Jx{3%*XA{<>BG?mY?6Rr|0jdyV3m8KHabUi+TMpuiT4+4kD+FoHKIL{D!keP8&II >zTXW*bnIor;oI7&z$k`*OkDNb}0FnWc0+Iug1d;`k29gJoh^@&4Nd?ITNe0OVNe9UX >zNeIaZNeRgbNeamdNejsfNzB${hNNa|azm0svP05C@<S3tGDK2Dazv6uvP9BE@<b9v >zGDT9gHMt_m+L~;Ubdh|KgprJql#!f~q>-$Vw2{1##F5OA)NM`fNb<HOdnA1%e`ErX >z89=50nFC}JkXb;c0htG6B9NItrUID@WHM~cY#`Ht%m*?d$c!LUg3JjrDafoK(}K(k >zGBL=^AX9_P4Kg{lW_FP2u{HC9Ob{|d$P^)SgiI1LOUN`?|LHabnz0%l&ulrf6JnBL >PT(Jqx>^PVGEiv#Xi)pZk > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk >new file mode 100644 >index 0000000000000000000000000000000000000000..60041a41890eae1902b2410f1225a38cc7614a13 >GIT binary patch >literal 1370 >zcmds$Pe_wt9LIliT5GB8kj*z;nPx7XwVc|jX{$NKKLbna5EUMVRCKWH82Jz)9iso8 >zl8O)`DIxlE$b=3Z!j`Q=V609Nfrol8(LZ86pSKo4hdTFtc%IMmKJVTQ-hIB^JNEY0 >z$REkmCrr|;C;JsjFJs17@Xm<QGqt-fnRwgodUDNuYWhmV_4G`wE9uPYDX6%bTvYfn >z>~^F&-Cq_wD4fkt8mUNlapG*U=>BE1`1)znGknxsa=hPMdN^*D?B8ZC+u3ZEcC0na >zLSA#Z&oIl2oo4yP{?3XIg?-*PZng5cLsdTftg3F$D&I&-Ri8_!RfCgi^`UX)k6%)2 >zc0HDwgQF5?xFNM$k4c^9q}12!llpH5Bv>@0g0H${-Pb*8{bZeNNVTcZ=oZy5;Zu!6 >z0k!c$z6$pis7-@avN`%uMdEqVRQ^ImBk!d-XF|1<J(HGqGtz3mC9Tu<r0w;2X&)b! >zj>JtBJ8?t?(&@A<%RVPNCp*VJ_s4L|`!(#&`TsU@b4839{es1KB-tXxCE^gN^ou^v >zcZrJ=+rrEm4BL#%-OS$R`R%FFj##(E^o&L|yV@n98Hsjr(WDRcrph1S=fq}X>R4Bq >zrTgz*wCK-TUVQrbkbV{E?RTfV5KkbkKzxBX1Mvpp4#XdbLwp?`L0p3PWKlZ>@e1M= >z#4m_r5YHg4L41Qa2k{Q#9>hP0gAflPE?U$+LY#zn32_tRC&W>Rrw~^mzCxUZcnfit >z;4i^pg2x1x2|ioYP7}PgsNE*`4RM^{ImC5{?-1u9-b37n_)q8nqz8m9K>9%F1f&-h >kbvFq8u&6si=n0`KguXyJLk9GJE&pS2oFQGT#_E9cJ1oC86#xJL > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco >new file mode 100644 >index 0000000000000000000000000000000000000000..0b40f1ec9321e0b521a0d36a8e6ca9a9de08282f >GIT binary patch >literal 2953 >zcmeIzYfM*l9LMqVS5d^<7fmohF$qya?vR?KhDatL>OUnF!9>&~JCZrH3|-FDocr3C >zWoV)z-Vm+u3f^ycBdeKdxtcER;_TPVX*IL+KFjr>2hB%4>71Sa>zuPcJYl>)-cghD >zW37K2&73z}9J`&1`;a-#$I{%)A*HEBru2M-y`pxhz4E}*=KY0#*sIFAo3h+>X7!xr >zW=&*kvvyXRDNmSd){PCdE5Z`Y`tVY-A*+kMvB_++@kYG8=~|B2d_L1u9`A3qoLFzF >z)`yy{Wkc+3Z~B-I7EUoA+MVr>3K!VbnT_o2gQCoisH^tQ*fe`rt2%qvz1{ZipElWh >zKF>8ZUmP>Fbvw=8T^r24RXO(lcNduh?-_HjsK6YWlx+@YWtby<ee9z>qs_72%gpht >zO8fZ5re!AsN1KzEz2BVLGTEHIHdxMV4AlBH$@1~r@p5+I&*qcD0QoedpEj%MWi{U% >zWLlJu*OqU!msayqRHi4Ye_pt@_O{bD=>z1UxZkvG=#LuE<|_?sct!(n?$dTxw(7&5 >zm1+CKOEsu=uLM_CNrx4yq~l_hkk{r)r-DLxWXyQ!oaU9#J}L5OM52TRhf9~{?IheM >zS;KF|Yu9hXwA;A=?S8b0K3084Bg((m9wiqwa^5M8nqI5Xd0R9l`+~$4R!dw`jl>UI >zCJ7x@N@8r0B;GBSo<Swr^U^r!_4^F%y*F8&_%ciTRODz<O>cd2et+#-8m#^DL$&|B >zUh>pHA5G2+k^y1YG$r}24D>mnsi9v>>W!;1sNq2wR9`30Tv;oFt2Rm6>HV6%WU*va >zuGS$_r%LAHH+1O8MLMitf)0PYK)q?H`fOl^j)>@{BW_1)R@;G+b-uMecdM(6+VP8y >zKIbQ6%KRm}`nrrQz9~5+^^%)&PR7mtL7(rtQ^seX*1VAAG9jr-^L@AL#15(xzk5d~ >z-7VC~bu;yaOJ1F_VYC(;n<g(VNYbel!{wz(A!^T0kZD8vNMU}Uyd2X}rl<TWulQRs >zBdV>=FqfsM<!voGdqig5xS+GPRmiLLHTv4}Lpr-^rM^D1T#J_!tEX{;h7Wc&^0|Nd >zHt}uh_g|fs)%d#e|7kUdu^L%cOY!*fWVN_|AKb~~fB%hhAHaJn$g=*vPfPb&na(vb >zWjG&P&Qmf^$<C8yc|7hf_zUhm9`C>RV~_Jiw;y-hAGfS~&M~Dfr3C2-(iB&xD@a?A >zz95Z3I)k(Z=?&5xq&rA^kp3VILOO)B2<efl(<G!zNSly8A&o*hg|rIk71AuETS&W* >zejyD*I)=0i>6xq3G^A@t+mOB?jYB$zv<~SV(mbSlNc)ifAq_-2h_n#tp{vtGq>HXj >z8<9RDjYK+$v=Zqh(oCeANIUs+(@zc>igXldDbiD<sYq9mwjzB+8jExmX)V%QSEsp1 >zcaioY{Y4s#bQozd(qp8_NSBc|BYj31jdU7mHPUOO*{)8vk#-~fMjDQE9BDbybEN4= >z*O9g(eMcIPbRKCv(tD)&u1@!n_PaX$M>YW20b~o1JwP@A*#%@9kbOWl0@(><E0DcF >zHUrrWWIJ4){XjOv)!7kbOOQQ5HU-%gWLuDZK{f{28Dwjay+Jky*&SqiT%G+vHptc4 >zA!Lh?Jwi4K*(GF~kbOcn3fU=StB}1yHVfG;WV?|4LN?6R*)e3xkUc{-4cRqh+mL-j >zHV)Z2Wb2T<LpBfDJ!Jck{X;g;)!9L03tgQ(L^cuGMPwV1eMB}A*-2z8t^ddJ!N$_h >Z+0h;`ENVo0Tx3FIbVPbgG)Bew{Rx9T#Z~|S > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow >new file mode 100644 >index 0000000000000000000000000000000000000000..906bd05f344ae9a806c1b20b8e2bfd7061d35fa1 >GIT binary patch >literal 1544 >zcmd^;&r4K60Dxy*f3=#`!F1C#&2)9u(lt%X)va|EQ%iCyup%ju1f!vX6gn&+cBw!L >zJXof*>Y-mAs!LW&1QJ<z=n!ZSL<b9G2%=Q_G2b)M>d+t1JZ8SxdGE1@_kF&GmS(5; >zYpl{IOvX+<*{A#U(sL+j^lIs+_Fl*IOz)TCmTMjRX8K;YPW6joe}BoKJFxOtFyL|y >z55yiF9&nk1LrLDcdjV@>tbJ&Fb^N3|E^?wSZgxd5{zJ^Tb;9FbGj?e_VWdwb-t1Dg >zD`!>G`IBnxnI@Iox<{oPs8H)_HmlT<47EPns?riIDm`jW*~9G8{yAP|ypQu|wmtS| >zzM7Seryph3-AS1pcp-BxKav|d?#PX&`ebfXm&`jjqMRqXRlciNZQ9+g3T%E==-jUg >zza3UZ32n0IO}Q$bYmi$WrmL+JC9-7DBV7-YWNBxbEb9@{-5epebtJ0o-YMxh@?Dju >zJ(ph3TU8NuOID^nQI*rrRFyfPs$SkuJKlAw>f0Ao&DeEWd-1sP)z}(M<`8peNN8Ai >zL}Wzxvhaxc%M!KZieA3t$I=^r?qe)Mq!#NB!5S(=-Z@jG-k)Y))@_OwqR4I1U(1mz >zVi)!mbtbD2iOItD`?(|6l(KMM<X(K9cWY{WqLx{&XE{rKxt`S`E4M&+y*@qlp)pLX >zrungWVC;nO{oAiy`ccELufN{;p~v3)!BL2B5a%G?8Px7U{DU|M@z9`l5#pmk?IgrY >zgW64qpAbj+dpw1>3h~vTb{66-#9fHL5QiZiLtKXV3~?IbHN<U*-w?+ko<m%R_zrR2 >zp!Oc(KE!{6x&cTBkQN|4K$?Jb0ciu$2c!{5Cy-Vky+E3QbYoDr1L?=0ZV1v5q$NmC >zkftDALE3`!1!)Y@8KgBxZ;<97-9g%e^k+~v2<gzEZV}QWq)AAZkTxNGivKxKi;g-c >G-|`bm1(CG? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia >new file mode 100644 >index 0000000000000000000000000000000000000000..3e663b215327d8899a4b3fbe4623f066630b97b2 >GIT binary patch >literal 2016 >zcmdVaeN0t#9LMoP$d(r$zG#Sgc`(Toy1)g*#K4CL@PVtxxEZO$QQ?9`lqdwI;wG}@ >znER@1&Q)7YVy!vU%^o&;nC6^rj?PxDwZ=MWtLB8YnX`1ve($sOSAV(nPv`8O*V)~@ >z|NY*d==!a(0_$H_g87CI*Ix7CeIhUKzn=c-_>q%dVEC|`c(>l0@Wn-YVt=tS>A+9! >z<nEv&ZEM`5Eo07<YR{e;nc+QBc-~IVJm*ZC+Ha@CA9qr2_1M#|?{{W=(`3*5s?iC4 >z*6pUA*yp9a9dpxr8@!BN%iUScmENNpv)$QMSzczz1oyE}qBkcv>OP)0;>}G+wCCOq >zIP-oUv9rFt>11E{+J559kQ3@ZZRhlza&o(m*m*k+JK_2^JHK|&D~KF&3rp3TpR?U9 >zN^A8N6m-afu`XE{?9+wAo22+&yDs{?OrH9oMoR|jwDjyEUEH%wm%Np#OJkY3th-pA >zu1L_b`k*{B=T|K+8<UEJ%UYTFqg0OmA}iw0$%>&%vhw<ISvB~fR9*Q}BL{nB^@;a% >zO-qZ|z58_S^9S_V<_4{PvRR{5mHJ%DYF!t~(sg&jT9aHMHQ!Cq7jDm!^&kJC8?FXq >z<GV>xd*-IR*mX<l`i8`*yDFP@-_XrVK9Mc8SF}Fkm^73QYV6^Uv@uP!@wcPeG}fwH >zFLmlm!%=<tgALkzahtsIW~sIeRLiSP8TwjJk!)LABCW9$*`A*+JIeo(wj@j1^OCjw >z_iNHI>5g`|7o>Cad);|zK;9TStGkY!*WH8f=$_7g?K;?{)<ba*cE^wVPjAc0SZ<D> >zl^u>7XIZJUtnvRm`KBrowaUw@c|`eDT%7-iKEMJ0lmD6PzPUK)ymQ!*1CJbf<lrNR >z9|-`700{w!0SN+$0to|&0|^9)#Mgv^#DWBaM1zEb#DfHcM1+Kd#DoNeM1_Qf#DxTg >zM23XsYhpu!L!v{%L*hdML?T2&L}EmOM508(MB+pOMIuE)^);~~!TOqLk#LcCk${ni >zk&uy?k)V;Nk+6}tk-(A2k<gLYk>Gtz^ho%=CVpf9kP$$J02u>h5Rg$oh5;D|WFU}{ >zK!ySt3uG{S&1fLQ;cLbN84zSdkRd_F1Q`@$RFGjo#swJ|WMq(`LB<9d9AtEm;qf)& >zgA5QdLdXyyV}uM6GD^rWA>)J$6f#oCP$6T53>Gq4$Z+|Z@j?d7*Nhl4WXPBygNBS6 >kGHl4W;s18v0%q@W3Ru2Sq%gNAH=I`(isXm=xA}p;0b|0?X8-^I > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo >new file mode 100644 >index 0000000000000000000000000000000000000000..239c0174d361ff520c0c39431f2158837b82c6e0 >GIT binary patch >literal 2251 >zcmdtie@xVM9LMqRfk?4(Z-2m9fRIS1cJdqi5tq^l%)GOd(?~^75wR}H%NV3anRBi& >zeCt@|$f@O+HN*a(`~$6(+GyeBFXpUVTdb@!x<tZitUk|gYyDAM|Mf@T@9z8f?z{W` >zaofF~fu-wea;(1{vE~UMju!Lb{`Tk0rOnl6wO!a))qT`o)pKROoPOP@;a9!#$*w#( >zvn5^5h7#o5s#v*tBvr2+^2zrvd!&DRhWyZwB9U5=AIlwbz4W>aOz)E$t_w2gJS9I# >zM29j*%24E-jtTFMjP=izak;-}eA-n_82h<8qfe`I;9VWxcSP?vzhCb>u~QR|9haoT >z9g_UYKAF(0lCtS}NezbNuH~y`qAwt6g~c+-T_EX6F1h=*@#2c{s%tP$Cx4Z$Q+gA0 >z>Zw@0r}L(|4}PoDT0hl{tsiUVhGUvl{ibGDT#}qnr{sFNByZ76lApX+3UV5xV7N(U >zB(~~|%PVE(uk||XxL5A|tXvD*E7j9AOYhrOq_f+SbWTm07Hyp=_m{+|w>nYgreD!w >z@354_e59pmUr1^H*D^2qeVG^TmIwM?lldKQh_B~8^|v(3g2M;&!MZwmsQCq5`0$Im >zD7Z$;rUy0PE7ir$1-isNMVAa^X?c8!lwTa9j|@(hrSII(Wxa8-eE(>v=)5K?ng*n@ >zH7r$?y|Qxice-l!QCVHlqtz*UWR0goYi@a4*Cwm3{bsk;4u^DIccVUfIiQanTBgAd >z*URJEJzCdZCQsC+=#$&>W&OfJ3Dr2|sq6`|q4;NcdbB0=nekd5`BEB24Qa!flhW9K >zNuPPET{echbkm*>baTgEeYWwSHnlWqlq1R!J>nnEsF;!e{b^Zo<IEq~N=kK%u&hyH >z-TLSCk0*aU_xS^sx44W;fHxfGKywrL_u1?)U$kd)(|*UYeltg?e^L;ck*%2$GACqG >z$gGfQA@f2ehRh6^8ZtLza>(qE=^^t&CWy=snIbYrWRl1%k!d3Hv^5ju=P*-bs>ocC >z$s)5wrfX~Fi%b}qF*0Rj&d8*ZStHX%=8a4onK?3bWbVl1k=Y~DN9J#95`bg?Ndb}r >zBne0skTf89KoWsu0!amu3nUpxHjs26`LHz!K{8@%Qi9|JNeYq`BrQl@ki;OFK~jU{ >z21yQ*9V9(Sevkwq8L~AgLULqll7wUlNfVMMBvDAFkW?YLLXw4K3rQD}FC<||#%xW> >zkeu0?q#;>D(uU*>NgR?nBy~vckmMoRL(+%j4@n@BK_rDp4sA^mkt`x<MDmCv63HZz >zN+g#^GLdW|=|u90BoxUgl2Rn6wkD}aR&7mMk-Q>_MKX(|7RfD=TqL{J|FFApCdJdT >UiL%?Dn~|T9<@RT1VP<aJ?<;p%>i_@% > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris >new file mode 100644 >index 0000000000000000000000000000000000000000..cf6e2e2ee95355039a90146a7f77d14224551b65 >GIT binary patch >literal 2971 >zcmeIzeN0t#9LMo{6$BCSi-wq>n1rYy&ybp=hDa(P>P<;SFcCG$j${r^Lzgq3=Ds#( >z8JehwPl#5i82J2zOUY_xS}x0_J<Wd2oK`bC?^9c~{%EZ~`loYu&g<N>d&eK_zCWJP >zQwrl<e>qy(PdGVh?UVbkdG=*Re)iI`^b%8cKFV5CzrtF3=uz|9;-9T`<=str{wA}2 >zp1;`;-P&xNonb1H=9^99!mY}PB(piP%xuZ&Vr})AYqnlbw6<N#GuzK+o2rxj&5l!> >zP4(t*v$K4twd+N1^ZMec<_)W}^=9!Rt0vpa+C3=7?1{N*?Tyc{YFjl}wRiVf`@Y>~ >zz4bx9sr&GRsc+b8_SbGP2iE0T2VYrY4!vs3;gTYAWOA-Knv-RY_4T%n_lz|sdap7k >zbE>S97n_$i6h&S>eQk)G*&3{k8&c(+mlEad&`&R)UHqMSx45mmm(@>O)b(=tZx1mo >zD<){b()QA7L7K{pWDP8c)YhJM+9q>=+>`L528DmEZQFdT!A;L-@Qnl7?#fQR_x*Bh >ze{_Y0)bE$js%q)5W}S3grV=)1zH}-omixv|kj@z%3Gb68_eUj5L};XR@oy)Q-l-aS >zGf}&K9--aNwbky&ee{8v+Zt8zrS@2PQKJ{UtuZs|HMU@f#^qj+_~IH#NU4*=;j1L6 >z!&*s>FOlRsrP4EGrS`luUV8mBQ+w}Em4`mc(LR-Vno`$WA70pB`<8`jzrt|szo3^q >zGSFL73qoW-#5GMzy(0s?PicDiCz5{sstjs+SOzsV$lxm*Wk~fl$vAybGnX%utg7`o >zblNn@UiN|x8?{7-7fsX=4;HB>BV8X0&eD-l-E`!wSj`C<C^_d_>*F`O%IH1c>zH$X >zGPXQWa%;YkaiupTZ)Kz8=be-BbHCCj`tFqpxu>-tY_&{Gsn$Z@-8!j*>ZC7T*2#B@ >zbxOl5ee#k=r*0XeMJJ}qQ;Sk`TIC3NdUBXr3zKB}us%{;7%b1kb(9%tKghFzE}0n< >zq%+NDQW9`WOU@pXS=TS<>|K@eTw|TiS$#z3R<G6PXH{tF@=|qsH);CMUS7V<e46<* >z_iFCv>(|2nzk0b`P2%jICRZ<)D?r@7yyG|f=X+P6%N5$m9rTB5dp`5~bM7-TJ+5r~ >z9F;bLi^rAfoX#8jvCHLl|9Uz%&R^o<c6<IlCHw3TIw`sR+xPC;$JB<wOOdo7d2zH8 >zgJcFt4U!uqIY@Sp^dR{`5`<(3NfDAGBuPk?kTf~kc|sC}WC}?Yk}D)xNVbr4A^AcQ >zhGYy$8Im(3X-L+Pv^m;&LlTE%4oMx7J0y8X_K@@;`9l(jWDrRql0zhkNEVSaI@)<e >z5{YCINhOj?B$-Gy9qn`?`9u=RznP43kWwV4NK%okB56hPiX;}vERtFzw@7l4>^j=% >zMe>Uz7|Ae_VkE~%l94PUX-4vlBpS&yl4>N^NV1V^Bk6Xu^Nl1N$vBd7B<D!dk*p(W >zNAiv&9?3kCdL;Kq@{#N#>36jAk4%80Jp;%TAaj6B0x}E8G$8YUOaw9$$W$P6flLN6 >z8_0AZ^MOo=qdg<YlsMXRf=miBE6B7U^MXtaGBe23AajFE4l+B)^dR$tOpv2JL&y|4 >z+H-_V5;9B3G$HeZOcXLx$W$S7g-jMQTgY@F^My<pGGoY;IoflEOd2w4$h0BzhD;nX >zbI8;obB9bGGJDAMA@he!AToo<6gt{-h)klRJ&VXRBJ+q$Br=o8R3dYUOs4Dq%?$WA >do9SndYmc~8dupRH6QYx%W1}+TVlgJc?-wH4z0d#v > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica >new file mode 100644 >index 0000000000000000000000000000000000000000..79c25d70ef09aaeec21f0a10a029650967172a80 >GIT binary patch >literal 1957 >zcmdVaYfQ~?9LMqhL0H4S7)2!{xg6a~D7WL3s9ZY8CAlQGB%zgCF3rrEeOY4-b6vxT >z2jM}?T<4O6HN%WC*O}Qcw>5t6|7Np!;F-<;od5sTPMse8-XG7D`8ko+A6E<W2{%`< >zx%s*ETJyNxB<4x&%h7W4u#eX5cgd}7(Ne!YSn9ty@^9}elRIfc)z_Vs@B8eycDlP) >zJ73(YerL{#|IsQ5*tJKxl&J)+S|?p|3#8k$+0s45BSG<Q>EVo(VE+*5*~(W!yj&Xc >zDO!6y57yod9ktKp7TUM^i#iX!)_&y=G_>@FhAlgz;n~MDBJ;jP7F0`ALXAX^-!3r$ >zyCpWVNMajHB+jo~;~veF0pAOC;8~XpdYGZ{m06llGf)R_9Hv8d`s>h~ARSgZK!zuJ >zsVm!0Mg+f9x2sVSy{>6e&|^t@_d=4Jo|ojht1{}@0U2F&L{e(cY3i0TNjthv$K>V7 >z*s={eZqjBQpF2m>`{$}BB}pgvr0GOwZ=Lu#Tr)Z(O2)l*I{8yCnR4o*PHpg(X?xpB >zX7yW{Uh+Y*%IjoCR)fr3{YGaEIW4m@Yc)HtLgpk?X-><NIyXRd?yDU-udzVqUoF-J >zk372Y&{WO6vP2ebO3=K@bXhzvQ1ds&$dYmKQjp^#OC!3-GWS<m-qw=Bunt=I{;3qT >z`K(3tm!$aJeO+;)QdZX0=&Fhfy1Ht&t|>mKC0k0=(X2^R^KzKCSMz`QvaI%T=6qRg >z#A^2I>EG4S(z1Sk^4pYDkL7Z6r+ds791h-G4u|LOr+J0>L;Ey;vA<(kKg=~f{{2Yg >zbR#DmIpxSnM@~C(;%&{TM@~L+`uVpMU~4KsN<eBria@GB%0TKs3PCDCN<nHtib1MD >z%0cQu3bHj7AtfO-Aw?loA!Q+TA%!88A*CU;A;lrpA>|?UAqCo+3Xu|RO^ryANR>#L >zNS#QbNTo=rNUcb*NVQ10NWDnGNX1CWwx(vJXj@Y?QZ`aIQaDmMQaVyQQan;UQa(~Y >zvH-{mAWL9t)&N-qTeAwtG9c@KECjL=$WkC{fh-2H8pv`W>wzo?vLeWmAZvmwimh1{ >zWLc1PK^6vC8DwdYwLumKSsi3~ko7?p2w5RyiI6oy7RlDE60%ITW}T3QLRJb{DrBvY >k#X?pKSuX4Uo-S`QY5gMDG-qm5XiR9hGc_U{!=k)@0!L5Jf&c&j > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague >new file mode 100644 >index 0000000000000000000000000000000000000000..ba82f311b74838347de6dda464a22e95a16e0408 >GIT binary patch >literal 2338 >zcmc)MdrXye9LMqJfXHRazG!eru7!lukvoJ2nH_<lU@9jgl|V(*B7&1KC=E;ITx0I5 >zGMz)xjInA)ZDFmUwXUOucs&`GYs-~s<=o6kHCDg(6ERx;@AGiZ>&L@(Ha0%*;aRr6 >zCd2yQ6=a_9;@V+eoWnMow~k59st(_|tNVs}w6p85zWl!G{?<L(AKah=7Z=E}*PS|e >z&@IPzX32>c6Xm2gLQWohr|Q(IKsmiRTF(@pk~6z{<9&YKcwb4be3jfQXI<0e>)_oo >z<fxaSOHCrbR@aABC+QSVq)siJC%0w(q2UQXYsA!V)#-mso!36l$O~`j?WYguv`=<u >z)RChSeW*ub_U)J0HkG)IFGzf?SMFG`TJ9|INJ3tLOn2o-Vsw(+H7Qb(0^FK(Jxgc& >zkf_PN2)+BWK)t7TSY2J0bY}ZGO=<m7Q#TyZwCXoCy<$i*yuFf{-zQm1c1w0lr{rWb >zNzO=%<VLk??)jB6>(54=ebg=YeN(P^-Ibc(H(T%DI#=g(MC$`J2|BlRmONM(pzi7@ >znU{D`3)~}881RJ_C447ESALXY|Bs}2uwUk1cvTkkydfn6A8P6LHd%P+6@93#P8PLo >z(Z!Fvq)TeoXxY8B>M1GGhn)*`sViBR-bmB(@Iom+J4GM8K0}th`<pKJg~*BnVN%ii >zi#*nHO)A?5rK-{=D>q%%Rde2x)fEF;9k*B3<o9Sz&|zI0qq_E|J-TkhtLyul_3`r_ >zed4v{TKjo}Jh?4j>$=P2sdaH$zcpJL7Uzk##wkyy$I6C+-{qMwOBz$dwejlr(iD0_ >zn@)Tx%~yu>*|)ppxxqf&xc6h-)YGZYH+N~v_7?SX`1wy5yB+2jF#5o6V&JW~Eo<^N >z^LK4U$2%riR;XCP|2<olWAgYXi%LC~yP%9Wk5y#8F_*)^mwh=Lo|`Yqd@LVrU%N)n >z;lra3{xVl=@y=naJ$~7irSUy$Ll%du4p|<uK4gK&3XvruYeW`_tP)wKtyw3sP-LaZ >zQf<vzk;U4Y)gsG9){86{S+T8IGQS>cMiz~%8d)~7Ze-!e%8{kpnzbW~M^=w4A6Y+A >z0Hgv)36L5fML?>6lmV#&QV66HNGXt7*qUM>)j-OD)B`C9QW2yiNKKHUAXP!ig46{m >z3{n}SG)Qf1O>vOw*qZVn^+5`RR0t^%QX`~DNR^N>A$39ug;WYD6;dmtSV*;OO}UVI >z*_whO6+=pf)C?&aQZ=M(NZpXaA(cZ)htv)!9#TD9Q$D1Awx)nc1(6aWHAIStR1qm7 >zQb(kaNF|X{BDF+{iBuCQCsI#aQ&6O$NJ){JB1J{2ij)<pD^ggbvPfx>+9Jh8s*98t >zsjsamFj8S#Q(~mXNRg2$BV|VFj1(HFwB_(ORSp=t{mgOV=mY=2pj&bO+i6p4(`i#{ >y^DjxLSpT$n>}*;bHvXq2CeSx4_V{F*bBKxg%yhEuD$PvEPDyi>rl(<QX2{<symJ`< > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga >new file mode 100644 >index 0000000000000000000000000000000000000000..b729ee8c2ee26c7bd74535ead106e8160afdf181 >GIT binary patch >literal 2235 >zcmeIydrXye9LMqB38)hh{%qla0MU?(cI1wdL1IT>2FH+dBvKJGKrJF~IVhDUWM+-A >zZ^de^OfpB88MS7%Lf2)kQ6imxSZj1~xuUUVPb+7(LH*tju-01ZkN)lV?3~xb17~cE >z&pWtgOJk1u+nHgW@ZwnJ#eFI_&%g8N#Nm#viJk+cdwb5bPrNqz(^mtp*Khb_V?*WO >zXt_T7ibsZy`1Gew=IKy-iVn$RTVv8*3eAfBqS)gesr39d<NesN=uq5<ulR<+r$X^3 >zd+dZ`PuPjiwcE2hci2h0>+LyBtL?e#O6?mf7Td{%>GnKtoSl*or&6OLRa!*8m3A@J >zO8?el%^!AK3r=6QZaO|@d5?}*3%ducjE+-Q=FUDVtNyT+U3*65_)n^w^JC|7i~4n5 >z)zdmZ@sM7W)1nuRx9NiTZYg;8$8$?g`SdL#HB#7HCq?~B<ktPmWa+aBQrws<%Q|k> >zx0ObSuRdNcPZ^aG-?%P~_*lx4zt&|JzSAqhKF}+M2K4RcU)1G&uj-1y_r%}TsaGC* >zLGEa7)|H+6WYwLIOI1^Y1Qs_*u%b*>dsa%dcfM3#%95IxQeE@eb#m9mbiL-pFS2$x >zQm^ZoscVn_px3wktn0dm^oF`&efOR**|_v=eNXM6)F&O(4Mly@=zdE!C5mkN{u$Xk >zzFoEqw936-2Ian&*Gkhz+w}bhiln(WpdZ+rBwP3A>uswF_4Y=O-jO|9?<~2jADpT5 >zuFM$OWq+evqAy8H=(KLV@VPwnMz4N&s9$y;{80Av9g@ARN2RT+O<Y%)D=hq~h%3z% >z?w-7^j-0x#iTdjmc5O7*6q8^4w|Avx9WnocyoW0_?@gCmsf0NyN~r}|N-Gtu)%84a >z#ZJE$6uT0qzdL>Jn)~Ocrtd5KK~-g56@j2CDG4fnpj`Qkz7q4mA6RZ4nj7c1TuQl| >zGx_z@yUP{)_a!}Ie%M*kuT!7;-JI$ZXV)XkLe_;W%+ah2SsJo7WO2yqkmVukLl%gv >z(9tZBU&|ViMIx(oG|NQRi7XUZDY8^#t;k}L)gsG9){86{SuwI?WX;H;Ijow)vK`I3 >zk%c2GN0yGP9a%iGdSv;?`jG-472r?;M^gi&2uKx>G9YzuG=)Ga;b=;M)B-66QVpaW >zNIj5(AQeGMg46^l3Q`rMEJ$6D!Z@1BAf<6MwLyx5R0k;!QXiy1NQICRAvHpZgj5MB >z6H+InP>!ZjNU0o6t&n0N)k4aJ)C(yXQZb}tNX?L<Ayq@lhSUuy98x)?bdIKWNb!*B >zA>~8rhZGR0AW}l4hDZ^SDk5b>>WCB)sU%WLM^j6rn2x5JNI8*uA_YY%ij)+oDN<DR >je^Sj~;vbV5X<EE6hxU5?xf%HxS(&+Be|DC0mlyd5O7kz? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome >new file mode 100644 >index 0000000000000000000000000000000000000000..bdd3449e76a51eb8ea7693fbc1ebeb5be5c1e5b9 >GIT binary patch >literal 2692 >zcmciDeN0t#9LMo<@8t@j(icrJ0kO!?L<A8P6HO5v36^qG^AVp=i|9y5S}H!}$~pHf >zP3M5bhgc6vtuWVoXq7sfh=yTVIay{_Hg`62YKr!IAI6x~-=1^td7XP0f1dXzFll~X >zU+X_duzA9lW0(1I-)_0Nln%UZm)6%blpQ|il<&22-+ukJy|p5$p(6JkXWO#fx!b1< >zuy<s2$vv8%;?!ImEyv%B(At$n4Yk|T<;0u)<iz<S4JQkx={JR)q%Nz@IW;6nzs;<Z >z`si!+>7JXN)0dX(_pLX{jpRMfjWdTDZbsGFH$SU(Zr!T38@Ft7ZeKX*+*$dFZ5{sD >z@yvY7_LfbueZya}gI+Cm{Jl0ftqL~S!EF{gAsK_5kV_Ms(1Zzg=&@9%ZCI+^_Jc^L >z-7gJJ*xE+tzT=Iy6m_w~cb~J{=iIW}*KT$?WRH;hlmFI^v6r+{ho3aUcU&W`9MsO| >zKhy_KRcM#5-q6VX2PA4&l|+|qm9FblVwS9sZuy1s;FMYNP*y-<2WQB`@%^QHRGd80 >zwzI_f(>3mDKkad$yY{T_q>mmB)?U@uHGb#s+I!;<ny~tq_9@!0iL-ZW($q83x3F50 >z)AmWfahoJ1x?KAAT_pV*OJrc=Mjd!|hNRvs)<Fl-<*^?p>fp-hnznC{4p}oyhn7a^ >z<9V?<Y;~#(AL-Zh*^x4$`$f%2Z<LY#uXR-HIT>~NSIP8!A(^#D<%#n<WOUX0l2!A$ >zX0Kl-V|H!RCkqPXsdcM#?1Z&CE`N^Z49M3&)+l{CVvLTD@2TUjCF;bEBW2=u?e&?f >zJ!I0Sf9d4<P?=H@E>o-jlxZbbWctQh$(>#=GnW3LGl%Y#SyO9tcFY!;lUAj9A$xRg >zwCdd7HtW2`LY;qfu|9h?pwGQKS@Vx9kmp}Z(}Kzzd0}3R+G|o|!Pvo4m=_^0CUupf >zj2p5r+>+ux9ktl`Sr&y|(?ur_$>Pgr^yQB#<(1lfx@60jy0ofXmo46@CF@Jn>uEWC >zK^{IHZ;;PDn{E1a*VXH9b?;BhYEx}qFDt5>C&;qG#A@AqZF<u3d|Y<GO3%pQ65u~P >z=0I~3`2UwV#Qc#jN0s?<AAX%*=D1^yw1Zu1(B8koMqYAP^P(d!JMzLKFFo?&BQHM^ >z03-rP2#^>cK|rE_gu&Is0SSbwi3Ab~Bo;_8kZ2&`K;nS}#MMLu2?-JtR}&N@Dy}9h >zNL-M>pc@%(2n~mc4G<h8I!Jhs_#gp7B7}qpiIJ-b5)vg>6DA~1t|m}Oq>xY{u|k4{ >zL<<R*tBDs9FeG9~$dH&JL31@xL&Ao{4GA0)IV5yQ?2zCg(L=(A#19D|5<w({NDPr6 >zB2jcTVMOAH1QLlP5=tbNNHCFTBH={hi3AjhC=ya6rbtkcsJfc4B5`#!fkh&VgcgY{ >z5?my@NO+O>A^}DsjD#48F%o1X%1D@zIJ=raBawDBp+;hj1RIGq5^f~kNWhVZBOym( >zjszWvIudpy?ye^ANaS5j=#khX!AGKxgdd4NG62X3AVYwR0Wt{4C?Lati~}+d$Vj-F >zp+Lq084P4Jkl{ea0~ruxM35mt#snD@WK@u0LB<6c7-VEz&CnoY<7x&6869MJknuqV >z2pJ({h>$U|JU(yB8RYl!@%sEh?%8b9ue+|kR>AlFY@Q=CN@kAC_?XQI6RTbGwdqOA >l^DHw;{~o56Wiof6X03WBv0L%k$q6Y5iSgM<iP$GO^dBI59Af|g > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara >new file mode 100644 >index 0000000000000000000000000000000000000000..0539acfd78ae58d4503ea88c2027c4b489a207e8 >GIT binary patch >literal 1253 >zcmdVZPe_wt9KiAC)%_6{;i1~nS(e$_)b%!<%u-vL4r_wM=nw@DltF)>As#ve4zwVM >z2#KI5LXu7)9_(b2hoFn@5Z#9GgXj_wBMK^s^?YCFA%dV|&%0-zcMs1Fd!O$zr!Jh2 >zsXxXhv%+Nbn#ui^oOzp8ow?^TzTvH*`%BvbdD~yLlJx(u<^mto()L2!u3f&qRQF;^ >zg3l(T{^6MHxHTd>ubq^J%PHA)Iw8B$VQK8Dl|3y!X$n>s_xjd~A$KSn`WndYd+*PM >z)oT@g`%y<;t?K6ayl$C!sax;P>FDIN-aj^_?Q;|Qz?oTzjoy^D?mN<c;*!McN2Mb+ >zBpp99lBm0=6RRE4xt7)k7Xxyr5Y=5z<GOpHM)%zC>%$K|>*UCHePnX8^!68Y-`S!Z >zZCcd*eQ#vI{aB|O=Oy)NK?W=D$zcAG9D8?Fj?a!udihCq==PQ3c&SuURz>Cd<#LxV >zkJsa^@>Xno{F@%H%cWHGi+PwTVk>i>NUAEO28J#3lz+ds%=-GCh;5mj!3I^s9@g2J >z9?Ga@yUomYGvj8Ov$V{sJh<N&nSVIxZ{;tUA6w$YkyB@xlSfV;DZtTGfRupLfE0mL >zfs}#NffRyNf|P>Pf)s;PgOr2RgA{~R<Y-DlYC?)~G*uyGA$1{zA(bJeA+;gJ85Gqa >z<stPU1tJw9B|4fKks=*Ul}MRLok*cbrAVnrtw^y*wMe;0y-2}G#Yo9W%}CLXrfQ^Y >eM^iUaI8r%MI#N51o3sBvi?8l7|BIg1_Ud0fCJ_Pv > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino >new file mode 100644 >index 0000000000000000000000000000000000000000..bdd3449e76a51eb8ea7693fbc1ebeb5be5c1e5b9 >GIT binary patch >literal 2692 >zcmciDeN0t#9LMo<@8t@j(icrJ0kO!?L<A8P6HO5v36^qG^AVp=i|9y5S}H!}$~pHf >zP3M5bhgc6vtuWVoXq7sfh=yTVIay{_Hg`62YKr!IAI6x~-=1^td7XP0f1dXzFll~X >zU+X_duzA9lW0(1I-)_0Nln%UZm)6%blpQ|il<&22-+ukJy|p5$p(6JkXWO#fx!b1< >zuy<s2$vv8%;?!ImEyv%B(At$n4Yk|T<;0u)<iz<S4JQkx={JR)q%Nz@IW;6nzs;<Z >z`si!+>7JXN)0dX(_pLX{jpRMfjWdTDZbsGFH$SU(Zr!T38@Ft7ZeKX*+*$dFZ5{sD >z@yvY7_LfbueZya}gI+Cm{Jl0ftqL~S!EF{gAsK_5kV_Ms(1Zzg=&@9%ZCI+^_Jc^L >z-7gJJ*xE+tzT=Iy6m_w~cb~J{=iIW}*KT$?WRH;hlmFI^v6r+{ho3aUcU&W`9MsO| >zKhy_KRcM#5-q6VX2PA4&l|+|qm9FblVwS9sZuy1s;FMYNP*y-<2WQB`@%^QHRGd80 >zwzI_f(>3mDKkad$yY{T_q>mmB)?U@uHGb#s+I!;<ny~tq_9@!0iL-ZW($q83x3F50 >z)AmWfahoJ1x?KAAT_pV*OJrc=Mjd!|hNRvs)<Fl-<*^?p>fp-hnznC{4p}oyhn7a^ >z<9V?<Y;~#(AL-Zh*^x4$`$f%2Z<LY#uXR-HIT>~NSIP8!A(^#D<%#n<WOUX0l2!A$ >zX0Kl-V|H!RCkqPXsdcM#?1Z&CE`N^Z49M3&)+l{CVvLTD@2TUjCF;bEBW2=u?e&?f >zJ!I0Sf9d4<P?=H@E>o-jlxZbbWctQh$(>#=GnW3LGl%Y#SyO9tcFY!;lUAj9A$xRg >zwCdd7HtW2`LY;qfu|9h?pwGQKS@Vx9kmp}Z(}Kzzd0}3R+G|o|!Pvo4m=_^0CUupf >zj2p5r+>+ux9ktl`Sr&y|(?ur_$>Pgr^yQB#<(1lfx@60jy0ofXmo46@CF@Jn>uEWC >zK^{IHZ;;PDn{E1a*VXH9b?;BhYEx}qFDt5>C&;qG#A@AqZF<u3d|Y<GO3%pQ65u~P >z=0I~3`2UwV#Qc#jN0s?<AAX%*=D1^yw1Zu1(B8koMqYAP^P(d!JMzLKFFo?&BQHM^ >z03-rP2#^>cK|rE_gu&Is0SSbwi3Ab~Bo;_8kZ2&`K;nS}#MMLu2?-JtR}&N@Dy}9h >zNL-M>pc@%(2n~mc4G<h8I!Jhs_#gp7B7}qpiIJ-b5)vg>6DA~1t|m}Oq>xY{u|k4{ >zL<<R*tBDs9FeG9~$dH&JL31@xL&Ao{4GA0)IV5yQ?2zCg(L=(A#19D|5<w({NDPr6 >zB2jcTVMOAH1QLlP5=tbNNHCFTBH={hi3AjhC=ya6rbtkcsJfc4B5`#!fkh&VgcgY{ >z5?my@NO+O>A^}DsjD#48F%o1X%1D@zIJ=raBawDBp+;hj1RIGq5^f~kNWhVZBOym( >zjszWvIudpy?ye^ANaS5j=#khX!AGKxgdd4NG62X3AVYwR0Wt{4C?Lati~}+d$Vj-F >zp+Lq084P4Jkl{ea0~ruxM35mt#snD@WK@u0LB<6c7-VEz&CnoY<7x&6869MJknuqV >z2pJ({h>$U|JU(yB8RYl!@%sEh?%8b9ue+|kR>AlFY@Q=CN@kAC_?XQI6RTbGwdqOA >l^DHw;{~o56Wiof6X03WBv0L%k$q6Y5iSgM<iP$GO^dBI59Af|g > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo >new file mode 100644 >index 0000000000000000000000000000000000000000..79c25d70ef09aaeec21f0a10a029650967172a80 >GIT binary patch >literal 1957 >zcmdVaYfQ~?9LMqhL0H4S7)2!{xg6a~D7WL3s9ZY8CAlQGB%zgCF3rrEeOY4-b6vxT >z2jM}?T<4O6HN%WC*O}Qcw>5t6|7Np!;F-<;od5sTPMse8-XG7D`8ko+A6E<W2{%`< >zx%s*ETJyNxB<4x&%h7W4u#eX5cgd}7(Ne!YSn9ty@^9}elRIfc)z_Vs@B8eycDlP) >zJ73(YerL{#|IsQ5*tJKxl&J)+S|?p|3#8k$+0s45BSG<Q>EVo(VE+*5*~(W!yj&Xc >zDO!6y57yod9ktKp7TUM^i#iX!)_&y=G_>@FhAlgz;n~MDBJ;jP7F0`ALXAX^-!3r$ >zyCpWVNMajHB+jo~;~veF0pAOC;8~XpdYGZ{m06llGf)R_9Hv8d`s>h~ARSgZK!zuJ >zsVm!0Mg+f9x2sVSy{>6e&|^t@_d=4Jo|ojht1{}@0U2F&L{e(cY3i0TNjthv$K>V7 >z*s={eZqjBQpF2m>`{$}BB}pgvr0GOwZ=Lu#Tr)Z(O2)l*I{8yCnR4o*PHpg(X?xpB >zX7yW{Uh+Y*%IjoCR)fr3{YGaEIW4m@Yc)HtLgpk?X-><NIyXRd?yDU-udzVqUoF-J >zk372Y&{WO6vP2ebO3=K@bXhzvQ1ds&$dYmKQjp^#OC!3-GWS<m-qw=Bunt=I{;3qT >z`K(3tm!$aJeO+;)QdZX0=&Fhfy1Ht&t|>mKC0k0=(X2^R^KzKCSMz`QvaI%T=6qRg >z#A^2I>EG4S(z1Sk^4pYDkL7Z6r+ds791h-G4u|LOr+J0>L;Ey;vA<(kKg=~f{{2Yg >zbR#DmIpxSnM@~C(;%&{TM@~L+`uVpMU~4KsN<eBria@GB%0TKs3PCDCN<nHtib1MD >z%0cQu3bHj7AtfO-Aw?loA!Q+TA%!88A*CU;A;lrpA>|?UAqCo+3Xu|RO^ryANR>#L >zNS#QbNTo=rNUcb*NVQ10NWDnGNX1CWwx(vJXj@Y?QZ`aIQaDmMQaVyQQan;UQa(~Y >zvH-{mAWL9t)&N-qTeAwtG9c@KECjL=$WkC{fh-2H8pv`W>wzo?vLeWmAZvmwimh1{ >zWLc1PK^6vC8DwdYwLumKSsi3~ko7?p2w5RyiI6oy7RlDE60%ITW}T3QLRJb{DrBvY >k#X?pKSuX4Uo-S`QY5gMDG-qm5XiR9hGc_U{!=k)@0!L5Jf&c&j > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov >new file mode 100644 >index 0000000000000000000000000000000000000000..e8cd6b10efe42e43315c12b28d87cb69bbb0c8aa >GIT binary patch >literal 1197 >zcmd7QPe_wt9Ki8s`L5aQ(50NY*&mxrr}Z{BnKf-WbyzbbMuZhee}o|DAv_cW4l+*_ >z6hTB0MWai94|U39M3+cCb+h1wPW>T%mmrc_&-Y!PIz+dgchCEIdA1$4-#0&eY&53+ >zSj)@_o7H1B&npV%c3X88o)&9{Rz|LsRt4tl+UnVK?RU@Pz(-Z8n@`xQXU>)Cr!G6e >z`)8fdjWMU;{84AknZ3^1<5_3jfuyrO*X%T=Hp+(9Itd5;(p0k`5pP6Cz6Nyjo6jRH >zFF)z%lefCHIIG*POzTY(kM!oTTiQNyNpCqgC9#uNrM>H>#P^(*M5rJgvHjBV<B%ll >zPwC{lUg=yI)?1%9$+r2FPTkGuu4fIpdorxIUspOk>eD+Wg3{CXL1zyCl-}@b-IsBs >z-}^vk8(&EF%PSeED$2mzJ=ytwQg%JOAi0@4dhp^2$>%~N`!c)rc)46wo~k94%ksL{ >zQXiL9;cs`#XIV-`-9Np>R_3{X$WyIUGOd;`-WN|i=A`l&-pvi>Rn%@bJ7IQQDUW%v >zcyL$#AEx>3_jk+>Dl=7NvK%vAWWvalUCpGCX(JOyrjAS=nLbhgQUOu|QUg*1QUy{5 >zQU_89QVCLutEmMk2B`)q2dM`s2&o7u38@Jw3aJVy3#kh!45`f3l!nyiYKlXuL&`(y >zLkdJHL`p<zM2bYJM9M_!L<&VJMM_0#bv4Bz)w-H;k$RDWk&2O$k(!aBaoo)Q|E=1e >LGPQTN#r?kkoc0kq > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol >new file mode 100644 >index 0000000000000000000000000000000000000000..f3b42b004dcc2af1d69949ff18f35fdfa4cf6088 >GIT binary patch >literal 1490 >zcmd_p-Ahwp0LSrXZq{6;&qbw6m!{c^so6B0rZt;W%*~ctFGMd3%m~DbjOZdt%DM=R >zr;=`Zvl1hbD5!2MdO;$|bQj%OBm@Z&aW12fdcH^WrVIao&f)BHcE&{U`-|*3((D%h >z9Lf3#7e`QE+-J4xmwsn&=96A$^qs9MHZoZ+-``JBqj!9A>~gUjyXBc!yy{+TN$N*$ >zihVqk@+<je>bInrbKK`$I&vkJ_N>Q9AGl<=uAecMb+#E9C!37SmL10Oy){Nwpw!5& >zSZ%Dxa~e764kPDgTWDohfwAVp_h|0WSZM9z(P&=pqfmbL!)X5NH?e|_bKZ5wIzoj_ >zhrR3f^~Bsq`-FS=RII3SP!=~{l^a|)WQqHPESWkjJ!##_^XZ^0`+Z!MKljOv<GWQw >z-vL!QSgtmmuTq<@r7Lf9wyNqVlUr)ym9HsHR_9DAzi&#`#1E_5?9a0H$5&ZreI@Hg >z-^#6D?#lWH{W37}LIp2&%7%g4YFlfo40WDW+jm`1jV*^%xO9JeB;bl#;;i#*@wRyD >z{OQx4Fne0#9GrZRV7D$voa<a@7b4@Q{vU{p31Jf=JyYl>xrHK8h$JZ_Pb`aOUOirm >zbLP{Tdy9)FyiR}D<K?^jgg`JN!us<2BO(~C7e1}eALdQ9eyDFaEEe<9=$qMtr;)ic >zYS3RWGcx}K{pOE8c0L`lBUvG7A$cK*A(<hmA-S3A<oHF%4oMHm&r~OfWQe4Q<cK7R >zWQnAS<cTDTWQwGU<ccJVWQ(M0s`Et>MlwcHMsh}yMzS{5X(M?fi6faKsUx|Y>g18^ >zk@S)LkqMaU86Z<I)pI~5fy@G#1~Lz1BFIdTsUUMfCWFidnGP}^WJ1V{kSUq!IU$oW >o)w4pTh0F_?7&0?tYRKG>$sw~triaWAnV|SjHt5j9%`bBN1rVfCY5)KL > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje >new file mode 100644 >index 0000000000000000000000000000000000000000..79c25d70ef09aaeec21f0a10a029650967172a80 >GIT binary patch >literal 1957 >zcmdVaYfQ~?9LMqhL0H4S7)2!{xg6a~D7WL3s9ZY8CAlQGB%zgCF3rrEeOY4-b6vxT >z2jM}?T<4O6HN%WC*O}Qcw>5t6|7Np!;F-<;od5sTPMse8-XG7D`8ko+A6E<W2{%`< >zx%s*ETJyNxB<4x&%h7W4u#eX5cgd}7(Ne!YSn9ty@^9}elRIfc)z_Vs@B8eycDlP) >zJ73(YerL{#|IsQ5*tJKxl&J)+S|?p|3#8k$+0s45BSG<Q>EVo(VE+*5*~(W!yj&Xc >zDO!6y57yod9ktKp7TUM^i#iX!)_&y=G_>@FhAlgz;n~MDBJ;jP7F0`ALXAX^-!3r$ >zyCpWVNMajHB+jo~;~veF0pAOC;8~XpdYGZ{m06llGf)R_9Hv8d`s>h~ARSgZK!zuJ >zsVm!0Mg+f9x2sVSy{>6e&|^t@_d=4Jo|ojht1{}@0U2F&L{e(cY3i0TNjthv$K>V7 >z*s={eZqjBQpF2m>`{$}BB}pgvr0GOwZ=Lu#Tr)Z(O2)l*I{8yCnR4o*PHpg(X?xpB >zX7yW{Uh+Y*%IjoCR)fr3{YGaEIW4m@Yc)HtLgpk?X-><NIyXRd?yDU-udzVqUoF-J >zk372Y&{WO6vP2ebO3=K@bXhzvQ1ds&$dYmKQjp^#OC!3-GWS<m-qw=Bunt=I{;3qT >z`K(3tm!$aJeO+;)QdZX0=&Fhfy1Ht&t|>mKC0k0=(X2^R^KzKCSMz`QvaI%T=6qRg >z#A^2I>EG4S(z1Sk^4pYDkL7Z6r+ds791h-G4u|LOr+J0>L;Ey;vA<(kKg=~f{{2Yg >zbR#DmIpxSnM@~C(;%&{TM@~L+`uVpMU~4KsN<eBria@GB%0TKs3PCDCN<nHtib1MD >z%0cQu3bHj7AtfO-Aw?loA!Q+TA%!88A*CU;A;lrpA>|?UAqCo+3Xu|RO^ryANR>#L >zNS#QbNTo=rNUcb*NVQ10NWDnGNX1CWwx(vJXj@Y?QZ`aIQaDmMQaVyQQan;UQa(~Y >zvH-{mAWL9t)&N-qTeAwtG9c@KECjL=$WkC{fh-2H8pv`W>wzo?vLeWmAZvmwimh1{ >zWLc1PK^6vC8DwdYwLumKSsi3~ko7?p2w5RyiI6oy7RlDE60%ITW}T3QLRJb{DrBvY >k#X?pKSuX4Uo-S`QY5gMDG-qm5XiR9hGc_U{!=k)@0!L5Jf&c&j > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia >new file mode 100644 >index 0000000000000000000000000000000000000000..763e074795b3c7143984c9b334bd6f2f5a50445d >GIT binary patch >literal 2130 >zcmb`{ZA_JA9LMqNC@3Bo`=cQ$AQ%v6N1pL1h>U=dU`II+sl+i6v4{|rL28H8xz?Eb >zN37<`P0O)rj%Xu$L9GW}vyBd?m20hBELygv)@IHg#_Ias?95H;o!7nld~VLYF<$Wd >z`Zn%p&NH_hxBZ5j6R<bW^Lp&Z=*6}2`J3??e63W*`U)g;AYDR#x!S+zNK1*``m1+N >zZOQoD>e-<?3Kx&Zc`k?M&Hbo7K6)$^e|4y5{=|u%1z+~{EIf0tC*l3KP2#EJCh64| >z%%a`{CVAg3lhWE`7H_UKcUF~~)S?w8&68=;6Bn4fqTMDVvaly3Fg%`d&F#<p@v?Wx >zSC{-t&yIQT9uE3FC*Scd>mTxG9eUB5y}Qq!)3nE%+b}qu*ReO0UpyiO8(xyaq+_x? >zuS=Fs24rPIzplKnMOOXYsjELIm3zLe*P?+&Ego5|_a0uOC9fpvea)%5=Flp+zdTY) >zn-b)K^ov?nIw|FmpJ_$v_fm1?C#jtNu~Y`n$%7NG%i6)Wq-yj-tv=E#>rS1}huYf2 >z+j~&gKm5FIXx*kYD_Yf8RiU-<>$J|ZMC-2SXnkC{)PFrkAGww(8&ChPo6fss^YK_| >z7``Nr2ChnDe^C65=Vi<OU-Yq(_hf6ss5T`Zm2Jg?+8p(+ZckF({`1S)GTEU!&UNeK >z7kv7}8=JKC)1C6<bH&;=P$N&ZBy0QOLfN^#NIIJ1WmoPZ*<JRh?1?qfnH{H{zx^Ox >zG1s*#bXK~re4|ef4anZ$i0(W3iS8dfrq6Vr)WDH|x~5IHSA;8a>Y6e0rYroyF>2QB >zzKls|vHyK0F~vj}6C);yXIFIid1;O-HvD$#`NlVu)jm^J<};<vUBeId!x)!~o6o7^ >za{2yy472TfZqBpz=6T^C{AABR_SBsYreVjKiTTJ#kf9)BK?Z}2#?cN384tgU0U;wo >zhJ=g>85A-qWLS=NT*$zXks(7v#>QcA97e}scpS#ZVSpS)$YF>a#>ioi97f4um>kCG >zXb0+OM~Vy;87neaWVFa|k?|q}Mn;Sb85uJ&Xk^sLu#s^i19!9|M~3cb$Bqmh89g$5 >zWc)|~kO&|lKw^Ld0f_<<1|$whAdpBPp>VXZK!V|Dqk)72i3bu8BqB&ikeDDrL85|$ >z1&Iq17$h=CXdG>9kl;Al=pf-i;)4VTi4YPZBt}S(kSHNxLgIu33W*dFDkN4&upDi) >zkZ>XKLIQ?F3<(($GbCt8)R3?taYF)!L=FiZ5<4V#jy8Ho_#AEgkN_ePL_&zf5D6j@ >zMI?;ImNCL!k<(^OT{EL@y239UXSr|pWwY=de~b;JO`{E@O=FB0n?@T*2|wE$#)aQb >qJ>U4I$_DcPB6&+C?H6ua(`9*7)Ki_GRhX5No$sm6&2gRz-2Vcz8|p{^ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm >new file mode 100644 >index 0000000000000000000000000000000000000000..43c7f2e23f3c37c24d39e78f8822b12c5a74b5eb >GIT binary patch >literal 1918 >zcmciCUrd#C9LMqJ0H+uu_9f+y@y{Yc^2lEyHOTaMU@FId=aC3S<Ub}-0udBOPUl)< >z?%T#{4xKg~YfjM%tP8Z3TBAj*&7C<>=N7B1m}4U*)mZ)BkL#wo_Bnf=*WsLV!Nu?W >zu`6~p<XZo^+~yN*t~boh`^VlfkN)J|o&CY_sd@f2GC%JRjY<7gW9Qw{xX^DkZu&Eg >zpE#!ruAR^)uDq`a7cWWTnL$Z9dR&rwRZ_b5%fjYXd2)NLJXLB-YN1b__7q53V!AvN >z887K>ucpr|)kQy~X+|(spZ)StT|6|ao>M>TlD=`xJot@fwO`ciy0e;7c|&qrha|6P >zSe9=2K=PB0NkML>6wLL=vV=ZecDq`Z|Jk7{E_vnoo8?+KP^Cq~EA)j!t8`_5qQ2OW >zs;dqzm(|5?_0}cGnzWzP=be*c_t#pIdPhp`{U~cgzmT<KBeHJdq^uu2Ev2KMtN(DX >zY&i3gZft3hO}z(n^GomPmgag5JlCvtX^C!)+n{Bh3@y8#t>rPrQhxn$eR*b)RDANA >zZVN`p_7l-kIW#FddZwkSZ%lSp1*Ll5FIuzmQ>m>S)w+};QeQNv4dEBGF-f)Y?uXhm >z*Q&cly7ZOXw(kCTn>K&7SN6PHq%8vhd9^7;Uptg9dp8$KYeSs0<s?hH?{|4U+LDf} >z810z)UOJ=hYv*@YrR&}eee?W)yfrqg-A69#zQJSqcGoHGIozYJ5Lal}!+%*;RI)i$ >zR+Ly_mX)~B75>kYPXa#M@;Z0G=2tG4^RWN_%syhi<mT!!H}9io`O92?nad6y@5An` >zZ8gYQb~NXi-*BdpbB&yB<a{G%+|itK<g6p-9Xa#Jxkt`Ea{iG9kPeU*kRFgGkS>rm >zkUo$`kWL&;D@ZR$Ge|c`J4ioBLr6zROGr;hQ%F}xTS#9>V@PL?rZuEDN7EeA9nv1s >zAJQPwA<`n!Bhn<&CDJC+C(<a=Dbgy^tD|Wa>DJM-i}Z^$jC72&jP#5&jdYE)jr5H) >zj&zQ+j`Z$mnn${KH0>k(BO8G10I~(h9w3{5>;ke4$UYz&f$Rjb706y7n}O_xquCB* >zKadSUb_CfHWKWPyL3Rb%7Gz(LjX`z>*&1YTkj+7M$I)yLvOkVygOD9Uwg}lHWRs9x >zLbeInC(9KQ8WQGy_%F+nN&X45Q)Z!}#Cot$k<Lz;C!du1ZR_7#^<b>bGr}y`k{quu >UV0-*|nfaO79)C_YX5~fv4Z~=$r2qf` > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn >new file mode 100644 >index 0000000000000000000000000000000000000000..18f903fa6fd864237a679dd06c6a55eecce89d98 >GIT binary patch >literal 2187 >zcmeIye@xVM9LMp`fk$-7`Js(Y;t-M)!~>3>T7$$8m~m$)C;5x$2cj0C0y!v%?}|Cs >zn7u1D<|=;_qaQQoA8Kp%d(Kf_bpNo{sO4&9W6gcHa%LN=&-0ttKd$vpfA+b3zmG4+ >zF`VP|jBMG}UZSo$+PuTX={Fb8i!F0IytyEH_+61BL!)v`E#EWNy*o5{;?#xD&W$!k >zFE;4U-}K4Ut2O$I7s_<3=lq4V+}C5bEd09Kmps$x`+dPj3unEt^qHFKTca<=GTu9C >z`;R|wXTJQjy=b`G&gyTovpY80w{5Gl7l&5ZIhA?#?SXWAi9cN}o$pb(?s6;l@=`1B >z2cNZUI@!uUd(~Qga@Gor%~%B^QLAw1eXFQv!V0z>v5H&HtCFs9Ra*77D%)^Cm1jPu >zDv~~EtSIT#6?21nWyXk9j<-tHnLFjK{i|iwOMa<t&ym$bcj&w8+)~q)q1P<AD77_n >zy3YNn)aQJw>o5JN*Cu|f*G^69d%k~7H%z>xL(vZ<d~jH=JAO>=?d;Tz!_Ub2`<|5z >z9owa8MTbN}^|H~oPMQPDr1?rvHl@|+O<&$Dn=j|-EvJ8#t<xU8?P#iQIr+1`fAAOG >zIx?jnXr0y%4$R6!tKQKMw?w5a>yX}FH6iWEr({Q_$c~>zW#?R%?3(P8N4|;3qi<}L >zj&pnUV+X3FbG%9K-kBwP_Lu9u>nn9vyH9r)FVa1=SM}qmO7AO5lYRDgy4QO}dShpG >z-=(kQi4)`c$*D8af9Mk#n0Q5=>Kl{6gM;FlmyqakC*6>kkeHB^{MYM7&$ZW0^RIg? >zNb$P8DgVt&DPNiSbK^cwDSx&rSt+kpDe=2MTcs+MA5>}a@2;$NrN`fiKf5ydE}x8l >zo_F$tuFOz4q9W$1scqsGQMKj@H#L}Rjd?b2D&=zVFEDVN$G>mp>&U+^XTW^kS<Y|Q >ze((=-nomcg$dVk*nvg{yt3sBAtP5EfvNB|8$l8#_A*<upu{>mb$O0YB3XvruYeW`_ >ztP)u!vQA{7$V!o=B5Oq!i>ww|F0x(@3+Aw5N3&#P&B&sWRU^wr){QJ2Svj(FWbMe} >zIjo+;@;R)ZLjgEcz|oYz(bNDb0#XH}3`iZ2LLikuN`ce@DF#vvq#Q^+kb*dxiXbI% >zG&Mnrf>Z@53sM)PFi2&P(jc`#ii1=KDGyQ~q(F|QLP&`mO^uKuAyq=kgwzQs6jCXq >zR7kCmVj<N+%7xSmDHu{Qq-2h!W=PSHsv%`V>V^~!sT@)|q;^R0km@1jL+XbV5UC(i >zLPt|Wq==5DibxreIwFNcDv6X5sU=cO^?x$?ulT2AdQ4;sN~mifTv}LO7%VCcgo}gD >HQ<>*aTU8Lp > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane >new file mode 100644 >index 0000000000000000000000000000000000000000..52c16a42bf1ab1b5db5c1e3d4b808ab37384ad18 >GIT binary patch >literal 2098 >zcmdVaZ%kEn9LMoPdKbGPeZlZ*fLKJJUV+QML_yOVpb46CHT**y6A=^XK*XRlYC3F< >zx$lEJ%ayB^W95uoBmWGYe`XCAGS|kOI@9S=agOd*PFu42z0aez)`On3b<WOto!y=L >z?0nv#RU7MatiK%|^9vV8r@43@_qMt1+Lu?~zj=o<aC4EI{lceb4-ac}MqwoS=Q+05 >z(-!fbYr6W#@DeAccY!_bhfR^#@HG3;0}mW&iLvAKM<>2=#2)XQa2}g|#7<an#F;Su >zYugtXiufK3UY%rxok^E!?8gVbiX<LACQ18yB>AI{WpbBF%9eLzN<*_ev1Xk-Sss$q >zq7r$^Um$5o>GE{UL`nAqHT`a$X8e?<Q->z#v~M5Q>Am;Wzjs(?gfD95_U|>T<)~)Y >zeyM@#3zE~^E4jselDBM^<R|Zuf}A!f810amiD8|2d94)w-m0^X1!eZ7DlO`+(c->Y >zI;V4<&iyb+pRG&PdD{zReyK-;wTbdv+D$D9j!LQLjFzQdk+P8+vT)2vSvc4)&tLyc >z7WM3t@`2-8v9n7S@BdVnG&af$UE6f&i|^^OhV@$cOoN8X%XGPKv99n>)fM-$wJM=h >zs?Nvj%DWk|>fo=sddMqlK8cg+-aGPA$1hS79u&J~NY-w>tuN0#B<rdNv^Hh8tS|1- >zy6A6oL$d0ITkmWAXtQqYZ`W5Yhji2DtF_^~CfWRMu{L&B%B%G$>U8Ey)6ybouJg%j >zfyvTR@|(OKXGv>Tg0@DkNn7kaZ98{b+D9(v8wa}O&A~q1vip>7?b)MmweQuAogHdL >zJ@ilKn6dxaX<6|fm=Dy76>F?zB~6Kn{_AsjMaT-4a8-tQD=Nyph5p6of1m%E;}3H% >z17r%w9FR%4npyBJ({MHOKqlg9W`axwnF}%*WH!ijkoh1JLS}?a37HczDP&g2v|P=+ >zkcqjPnITg{=7vlTnH@4cWPZp5kr^UWMCOQ05}743O=O;~W}?VUk*OkcMJ9{P7MU(G >zUu43_jFBlLb4DhO%o>?CGH+Kiab)JMX6ne?k;x;oN2ZU=A4vd`0VD-T4v-`uSwPZ& >z<N-+pk_lIn3M3b<CK*UJkaQsVKoWvv1W5^!6C^1}R*<wHc|j6`WX9E`2FZ=9Ne+@7 >zBt1xekOUzaLQ;g}2uTu>B_vHqo{&T#nL<*9<jU0~3&|FeE+k(_!jOz1DMNCGBn`<L >zk~So7NaB#pA*n-h=W3FNWY5*456K^rKqP}m3XvQlNyPto7QH5wGXk{IUy+-cpPB8i >K2xMbcuJ=#K(Bz>2 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol >new file mode 100644 >index 0000000000000000000000000000000000000000..2109b52a734c1eadbc8ffa4fbdd5e6a53fbbb60c >GIT binary patch >literal 2445 >zcmeIzeN0t#9LMo5@hBo)*NA5|OhCQzD2gRY;>8ruiy)E-o{|s+EmRB>@HgieO#>5a >zR;*ZSDw{G~j8f33Oj!|7W2=VN*_ve!)3eIyGFQL%Ay%zFT7UFkpSyG4c!y3mzc2FF >zY%EQZzs;dP;bD#X;p=Fn-(D_%CE$&YkNr+9_|Z6Zt;IO~#WP0tV4cy^*Jhr1^F{OQ >zv3=%ShilB<hRx>N)y3vJWh=~g3)9VW4<?%LrAC?OWA8FAgm{^KJ<Z1ZPu9Bozs_=e >z*cN<X;MEMr;KA9Bq2&jRpqQgWcZXa|5B3{z2mgF$Z^*ZSL!l!X>0$lNL*YHGR>bjV >zt;m)=)};O0tjRSc)|84>);()8t*Gp|*3|j2*1gV9Yg&ZA6+Qlz6`hf7#(1ZwnCsCh >z_HwYAZd@^@4}WjWI5+5?**Rc1UpwiZb*RIL+uQ7p-+s_YD5-KM7PXs6TXzj5r=5`5 >zD;p#wvPtG7ZIU^+D<w6&UZq~jlX<tw)O}}C<o=OmYW|U2mDcT43+j{A!j}S7dTEe) >zVDC&><hr3UN+!tSX`d-q#x=?G?p8~tek4n-ekw~nUzeo=r)Alf&q-E$i)8noR5^`x >zvix|nTCv3t_x>uCyShfLtXQq`<`%2`?0ITcaJnjRhO2@bQK~Q~RSG}xQV(4ZlQmsm >zsfUMuk+rR!Qq=jm6z{$)>kjpbvF?IAQhQN7y0A^w7oAllllRGEX|1Z%@2J`kxkqid >z^0X?uU7|Mjm8(scGFADp9940Cy=-oXS6hy_<ngkJ>WTUosmzU&t)=5+TcSg@yS|eu >z#}Be2-dF9ghNU|28&y5jB|EQvpq}bDEV~9ysG1i#Rc(8ds@wUz+TB>GJnr!J^!n?| >zXPmE}uitq8(O1BPKVCliJH37W!<R_7pZ<?5VLyqNNJzElU(HDH2oQ;wA`{2nM?VR4 >zND!ZRgpR$Zrh81{`z31Zee9F5KOs9OUo!NwNIx!D9&h>s`_aG1$y=<SEdBx>9;1)_ >z1t0u*`Tu;EP5S%oyS(}PZ~RrSpsVjD<xVNLO1W3N`erG2OSxUj{Zek2a>tZgrra~- >zrYUz#xoygQQ*NAc=agHg+&kswDR)n~eaih)44^o`KMM;e9#BlMt6iYjK=FZM1jPx8 >z6%;QhW>DOq*g^4wVhF_%iX{|JD5lueu25{Tt9_vuLvhBgwua&j#T<$|6niNCPz<6t >zM6rnC5yd2iOAMPBKH1eqF`TlitzvjZF^l0A#V(3p6vHTvQ7of)#xRZI8pAe<Zw%uo >z&e_%0F}$;@&11O7u#e#%#XyFG6bl(1QcR?{NU@RPBgIIHlXkV06ff;+GbwH|?4<a~ >zFqGja!%~K)3{x4dQfy`TN->t<EX7)iw|2F;6n821Qv9VDOmUcDF~wts$rP6vHZy!? >z7|n2+VKu{RyV`7q+jh0x48JLcGaRQ_PVt;#I>mMQANGF_yTAT%Fe`~449=Y7xRkgA >MXHH@QjZgOf4F;`^qyPW_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk >new file mode 100644 >index 0000000000000000000000000000000000000000..c280f430fad27873cf7b20af55bf47c816ea1190 >GIT binary patch >literal 1281 >zcmdVZJ!n%w0KoB!O`4cEI8+ncq*iMhlQ#NHlagv$qe&a8DHI7EszULjAP64Pp@PtW >zwUY{pAfkw3aPf1{$*MtI#I}=L6&{F#3UZ4mEgJ9tl1?r<dN22WkK;1r-9LqqV`DM# >z$5^FTn2fBRJU0~e?Uv{+J}G&I)`YH>*ZSrSuWK&tU9>&&eHP_)3kjof_H4On=91~Z >zcg74{A2*xN9W~dV9yVK!=gbWUlIF&I*lbNTnwvU2X3+0eZJs3+a)e~)n@?{3=q-jP >zUKGP`7iHwt7uo*!o$M&h$>`<ha?8|1xpn-eG>%-9+YZjC*vTuZv*(72?>nUufuib) >z?N?nt52<9+giOBAs_vx`x&2w2+Od$5sXH0j^R!v^P6y@AYeJ^SoO0KcU+wPuBr}J9 >zsci6#?8}&{-*I2&T3@Q%*Vk&GuA~O$@2Wi?rq$jD=T(08wj8{0LKX6X(c$k6a<WpX >z2wUBX>ScG-u6k#^)3s9H{^qhf?RFueqx!Xqh#~ZI|B%fkL^93$uHKhdY<i`-Ct}$2 >zPJfG7%^ud-nI9~OcB50zgr0Fd^{LwQr#5(A9)*86^B=V@>7QHS?2+?lnFf#!kQOX; >z4@eV87f2gOA4nreCrB$uFGw>;H%L23KS)DJM@UOZPnNnVq${K?OWhaJ7}6Qi8qyom >z9MT=q9?~DuAkrbyBGMz$q^0f>Y12~oi8P9IinNOKiZqLKi?oaMi!_XMjI@mOj5LjO >qjkIm4`$ihK)SV-(BfTTdBi$qIBmLu~ZsC9Z54cnMU(y?myMF_y7abG; > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod >new file mode 100644 >index 0000000000000000000000000000000000000000..8ddba9097f804a762815a54e47708bf6bfb5814f >GIT binary patch >literal 2103 >zcmd_qeN0t#9LMo<QVefJUs`k_E)PZILsz&wDH<ety)c7oSGgLg#I+C~A__1DK7=dh >zS|j&WS<RIW%TYFCv{C(mt%tcr8(nW(t~qkGTIrl)XDeq9WA%F<v#s?<fAv@A?3~xx >z8QlBN{k)@Vx3m;n|2S?kZ@4(Nn~Ue{-R3qnvt7r}*UD$dy&8WtD5npUN@Dl%SmNlB >zZ$AHi%1N8`dg8Y9ud2Ms6A|yPH-DIZF(r{P5v;m>{9q#U<bdNlvERvh<ryctuhYrd >z+3e)Du6FKNU+vskx4_A(nC;x<&v5d69w+}uXXNe|3Y=M&mk!MN;!<qxsnd~rM&dF5 >zv9}}h`iEl$dk#hlx1H2L^IKZfcvgx#Mx>;2R7zL9C}mlPWqxtD%%AF&^2~lMKes^^ >z{??_7-Ve&X6AfB1*rb)Ci}b#|OLXzeKCNoW(<OTr%F^m24K`=Wvi$QJ3QkFN(x+OJ >z_qEha{vgYzeI(1{V{-p@uSxCDn^HIafrj_>$%+$4^?|lFiS#|ID<6DbSG8```UR~T >zt*g=1-W9sWKS$SG31~xFwKRNri#~LDwyb^kCtY{OBkKoJrE%nvJly-EH1)?N)^tWT >z?7FCrEPhWOZ5-F;oI|p)a!6Z}-_cE3s+%snq?@NYbjw(eZao*($KF_{t)H~Z<Ih!U >z+hDysu{lSd+*>B?D=Va<#Vegf*|IJ4i#(NTNmpT-b~)clcghv*PMngS$+NnBcu;o4 >zM|J0+k9F73VST#inD*}LRr|VW=A3TNNV<AnpZwQ3!=CAJ&l_(1FHXz4^@914St(*o >zw=7?-o&5Lb@+#Z>66Xf2)NA*vZ+y8{8gJ~3Yj@t%g`-w5#8n@)!u89{RcnRJix4j? >z%eMc#xet6VhiymyeG@y(AG(|P+5I2O`rRB`Cx_FKjUYQgwu0;h*$lE9SF;^tKYSb; >zLUx2~$<^!$*%Y!XWLwC-kc}ZbL$-$O4cQ#BJ7jyv{*VnKJ9IT$MD~bm64@oPO=O?Q >zMv<K&TSfMYY!=xqvR!1q$cB*}BU^Sgdqy_xYIcom8`(Fqab)Mn){(s<n@4t!Y#-S_ >z(g36bNDGi2AWd*JT|nC4YWjdQ0_g<O3ZxfEGmvf|?Lhj0Gz94g(h{U6NK;%*SCF>2 >zn!X^7K{|u92I&pb9Hcu)dyxJh4MIAEv<T@D(j=ryNSj<upO8i&okCiL^a^Pf(k-N2 >zNWYMVAss_nhV%?+8qzhSZLX$oNaI{h=aAMRy+fLZbPs7C(m$ku*8e?%9uvxW#gx(? >TE-5H02o#q1!$kr2snqiaa76ol > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz >new file mode 100644 >index 0000000000000000000000000000000000000000..9c2b600b103dc4d1f49b5f087055e19d3e031129 >GIT binary patch >literal 1918 >zcmciCUrd#C9LMqB0S*~U_N9i$0t7oE{yFj=LW4|?z^DVIoRk#AKL~0>K}Mh$G#PV^ >zxvv|mxnj{|%sHYiP%rS$(sHK6+KM$S=cY5wnsZYI)>!@CPdBW(_IY-m*K>diE`IM% >zaQ%+zbn~CfZGXat>mB>yeP)||T=eWT7q8WuOA`Sze74j?dw<hePyDQ&&~Mdq@3hXo >z{<%K+eUCnM?x4n;JSDOH0}}V~Co-o~CBEf7NvLg*x#e5s=|E7tx%o2Bmo160NizSj >z*^=b;Ytne8F1V4X3rA<^qOTv(#e<XT>-|-ibY0fu_Dh<w>!hYueWqy@W0Kx5C>eP} >zlDXys$%^Zi?DQtdo@$kxm@dt^vRRh?*{I7-`Q_Q4$~3pHQuBtE>2n<`boocI`h2xl >zSF|scl?86~SH;Mx#G9J$pOOOiH(KbuDus7`k)qHqrD)`Wym0-nyf|=F0>fvt_&}$W >z^na=^)z!(%o%?k4y7zTW?KUlardET2LVd+kqHBE%b?ro|mPHpx*^iIwtK$n~{qg&{ >zVKhR@d!nRb@ORnRdQU35Mr2dvsBGSQTemDfAzLekwJQFQY|9(a>KVthCQh~H)`z-% >zszG;LXx5!qg8JH#4O)A?US8jyr*(a$^2YXfeX}D=>R0DVL$ycVN}D6Q@*l|CQAQe5 >zqP6kvHED{R(5COclIA;Oy8DYh*)uYvEr-tP-hpm?x4Bna5438C%if`35BoMI{11Do >zOl*QH%$P_qk4}GISsXO}{8Ao4{>tTY9>M=Vv*Grae7KtJhxe#SzS-+9d(FFhyAA7q >z2=747vZFoE$eBjYH5X?aIp4?`ceLjmIqS%IN6tKQ?vb;PoPVSNqywY{qz9x4qzj}C >zqz|MKq!UNm3epSG4AKqK4$=?O5YiFS64DdW6w(#a7Sb2e7}A-eZ4K$o(Kd&4hqQ<E >zhct+Eh_s0Gh%||GiL{CIi8P9IinNOK>S&uqx^=YeBK;x_BON0xBRwNcBV8kHBYh){ >zBb_6yBfUG?=8^6lZTm?7$Oa%gfNTM>2goKMyMSy1vJc2cAUlC<1+o{&W+1!aXtx8| >z4`f4-9YMAP*%M?_kX=Ex1=$y5W00Lewg%Z7WOI<+akSfm?2n_}AY_M-EkgDP*(79_ >zkZnTt$+$v8>>cKQ*tan=_#fCQyHIwg?AJ&!GpD}?>`wiAtNs})`;4&TwIq!h^A%?# >PXC<fliqldtB_rZ*zi7H} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican >new file mode 100644 >index 0000000000000000000000000000000000000000..bdd3449e76a51eb8ea7693fbc1ebeb5be5c1e5b9 >GIT binary patch >literal 2692 >zcmciDeN0t#9LMo<@8t@j(icrJ0kO!?L<A8P6HO5v36^qG^AVp=i|9y5S}H!}$~pHf >zP3M5bhgc6vtuWVoXq7sfh=yTVIay{_Hg`62YKr!IAI6x~-=1^td7XP0f1dXzFll~X >zU+X_duzA9lW0(1I-)_0Nln%UZm)6%blpQ|il<&22-+ukJy|p5$p(6JkXWO#fx!b1< >zuy<s2$vv8%;?!ImEyv%B(At$n4Yk|T<;0u)<iz<S4JQkx={JR)q%Nz@IW;6nzs;<Z >z`si!+>7JXN)0dX(_pLX{jpRMfjWdTDZbsGFH$SU(Zr!T38@Ft7ZeKX*+*$dFZ5{sD >z@yvY7_LfbueZya}gI+Cm{Jl0ftqL~S!EF{gAsK_5kV_Ms(1Zzg=&@9%ZCI+^_Jc^L >z-7gJJ*xE+tzT=Iy6m_w~cb~J{=iIW}*KT$?WRH;hlmFI^v6r+{ho3aUcU&W`9MsO| >zKhy_KRcM#5-q6VX2PA4&l|+|qm9FblVwS9sZuy1s;FMYNP*y-<2WQB`@%^QHRGd80 >zwzI_f(>3mDKkad$yY{T_q>mmB)?U@uHGb#s+I!;<ny~tq_9@!0iL-ZW($q83x3F50 >z)AmWfahoJ1x?KAAT_pV*OJrc=Mjd!|hNRvs)<Fl-<*^?p>fp-hnznC{4p}oyhn7a^ >z<9V?<Y;~#(AL-Zh*^x4$`$f%2Z<LY#uXR-HIT>~NSIP8!A(^#D<%#n<WOUX0l2!A$ >zX0Kl-V|H!RCkqPXsdcM#?1Z&CE`N^Z49M3&)+l{CVvLTD@2TUjCF;bEBW2=u?e&?f >zJ!I0Sf9d4<P?=H@E>o-jlxZbbWctQh$(>#=GnW3LGl%Y#SyO9tcFY!;lUAj9A$xRg >zwCdd7HtW2`LY;qfu|9h?pwGQKS@Vx9kmp}Z(}Kzzd0}3R+G|o|!Pvo4m=_^0CUupf >zj2p5r+>+ux9ktl`Sr&y|(?ur_$>Pgr^yQB#<(1lfx@60jy0ofXmo46@CF@Jn>uEWC >zK^{IHZ;;PDn{E1a*VXH9b?;BhYEx}qFDt5>C&;qG#A@AqZF<u3d|Y<GO3%pQ65u~P >z=0I~3`2UwV#Qc#jN0s?<AAX%*=D1^yw1Zu1(B8koMqYAP^P(d!JMzLKFFo?&BQHM^ >z03-rP2#^>cK|rE_gu&Is0SSbwi3Ab~Bo;_8kZ2&`K;nS}#MMLu2?-JtR}&N@Dy}9h >zNL-M>pc@%(2n~mc4G<h8I!Jhs_#gp7B7}qpiIJ-b5)vg>6DA~1t|m}Oq>xY{u|k4{ >zL<<R*tBDs9FeG9~$dH&JL31@xL&Ao{4GA0)IV5yQ?2zCg(L=(A#19D|5<w({NDPr6 >zB2jcTVMOAH1QLlP5=tbNNHCFTBH={hi3AjhC=ya6rbtkcsJfc4B5`#!fkh&VgcgY{ >z5?my@NO+O>A^}DsjD#48F%o1X%1D@zIJ=raBawDBp+;hj1RIGq5^f~kNWhVZBOym( >zjszWvIudpy?ye^ANaS5j=#khX!AGKxgdd4NG62X3AVYwR0Wt{4C?Lati~}+d$Vj-F >zp+Lq084P4Jkl{ea0~ruxM35mt#snD@WK@u0LB<6c7-VEz&CnoY<7x&6869MJknuqV >z2pJ({h>$U|JU(yB8RYl!@%sEh?%8b9ue+|kR>AlFY@Q=CN@kAC_?XQI6RTbGwdqOA >l^DHw;{~o56Wiof6X03WBv0L%k$q6Y5iSgM<iP$GO^dBI59Af|g > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna >new file mode 100644 >index 0000000000000000000000000000000000000000..9c0fac5369e4924ceb9d6fe9f39ac14b0a712c98 >GIT binary patch >literal 2237 >zcmdtie@xVM9LMo5zcQHF+YHY5Atn)GC%++4$m~2A%2~*1BoY{iT7+;Z1JkaIxz>oi >zb4=$De;{Mk?CKA!HT*HN8Z9K$E<<x|xw2n#EOXi#tIzZMNB_9ifBn(-cHhTmxBLEa >z+r6INRU7KFtXr;0<`dprubDUJJ6<%m?#Ygt?%;*-y<-9G={utPK2Y7?zFQCedZMYf >zDOL_GuGFE(W*xq=R8GI?(2-u3e7-YBMz<%+8DET?@w?^h#hmeTwQ>4I$yo{JpOP<A >z2jsjnR=$edCDS}9<9BC|)<h@$tTEHRR!7)rbzD2H(=WfH_nbSRv8P_wxTD7;{%}AN >z_U@M%9V&@iUy_*(KDl>wt;{O*N>YJa?sMiza(s&1KY6;OM7T8NdXCQiE?HB9F*@ht >zN&3LRO?CGDsB^n6Xj=Pcn!f3%X4Ji{nN?$w<r|Rf!a>PdzDsfwdL%EaRq`hMGB2)6 >z=UrMO`G2(N{9`UzaIr!Q`m42YaK1jYW05ZGj@O6llXOvgzC2PCp{}|(S)6=D-L45K >ziuhEElfIGStKUmW*hwiF8ImQJ56RNNTT(iFLOq=wvh46deYCMr9_x5n%N~DKmp81{ >z@&_B#TUx9u9Lsd2GgVjK$k2-DBB?lkmp*ZQwyb*ZH?0gt$?5}BrE1_8dD4GPs=G#{ >zraCBVw*90}Eqq^UtA@2MagVGm3~2rBM|53+>bf6x>-q_wZWwCQr!RT+nKvr6;ge>0 >z_LV|y>@Sy%>l3wUN3JxN6^O6iA<t#bkWKF2W%E=^TGFGnW&B%dopM84M?aFbt7E$5 >z-F|s~WKg&6`B1k7dh~_1KJ|C{H8dnNEIcgSzH#{b7!n$B+kgGCtUJrhf7ptj84_+; >zQ^bn=r*o;tYq{Lz+`K#yVlFfX@4qjm(|plh%uV|l%lgw?8+)tMkp<bB6(LJP)`Tny >zSrxJ@WL?O@kd+}zL)L~Y4p|+tJY;>gW`W2GktHH)L>7sx5?Lm)PJRvxMOKO|6<I5? >zSX;ANWVy(Ckp&|wMwX1M8Cf*4YGm2Sx{-w=D@T@&tQ}cAvU*#yd}RGd0gwtHB|vI` >z6alFMQU;_BNFk6)Af-TRffNI&hOH?FQV&~G5TqhVNsyW#MM0{9lm)2^QW&H%NNJGT >zAjLtdgOmrUkF6;XQXyMYBBVx0k&r4OWkTwN6bh*nQYxfYNU@M=A>~5qWortCRLs_t >z45=AXG^A=s*^s&+g+nTbln$vKQaq%3NcoWZAq7M#XlqJ{)DS5mQbnYUNF9+vB9%l+ >ziPRD)CQ?nLoJc*9f+7{QH6=xAYHNy$R23;JQdgv~NM(`IBDJ;tf4Pk^1)iHpi=CeA >QwA{1|rzbN5)3c-g0&7TFt^fc4 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius >new file mode 100644 >index 0000000000000000000000000000000000000000..da380af0ed2f4f6eb399ab4a3bf3a0d9b6a7ebc0 >GIT binary patch >literal 2199 >zcmeIye@xVM9LMp`1*g|V=Nk+U0z@JK>4f8#+9rw}Kc;}9ocNQZ!V`-~(H!_AzAJOC >zG54w1%B9O+qjJRj!|ac2S#yo*!uyA{My*yW8*A>{%9(AfKF=>utNv(h{n_XCy~lUo >zJK!H)&+x|Wkz)0?lVqN7arT;v`y9)>9b1*zaPsLDFP{1#XrGRBwG0hh+413q{8;pA >zt$h5NUk{%O$(83yB^E6IGCB8^*sPS#D*T?&2LCTJE~Sk5VyUB{iaVpv$I>pIu+s;g >zwKI-AY0vK6WoPbhwdb_2wX-%?+jrG1w6hoI*>?w0?YZfxDks6Ka@}QC?)4li?;F20 >zZ^UEeU%qMGbAHSUoEf#|_eHIOgKt}fy9cdc>&sSA^GB+<vtN~zzphHx99E@gFSV3q >z9G3;fU9w=jM;4{^=_N@sTb3MJrkB2yt}7zhdfCBy<-TgS4z;F9<=m^fDl{(D?hkZL >z_7_rf?ORzM_pU4-9+DMbpO)Ievr-p*N7o<em6Zc0^{S2zY3O}QuU_|zUemr+H!f_~ >z;kp{V*1u9W1?K6d8$rE3xmwnLlB73W&y$T8e$typyt4U3qBNiXUhePtQMU9AOUsrK >zdEmg9esJlV@=$YBw`Lxdt>uF{;(0@F%g}n;cQ5F+@lL&cs9Qh$d00R4>L%U({!V%H >zaJla2Z<NQ{GWCu_WwLYiV(E<dWmnN`*<E#09#2%Vr!ZOXvA>co-woXryDZ(;KGl2A >z^~=8DxAgv_@96`B$MqB4XLQez9__j%E<VofnKpgeboZ?jFYj%WuY}wG`il3>@JW24 >z{1-2!{1?qXnVNY{#Va+dO?i~^iAqo^eU1{P@`LJ*Kc2W!c+UHx3RlL|r&IT?tf`-x >z_|Bhyk1MOLKCIT6tJYkhs<5guSAAoxxo_mA(mXIX6UXIJ$~Ac=AN~G`%N73T4ec{u >zcQ*9%<j?(TPSb^GC9)}GSID-IeIXk|c7|*X*&DJsWOvB+_%rMe*&wn*N3%s_kH{vG >zT_W2=_K9p1*(tJBWUt6(k=-KOMfQtqn8S`aY}wK58QC<lYh>HVzLAY1J4d#T>>b%W >zvU?8O=dgbc4RACaKw5zGz|k}T=>pOQN7DzS5lAPHRv^7Vnt^l!X$R5|q#=%`BS=de >zO;3=fAYDP)g7gJx4AL2-HArue<{;fc+Jp25X^^Ao5Yi$?(<7uwNSBZ{A$>v`g>(vO >z71ArDSxC2#b|L*j8isTXX_=$x8PYVQYe?IWz9Ef6I)}6l=^fHMq<cvFkp3YJL^_DH >z(9!e|X`-X)BGN{rk4PhtP9m*DdWkes{U6PL7fr9}?fhaI8>lZSC@TmSmIUgHg3ev3 >F_cv^;2-^Sv > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd >new file mode 100644 >index 0000000000000000000000000000000000000000..f4cb64f16c730b1da6fe427a786ae939712559d5 >GIT binary patch >literal 1167 >zcmd7QJ7`m37>DsMHZdi2aM89lsh66@^rA6oO4PKbrcJ1(P$W21h2o_k2);-M1)&9N >zClwSyL=nZ{;&sr;DnVStwv$^c9B}f2yh}kW8o%e%Ne6NB9M1V24#|-GpW@K5k+}Ke >zsJ3soIC|{G^U861yS<Q`e_E;;Tot)iUR^gEtF4~N)PD0kuKQ@p^>fMCn(1@phN;U= >z@cvmRbYs+MJb%<#duE@r?s(o=e<0;-C`6s6^d{ZdR<Ge;K$~k8HR6j%WT8%?Z$A&W >zy!s@qPv)hqG$ZX-UdZN&N3vz~mc))+lC1})G=B1`Cc18F$KKPL42^4Ne7|;nKcuOK >zQ<8eutJ@ZbWc%}G-7%Mz^xdp<J!_Qi$*}CaZX`3}m!65B?&|v>*~34yH~dEWvX16_ >z4<z68QuAM4YkyTq`)BXz?)Q_r=ivn{Oy7}#izl>L2n~-_Diz~dR<(3`eeSv3&*@#_ >zZ+EZXZ%njg|3}jjGhSm-8UEVbpl8MJ&mQ}p&lCoVrZtwZSBJfleARgD;Xc?~@gD~K >z`s+*fcT^Y>8I#uxij0a3>uSeE21Z6khDOFl21iCmhDXLn0ze`_LO^0bf<U4`!a(A1 >zwSgd!AfX_!Ai*HfAmJeKAORr}At50#AweNgAz``NxRAhHZDdGjNNh-ONOVYeNPI|u >zNQ6j;NQ_93NR&vJNSsKZt~OF6R971-5-bue5-t)i5-^V0&HuZI18JLhcY7l66LKOE >A0ssI2 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw >new file mode 100644 >index 0000000000000000000000000000000000000000..5cbba412eef406b4baf89100f2c4a8e1f5d12798 >GIT binary patch >literal 2705 >zcmeIzdrXye9LMn=AgP4(#T$xTG$NG{K@=4sGXiIVc{$$jhK8s`hL;FU;#o4+jJa<N >zafp-_F?C9Ap)JulyUmsnUeK^vD_4Re!_c%fX217itu<@?)qnlY&hvWC**Skc?~f;Q >zMa~Fw*SXhz!<)0)zPS%}?4@FNRAZ%oP*!Erh4vlIwOUnuP+xmb_4VRyx^w#>vuo*5 >zQ&YGh>qP!na`N(I`D{;+HoTD{pO=o5MrTh}WAR~gYHMlU>CN?7XO`T~J3Bc-n-=bu >zb3^Ood~~pU(Y;)ny^m{iYk{<QPMel%bx!LyZ#h>^l{;;{%T3$icgzoatIgHzTg{JW >zGfn&Y=gqacB=b||T+>k&X09iWGdBtoou7k4O^>L~ydKpvoq$*T&3(nA9a%fX3C!;A >z^z`^Sy)qI^@Ax*SPsBy1Z?6U?$mf_7)N#P+cWIZ?|4gY9{J}<Nz>&92$iAH>bjPbE >ztmGvVzG00Sn44_|&7WxoT{zc%f4WB^l2YY?=md!j87vR__mjcCDLVMZNFDNBqz-NB >zt5F|y)rabCX>@g~4lBE$F~y(i@U=%YHhaIuEohbztLr2_xn4$2FPBlFRgy5GKoUBO >zWXymv9dmK9jQurV6OX3IxG(2uQq3Ywu20m5H%-v-l_B~_PJ~V<9xIQg`D#k`0C_C( >zvZkhVN}BH{Ix*sFnRxYkndEa^CN-Rp$1lAplWX@%`pILOv86<&?AxVJtXwHmOE&7X >z*_(BG?oypGI#)gE6Ln_L6rB}4RA=3c)j56AWX}1XI`_s9$vkvj=Qa7s{GEZapsr08 >z7Iny?vIfao)Fg`wujrET@5+-4PHJ{|g)B|3)tqhzby=wDvX*VSymPg#II&Kjy6DlT >zchA$@k5|bvFDL8Dni=x!@^H=DG)h)YOOn+&L9!+;OxC9UBF_aH$sgWF^V`3bf`FS^ >z(D<ROyV|Vl57fvD4fVRA;(aZwt<o3QRcq0fBK7j|_UYo=rQ1DSeY}0`jrX0;+}`!# >zhkx_(>F)R6zl`a1z&=V`yBHHP(5ss<0b+Xm^*$=rE0AwY-#@Q^{4zbmV`kfTO6m+Q >z9+S#Vs=eWO*<&y6{hiOAe}BsN*k8I&`K{mociWy>hZ?6MPd)PFyV|E8DF9Ldqy$I} >zkRl*eK+1sB0VxDh38WNAEs$ck+G-%>K<a@M1gQv85~L<bQIM)2WpTB2K?>t)D}$5< >zsSQ#bS6dyVJV<?z0wEPbN`%x1DH2j8q)bSiI26j&RthN<hgu=ULaK$73#k`}f*}<{ >zN`}<T)fNq@8d5f-Zb;!cRE|UGIMj|q@i<hEL-|~7{g4786+}vi)DS5mQbku=Mx>5N >zA(2WVr9^6p6cec?Qck3vNI{W`A|*v?iWC*8s;ez4Qdd`7SfsK@X_49@#YL)%lozQl >zQedRQNQsdeBSl84jFcIvv#TvMQfXIPYNXakv5{&c<woj_6db8IQgWo`NYRn1BV|YG >z?rIB<RNmE=9;rQ2e5CqF`H}h~3xKQuvINK)Ad7&k0<sLqIv@*ytc0sw3S=#i#XwdA >zSq@}9kOe_j1X&VfO^`)FRs~rWWL=PjK~~1qE)B9au6A*d)j^gASs!G9kQG9f2w5ZZ >g{~Z0(9QoPF8WzWRMQ6mvjEaek&WMY};qiXI0efH@v;Y7A > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb >new file mode 100644 >index 0000000000000000000000000000000000000000..79c25d70ef09aaeec21f0a10a029650967172a80 >GIT binary patch >literal 1957 >zcmdVaYfQ~?9LMqhL0H4S7)2!{xg6a~D7WL3s9ZY8CAlQGB%zgCF3rrEeOY4-b6vxT >z2jM}?T<4O6HN%WC*O}Qcw>5t6|7Np!;F-<;od5sTPMse8-XG7D`8ko+A6E<W2{%`< >zx%s*ETJyNxB<4x&%h7W4u#eX5cgd}7(Ne!YSn9ty@^9}elRIfc)z_Vs@B8eycDlP) >zJ73(YerL{#|IsQ5*tJKxl&J)+S|?p|3#8k$+0s45BSG<Q>EVo(VE+*5*~(W!yj&Xc >zDO!6y57yod9ktKp7TUM^i#iX!)_&y=G_>@FhAlgz;n~MDBJ;jP7F0`ALXAX^-!3r$ >zyCpWVNMajHB+jo~;~veF0pAOC;8~XpdYGZ{m06llGf)R_9Hv8d`s>h~ARSgZK!zuJ >zsVm!0Mg+f9x2sVSy{>6e&|^t@_d=4Jo|ojht1{}@0U2F&L{e(cY3i0TNjthv$K>V7 >z*s={eZqjBQpF2m>`{$}BB}pgvr0GOwZ=Lu#Tr)Z(O2)l*I{8yCnR4o*PHpg(X?xpB >zX7yW{Uh+Y*%IjoCR)fr3{YGaEIW4m@Yc)HtLgpk?X-><NIyXRd?yDU-udzVqUoF-J >zk372Y&{WO6vP2ebO3=K@bXhzvQ1ds&$dYmKQjp^#OC!3-GWS<m-qw=Bunt=I{;3qT >z`K(3tm!$aJeO+;)QdZX0=&Fhfy1Ht&t|>mKC0k0=(X2^R^KzKCSMz`QvaI%T=6qRg >z#A^2I>EG4S(z1Sk^4pYDkL7Z6r+ds791h-G4u|LOr+J0>L;Ey;vA<(kKg=~f{{2Yg >zbR#DmIpxSnM@~C(;%&{TM@~L+`uVpMU~4KsN<eBria@GB%0TKs3PCDCN<nHtib1MD >z%0cQu3bHj7AtfO-Aw?loA!Q+TA%!88A*CU;A;lrpA>|?UAqCo+3Xu|RO^ryANR>#L >zNS#QbNTo=rNUcb*NVQ10NWDnGNX1CWwx(vJXj@Y?QZ`aIQaDmMQaVyQQan;UQa(~Y >zvH-{mAWL9t)&N-qTeAwtG9c@KECjL=$WkC{fh-2H8pv`W>wzo?vLeWmAZvmwimh1{ >zWLc1PK^6vC8DwdYwLumKSsi3~ko7?p2w5RyiI6oy7RlDE60%ITW}T3QLRJb{DrBvY >k#X?pKSuX4Uo-S`QY5gMDG-qm5XiR9hGc_U{!=k)@0!L5Jf&c&j > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye >new file mode 100644 >index 0000000000000000000000000000000000000000..6f148505b239ad9adebfd94606f1e4f311fb354c >GIT binary patch >literal 2115 >zcmeIyZ%kEn9LMqB6)3tEeRabN0YagHig3AzqCsNU3p2p3awSrUYawb8AsPe!L@Vc7 >zWA58zIcIK`jEWhv4ebHC{<&t2Zuddf9J#h?(VV%nm9uiJe(&RGZ9V8w&pK!4yv{wq >z-~pd^Wc{|*fceL9hke7vvCCdO&w0+?hSHDwPYt9;KOLHgk4@CbXK(p5_IglaXTR)7 >z&3hw0EA8t_U-Ed^_xqjir(I5or;i6K?;1N8&p30;$vpA0llAKJ&g{M&PWGM_C#P+l >zbN9w7=bqXnPHuU=Gp8WknVac#?wx+a$xF)X$h(%-k^lWq;dx(NiOxUwd3eD{ELt$| >zPIzJe$!OuegW;l`XVl;FwiY*CltAZ*lvIq$qP4F`Y1UC$9O#zClf6=w(XVBfHp$W( >zUApXSQ0^OV)bhb*tr%UV_wQe!%a3GgWoxdk*tb+3s7lgcONOkRJE5WAq*Nt+qSd+I >zNcGhpWL3fkvMP379{ldO)C><v?bv%-cc4#JpLk6lYHyct-wV3t;g@u6+h(m_(x#Ex >zYF+1Btqle9wBfp68&j*K@vE8o$hCY~fBF~QaKS4ZkIj&#kt_0O@6XcQACqYF1=+Os >zvOc!_U3t7|Ok1)K%jSw<ZB0I<Te4KQ{CG&WPIl_H^F8{+rHDTH<_2y1c)L9HVuiL3 >z*2~jdv$bP?scc_UE}gAD*-<=Oc7}eFXJ#1bDoWKZ=UeGcxvt&ubJBD5qV765D7#~$ >zy65nRx_9`fKHD>(y$5>LGcDnk#H7T8TW_ApxBcz(PP=(dzx}^Bjmi1d{*#%UxJfi7 >zGsk$1neR6##-xau$s5nCse4(aCu8cXQ_r4k-f-t<YwIFrfj<!Nn@}iX>gsDu&>9TY >z^I@fZX&*Q|9`}O34v#1D@5|V2zujGi`$yXkf7qkp^he3aQjoPEi$PX{EC*SSt6dPk >zo)sZWLe}JJ7lo_}Sr)P`WMRn4kfkAOLl%du4p|<uK4gK&3XvruYeW|5YFCLY6Imy+ >zP-LaZQjxVHi$zw8EEicXvS4Jz$dZvYBa3#mt45aXYS)b{99cQCbY$(w;*r%O%SYCa >z6ac9JQUas~ND+`KAZ2j1bwCQ?YAb=10;vU345S)JIgolF1wkr;lmw{>QWT^rNLgHM >zU68`K+R7lML282(2dNHH9;7}<fshIzB|>V16bY#kQYNHMNTFP9rI1n~wL*%8R0}B= >zQZJ-nNX3wnAvHsahExqH8&Wr<aIUs;Na<W{?U3Rj)kDgM)DI~jQbDAI=KmCuMz8JX >Z!T`N2s4FQfE%X<a6x0>_-KRy~KLI`|_-OzD > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich >new file mode 100644 >index 0000000000000000000000000000000000000000..9c2b600b103dc4d1f49b5f087055e19d3e031129 >GIT binary patch >literal 1918 >zcmciCUrd#C9LMqB0S*~U_N9i$0t7oE{yFj=LW4|?z^DVIoRk#AKL~0>K}Mh$G#PV^ >zxvv|mxnj{|%sHYiP%rS$(sHK6+KM$S=cY5wnsZYI)>!@CPdBW(_IY-m*K>diE`IM% >zaQ%+zbn~CfZGXat>mB>yeP)||T=eWT7q8WuOA`Sze74j?dw<hePyDQ&&~Mdq@3hXo >z{<%K+eUCnM?x4n;JSDOH0}}V~Co-o~CBEf7NvLg*x#e5s=|E7tx%o2Bmo160NizSj >z*^=b;Ytne8F1V4X3rA<^qOTv(#e<XT>-|-ibY0fu_Dh<w>!hYueWqy@W0Kx5C>eP} >zlDXys$%^Zi?DQtdo@$kxm@dt^vRRh?*{I7-`Q_Q4$~3pHQuBtE>2n<`boocI`h2xl >zSF|scl?86~SH;Mx#G9J$pOOOiH(KbuDus7`k)qHqrD)`Wym0-nyf|=F0>fvt_&}$W >z^na=^)z!(%o%?k4y7zTW?KUlardET2LVd+kqHBE%b?ro|mPHpx*^iIwtK$n~{qg&{ >zVKhR@d!nRb@ORnRdQU35Mr2dvsBGSQTemDfAzLekwJQFQY|9(a>KVthCQh~H)`z-% >zszG;LXx5!qg8JH#4O)A?US8jyr*(a$^2YXfeX}D=>R0DVL$ycVN}D6Q@*l|CQAQe5 >zqP6kvHED{R(5COclIA;Oy8DYh*)uYvEr-tP-hpm?x4Bna5438C%if`35BoMI{11Do >zOl*QH%$P_qk4}GISsXO}{8Ao4{>tTY9>M=Vv*Grae7KtJhxe#SzS-+9d(FFhyAA7q >z2=747vZFoE$eBjYH5X?aIp4?`ceLjmIqS%IN6tKQ?vb;PoPVSNqywY{qz9x4qzj}C >zqz|MKq!UNm3epSG4AKqK4$=?O5YiFS64DdW6w(#a7Sb2e7}A-eZ4K$o(Kd&4hqQ<E >zhct+Eh_s0Gh%||GiL{CIi8P9IinNOK>S&uqx^=YeBK;x_BON0xBRwNcBV8kHBYh){ >zBb_6yBfUG?=8^6lZTm?7$Oa%gfNTM>2goKMyMSy1vJc2cAUlC<1+o{&W+1!aXtx8| >z4`f4-9YMAP*%M?_kX=Ex1=$y5W00Lewg%Z7WOI<+akSfm?2n_}AY_M-EkgDP*(79_ >zkZnTt$+$v8>>cKQ*tan=_#fCQyHIwg?AJ&!GpD}?>`wiAtNs})`;4&TwIq!h^A%?# >PXC<fliqldtB_rZ*zi7H} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Factory b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Factory >new file mode 100644 >index 0000000000000000000000000000000000000000..afeeb88d062851fca5523d23a73edaa1d8f5ff6c >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffN|%8W;fS5E4xI0o4hjFiqmJ0h(xM >Gzy$!q_YOt? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GB b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GB >new file mode 100644 >index 0000000000000000000000000000000000000000..4527515ca3f249a44599be855b3e12800ebe480d >GIT binary patch >literal 3687 >zcmeI!dvwor9LMqBn$hO=nHU-N(OjC={5BD438AqqmtXotj4)(rmX?v0Q>h%sdF!Yp >z<U?Y)%x%kMU5MsB*GZFmE_1(T%%;!t>o})#oKr`C_xqiB{Lb&^cR0@Re!e`th9*Y2 >z?s+_D-{FVH75l^M!1wGg(;6)@)Asu5>D%3A#+-HLtLZb$%#7N`e7IWAO1))f51OvO >z9<$NRiC<~HX;Y%-HteV8HO|wSO~Q5NnPM~FwcE@usG%1WUDOLVB<V$)cIm8n@p`dI >zGfO^l>!qLWFw2r-&GM9GCcA5d$%*NuzjG_IA}ZCata{n3s^>F6=R@i(EQ)-zEM1 >z{+IL*D|hQ3mzJ5IzR1yQrUmP@qcZf*qf7NVZ<=1;ZI1b+WpAC=dad5z-D@@!`kT!` >zjbwAi%d%x>J=yy9Q?hNTOY-}9)pj{5JBIg_ohd<TXGxUWHMC6c9uQ{s#2nTI_3E2~ >zcBN8q=&;%wzfkWj^ELY-Ch2`QKGTI&l6B#kvwHvWn&$T{`TD^68|Gm4X>%wmNFScE >z)f`EA-W(k^QXlKy#QfnAb3Ce&IT5``p9~Jur>c9*sgjDisC0xrU3gBPInYC&UA<kO >zTYl4=|8l9mFmAB9ICHGN)IY{tPEXKRIw$I@32pVY`jyR}Z9?^R*9B7?;-`xb?=&~c >zPU@R$mYb4OzUJ1L1*UXEZnAH3o-P;W)qY(wb$S2Rx`KOxu257*`>Q1Fzp+dQT#VNh >zm(@0vcDQxr$+t|ECDnA*5eJQ$8esyvtufWolzAv}wyEyDY-)s_k)W1&Qqy;v)T)&! >zwT>;8hl?jj?RAqS_{cm}XJMAAyY>@RZ=$G>S;Lf0N>TO4#i>VPJu0++Q`I26g=*Nj >zi!`cKOEqrtxHP`@goFiDm9T;!X;O4a9?LG4@J+kr@hOE8@okPY9r?YuKgkgH$p)^- >zKEJ7`lx)>3I#)f>{d3j4?hMr;YLseGnyy*~Pmz`f`m0tYsnYs~_UftqUU_<Mf<))G >zmS@Jdl{VAr$g_!|()NQ^s$EAvX+JPnJ=gH0bZB3yI{IyrPN9cXr}HONjPF_%lfO}Q >zKK8Zhk~Lq&Zv9E(CQVfF3unm-!-uP`6W^C^FHMl{NrR-vlS$%<?IbVOjF+C_Vbb%u >zTf8+oD(|n=<mGFRs$Sn+mEHvb>J<~H`edI~ebcX~gem!|UqXTEKlZe|+Gd3s&}XX* >z44JA1MQ2IkgE=y|uE^k188W0aMTTxnlh+P-WLRczNy;0cUjH~+hR^Mx-WU=h$>W== >z5#63vDTy`Jo00X@$PPEuTY)Z>+O&qGUOcKsRk<#scC1%v=YNyYOXjLE`ML7W)SqQ+ >z)(m+!ZH}Z*N|y(G?)T~IbN9(NeedJ@<;vgtoBhiF)3d@qefVELyM6n1j=f;6D$1uE >za@6W*pGv&rvhV!;eLjti^SIje@VGkRbM}SH$H&M1INwFjzu(TQcm5bxVDX)Ax$Ix! >zcI`g?Taa7oXzwX<Q<1xh+*ahiA~zPfv&gMQ?k#e2k-LlBUgZ8FH`vkMVdNG&+Ix)L >zWaKU*w;8$5$c;wsG;*tvdyU*|<ZdIk8@b=e4M*-ca?2g<Jx6Xja@UdDj@)<T#v^wg >zx%J4sM{YiH_mSI=+<&A2NCzBk3y>Z-+9n`fK-z%x0cix%38WQBFC1+%kZvIDK>C3+ >z#L;%d(Y6HXiKA@_(iKPB7NjqZwlPR&kk%l*L7Ibf2Wbz|AEZG@hmaN_Jwlp<bO~vb >zqwN#YD5O(JtB_tH%|g0`v<vAM(lDfBNXw9(Ax%TNhO`aoo1<+U(mAAcNbiv5A>HG@ >z8|_2-hcpoBAksod+e4&@j<$<P8<9RDjYK+$v=Zqh(oCeANIQ{!A`L}4inJ8zDbiF& >z+f}5kNMDi0BArEAi}V(0F4A43y-0tN1|uCtT8#7<X|kj3GSX&8+h?TFNT-ojBfUnN >zjdUAnx1;Sh4;qei9BDbybEN4=*Bx!!k-j_H#v`3aT95P|X+F|@r2R<$kqv<C0Avdw >zdjQ!4$Sy#(0kRJq?M6U$f}`CE$X-A;1F{>C?SSkDWJ4f30@)JCo<KGQvMZ2nf$R%M >zyD^ZR;b^x8vNw>;f$R=sdm#G**&xUcLAD68N03c|>=I;~Ao~Q_D9BE6v|9z)E68R+ >zb_=pyko|&e7-YvFTL#%P$fiMd4YF;JeS>TqWal{At%K|xN4t5D-Ggi&Wd9%=2-!i% >u7DD!r>wf1D6X@>q|3PH`740Ajuv5uxCsTM_vxw#q?xvC9aglCb1^fkK<6HXx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire >new file mode 100644 >index 0000000000000000000000000000000000000000..4527515ca3f249a44599be855b3e12800ebe480d >GIT binary patch >literal 3687 >zcmeI!dvwor9LMqBn$hO=nHU-N(OjC={5BD438AqqmtXotj4)(rmX?v0Q>h%sdF!Yp >z<U?Y)%x%kMU5MsB*GZFmE_1(T%%;!t>o})#oKr`C_xqiB{Lb&^cR0@Re!e`th9*Y2 >z?s+_D-{FVH75l^M!1wGg(;6)@)Asu5>D%3A#+-HLtLZb$%#7N`e7IWAO1))f51OvO >z9<$NRiC<~HX;Y%-HteV8HO|wSO~Q5NnPM~FwcE@usG%1WUDOLVB<V$)cIm8n@p`dI >zGfO^l>!qLWFw2r-&GM9GCcA5d$%*NuzjG_IA}ZCata{n3s^>F6=R@i(EQ)-zEM1 >z{+IL*D|hQ3mzJ5IzR1yQrUmP@qcZf*qf7NVZ<=1;ZI1b+WpAC=dad5z-D@@!`kT!` >zjbwAi%d%x>J=yy9Q?hNTOY-}9)pj{5JBIg_ohd<TXGxUWHMC6c9uQ{s#2nTI_3E2~ >zcBN8q=&;%wzfkWj^ELY-Ch2`QKGTI&l6B#kvwHvWn&$T{`TD^68|Gm4X>%wmNFScE >z)f`EA-W(k^QXlKy#QfnAb3Ce&IT5``p9~Jur>c9*sgjDisC0xrU3gBPInYC&UA<kO >zTYl4=|8l9mFmAB9ICHGN)IY{tPEXKRIw$I@32pVY`jyR}Z9?^R*9B7?;-`xb?=&~c >zPU@R$mYb4OzUJ1L1*UXEZnAH3o-P;W)qY(wb$S2Rx`KOxu257*`>Q1Fzp+dQT#VNh >zm(@0vcDQxr$+t|ECDnA*5eJQ$8esyvtufWolzAv}wyEyDY-)s_k)W1&Qqy;v)T)&! >zwT>;8hl?jj?RAqS_{cm}XJMAAyY>@RZ=$G>S;Lf0N>TO4#i>VPJu0++Q`I26g=*Nj >zi!`cKOEqrtxHP`@goFiDm9T;!X;O4a9?LG4@J+kr@hOE8@okPY9r?YuKgkgH$p)^- >zKEJ7`lx)>3I#)f>{d3j4?hMr;YLseGnyy*~Pmz`f`m0tYsnYs~_UftqUU_<Mf<))G >zmS@Jdl{VAr$g_!|()NQ^s$EAvX+JPnJ=gH0bZB3yI{IyrPN9cXr}HONjPF_%lfO}Q >zKK8Zhk~Lq&Zv9E(CQVfF3unm-!-uP`6W^C^FHMl{NrR-vlS$%<?IbVOjF+C_Vbb%u >zTf8+oD(|n=<mGFRs$Sn+mEHvb>J<~H`edI~ebcX~gem!|UqXTEKlZe|+Gd3s&}XX* >z44JA1MQ2IkgE=y|uE^k188W0aMTTxnlh+P-WLRczNy;0cUjH~+hR^Mx-WU=h$>W== >z5#63vDTy`Jo00X@$PPEuTY)Z>+O&qGUOcKsRk<#scC1%v=YNyYOXjLE`ML7W)SqQ+ >z)(m+!ZH}Z*N|y(G?)T~IbN9(NeedJ@<;vgtoBhiF)3d@qefVELyM6n1j=f;6D$1uE >za@6W*pGv&rvhV!;eLjti^SIje@VGkRbM}SH$H&M1INwFjzu(TQcm5bxVDX)Ax$Ix! >zcI`g?Taa7oXzwX<Q<1xh+*ahiA~zPfv&gMQ?k#e2k-LlBUgZ8FH`vkMVdNG&+Ix)L >zWaKU*w;8$5$c;wsG;*tvdyU*|<ZdIk8@b=e4M*-ca?2g<Jx6Xja@UdDj@)<T#v^wg >zx%J4sM{YiH_mSI=+<&A2NCzBk3y>Z-+9n`fK-z%x0cix%38WQBFC1+%kZvIDK>C3+ >z#L;%d(Y6HXiKA@_(iKPB7NjqZwlPR&kk%l*L7Ibf2Wbz|AEZG@hmaN_Jwlp<bO~vb >zqwN#YD5O(JtB_tH%|g0`v<vAM(lDfBNXw9(Ax%TNhO`aoo1<+U(mAAcNbiv5A>HG@ >z8|_2-hcpoBAksod+e4&@j<$<P8<9RDjYK+$v=Zqh(oCeANIQ{!A`L}4inJ8zDbiF& >z+f}5kNMDi0BArEAi}V(0F4A43y-0tN1|uCtT8#7<X|kj3GSX&8+h?TFNT-ojBfUnN >zjdUAnx1;Sh4;qei9BDbybEN4=*Bx!!k-j_H#v`3aT95P|X+F|@r2R<$kqv<C0Avdw >zdjQ!4$Sy#(0kRJq?M6U$f}`CE$X-A;1F{>C?SSkDWJ4f30@)JCo<KGQvMZ2nf$R%M >zyD^ZR;b^x8vNw>;f$R=sdm#G**&xUcLAD68N03c|>=I;~Ao~Q_D9BE6v|9z)E68R+ >zb_=pyko|&e7-YvFTL#%P$fiMd4YF;JeS>TqWal{At%K|xN4t5D-Ggi&Wd9%=2-!i% >u7DD!r>wf1D6X@>q|3PH`740Ajuv5uxCsTM_vxw#q?xvC9aglCb1^fkK<6HXx > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT >new file mode 100644 >index 0000000000000000000000000000000000000000..c05e45fddbba6a96807d30915e25a16c100257e5 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<UarX@YGC~OJgPFnd17-@c0bD?H47dQeKL=s} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 >new file mode 100644 >index 0000000000000000000000000000000000000000..c05e45fddbba6a96807d30915e25a16c100257e5 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<UarX@YGC~OJgPFnd17-@c0bD?H47dQeKL=s} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 >new file mode 100644 >index 0000000000000000000000000000000000000000..c05e45fddbba6a96807d30915e25a16c100257e5 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<UarX@YGC~OJgPFnd17-@c0bD?H47dQeKL=s} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT0 b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT0 >new file mode 100644 >index 0000000000000000000000000000000000000000..c05e45fddbba6a96807d30915e25a16c100257e5 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<UarX@YGC~OJgPFnd17-@c0bD?H47dQeKL=s} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Greenwich b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Greenwich >new file mode 100644 >index 0000000000000000000000000000000000000000..c05e45fddbba6a96807d30915e25a16c100257e5 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<UarX@YGC~OJgPFnd17-@c0bD?H47dQeKL=s} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/HST b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/HST >new file mode 100644 >index 0000000000000000000000000000000000000000..03e4db076900c74add3918ad293c77f771787467 >GIT binary patch >literal 128 >zcmWHE%1kq2zyORu5fFv}5S!)y|KbD&29MwnASZ;dKA0ISKVYUH8^8rL$IyTa0N$$& >AN&o-= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Hongkong b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Hongkong >new file mode 100644 >index 0000000000000000000000000000000000000000..dc9058e4b578ca8c9bb954af1bbe26a964eaf408 >GIT binary patch >literal 1189 >zcmd7QOKgl$9ES1JxivGCw22K1;+B(05gVrxw3R5GRu?8|QlVubhN3I1CL<z|5Rpho >zNGz=WMMPLQHkNu3;#y<Sx^=3h>e7xGTH`z)iG`KeIFs-DolG*Dd7oHQeCrbR#|gS` >zcsQ%w!@V@=UI*h%*{-2R+nrt}H>3NK_v*H^-QRxIJUCt}534Vko>SN4(TXaYS~yoy >z`3jq!5|Z@e8TQHW8+mFc?6X_l(tCEg>ASE&Ki@xYUYzLCFB{_K)t>YE^`fZhZ|;!H >z)N(VhvRwvpYwh67!!np!V227j<*hBT@A?{K_~eLv-`T21_TIH0WS#!lc*TA?v{-+x >zykkbUmFclrmrb^2RDYS5Fu7@)bw1c)@?)#?*Zykrt+!dmZ*Q^_*Q@0F#Y$T^Ge^|X >z*|sPV6yL6Z^=}-IKz+srYXUm7)NhLCXLRv_<t7~J)ZuK0iDb^{Nj>dm@{J?9^mK(O >z+ubV4SLE}%=ifd`?TENPSS5}X1(a$_sxWs|^7CF-A5&|h>v_dgt@HPZ{l$d2Uq36j >z!<5LJ$fU@u$h643$i&FZ$kfQ($mE`Gc4T@_H$Rd9k^zzek^_<ik_D0mk_VCqk_nOu >zk_(cIr^^OO$J6D5B!pyyq=e*zB!y&!q=n>#B!*;$q=w{%B!^^&q=)3^=@LXTL{da@ >zM3O`=OD?3zad`rXBAFtoBDo^TBH1G8db)g(ggsrxNXkggNYY5w_#dPlakZD5$PYD~ >B5Gw!x > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Iceland b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Iceland >new file mode 100644 >index 0000000000000000000000000000000000000000..dc49c32470906fb2ff94fc599c73141597443f98 >GIT binary patch >literal 1188 >zcmd7QPe_w-9LMqBnvSrDL7-$%-zYVZVEsW5ifFMq)DE#h)Ws1MBn2r&w;GlZ{UJTn >zY1KFJ6#auhFm?!nL``d%wwBpnb83Gy%Vt^Y_kMQh(5X&64|`q@&$C_jd55>}*}cO2 >zad_+#J{$r2;ocjymy?mB8f#o&&L@sHT&Ud=z1ZvaYN*~^YN=>wUR@S#Zav_=8!R?$ >zYs#c8Rdl1hbiKCUDV0u7iFRJ`>%IOi={mJUyW`j8{$7thh&4)LQ(7O^U)7%S4t=!i >zjP_P0q%TmTkLTT#WJySqQ)eYLXTPML9FnJlMcUuGO`dhHl7Xg!`utj<yr|o%FHdLW >z)s9Miy)Pwi{PT4%7?-z;e&|p|Qq!}FWw`K`4v$RB$Ye}MI|k%k-(h`!`L=v$iRi}@ >zO)_@QujAFn<kOKVnFy(Vu39HwR@Uj{+Qss9?oQ1t%$Ll>2A%pjB;R_L>i4u;r{e)J >zGhDw<ciump`PuAf#QwMTaOGvQ<6~xK?wWhzyqLW?7&hfTpIPQxZZ_I`zU*>2?@ahF >zM$F`XVzTyNOk_}GRAg9WTx4KmWMpVZJ2o;nGP<K39vR=!27pB1XhT3^K!QM`K*B)c >zKmtJ`K|(=dL4rY|LBc`eakK#;5jonBkeHC5kf@NbkhqY*kjRkGkl2vmkm!)`kob@Q >zkq8}ah)9e`kVuqBm`I#Rph%=hs7S0xut>B>xJbN6z(~Z7He@7bBxodR{BOc8u%-J7 >FegQpVSd{<( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos >new file mode 100644 >index 0000000000000000000000000000000000000000..0e5e7192795decc47a8d338520ce12197ae1cd31 >GIT binary patch >literal 225 >zcmWHE%1kq2zyQoZ5fBCe79a+(c^ZI3XWjQX2G8zpsQ>@}KLaBZ69a?u6QD4ITL4I1 >yNCE?gk8cQrwt*=Sn}H;NAcO=ven7M^0FD0-vJ1oo*$1LYv6IUNXuqAV85aO6nk5+k > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas >new file mode 100644 >index 0000000000000000000000000000000000000000..066c1e9fa6e0f6aa4121fe0f2378512523cd5fbd >GIT binary patch >literal 182 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m14FV5NGhp-fyKu+ghAWD9K>Y^A#55m >lP#MTXjvpWmKmauGf3eugCm=S+bOzkUbJ+kbvePx^0swfE88QF> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos >new file mode 100644 >index 0000000000000000000000000000000000000000..34a2457bef2a41129dccb62f4320ad66a52f64da >GIT binary patch >literal 191 >zcmWHE%1kq2zyM4@5fBCe7@MmB$f^JT|34!m14GmukW_RA1B;Ju2!pnPnXv&#fFXpi >qdCWj%ATzmsfHVLB(8&Kap=wJ&Y>@d3_$=VE0b6FLYi4C^zy$!wEgQ`M > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen >new file mode 100644 >index 0000000000000000000000000000000000000000..e7d4d3d0660ed68ccf7a9fbe6cc0b41eea23dde5 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(t;D2;`v3p`GcYm&d0^lcz`&wwV8EblU<&4k >ckYMBws2M;L|AUMMaS0gDWdpRxPS=zR01C<(82|tP > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe >new file mode 100644 >index 0000000000000000000000000000000000000000..db8ac687561c40e85c29806b30966d0d7f7d8076 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0aON6NF7`v3p`GcYnTFc|*<iZEC>FtGUehA?Ow >jn1HwpAtV_21FVCA0chfXkkKG60pq!BfEL;5ns5OC3tb#( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives >new file mode 100644 >index 0000000000000000000000000000000000000000..3f1a76e55bc1a7445d9dc2df31be87d6b35b4f74 >GIT binary patch >literal 220 >zcmWHE%1kq2zyQoZ5fBCe7@Ma7$a$-Oct-vI|Nj}8m>3vbUV!9*BntzBTL1%xk8cQr >zFA!@Rn1UpLAcU~-K)qlqcz%F&Ffag3{~xw(z66K{SqBoX2eKK6w3EvQXuqAVDHi~T >C^d|iP > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius >new file mode 100644 >index 0000000000000000000000000000000000000000..fd8d911129bc22fe5a1d1ff93e30a070d3452d84 >GIT binary patch >literal 267 >zcmWHE%1kq2zyQoZ5fBCeb|40^c^ZI3XFcl-3D&m`61R&CJej9G@I2Rlq5l8>{|row >zK*+?vVEO{6ioq>_k%fW5!hwOq$2WvQ+rSivO+XSr5JG~LKOkBdfHwRGSq<WXtOwIT >aCxB>>Gr%;^DIl6e=Wy8ooo1(N!UX``@hg=8 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte >new file mode 100644 >index 0000000000000000000000000000000000000000..39631f21486c61a19639d73d7571ef0840176b3e >GIT binary patch >literal 285 >zcmWHE%1kq2zyPd35fBCe7+a(P$l3Vr)}JkhW?eWw(f!6-{fAc=7@3$E85opWKq|Ei >z7+4q>lr<PQ7#P&nFz`V{e0)O~TpdFgv<-}m4M3!cDM&FCgplBXA5cC2fdJ$X5Djt+ >Thz2<bL{r64TtN5g8gl^vna4UY > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion >new file mode 100644 >index 0000000000000000000000000000000000000000..d5f9aa49d5e0f99abbb104072db7c781137365c4 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(#50x+_5c6>XJBMxU@!p+Ffdp+FtGUehA?Ow >hK=>gf82JNi0s{lk#Qz|pL0kgHbJ+kbvePx;0suyn8S?-D > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Iran b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Iran >new file mode 100644 >index 0000000000000000000000000000000000000000..3157f806b7d7fe650ec6726f31398824caf82cec >GIT binary patch >literal 1718 >zcmdVaOKeP00EhA02NkKd+7c0ohIsaMJJZKe+Kvj2=~GQx+IqB@K4{Sw>eVg~LKnnB >z<DFE}s0ATTBNYphBS=b0NJ+5Kg@y!)AQ|TyHezLA;ZE-T&D^AmCjakv%4)q1>yInM >zyy52Znw#%a+RdYD^B(<pC{l;rydcAy<6RM*E<0i*-8H_rT1PH+tEjYhIy!!WnjO=s >zXAhlLbMBwgb8k&kvAqK_?re#O?+nrj?T1w2mNaQs_KT##I_=2*pq!5PI(bHmN{OB> >zQ%CoR)Xyb4?d=OCo*tI-?nQ|7zHmAJ(h0GkD_dtA(JFIStIVqZE?gBodSOAL%FasA >zi;}LXrEl&@`J_NByPGfFHwHz{#SWc&GDPJaye{+G=8J-wVO?0>pqA&<>!OU0YDL_6 >z>6to96ptI!C03a#c|S&$zU~w&A03se?nH^QtG9J|_Yzfc{F7XLpiQi4nWfiOUsmf% >zdv>p{m3yxjxn_HcXDv8$(a3jo+3^@5n<@{qljV87LC9w|u(p%6_%!oKtQ-)+g#a >zyt<+3o!U~>CASvGh;56f%Eq*A(KNG2H&1$|T0#!Uman0rb+}J&AIefY?q}+q{dZJb >zZ=>9G=8M>Uv|I0Kk5zjcp38leYsEgF&u0Y$1_uQPj{2vcK+Cd)834~<%SsZ~7|U8x >z7!YPz!evETR+bEy`15^kp2zZ-JJxnOZSzbqcQUv6_50=di}ii^^{3_^_OU`_iM(cw >z$Rd$d`Zdc$)`=_>St+tqWUYS9Vv*G%%SG0UEEriavSeh<$fA)|Bg;nCjVv5lIkI%W >zX6?x0k<}y1N7j!NfK-5#fYg8#fmDH%fz*K%f>eT(g4BW(gH(f*gVci*gj9r-gw%u- >zg;a%<h17)<=GRn)l!nxX6o*uYl!w%Z6o^!al!(-b6p2)cl!?@d6zbPhij<1fiWG}f >zi<FDhixiAhjFgPjj1-Mjjg*bljTDYl?$?x#)Q%L7RF9O8)Q_A1$SHuF1juQCoCtnR >l8~^XAFm{3e<j9P7raNu(-JBblac*HJ+Hr12YI34I_6L+)nlb<Y > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Israel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Israel >new file mode 100644 >index 0000000000000000000000000000000000000000..df5119935c5b01676e63d1fb1efd7273b8b4b452 >GIT binary patch >literal 2265 >zcmdtie@s<n9LMp8WDL=qEV0%QuuMboa)Ap{Ng4_Qf!yN86a$VCn5p!b#55tF?1vc^ >z&SkCnbIaK1heO4-<|1p;*+y_umZ_LeKft>LcU*$tru4i|t=jsdKim4U!|Uu0{$YIH >zfs*A_DdHa&W<KHJ8qLFdlrrCTd$V3UvG|~F@A<<2^+z{F$MLInXJeJNo7dUjylm-{ >zuYV;^Rko<E71};sGQm21A@=BZiHGHxm~4G^e9$?2>5x9x>J#0c#_99=4e@<zhq|!u >zbEO+<#Sg{x;>Wf;>!&oI{qxRiqG#enySL_)z8HB@1*eUOV6e~*uWQiZH(Kn`gTGi2 >zO(}MC+mN2L`HCIWK4QgM@A~659<V0o9=7i)+pX`8EA>w)@mlwYIsU0*`t{Urd+lkL >zI`zFrNBQHs`mE{AvG$B3l{#T_h&^-10_`bp_9w27*WR3Cc2dsUI(c@rKPBmq<-7By >zof^5_O1;wLpA{OeW_5<h^ucm<U-z)S-|m+W>|bKdes8bL*n7}=@THA%PTd|ocTJjn >z$iL6Z%x@I)ath`Agw-M|X3)tVTO_jkDx3v<sUqj%fXr>bUF5axbRPb2SmbXR?G$W} >zQVTcjkcBnZl)o&~c_eT~J-RYi7Ws~-K>iH**o0lGIN?@Ve076b6cz6*>RPH64~%h2 >zTIZ=HUH#7EyDU-K+Ub<lXNvN-4mein6tT3vLq3raCMrr><de}sQJJw#R)vMCWs_>; >zvYuY`)Qw`f{MZTg^!aqT;{6ZQ%HsiN)hk<6byJ%2Ol7r_uioLTUf3X>t-S86@vIUx >zS>4Wa;|fKsXIR!=P7-U!os(-jZWHS+e<q**ctEW0*dy!SiB$FbUz9J@{;D>-Ss_D4 >z-SX#G=wGk@)teBL-GA@6ArUIXbZ<zw5YcgBtPtsQL&pF9Nq#{<<e4XTzIlq!y!`zF >z|Gu5A=I7n*4E^zoBj$=f`SLolC1g*?rjT7B+d}q*Yz)~MvNdFH$mWpUxti@E`$IN} >z?9kP05!oZMNo1GEHj#ZI8%1`CY!%rnvRP!e$aazaA{%x!JLb>9mR-%Bkxe7JMz)RY >z8`(Irb7bqt-jU5CyGOQ<>>p`>tLXsJ0;C5>6Ob+-Z9w{fGy>@a(h8&(NHdUbAnic< >zfi%R`bOdRMtLX{S6r?LiTadmWjX^qtv<B%7(j25aNP9T?gEWYvLr9BUO^=W!adZi3 >z6GxwrMsaisX%*5dq*+L}kai*cLK=p23~3qCGgs3zq-(CGZAjmc#vz?UTF22lq<I|O >zL)ypDKcs;i9Yk8l(L<z(NEcmA8<9RDjYK+$v=Zqh(oCeANIQ{!A`Ru}DAH1no+3@< >z=&Gw}D@R{lO=CGai?o)bw@7o5?jr3)`YZmA0gf<Po|$a=oKTSB@p*iS$!Q4%NnTH? >H#~bk*I^)#B > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Jamaica b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Jamaica >new file mode 100644 >index 0000000000000000000000000000000000000000..7aedd262a57f096cda47a8542b3b66633561641d >GIT binary patch >literal 507 >zcmb`DJx{_=6hI$^L};s25fDe6%4p)?u2F(abkV7ckZxUFjEP@yVA92vurQD~ILOB4 >zZ*Y5mz~qfgJnyM)nz(qI`%creNzaK+lirT{F$H<TGBsK5gG)Ic$}fwhK_e{%qqsDA >zG_JXgJ$;k<??b&j>!&NzYh4~+nc%6XSMSfv+WC>LB!_1Gq^YZ|(A4&PT@O98u@%OR >z;)mIEyg29Nf4QuEb(G4^g0<6URkZePmh+E0k!s5xbY=G=`KPam{x+%0o0-Y{`x`5h >z+-+Y#%y^6)#4w{+LQEmH5Mzin#2jJ|DFCSeDFLYgDFUeiDFdkkDFmqmDW(1=l`HLb >F-A~yjc0>RG > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Japan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Japan >new file mode 100644 >index 0000000000000000000000000000000000000000..8ad44ba981a2d97d40d3de2c8bf29606be50aa4b >GIT binary patch >literal 318 >zcmWHE%1kq2zyK^j5fBCeP9O%cc^ZJkbvvel>u<du-1zaU;O1G~2e;W7KHOf*|KQHE >zM<4F?e0;#n$OM5549(0y^$a}=7=fDWCNOY7NFU!21}_&N4h{iHGlFmkVMlNQ)qx%H >z1EdQG{sTekp(O<%8ssQ24RjcY200EygB%E=L5>8|K!<{8kYhnK$iWO`xtI&+d|gW} >E0KK7P_y7O^ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein >new file mode 100644 >index 0000000000000000000000000000000000000000..1a27122ee09410095d433adabe6bf2eb772710d0 >GIT binary patch >literal 259 >zcmWHE%1kq2zyK^j5fBCe7+atL$obzU9iUUP=Rp1c|Nj}8n3)+E<~#rjGtAn+!1Dip >zxB~+R1H*~~3_L!*Aq?7vh77ufMnD>2LkMB}Sb@fY>=gI`G8hPeR{gItlTZNBAp1dL >XAUA;MdY}*kIS%2n0XoYL=sYd}4N5Vv > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Libya b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Libya >new file mode 100644 >index 0000000000000000000000000000000000000000..b32e2202f572b8ca6ef3c5cf1d9e787a24f2c328 >GIT binary patch >literal 655 >zcmcK1y)Oe{9Ki9Xt$}*US=39>YHJ`OImJk57onkU5{bt^(oWAP25I~WOa>97K}6ET >zAO?%6iNq#Co+cUzi5v^D@O)2ACWBx5Jm0%Z+FU-5vyfZ0#jmL`PgqRUEUudiX4`)~ >zkKdjiTX(TTSzf!c$`32LGB~Cx2POTKxo}&yCS<7gO@%)Cb?alF+jg@g+e=4o$JxCM >z7uVg+y^!wOu2<cg&oZK>RCIYm_hc_sEEUl4q~A>>MrH5#iEC$G<WOovC5Q8Rc6Ue2 >zIoE}3u2>L$pZ5t=`+di5p70f-VbQ#&2uFP8rJF2K$F*pjo^ixvdY;V@X|sOD`GdfF >z^+%s(kf3N#L?|j=jSNM{s}Z6o@i$0Ow7eQIiW)_ZqDK*=C{iRTniNrrDn*u}OA)3h >cQ=}={6mg0=MV_M1a02vyP9bQHWWWx70c9krqyPW_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/MET b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/MET >new file mode 100644 >index 0000000000000000000000000000000000000000..71963d533e444362250dec5465ec58517ab6c09d >GIT binary patch >literal 2102 >zcmdVaUrd#C9LMoP#7buLMT0{EViKZt<UgbasT~i@<WS1VNF_87wTR+G3`%1ab55E2 >z)L70TX~mc|J9UAzhSvH!T1Zx74a>FV%Kpu{nX^A*^?N^8ZC!O&zq4nrXXm+jE}qXj >zvTj>*k?$Ypa`z7xXP3LUpVmL!zp;Pf)cFIGF%1kJ)pKu32YdEubXuFn&aSc(FZnh8 >zLeM^Wro>J@nPZ<uQ|+^wWx8sxQAvAd+0{KES$mn1n{qWHlBSvA6?RSW?@G!3NvSix >zl0W{0{1@I*+L>2%?dOLy>%FIye(bnq9En-xfrB=?SC+N?37gXrwd*!C+T7}hWtWHS >z`aqfGWaQes>1mdm5LE8P63zcMM++uWb;Ac&=*Hn+6&U<M3;Rwfujgasw;xkM(<>^h >zpR}UruoYK~Sjn1atu%AM%8ELzY^vK9rT1yk=}oryj}9$49<-aktW)_=gDOUr=$4(! >zwX{D&%bK&byl1i9TA83=Q@X9lIjc}`$|@5+QdRcXR(0+>TN(e3tsEb<+s?dbt70!( >z_1N1A@9njkBhTyh)>gZt_bIKuYq!?4Y*y_}Es9iE=}v!*)&>@6?WF?MrBqto7c+GC >z#rd}G^<T7pBGEP+O1ApppY5LR3)av#ZW|jWY}1Y(b??$Qtg(JfO<DVGb45(eS02@t >zOliya`?Pf`s%@iPy6<#E_a9!bmJi$Pfn6199jdhlw`S>~ou$^cy4<48etWoZwzY?T >zvqzGB){&p0j`QDGXVN8go_ycB&Q0pk*M{t|@eys`|E_k#2K0E>pt|>V%NKW9{D0x+ >z^JUD5b02Jy`4awq9}d+<eBn^UJ&NPGFY+%w{y*Je0G@6H$Pkb*AcH_gfeZr~2Qm<3 >zB*;*Zu^@v%M#K9t9ArGmfRGU(Lqf)c3<?<)GAv|V$iO_^$dI8SV?zdqj1CzdGCpL0 >z$Ow@kB4b1biHs5%CNfTBpvXu)-B6LSB7;RniwqYTFEU_c#K@45F(ZRUMvV*`88<R; >zWaOT1=*ZYT-QbbYBg03=j|2dT01^Tu21pQ)C?H`#;(!DKi3Ab~Bo>}77)UfcT{w_< >zAOS%lf`kN#2@(_}Do9w6xFCT+B7=kmiH)ZV4iX(t7ak-&NPv(CAt6FygaiqR5)vjP >zPDr4TNFkv@Vub_?iI%4e7ZNWdU`WJ}kRdTcf`&v52^$hOBydRNkkBEqLxP7y&(nnu >viJzwnAQC|&gh&jLAR<vj!ifLNI3~JME-a*(fpBqNX<k7fTv&kl#fg6bFZT@= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/MST b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/MST >new file mode 100644 >index 0000000000000000000000000000000000000000..a1bee7c6f0b76b6b03373eba880f52e8e83471ac >GIT binary patch >literal 127 >zcmWHE%1kq2zyORu5fFv}5S!)y|G5(w7<_|6fSeG*`e0_T{D7H)YycO~9CI!J^w$mJ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT >new file mode 100644 >index 0000000000000000000000000000000000000000..726a7e57176567044d585800c37cbc917b441d22 >GIT binary patch >literal 2294 >zcmdtidrZ}39LMo5NFgUKPZtaU&9o#45Kt0MW>nA#=>*{s&<LYIcC-R7owN|2f@1v9 >zd{)LRlc1ZmW?t89Y^ZCvwz9e7*0dIOzgRZ9Y_YhUp7--_fAwGM%bxT4jsHLIz^dSy >z0{O?q*#Gdj=k4QL^}XRWFAv7*{-@K;z>7cX4}0QGc-|jv;l>pCYwQs<{zIKioT*il >zA9!WzNU@5%nJ%(3O+|H2N%W(WYTEi#9n(0|TvRooFD@B3v3Vmp_L)Kxr;h2ky$6(M >z^c8){7Xv2#>`_TL)@c&o8<3>8`jvX2Q!ed!QeC#CSuPJYsVi3cB)R-{HKRCFuFSkn >zrOYkUGvhoeH9AA5{x;vFeHEwE!_&>I<3H)y2hN+T22ScZp;_wcC-&*ND<W#%+K=R# >z!Y|de%ifXs$?vO-EF&3H=S-$&gJg~zH(BQca{bV&Ci`@o&gpx~<Q}Tl3p!d%-gAp| >zeoL1s*f>Kk^sP~gs>gI;#vSU0f=~70*eq3)_NNqmAFqnX&x-fNFY3n624%^9kGW}Z >zw=CWMv$=WKHYsWS*xb^!OW#_#-`v);RhKS!)|8d5)@8pBD_>5#_)hOp<p~W^eyB$+ >zyHFw(FTHN={G?v{+q=zO?=IDq^+8kBJ4fHWq{38(qV@9h91~dajSfsCnVP~Ay5`$# >zRX6)<sT)pIE2oBK)oY{bo{>FL-xXH(4)sVw(_yu`Z=KxdKV=%byY>A!2h9U5LEV(F >z!!-LUbn}IfY01dZEhp<tFg8gC_j=9R?|#+mdTZ5#rxN9%P_cS=->9_Kq^Y*;VOd`| >zsW!A8mW|2h)TYW_*)%n7LPZC4XykLVIc105Jap7-84Kyh`UcG7XX<o&N2l3(#H%|R >zn$5PI=~|*BDtemz`7ixNB5(IcNhGq{NR0cQ?tbI_r2+9Tx3AW|ssQ7N;syT2h$8kF >z5;7)aP{^o|VIkvk+JPY>LxzTo4H+D|(ec6XI6FRIfE*)4hKP(286+}FWSCAnPGq1? >zJ5pq*$XJoVa*P%kF2{J00dtHP88XM1kwJ5e8W}dnxRHS)BS(hrv|~pGkBlA}J~DnJ >z07wLo5Fjx?g1`|4Bn%vJKmy^kkw8M>w6Q>f!4VB497sHnfFKb;LW0Bu2?`PwBrHf= >zkia03K|<rSu|a~v5gjBv9PvQ{#1SDRL>w_ff`mi~2@?`0Bv4KpDI`=*8!IGOP8%&G >zTpaO20)|8k2^kVIBxp#~kgy?fLjvctkwZe~w6Q~i=d{s7!p9LmB!C<dL_)|BLnMeC >zQAEOs#1RQ35=kVKP8&-km`)o_B%DqgPb8p7M3Ink#1siCM^urpa>Nx0EJtLK&^m2w >zk>EOQbdm5nZG4dcBN0YIjKmlTG7@F{--Ov?YrWW3JKMi7w;(q!+n=AGo1dHK`5U$l >BL=yl2 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte >new file mode 100644 >index 0000000000000000000000000000000000000000..29c83e71ffa6b071c52b2360295bf55009c09b76 >GIT binary patch >literal 2356 >zcmdtiZ%oxy9LMnsp(Ki)RFwE*C#4t&SN@A){}j7|+(5aKn2{NO24#>CO3@7+TWihn >zMJMGdIyrm5S`o9z{xNdPtu<C*E6m22DKLy8){4q;JMUi)d(^Ym@9vz}-QDi)?t{<U >zx2w7`&GnCGuKk3=(_s(qBU|kCTJNtdT}_2`-P6rey_My4??x-vnXu`p&nAwv46gd6 >zZt%qWb>Bpnx`x`{p1S1UD&OaAm&;|zawQ={Mm_mzZ1FZV9-pMfr_<F$=t4Cy7@@9? >zPN^Syep8d@2Gx)47u5WbZnNORfC}$#Hw)kER*Smc)apdLy5U*Ti<|1zlIs0>Y3U9X >zk>}IP)~!{`6S8#V%3`^3UZjo+&XlO>3=@56xx@@EGqE54E-QLw%uTOe6y3O5-+bsJ >zSy>XUSJiy0;xd2Ix8#4QZjJa-$0v5G_}NL55Z0m+hCern6MNO_z8;fw-Y?0W$Bg^* >z9$Djm+@u`aD5+IPby|I#q<b24M)6$9j4#nyY2&gsG+SrK%u(56QF`5<V`}}mYdYuR >zr)tAnk><7!URSrb{bBBS@rb&!_B(S|YnN;+>@%CnpOf4*#%#{rCwDJ8Y&>y=;+c6x >z=Y^z7-q0bPe|d>)ed)9*__{{C&Bx6>y#-RZ`+zCxaLcw0rDl7hlH!;g<J&PUzH70j >zB=ajNxw2mGT=BEo`ALi}ojtF1otoA64Zovyw~pxh`<_>2<!AK+olR<wci24m%yHS9 >z+;1MLIw0lYCryQ?R4OK0O;vo3R1H*`>d;uJeq)QN84bw89TobKFJjcbMvs29dsfw! >zB<Q-f5%pNse7(Q+tg4Tg)D4BFR6}5%Y0U1I#^I~xVB|?T*f(IBW?JQm&TjMMP^C2c >z+s#vFwury1-aP$6qPT*BgMzOM4w+-G|IRBAI9lLx1p+UND<lwTYjIuA`=ABRt(<#l >zf!F8q7W-U9oLqbEwWr8ucVeHQzi;2aSlEp76@E1kU}?zOki{XZLzaiE4_P3xLPxtq >zWR1uokyRqgMAnHc6j>><RAjA=cCpB69qn?F^&$&KR*Wo}zr&i5MI)<5mW`|%SvazC >zWa-G-k;NmcN0yJQA1MG*0i*<uwgyNMkSZW$K<a=L0;vR23ZxcDF_3B?<v{9z6vWY1 >z1SyH5tqD>Tq$)^Rkh&m+K`Mik2B{5F9Hcr(d64=b1wtx>l*rN62q_X$C8SJ9osdEy >zl|o8|)CwsUQZ1xhNWGAPAr(VP=4fk%6wT3A4JjK^H>7Y#<&e@LwL^-BR1Ya1Qa_}C >zj<$kG2_0<>ks><UDk5b>>WCB)sU%WLq?SlAk!m94MCyqY6saguQb$`;q^ORzsz_NK >zZC#PVB9%o-i_{h=E>c~jyhweK0wWbhO6+KBj1<|?Rv9U?qpdSiXr$6esgYVE#YU=) >d|NnA_*{o;VtS5QX-D&QWByVb}JJp>M_7|antVjR= > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur >new file mode 100644 >index 0000000000000000000000000000000000000000..afa94c2ac5c1679d39143eae062b812070876492 >GIT binary patch >literal 1564 >zcmdUuYiLhl9LIlSF0GZvatV=8qP3gNm>Ih;V}G;lj~TZAhX0IRZM0$AQ=|xcrbM}x >z2uqXfl1q6dmk?UHq$JsrvZiH7$MZRq7hZYch41M(pVO&xUVT2^++u%}{IS9I4Tt5~ >z!}ADjZ)e-OD_VNXUbp#I_}Y`7_&S1T`Z~Vv>AC;D()X<CYL7^Tjx5@(qN+ye8L561 >zoz<^nrY=%5qh9FPA=A~Yai3*YSFoD>?YYGDg_t>Qk0t(ckePe^gd{Y6F!PQz$o%q$ >zCUN&Mos@CeB(Ja2DdC6Af|Pu{a9FiTosy_i`<ql+;AEZltV%6@J4i3-Sgz6^OcKx0 >zShe(0pk&mHQOowflgxq`lT~s@vJ*!eZ~8@9KJklL5xQSi%1e_o^1RM@ebcP!+oyAH >zoieLCOZ1uxH`LnJr8;l#NtJ&%Li>ufDya8JVOpVDmlrPUr=_S33B$!7;xk3#KS@z< >zlG*sZQ;MHVF`Hhs%jPSCP08)2y0od=l$~qU<(2nL#hxR&GPg@@@z?6AxVx%);cC5g >zY_r-HUL)JS9#A#Ia;4@)xvKpbFWawWsvVCe$j&pRrmjV#epiNRIQT{+V1RoK3<&%O >zm*X6d7jc{uMgkqD`LqmmoJK9dJO`+s@6$bA@nm}?*`8(gcv8I9h2Qi3g+=|pK6C7_ >z31Sq)Du`JSyIfksAeO<OrtzZ+%^l+))<MjJ*atBXVj;vth>b3-kq|2xW<u;_7z(kJ >zVJgH{hOrQ9A?8Btg%}L67-BNSW|!7zh}ABw*$}%ShC?i8m=3X>VLZfohWQZt83jNp >zV3Yu<fl&mc3YWGFNF9(uAeBH$fz$#i22u^A97sKkf*=(!N`lnHC<;=QOIsGCE=FOH >z${3|VYJ(I9sSZ*eq&`T2kP0CsLTZE*38~VhEfZ3wOIs+UQbwteS{cPcs%4Z5|Brfu >ZY}&Cl=}=E}SY%j4s3$TaEG8@>=m(pAkqZC- > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General >new file mode 100644 >index 0000000000000000000000000000000000000000..f11e3d2d66a2d7c21f498df96c3fd1db3a0d8817 >GIT binary patch >literal 1618 >zcmdUuOGs2v0EUldWF{DuEqXvi5P_NR%*r&a!F2M`q-JGf*4U)!NlUD>4k$rTmW${i >zLKM9y)E4>377-*Eg<(Wx7z0I!EjkL4^tzqzQma-$oBqSO-(}!3o9}ZKcs)_#k4-ke >za9Odryw6hRakXPuwvCnhIy|}V&XfUnS8$xW>-%y2=xw{Z_gqX?-{w(Y-^fr_zkjc< >zzcV*$@It8XO?CaV$dYOiRTU_s9r+?AXGF#>P7rZXPvr6`^F;jIVIBYBhgk9Tu}&Bd >zP%Aqg>Q!yu)asr_op}1KTGK3bQpE$6+;B>+&AhBqc2&sKWesXwYPMV-;!%!8(b6$d >zFVX@+W!kIVV#B-7GQG<oGM>)V&htye#@pjMvu2veI{8v(7cEvfW!-vH@>J!@Xx5t- >zd{nt%bvjQxRr#S8WxlUXZ5gkX1rM6k))$3x+s#(7{ce&hJaI<sIJ;1~y_KTqXrkVk >z<`Tt)3-qofabkC(zxK??Q6=-=>yoh;wdZ@U_72Qedxvi5(mNBXtoM=J*EFcguU(fF >z`|m4x{Dj<J@LE)QN@Z0-k2tX2DG$zR5!K7Qy86p8Q4^A`YX*zNp-)To;d?3KNPmc~ >zy|P2qwT|ke^~vg3<8v+i{5g}%39z5M{o7+%SAvDGtd=t(z_M;#5`mW0-R>7`Kc{Cn >zUBbD^B~rMl=H|JK9>3@M3#}%8ePo%T7eq0LW)RgNy4f_!L9~OY2hq=_Q4pe`O`{@2 >zM~IUAEm|_vgy_jo6rw3ZRfw((Wo;U58R|mxg(wWs7@{&nXNb}ets!bd^oA%7(Hx>W >zM0betHjVZS^=%sc83{l#V59)afsq6x3q~4{JRpfcGJ&K5$pw-OBpXONHcdW|gdiC~ >zQi9~fND7h_BP~c?jKm<BF;au%#z+p59V9)QCO=4mkPIOyLUM#83CR+YCL~WtqL54( >zsX}sPBn!!wk*-aXFC$@_CSyj*kenGwL$ZdX4apn+2Z;xn^5abTVa}NF$nc0TXJkZp >IY<NV_PXY<#QUCw| > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/NZ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/NZ >new file mode 100644 >index 0000000000000000000000000000000000000000..a5f5b6d5e60f15ebdbb747228006e8fe06dd4a01 >GIT binary patch >literal 2460 >zcmd_rdrXye9LMqJpwhVKWemws!@O`gTvUW2LIninl6fQ~qi>S%pdpkbbb(AGa|~<R >zvNfZU955{rNzhUdL#TBjTa#+pH=TL5LUT2xEbMtd>%Z3evp;&y&hz^1>^y&*KR)l{ >z$}cI3HU4(pV12@yYnS!rJbt5fYi)0HA6U92udV95d2r!*Y0v93-wExLL-8$U$EX(R >z45~9bf9%!6!=>htkDBz|!5s6wb8bEQ_7(TB6CY~Vwn2Ay<32sU?uff*^EN$^z03W6 >zVY&7?YuqO@>!r_M-2D+{(towuJoVKp$zDN!sMo$d>V0XC_%!^kzJtfrujY*UcQ$H3 >zLAT!ca;=U{+O6ZNigkR*GddwJLnn+BX<&S~242`KK~vKusBg6dJHjNmX_4IYov%#V >zGD~jmz9=EZJ~H|B0hy9EBvUuG$t}@d8d~y+P7C-!Z*@9ky2k>Y;df4EoSmjKhk9jJ >zkEe!x+$7<9LnY#^trA%`Mx6C)C2GwDi7w5On8hDRY;K9p4%;hp;+E)K?|O*~jMTWF >zTXf!)0FD2=P7}VkthXI3)!V!LC2>cN-qG-rB(0CpJ8Mo!^2%(PU(hZK5~F2d(o2#u >zX`G~nR7vW!UnFfLUlv`h)$}uol5x6N7at3eB^?=>*<eW4&T!4HJ}WtuetK8Yh%S{d >zxjRjDS+cLVruXRb$rmNp^G(gYJ|Ope|E%VH+a@bcnwsDBqTIW`R#rB*>V3}_OTly7 >z_5QL95wk)c$O)HK>A6}M<tGo$jMvrvm!xRyaw!`2(c;VV#5_HuC7(@{H65So+SY6G >z(9Q!|`ocG|u5yQ#m3K+Gw93OPzSc*Qx6As3qgpYgLLQy?nr<+1Wy7yeYo*3Z)t80( >zSa+~IemGU1Xo=G&cdwG_twCC|DMg+#e^U>K$EbgLd5#|QpS}#EanPEBvA^Fj+A!Ye >zG`tL>xtsH$0f#?l!#Z=%%yJpo`OCQ3rxX{@84ibyb#wju1YfnjW>0YVuZON%*Zhvm >zW@M7cERks<^F$_!%oLd_GFN1>w$^Ns=_2z*CXCD&nKCkGWYWm2k!d6IMkbET9GN;Y >zcVzO&>}{>-BlG9yk^oyP14s&x93V+RvVf!k$pexIBojy~kX#_iu(h&*q{G(A2a*t5 >zD<eosY^|IiNkOuLqy@<fk{Bd2NNSMWAjv_pgQN$^50W5TD?><%kQ^aNLb8OU3CR<Z >zC?r!zs*qeE$wIP)qzlOxk}z8<V@S%7oFPd=vWBD$$s3Y5By&jWklZ23L$ZgY56K^r >zKwB$=ND7f0B1uHDh@=t8Ba%oYlSnF&Tq4OtvWcV<$tRLfB%?@5ZLORlNky`Xq!r04 >zl2|0ONNSPXBFROvi=-FHFOpy+!$^ve9NSt+MzV~g8Obw}Xe84}s*zkH$wsn`q#MaM >zl5iyBNXn6%BT2WlvW}!3$vcvGB=bn>k=!H6N3xHk-}s-j-<yAi$e7sd{1jJ2R)TY` >QGddz`jx)v?9W~qgPuMCAVE_OC > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT >new file mode 100644 >index 0000000000000000000000000000000000000000..957c80b79a30f38d7db99fc06b16c3255ccc50e7 >GIT binary patch >literal 2087 >zcmdVaS!`5g7>Dt1Dv)%#0g|Q^DEroFr=96Si*+o}mKHixrHoKZd1aYt!2&|1b)l>U >z2_X_N;8is&K~jtbOsa{{LZZeC_7GemzCr>Qq%6@W3U>US<E0l~5@#~s@61W(qRII` >z)in)azxmgzzrDkU*Jk_SI(ef#E`Pu8i`bOEH1^nGb>BNIaqW*a{@XK}(0W}HKRc*N >zbv-)p{WcvGIG}@DBKmaNRvj|GLWlH)HMzi}$+x#i%II=Q`Ffe8y3!@}$V?gbbG!`S >zK3PWe+?BLQoQ(YNqKqo*mC+kd$e8R{9oukT$0gm-@m`lqh?%Yv6K=}H8{>3R@0T+9 >z>;O$acSJlLV<qF`9g?}Tzj$}8kgVmmCA%>wzFFUhKh&T(=^c`rKU?$MyCgq3Q}cg0 >zs#AVT(t;~Hweac#oqDoSpXpANqP<o6Z2Nr)to7-0t(T>^c8*M|`&6bEWy_4fJ}DVK >zSW44cr1a6RQr1@^Gk<T>^6N!XaV?^=PN&K2t_rPeHxk_M(K+jHNL6!!J|FJW7bIO? >zEK{9Z952-q&g#68cO^97kcOfc<)vHObpB5#WWiVUTGRcWy!=U<)PB^d3*U`M-8*}9 >z(W(lO`X+s)$|H-*L%Jj@L6%M`&}E7DBs^%IgdfIf<iQlFzt*b_mxjvnt_!-N^O3x| >z|F|~p{!vyo@6}bSyJfX>%4-XL&^5(-WNqOoZ5q`iuMhn|*O`#4`(u+fYk{<Uw?yCQ >zNtHK0FV(k>=Ih%B7R&k_DcZWZL^jm_sT-ovsH<PhQ&03AV@$_m`!JegC8nP-XKGz; >zV@_6@f&ZM9!D{32`F(lz%*o~S+tV1Ai{BVi{ol|07W-$;Gyl-}g)#Quj!x?;*@|p{ >z+w8#6ZUNZ?vI%4t$TpCDAR9q;f@}rZ3$htxH;#5Y$bKB{hL9aO+ASe_a<rR5c7<#U >z*%z`gWM|0Mki8+BLw1L357{5GL1c%Hc8ka!kxe4IM7D|S6WJ)TQ)H{iUXjfryG6E( >z>=)TEvSUZPWn|CDrjcDE+eY?{Y#iA+vUOzd$mWsVBil#zk2C=3fTL{z(gUOkNEeVc >zAbmg@fph|C1=0(o8Avyfb|C#g8iI5LX$jI3N81#nD@a?Az95Z3I)k(Z=?&5xq&rA^ >zkp3VILOO)B2<Z{hBuCpNq)kYlkVYY$LRy9N3TYP7Eu>vYzmSF@9Yb1%^bBbl(ltlh >zHl%Mz<B-lFtwVZ;G!N+>(mterj<x~j{~keik(0$hrq4e$H_v{tr3_>Q3%z;X>@03& >O1arMUd!1vi-G2iks25xS > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Navajo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Navajo >new file mode 100644 >index 0000000000000000000000000000000000000000..7fc669171f88e8e1fb0c1483bb83e746e5f1c779 >GIT binary patch >literal 2453 >zcmdtjeN5F=9LMnkqQH%ZQ;8v<nU)CgtR#>b8FWLuL3o9$5k`URY6U)Y(?UE3#rVT< >zR*YFDf|Ayni4SWwHq<p-TiG0LO>3b&mt~`eO%k}b^FAy8>5u+w>&t$;e%!&IpEvGR >z-Zfd`A2->2!ozi$hxe(9ANJ?zJ^i7o`=tck^V$z;Z>?YNYndW?3oq&3_WkO^wg^2m >z=l6!8>R53#-KR(Ab%;NrJ^EUhPh1;)Mvi^&5##48<irPg!hbwh2Hs2%VrRSzYW0iY >zXD8&O^>Hesdb*xmI<BVVkLl2iVHLU~TZhY&D*WJK=@{9oZn)H=BQBf}ktdsV)O$T5 >z`mJs$Uu_mQw!I*4+EOcS_SVR$E1e>y=m9w`H%Z)*G*8CPE>zRQ9WpLBQN{f_SI2)D >zt`dgA^o&zKs+or`>sx!ys9C-l^0w`V)a(@jIcM!h;`Zz><Q+@j5p!eSmx;+*B>FGv >zB*zAkG<-@YUv`T-2lnZda}6rB>qVV*v`nQp)#;2^7O2d+7MZninwsxiBNvp7s_euE >z<y~2ys)eD+GAI73$oVcp=8jzud8dDtcYoF|7WFywJ^j1I;`X2Py}P!F{Q8geeJ#7x >zl9E1sf6Z1^kp8kRELg1ye;bs})JEYvcR&_JR*9mcZF1?Ad{O-R8+zF%mCDuFsvmlH >zu_~$b>e9|x>fuGjy37}>mM5fY_lmETdpuf~XP;K(-=s*-%&&xJFiNiU4~kX2Bl3~q >z1ER8JNIp8yCaP+V$<<x!#AB|ry1KPhJ)U|*KT+pZHIW^<)>*7-ulRIbVydb;<I&#G >zXyrYar`LY_i(1!NA)h=OC7$x-%BK&Fi2Cw)+0Z^D)@M)14fV&w#+Zw8Q%R@T<R8<% >zoFmFN{JGv7+o3iOoX}fFed@Wc9{v1zk7{gc)?1I~sivx0y=`ZL3J&_~Yf{Md*S|md >z?+pZYcL)&(yxkoXV&1g~v+oi1yIkgS3s-@8mYb)-Jf&{4A|Zn8H}}7<Z;$y!yS`EW >z!d$>yRY*i1vPNW)$SRR#BI`sJimcRXmWr$uS*+Ep7FjN`USz?@imhhJ$eNKwBdbQc >zY+hJ5XBG~uoMY+8+L6U0t4EfPtlw%1fK<S0N`TY=DFRXjjxr#1;3x!A364@AwcscQ >zQVouBAobuV2vQNGBuGuHrYJ~Nkg_0kK?;LZ1}P0v8>Bc$bvVj{)Q6)$NQJDXL`aRS >zrbtMYILd_72`Lm(DWp_Lt&n0N)k4aJ)C(yXQZb}tNX@LKXh_vK%7)a9qi{&&I7)}q >zj-z-;^^o!*^+O7XRM2Wlh}6((iilLvYRZVzk)x1EC6Q7hwM2@ER1+yDQct9yNJXut >zq)1Jzrl?3&t){F<T{#MiRF<Q(NNqWai&U4RyhweK0wWbhN{rOlYKn|h*=ov+)Y)nZ >zjZ_*bHBxJiVk6b&C^u4Xj)Ef<=O{T+bE_#jQgy2-J5qP6DLhhnr1VJbk>VrON6L@X >jUtDkg|1SRy^Iu`1`R|b8nxB@HmXYGh%uLHn%W(V&DI1f# > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/PRC b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/PRC >new file mode 100644 >index 0000000000000000000000000000000000000000..dbd132f2b0bcc8beab08e04b182751795c853127 >GIT binary patch >literal 414 >zcma)%y$%6E6ov01AsdnK0RGwCh(;k=S&0xTQ;84_wi_?7<`F!PCs;~}D7?f(B^vIT >zl7ch2`)zh+C+8E>VAZ0p#Q6&b$@1Vmt@shmEEPQ+dAwxQ={D8*Lz@c0P8P$BDh-yh >zJRhox=gVq;O|{%Y*PQ{??_KRC8|0oVI%a(=qV1LMrEqU0h@_&_Xe`L@@k|6ZIO2E7 >z93L|!ALb9D7bk4{9*EM0TpUDs5CS+32?Qb_WIzakkOCnFLJol-2uVX01tDw5!t~*5 >M#r`q2S-#n^-;pX<T>t<8 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT >new file mode 100644 >index 0000000000000000000000000000000000000000..6242ac04c09fd4e4952cd16503e954dcbdacec2e >GIT binary patch >literal 2294 >zcmdtieN5F=9LMnsqQq039#A5%lbXa8u7HA9u?H1*!9*~wBxWYY!ypY6x<VP*VwE+= >zmmF$Ox1)0{*9;xA*(@TrTCLFov}V~DYx7|htE??j;&$HW-~Q^q*10>s*V+C5^A4_S >zsLS*G<HXp1xSVc#d8_d2#pbnB$zq=Nnu9O>A)oF}HG?yM-#S=5TU{P|N?*BHr^e6J >z>c2iNRud-!I`W2Bc@AXisAm&ZbZdg1wCy&Dsm?HySI5hgC2=M;=O>BXv&_V)&m`{X >z`#S!YW0Ek^V-mj^P)Yq==IVEP)HO%m((1)7b?t7^*R?gP>l?P~8>-f*<dUGCx^RJ- >zmRX=vW>m<HaVa`AI$u&R%{MoFKTXmGr<(K+{*>v*$IQ(K&x#Js(YHMLp3JCB(lZ;s >zRkQMc*0-*BSItiTQfGL>Dq~{QWXA7OnZutO?+=^QoWA2GYp7ka!+VXdccaX0f5hbM >zT`IZtFX+7HSu!usqUTpkk^GEGU66NC7R36sKW(z|Ur5ypuUt@zJ{s4BXFpMkkENK~ >zPra$`=)7$1e0h($tLZzlq~nMzE$cJOYMz&(xyCFn+9Jz;8`6R7=Tu<mgf2<itV(+K >z>lLG`)ZMT2nw4KSO6ksSv+C`YQnr4FDc|Rl)r+glJs~9(X@w@Z=8^=*(@kamS5kRy >zkzPCfSGD%TG+i|@q}Cmt(Dx0WQ0qHJ^!<JN)rOkW`hjqp+E_Yls-NkWP1*hC!TKFi >zlXS?`2CAfXw8PYA6iWR-ooR?omxiOorty449@<x{H-C|)wuA!u;hqWARGF!_c8;iR >z1qph4(`nV5JgQsD4y%?(oC*2+B{ck_X-zpKt$hQgZLC8c4fmMG&eX}y_Ac}I$zo~W >z&}^PK;1y4lCn|c9{rs1Hk;tnO<%vW(cX?vm`zrTMEH4Ur$}8->*WU6V<A~x0|HX(R >z_An%5Ovs>+Q6a-Z#^tmFLq>)S4H+9UICP`q!SFbCe82#a5h6oG#)u3O86`4IryVCU >zP^TR!GE`)&$Y7DtBEv<-iwqbUF*0Oi%*ddTQ6s}f#*GXd896d^ryV;ocx3d*@R9K& >z0YD;vgaC;F5(Fd)NEnbfAc1h&NFbqb+E^gLK%#+!1BnL`5F{c<NRXHyK|!K|gawHU >z5*Q>hNNAikHb`)g=pf-i;)4VTi4YPZBt}S(kSHNxLgIu3%4s8ogvx1Sg#^oKqlJVE >zi5C(uBw|R&keDGsL!yR+4T&2PIH!#q5;~`i9TGgJjUEy{Bz{N$kq9CoL}G{p5s4xa >zMkJ0%AdyHSp>*0<BEfXpXd>Zs+IS)XMIwrX6p1MkR3xfMSdq9Qfkh&Vgw|<eiv-tc >xql<*sY2%9o7>O_vVkE{$kdY|k|0c}ww$^@I?X1#yzC2$}R%vdoFV~k7|2MIyR0IG3 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia >new file mode 100644 >index 0000000000000000000000000000000000000000..4091a85f388b57df98ff9ab056958e41c7d00fd4 >GIT binary patch >literal 1134 >zcmd7QPi%{E9LMort*fML2?w!VI3c=!j}~3BEju8StlQ9)4ck{|UFXj>R;zzAB!oC% >zBs)&Tfs=9|4l)suIGK|m;u{Ay#BKim{N7I-Bn}cMPxJKkq<@n3`Mi^z{h1Z!k7Krb >zg_EPsom`h6cTX3KznPcmV7z&9X(2HY(U#G-((?V>mDYTTwq<_k23al}*Qsu5oGZyC >z54C;K2T6slY06H^=69!c%bVNM@i?oUQ<r7y%~P`NdO^3J?~|@G<JvvAUL>2-9jy^b >zH>I?vx<qy^i)(M`N6E}<m(0u@?fbM^vd`aZ|FbgLb@!?6E_{_e6Ss8lh1W8Wzodgh >zQ!*q4+1K$(_cxBqaP57~EzZe-vPm5=DH-{ELh~AzgD-mY(1UV0d~dBDxv@%*UQNsB >z*@b%S<Qf^ve$g>&ZD3ZgC|DFK{)b1%n1Z`q)^@vlW^GrK30gZWfv~l`ZKl+iJJV*q >zF^@E`pgEB=m7W)^anGEdiFi?W#@si5Kazi6s@{FxUux#p7u}z*1NBebFR+&7ko9<* >z1(6kzC4JqR$fC%q$g;?~$im3V$kNE#zHV`3b!2&DeWU=S0;B|_2BZk23Zx9A4x|vI >z5~LKQ7Ni(oR}E4QQV&uPQV~)TQWH`XQWa7bQWsJfQW;VjQX5hnQk}0W52+6+5UCI; >x5vdU=5~&g?6RFeJZE60mM8kD1-G)jp>Wnp1Bx<WxR@GETD-y9P&t1gAKLN{CGT8tC > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland >new file mode 100644 >index 0000000000000000000000000000000000000000..a5f5b6d5e60f15ebdbb747228006e8fe06dd4a01 >GIT binary patch >literal 2460 >zcmd_rdrXye9LMqJpwhVKWemws!@O`gTvUW2LIninl6fQ~qi>S%pdpkbbb(AGa|~<R >zvNfZU955{rNzhUdL#TBjTa#+pH=TL5LUT2xEbMtd>%Z3evp;&y&hz^1>^y&*KR)l{ >z$}cI3HU4(pV12@yYnS!rJbt5fYi)0HA6U92udV95d2r!*Y0v93-wExLL-8$U$EX(R >z45~9bf9%!6!=>htkDBz|!5s6wb8bEQ_7(TB6CY~Vwn2Ay<32sU?uff*^EN$^z03W6 >zVY&7?YuqO@>!r_M-2D+{(towuJoVKp$zDN!sMo$d>V0XC_%!^kzJtfrujY*UcQ$H3 >zLAT!ca;=U{+O6ZNigkR*GddwJLnn+BX<&S~242`KK~vKusBg6dJHjNmX_4IYov%#V >zGD~jmz9=EZJ~H|B0hy9EBvUuG$t}@d8d~y+P7C-!Z*@9ky2k>Y;df4EoSmjKhk9jJ >zkEe!x+$7<9LnY#^trA%`Mx6C)C2GwDi7w5On8hDRY;K9p4%;hp;+E)K?|O*~jMTWF >zTXf!)0FD2=P7}VkthXI3)!V!LC2>cN-qG-rB(0CpJ8Mo!^2%(PU(hZK5~F2d(o2#u >zX`G~nR7vW!UnFfLUlv`h)$}uol5x6N7at3eB^?=>*<eW4&T!4HJ}WtuetK8Yh%S{d >zxjRjDS+cLVruXRb$rmNp^G(gYJ|Ope|E%VH+a@bcnwsDBqTIW`R#rB*>V3}_OTly7 >z_5QL95wk)c$O)HK>A6}M<tGo$jMvrvm!xRyaw!`2(c;VV#5_HuC7(@{H65So+SY6G >z(9Q!|`ocG|u5yQ#m3K+Gw93OPzSc*Qx6As3qgpYgLLQy?nr<+1Wy7yeYo*3Z)t80( >zSa+~IemGU1Xo=G&cdwG_twCC|DMg+#e^U>K$EbgLd5#|QpS}#EanPEBvA^Fj+A!Ye >zG`tL>xtsH$0f#?l!#Z=%%yJpo`OCQ3rxX{@84ibyb#wju1YfnjW>0YVuZON%*Zhvm >zW@M7cERks<^F$_!%oLd_GFN1>w$^Ns=_2z*CXCD&nKCkGWYWm2k!d6IMkbET9GN;Y >zcVzO&>}{>-BlG9yk^oyP14s&x93V+RvVf!k$pexIBojy~kX#_iu(h&*q{G(A2a*t5 >zD<eosY^|IiNkOuLqy@<fk{Bd2NNSMWAjv_pgQN$^50W5TD?><%kQ^aNLb8OU3CR<Z >zC?r!zs*qeE$wIP)qzlOxk}z8<V@S%7oFPd=vWBD$$s3Y5By&jWklZ23L$ZgY56K^r >zKwB$=ND7f0B1uHDh@=t8Ba%oYlSnF&Tq4OtvWcV<$tRLfB%?@5ZLORlNky`Xq!r04 >zl2|0ONNSPXBFROvi=-FHFOpy+!$^ve9NSt+MzV~g8Obw}Xe84}s*zkH$wsn`q#MaM >zl5iyBNXn6%BT2WlvW}!3$vcvGB=bn>k=!H6N3xHk-}s-j-<yAi$e7sd{1jJ2R)TY` >QGddz`jx)v?9W~qgPuMCAVE_OC > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville >new file mode 100644 >index 0000000000000000000000000000000000000000..dc5a7d73ccc59f704ec3bb12fc9065621bb66276 >GIT binary patch >literal 296 >zcmWHE%1kq2zyK^j5fBCeRv-qk1sj0G8E3PEOWHXfLgrm>sQ>@}KO++(GcyB2=Leu1 >zL(c+`;<^b8oD2-JHZbr8`1*!0Xd4<ZXd74pX+w}2FbKhJE664g1_5>;2C+qdfOtRv >zwCsP_wjd1<UG#Rz1P~2!4TuK02&4w&DiB={6k}jyVrF6iI(*^{kPy&?KsL~YK(_&1 >a$P0F%pbyZ2I9<uWz-0q;wVke^Ar}Br20-Hg > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham >new file mode 100644 >index 0000000000000000000000000000000000000000..957c80b79a30f38d7db99fc06b16c3255ccc50e7 >GIT binary patch >literal 2087 >zcmdVaS!`5g7>Dt1Dv)%#0g|Q^DEroFr=96Si*+o}mKHixrHoKZd1aYt!2&|1b)l>U >z2_X_N;8is&K~jtbOsa{{LZZeC_7GemzCr>Qq%6@W3U>US<E0l~5@#~s@61W(qRII` >z)in)azxmgzzrDkU*Jk_SI(ef#E`Pu8i`bOEH1^nGb>BNIaqW*a{@XK}(0W}HKRc*N >zbv-)p{WcvGIG}@DBKmaNRvj|GLWlH)HMzi}$+x#i%II=Q`Ffe8y3!@}$V?gbbG!`S >zK3PWe+?BLQoQ(YNqKqo*mC+kd$e8R{9oukT$0gm-@m`lqh?%Yv6K=}H8{>3R@0T+9 >z>;O$acSJlLV<qF`9g?}Tzj$}8kgVmmCA%>wzFFUhKh&T(=^c`rKU?$MyCgq3Q}cg0 >zs#AVT(t;~Hweac#oqDoSpXpANqP<o6Z2Nr)to7-0t(T>^c8*M|`&6bEWy_4fJ}DVK >zSW44cr1a6RQr1@^Gk<T>^6N!XaV?^=PN&K2t_rPeHxk_M(K+jHNL6!!J|FJW7bIO? >zEK{9Z952-q&g#68cO^97kcOfc<)vHObpB5#WWiVUTGRcWy!=U<)PB^d3*U`M-8*}9 >z(W(lO`X+s)$|H-*L%Jj@L6%M`&}E7DBs^%IgdfIf<iQlFzt*b_mxjvnt_!-N^O3x| >z|F|~p{!vyo@6}bSyJfX>%4-XL&^5(-WNqOoZ5q`iuMhn|*O`#4`(u+fYk{<Uw?yCQ >zNtHK0FV(k>=Ih%B7R&k_DcZWZL^jm_sT-ovsH<PhQ&03AV@$_m`!JegC8nP-XKGz; >zV@_6@f&ZM9!D{32`F(lz%*o~S+tV1Ai{BVi{ol|07W-$;Gyl-}g)#Quj!x?;*@|p{ >z+w8#6ZUNZ?vI%4t$TpCDAR9q;f@}rZ3$htxH;#5Y$bKB{hL9aO+ASe_a<rR5c7<#U >z*%z`gWM|0Mki8+BLw1L357{5GL1c%Hc8ka!kxe4IM7D|S6WJ)TQ)H{iUXjfryG6E( >z>=)TEvSUZPWn|CDrjcDE+eY?{Y#iA+vUOzd$mWsVBil#zk2C=3fTL{z(gUOkNEeVc >zAbmg@fph|C1=0(o8Avyfb|C#g8iI5LX$jI3N81#nD@a?Az95Z3I)k(Z=?&5xq&rA^ >zkp3VILOO)B2<Z{hBuCpNq)kYlkVYY$LRy9N3TYP7Eu>vYzmSF@9Yb1%^bBbl(ltlh >zHl%Mz<B-lFtwVZ;G!N+>(mterj<x~j{~keik(0$hrq4e$H_v{tr3_>Q3%z;X>@03& >O1arMUd!1vi-G2iks25xS > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk >new file mode 100644 >index 0000000000000000000000000000000000000000..289b795a8a8bcb6632ca97efc363267d2d491c09 >GIT binary patch >literal 183 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m14Ew=NUCQ61B;Ju2!pnv0f@^GLfABB >mpfZq&96vxBfB<OV|2i|ZEg&|?bOzkUbJ+kbvePv*-~s^Q&l)TM > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter >new file mode 100644 >index 0000000000000000000000000000000000000000..060bef81898b9b45492ce2e2e35fb218f5cc213a >GIT binary patch >literal 2242 >zcmdtiUrg0y9LMqB0R#d`5mT@~(jQ3!;Q`{02KbF2A>~hrnTmzv7?25pNQ5PMk<=`e >z*@!LEx@e?LAM66yU_NWDwCvBhAav#IqPf*tjI6{ge?9M~x@xVvF8ZDG{9eDEjh&61 >z&%0_}LtUo#w=2Sa!r|I&56`o^>}~i1>HaO4Cs%uZ(f;X=jo0#}4zyL85GmE6t20bk >zVzQoAP$A)7jE;yNk%;pXI`V3qTyr9*qt5*#(f!}6>7(Nk)BTyc_Q0^rs6Vb|J~w7! >zOZKZ-b%Q2u;Wjn<-ad0(Y>%Fk)M@5SZq@PO8%%ugL7i}6nVC0`tFQmGT5i}kPv3Z~ >zKyGUORnOm(D2Y2l)y+*Ia?6q{>elkF<+g-#YC*1N7F<4|l75&nx1W7oExh!eS@iCx >zzGM7Nll;a(oif;M7Vmskr}j3QwAx3t>e?mgg~d9fra?0E$JL#(Lb9TZRCdge<b;pu >zTyKWteiW&ee3NXJ9{yI{bt=Z>y>MFP_fMFD#-nOkchJbH5B1&k@0h~OxAi?GFPoyc >zmvnLZaVfsote3~`m*o>7s$_DTl#Vp1`+^V2iXl(099Sx4??<Te%AKa-)uXzy@T|Fi >z`(FJ(^3SrWx<yw-pOG~=7u1?#-<h>@PpY+hJ~8Vq9aig`w5cB7tu|Ejn1=_qs7KPa >znws89wK0C5)OKywwNtIKsis_SI<s2pMCrPr9H~#7rR!fwkOu!p-PnFb9y|ZJ-n?<H >zdHm!>wM8zQrv5S2ocM)#qI*!ac%!DZzE8D&b<nhxbgH&fBhsGUtJ~jtO*&#bbjR~u >z^3>#d-Puqp+k^S~>Cz&3W?;VFu_#G)_`V+q3km(l*R=5e@)hp;eNTFxyNCJykwbw< >z-#@U|oBr4R$RW>uGOPnLSC&<I#r7;#+4khvlVyMRfdKD6sQUNKylDT#ZDz_oaM^!{ >z->|FDeuw=QyCGyp=(fZId*ZU20(OOL3)vU4F=S`R){wn9?dFi(A=^XthinkpA+kke >zkH{vGT_W2=_K9p1*(tJBWUo%US!B0PyIo|z$cB*}BU?uHjBFa&HL`7F-^j+1og-UE >z_U^QsM|O{FAK5?B0Hgy*3y>ZlO+dPUv;pY@(g>szNGp(DAk9F!fwTkZhtoC$=?Kyi >zq$fyIkggzYLHdF;2I&ma8l*Q!bCB*hZF`XZIBkQF4k0Z<dW19y=@QZ=q)$krkWL}3 >zLVATX3+WcpE~o7m(lDp(7}7GNXGqhKt|4th`i3+P=^WBJr|limJg4m*(mto{AJRal >z?I6-Zq=!fokuD-_MEZy{66qw;N~D)aGo7}ZNIRXjpGZTUwxdW(owlb)Q<1JBZAJQu >pG#2Ts)274wzs5Ey&xW`l+upMZQp$2uGg7nDGBQ%ivi^LE`W?cWOo9La > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate >new file mode 100644 >index 0000000000000000000000000000000000000000..5cee55df32f377df2dbde0d9764df5db388434a1 >GIT binary patch >literal 492 >zcmWHE%1kq2zyQoZ5fBCeaUce<c^ZJkq_2mzNM8DWLF&-01JbwBF32p}b3k_Xw*a}O >zc?aaHZv-f0?{-j(-W8zaJ=a0mdQO0fcD;kDbX|ZNccO#Z?}PyL*Uk<aPiih`HU>Iq >zz4W-CooMV(|NsAg1|~)<kcoj|?irx13@Z*WvM?~r+Q7i!;~T=DZD<6<h9C(b2qD1> >zKOkBdfHwXIc?HA;c?U#;yab{_-U87euYqWg_dqnriy#{0O%M(8Du@Po7es@+45C5a >z2GJm|gJ_WVK{O}`z%(!zKr|>QKr|>gKr|>wKr|>=Kr|?5Ks1HH!({^uDmz_6LoNU- >C4QOKk > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury >new file mode 100644 >index 0000000000000000000000000000000000000000..a3f30e5c7b9166d408a0851bfac437293c72b0cf >GIT binary patch >literal 259 >zcmWHE%1kq2zyK^j5fBCe7+atL$Po%-IiSyKxuO35|No3k%*_A)$IoG4`2RoLfq~`! >z|I`2m4hDv87Z`Yad_x#?4UK@<kU`tf7-S9@gb=om6{rwor@#-07NF_>|JRv^rhvF0 >a`$06w4Imoi4hC`@!es+=mYuGlF&6;Tr!c?( > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo >new file mode 100644 >index 0000000000000000000000000000000000000000..6e4b8afdbddeb1ff2ba52168af01a9c8a7896208 >GIT binary patch >literal 221 >zcmWHE%1kq2zyQoZ5fBCe7@Ma7$npC-b3^_A|Nj}8nEwBduV7&K|35W=frWu#+XV&= >zAKwrLT|+|#Z9`*_Mj!|wY&=je*b1H>U>zV6|NpNu5A6VPLDqq2kd+KX+R0@DwBJtG >H(3lGVs@5vF > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji >new file mode 100644 >index 0000000000000000000000000000000000000000..912db189431adbc130b6397e317dd40733601fae >GIT binary patch >literal 1104 >zcmciAPe_w-9LMp;6%iI_br8bnP;^n3&o)%j1PQv#EwLeU_U9|2qEnM4ruJvip+iEK >zh=tH)hyGj!Q7Qz%kRXa6Awh_WFM$Nz3Zal{ec!*1og(Nrp1rnb48}h1L~3Xt?EP^z >z*&QxUn_ax#e%YSpc0DLIG*@ZE>V`D!k4V$vTZ!(d)o7tY+Lt~_EYqg({7X5u`>A$Z >zDM-i09qmlN(9SnA%ZbECNjx6buE=xgnrqkOo;6L*1hxCeGfkx`wddV^J#nN?PCl8{ >zQ~N69^zBiVz-Q^bdQEyiyq3O!5$Ri+m;R%1>Cfk6@Ibu`&OX$kEjwi>eN%_m)+HT1 >zrz5W_b+o2i#|mHc%(iA7zrLd5>q*IsEof%tkW9pH>BOUInQWYw$s0dqswyW_XH}-Z >zPRq>kB{{#^BNtlU>&3;xa;dtg+1y^qe$Q*RR4RFavVVF6JnwGN{zq?NxoorN-79)q >z+hYl@#t+*S;sZO0zZm7)@2`0F+e(bXTLyC4NXSr58w(lCX`>;-A>$zfA|oP0I&Dm3 >zP^XQG4C}OUk%65yGBUK&#zqE5Mn{H6#zz7`B0xewVnBj$S`<haPKyHx#A%Trp*SrT >zBp9bfgM@>`g9L;`goK2|gaqZZsF1Ln78eqj(;`Dcb6RXja88R32@i=62@r`82@#1A >m3DRj%I{#Og<t-LzYn>l5!>zS3-w*o1dNUXb`Um|;WBD&@X(Pn| > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti >new file mode 100644 >index 0000000000000000000000000000000000000000..3289094a2740500bc374d20904a70d7b307c2264 >GIT binary patch >literal 183 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m1H%dykkpC;3@kprAq?7v5Hmsuo5l>( >k1~QT32gm>*02=te&Wz^|hz&BG0k`p7Hb9H)bPbKT0P#5*egFUf > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos >new file mode 100644 >index 0000000000000000000000000000000000000000..76b2b3a126967bd410e57ce36cccebf7db167f67 >GIT binary patch >literal 268 >zcmWHE%1kq2zyK^j5fBCeHXsJEc^ZJkwk19dauP=Zw8gm|XcvA7sQ>@}KLaB(6EpMw >z|7(Eq|NrmYz`z0`8G+>L1q>WMz99^{2Btu429$?@5E5+t0o4Pv=s(DI5EtYE5Djt# >Tm<GB8M3d(lE*qfR?98|T79%`1 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier >new file mode 100644 >index 0000000000000000000000000000000000000000..625016d512b09d296dc340dd542a3d2d07c5c9ea >GIT binary patch >literal 186 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(lmHKw`v3p`GcYp#|KC`{zyKr*7+8FKLl|@o >iEP)Cb7(z%e@&{N4$dv#8K}LhP1dQjh0a|2d$prwXF(Qxv > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal >new file mode 100644 >index 0000000000000000000000000000000000000000..0c24095bf0f683d1e1c51fd30e294de40b3b3e5a >GIT binary patch >literal 188 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(6o2EM`v3p`GcYnTFiiad6k(XPfq})xH-tgk >k&=ACB2qD49A7C8}3_uhAgNz1o2^i011GLCa*U*p)092eEfdBvi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam >new file mode 100644 >index 0000000000000000000000000000000000000000..4286e6bac870c1ff15c73b8958c15210a3879c58 >GIT binary patch >literal 225 >zcmWHE%1kq2zyQoZ5fBCeCLji}c^iO)m2+GIBT%G$3y{Omvw(pGOmg`6hA_AXhcGy2 >z00{^P!EQ8A14t7Xz}UP$paTDaK;+@kGa$OoOxFh_46>4ek%{^Le=`#hp9rfN7`Q+V >J(KR&S0sur8B`N>_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu >new file mode 100644 >index 0000000000000000000000000000000000000000..bd855772054f8d41e0158e71c2bf2c04e50e47cc >GIT binary patch >literal 276 >zcmWHE%1kq2zyK^j5fBCeHXsJEc^ZJkZdPZH-HL?~r#o#=TuSt`xY}Fn!N>%J%>V!A >zFflLy$p{9P|NpBp7&-p`FHT@!@$n5|@CXKCmk^+S2nZo;D?3mn*w!CVJ^z8A<Uzqc >h5Djt#m<GB8M1x!dqCqYK(I8hbknSulpgRo>xBx^rPJ#dc > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston >new file mode 100644 >index 0000000000000000000000000000000000000000..bd855772054f8d41e0158e71c2bf2c04e50e47cc >GIT binary patch >literal 276 >zcmWHE%1kq2zyK^j5fBCeHXsJEc^ZJkZdPZH-HL?~r#o#=TuSt`xY}Fn!N>%J%>V!A >zFflLy$p{9P|NpBp7&-p`FHT@!@$n5|@CXKCmk^+S2nZo;D?3mn*w!CVJ^z8A<Uzqc >h5Djt#m<GB8M1x!dqCqYK(I8hbknSulpgRo>xBx^rPJ#dc > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati >new file mode 100644 >index 0000000000000000000000000000000000000000..762275d3c1d28a472dda088be5b602336e38e84d >GIT binary patch >literal 263 >zcmWHE%1kq2zyK^j5fBCe7+a_T$Po(t#Gucry`cX8|No3k%*_A)=KzKO|IY%d`~SZ< >zfq{#G;m899J|Eu@23<n~69W**plxUZ)C&P2gl%L6ss!08^aH8~XxaZdbB_iP7vusE >Y0J#E0gIvNuo>RDNfDW_MH8kM@0KKy@zW@LL > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae >new file mode 100644 >index 0000000000000000000000000000000000000000..f8222e66b554dc2e5e05be129662da3f8902280d >GIT binary patch >literal 251 >zcmWHE%1kq2zyK^j5fBCe7@Ma7$obzU9bnd-?oj{#|9?g%Mn(pP8D~I>W^DkeTXBGa >z1H$(44PnqWGz4OV=^=#eVg(unvXAEn$WR~vTJyioOvVI6gX{*0f$Rs-^*|v8QXRo% >M19X<1uAw0p0J1?WSO5S3 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein >new file mode 100644 >index 0000000000000000000000000000000000000000..1a27122ee09410095d433adabe6bf2eb772710d0 >GIT binary patch >literal 259 >zcmWHE%1kq2zyK^j5fBCe7+atL$obzU9iUUP=Rp1c|Nj}8n3)+E<~#rjGtAn+!1Dip >zxB~+R1H*~~3_L!*Aq?7vh77ufMnD>2LkMB}Sb@fY>=gI`G8hPeR{gItlTZNBAp1dL >XAUA;MdY}*kIS%2n0XoYL=sYd}4N5Vv > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro >new file mode 100644 >index 0000000000000000000000000000000000000000..b3a8c184432efbe040cd44a386a99c2cb58ddf52 >GIT binary patch >literal 221 >zcmWHE%1kq2zyQoZ5fBCe7@Ma7$obzU9Z>)O|9?g%CI*HDAQ6UH8yHv^7*-r$;PCMc >zVbC@-1Y($xA%u+w>IGZD^8;iU5CBd8UuP!L0HQ(GfyC;8Oa>zD<gx+UZ>MW$#03C& >C4<@1j > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas >new file mode 100644 >index 0000000000000000000000000000000000000000..10c5c9bc1dd5807c7bd13e556a4644c5f07ef261 >GIT binary patch >literal 195 >zcmWHE%1kq2zyM4@5fBCeW*`Q!xf+1PlmH)(`v3p`GcYp#|6gmt!0`WnRR#l#k8cQr >ou7Rbo0Z<78LkJ0m{s8L$ne+cY$Z!yspaonuV9V?*t&9!00P8;_JOBUy > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway >new file mode 100644 >index 0000000000000000000000000000000000000000..3e38e97c97ddf5e054fba822cfce1c5ccd422e3f >GIT binary patch >literal 196 >zcmWHE%1kq2zyQoZ5fBCeCLji}IU0b(MAqLNj6ji%6$}jj|HuCTk*NU;EIz&=48g%6 >mKouYmLfBN84IDrtz~Da+<k_C!0MQ^@7zkU#1+>x7kP855a3xUy > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru >new file mode 100644 >index 0000000000000000000000000000000000000000..6092119f66ca00e75e8ead98c286470d7c192fd4 >GIT binary patch >literal 282 >zcmWHE%1kq2zyK^j5fBCeHXsJEg&Kgw;^*2dr?>3)xZo5}AlS`vqW=H?{|t;wjLggo >z40CFL3K$md0I9B<z`(`8u;Ks%pO0?{gSMfeu>pg&fhCZIuq}iHyMKU;1_GdU|3Pj5 >g(I9t#Xpmb#av=AB=z5?Sxo+aJ0lLsm*U*Ry0Nn66!2kdN > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue >new file mode 100644 >index 0000000000000000000000000000000000000000..df6110dd108e529d2425752744d6d2a4512a84f7 >GIT binary patch >literal 266 >zcmWHE%1kq2zyK^j5fBCe7+a(P$hqTenjlbe%A)@N|No3k%*_A)Cv0J00FnzBSpNTy >z^I+im|35W=LBPj1ghAKP(8vHp8iPrYSzr)C*iKfULXf>8KOkCwHvIozXCC4MqCsu| >Y34`1LqU(WT4CFe7%LeE`J3~V*06J(pG5`Po > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk >new file mode 100644 >index 0000000000000000000000000000000000000000..d0b9607ed73a9a4bd6ca6b49a2b685609d561f96 >GIT binary patch >literal 323 >zcmWHE%1kq2zyPd35fBCeHXsJEr5b?59mgLHocyOUIJe%62;+a2QUCw{e?}%|CKeV3 >zhPf3$1q^c=7=Y}BI~cea7}lR)6kuSOwShs*$2WvQ+tAR^2t*ni07)Y-X$aB+1tEmp >z!VXjlcFPZ_9-#IA>&(PEKs3m0AYqXEz%<Z}AR6RO5M2*c!$2*^a@hbqVyA0p$OQn3 >Co;%$D > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea >new file mode 100644 >index 0000000000000000000000000000000000000000..d9c68f88afc0d9129366ce5b9a5ac02916cf4061 >GIT binary patch >literal 328 >zcmWHE%1kq2zyPd35fBCeP9O%cc^ZJkq_0Ox_@3<w;1An<K;YP%073Kj4n_;SKNw56 >z6x9F!|DS=05eS)CSQr@Q@Bq~_tT@03WY5~bz=6#6@eN_nHZ%faLy#gyMi9vmLV{y{ >zfORl10PXw_aukRQau|pPISxdF90;O8js(#lhk|I3V?i{<4(74}dcaQC(2xrNm{L3k > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago >new file mode 100644 >index 0000000000000000000000000000000000000000..3e38e97c97ddf5e054fba822cfce1c5ccd422e3f >GIT binary patch >literal 196 >zcmWHE%1kq2zyQoZ5fBCeCLji}IU0b(MAqLNj6ji%6$}jj|HuCTk*NU;EIz&=48g%6 >mKouYmLfBN84IDrtz~Da+<k_C!0MQ^@7zkU#1+>x7kP855a3xUy > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau >new file mode 100644 >index 0000000000000000000000000000000000000000..e1bbea561510bf6e8a7465a49647724bc243eb03 >GIT binary patch >literal 182 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m14Eq%NUClE1B;Ju2!pnPC5X!qLfABB >lpfZq&96vxBfB<OV|2i|XHy}31bOzkUbJ+kbveUKX0sx!58JGY7 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn >new file mode 100644 >index 0000000000000000000000000000000000000000..54783cf62eac51e9a575eee75688c4de4a15578b >GIT binary patch >literal 223 >zcmWHE%1kq2zyQoZ5fBCe7@MyF$T4+s;;8@s|34!W)Bpc%JPZu~|94a{u>Aku-@w4- >z;~T=DYhYn)03tzJfgpsi1uQ^iAWQgufHVLB(ER^(=6YX1Y><T@8e}O0(YA8g09{~b >G!36-BEh`8B > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei >new file mode 100644 >index 0000000000000000000000000000000000000000..9743bc3c9b8e8d2dc3a66bde761c3ef1917be50a >GIT binary patch >literal 183 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m1H+UMkkqUV3@kprAq?7vh9E9O2w~Hh >mfyzK8a{K^k00N+a|Le>Y)_~X`(;09Z&t(I&$WGVLkP86$h#GnT > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape >new file mode 100644 >index 0000000000000000000000000000000000000000..9743bc3c9b8e8d2dc3a66bde761c3ef1917be50a >GIT binary patch >literal 183 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m1H+UMkkqUV3@kprAq?7vh9E9O2w~Hh >mfyzK8a{K^k00N+a|Le>Y)_~X`(;09Z&t(I&$WGVLkP86$h#GnT > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby >new file mode 100644 >index 0000000000000000000000000000000000000000..3fa1f7fa80a3026d205cd0cb8870a75063ebc80d >GIT binary patch >literal 206 >zcmWHE%1kq2zyM4@5fBCe7@M;J$f^JT|34!m14HKrkW|kC2G#&y-w+0ELjw?>Aq2Z| >z%s?p+1_2fz2C;d6fOtRvH1U7fwkQq|UG#Rz1dv!gkj=oz1hl#ntPE%!P#@4bP9LCc >SC{{8saM=K@x6?H=-~s?suq6Nh > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga >new file mode 100644 >index 0000000000000000000000000000000000000000..ace1ce4b718e928c238f7469561c7ec41c3cd41f >GIT binary patch >literal 602 >zcmb`@F-yZh7{>8yEC?B-YA8pW*s~fcLLt#Xi=u;wP;|>+ofJW8adVJ%P`mjB#2c?$ >zhpv8sPNiM^2;x*XM<-w3=g>*S#S3@;OGqI1OODRZR>Y5y<|mjKK2PkuTV67~{L=LH >zqnv5B)okHGdbLyKQB!6syDB@r*RptG<lsu@oE?+v)^z?QH2&R&4*HX3t{&(@=hdh^ >z((~<+DaO8BXpGfj=0k?np$gxgWofymN>6=xLqw?w=eNrtYOD)Eba5!sM3=|HC2G}E >zQ~L*rD96!igjJNI3h%y0^7mN-e%GG${p%zC4Z2>d4seUJqc}eb0~8J@ENs~Wg^4Y@ >zps=xJ9~4Hm?1aJ!g%=7l6mBT&Q23!RMB#|S5``xUQ(JaLVQb62D2&B_BfFanzZFOB >ECwcmOIsgCw > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan >new file mode 100644 >index 0000000000000000000000000000000000000000..4286e6bac870c1ff15c73b8958c15210a3879c58 >GIT binary patch >literal 225 >zcmWHE%1kq2zyQoZ5fBCeCLji}c^iO)m2+GIBT%G$3y{Omvw(pGOmg`6hA_AXhcGy2 >z00{^P!EQ8A14t7Xz}UP$paTDaK;+@kGa$OoOxFh_46>4ek%{^Le=`#hp9rfN7`Q+V >J(KR&S0sur8B`N>_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa >new file mode 100644 >index 0000000000000000000000000000000000000000..3e38e97c97ddf5e054fba822cfce1c5ccd422e3f >GIT binary patch >literal 196 >zcmWHE%1kq2zyQoZ5fBCeCLji}IU0b(MAqLNj6ji%6$}jj|HuCTk*NU;EIz&=48g%6 >mKouYmLfBN84IDrtz~Da+<k_C!0MQ^@7zkU#1+>x7kP855a3xUy > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti >new file mode 100644 >index 0000000000000000000000000000000000000000..7867d8bd6c27774ad5a3b6f91fdfcec18845b7e1 >GIT binary patch >literal 187 >zcmWHE%1kq2zyM4@5fBCeW*`Q!IU0b(lz`A3_5c6>XJBOf|G)SI0|SsuU|{j_4PnqV >jGyp1KU<e_>$RA)GAXEPT2N@0G5-^_2256C;p#c{FV<04A > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa >new file mode 100644 >index 0000000000000000000000000000000000000000..334041388cbfac92c738453b5abf364a96cf1af5 >GIT binary patch >literal 183 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m1H&Q{kkpC;3@kprAq?7v5Hmsuo5l>( >k1~QT32gm>*02=te&P?bGhz&BG0k`p7Hb9H)bPbKT00Vd$r~m)} > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu >new file mode 100644 >index 0000000000000000000000000000000000000000..b3a5a89b66d2b74971646be2fea8066d4dd91fab >GIT binary patch >literal 393 >zcmWHE%1kq2zyNGO5fBCeZXgD+g&Kgw$zrDo=D*!9SX{2XV8y}_U{$ok!TRy50Gps$ >z4iU1~FGN%+T&Vy5|34!WGYcyd2r@A+tn~ouWLR6kz{0?=?E(WA1H+LAjC{y!AKwrL >zZ9^j?10ZP(#3mpOjEo=>2to)uk_V^^?8qNr9SjUWH~g<NW8VRyL5>CqgB%W`L5>H} >sAP<0PpeH~y$Ri*c<QWhR@(`E?dJ06>1I=Qfs?WG=fc~}9H8kb|0NRRA%K!iX > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk >new file mode 100644 >index 0000000000000000000000000000000000000000..289b795a8a8bcb6632ca97efc363267d2d491c09 >GIT binary patch >literal 183 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m14Ew=NUCQ61B;Ju2!pnv0f@^GLfABB >mpfZq&96vxBfB<OV|2i|ZEg&|?bOzkUbJ+kbvePv*-~s^Q&l)TM > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake >new file mode 100644 >index 0000000000000000000000000000000000000000..2dc630c606e32919db3ab5302f72d5523955c54b >GIT binary patch >literal 183 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m1H&8>kkpC;3@kprAq?7v5Hmsuo5l>( >k1~QT32gm>*02=te&P?JAhz&BG0k`p7Hb9H)bPbKT007t;q5uE@ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis >new file mode 100644 >index 0000000000000000000000000000000000000000..b4f0f9bfb6a6cf6b98b85993dbf1632736e9e19f >GIT binary patch >literal 183 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m1H+mKkkpC;3@kprAq?7v5Hmsuo5l>( >k1~QT32gm>*02=te&WvLPhz&BG0k`p7Hb9H)bPbKT02g!`)&Kwi > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap >new file mode 100644 >index 0000000000000000000000000000000000000000..289b795a8a8bcb6632ca97efc363267d2d491c09 >GIT binary patch >literal 183 >zcmWHE%1kq2zyM4@5fBCe7@MO3$f^JT|34!m14Ew=NUCQ61B;Ju2!pnv0f@^GLfABB >mpfZq&96vxBfB<OV|2i|ZEg&|?bOzkUbJ+kbvePv*-~s^Q&l)TM > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Poland b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Poland >new file mode 100644 >index 0000000000000000000000000000000000000000..5cbba412eef406b4baf89100f2c4a8e1f5d12798 >GIT binary patch >literal 2705 >zcmeIzdrXye9LMn=AgP4(#T$xTG$NG{K@=4sGXiIVc{$$jhK8s`hL;FU;#o4+jJa<N >zafp-_F?C9Ap)JulyUmsnUeK^vD_4Re!_c%fX217itu<@?)qnlY&hvWC**Skc?~f;Q >zMa~Fw*SXhz!<)0)zPS%}?4@FNRAZ%oP*!Erh4vlIwOUnuP+xmb_4VRyx^w#>vuo*5 >zQ&YGh>qP!na`N(I`D{;+HoTD{pO=o5MrTh}WAR~gYHMlU>CN?7XO`T~J3Bc-n-=bu >zb3^Ood~~pU(Y;)ny^m{iYk{<QPMel%bx!LyZ#h>^l{;;{%T3$icgzoatIgHzTg{JW >zGfn&Y=gqacB=b||T+>k&X09iWGdBtoou7k4O^>L~ydKpvoq$*T&3(nA9a%fX3C!;A >z^z`^Sy)qI^@Ax*SPsBy1Z?6U?$mf_7)N#P+cWIZ?|4gY9{J}<Nz>&92$iAH>bjPbE >ztmGvVzG00Sn44_|&7WxoT{zc%f4WB^l2YY?=md!j87vR__mjcCDLVMZNFDNBqz-NB >zt5F|y)rabCX>@g~4lBE$F~y(i@U=%YHhaIuEohbztLr2_xn4$2FPBlFRgy5GKoUBO >zWXymv9dmK9jQurV6OX3IxG(2uQq3Ywu20m5H%-v-l_B~_PJ~V<9xIQg`D#k`0C_C( >zvZkhVN}BH{Ix*sFnRxYkndEa^CN-Rp$1lAplWX@%`pILOv86<&?AxVJtXwHmOE&7X >z*_(BG?oypGI#)gE6Ln_L6rB}4RA=3c)j56AWX}1XI`_s9$vkvj=Qa7s{GEZapsr08 >z7Iny?vIfao)Fg`wujrET@5+-4PHJ{|g)B|3)tqhzby=wDvX*VSymPg#II&Kjy6DlT >zchA$@k5|bvFDL8Dni=x!@^H=DG)h)YOOn+&L9!+;OxC9UBF_aH$sgWF^V`3bf`FS^ >z(D<ROyV|Vl57fvD4fVRA;(aZwt<o3QRcq0fBK7j|_UYo=rQ1DSeY}0`jrX0;+}`!# >zhkx_(>F)R6zl`a1z&=V`yBHHP(5ss<0b+Xm^*$=rE0AwY-#@Q^{4zbmV`kfTO6m+Q >z9+S#Vs=eWO*<&y6{hiOAe}BsN*k8I&`K{mociWy>hZ?6MPd)PFyV|E8DF9Ldqy$I} >zkRl*eK+1sB0VxDh38WNAEs$ck+G-%>K<a@M1gQv85~L<bQIM)2WpTB2K?>t)D}$5< >zsSQ#bS6dyVJV<?z0wEPbN`%x1DH2j8q)bSiI26j&RthN<hgu=ULaK$73#k`}f*}<{ >zN`}<T)fNq@8d5f-Zb;!cRE|UGIMj|q@i<hEL-|~7{g4786+}vi)DS5mQbku=Mx>5N >zA(2WVr9^6p6cec?Qck3vNI{W`A|*v?iWC*8s;ez4Qdd`7SfsK@X_49@#YL)%lozQl >zQedRQNQsdeBSl84jFcIvv#TvMQfXIPYNXakv5{&c<woj_6db8IQgWo`NYRn1BV|YG >z?rIB<RNmE=9;rQ2e5CqF`H}h~3xKQuvINK)Ad7&k0<sLqIv@*ytc0sw3S=#i#XwdA >zSq@}9kOe_j1X&VfO^`)FRs~rWWL=PjK~~1qE)B9au6A*d)j^gASs!G9kQG9f2w5ZZ >g{~Z0(9QoPF8WzWRMQ6mvjEaek&WMY};qiXI0efH@v;Y7A > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Portugal b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Portugal >new file mode 100644 >index 0000000000000000000000000000000000000000..a85653044e0094363ea0f30d017a20ccdce2227d >GIT binary patch >literal 3469 >zcmeI!cXW++9LMpS5+i~iDnX2gREegttSD8|L{qVnix_E)h!yd;#tEglB~``A`BAi1 >zJz}0TV#O-4M`FaP5;an4#d<VUR8@cP#~;<xKdR@n|MkhqeO*`LKcDy4-fKvFpzSY@ >zyZVH0o{Q?6_g+r*GV5BZb3upU`hwpMIu|ayqc6&xtbdj4&=;p~GL2ZfzGQl#p4K*B >zUz#{VU*_#@F7KRXrn}zL(;uXot8-VHnJc}`HAZKB?WeBhy3dB0>-Bp22FFxAt4m3J >zb6|wNrDBf0<=Iw!>%DY+d(LJvd&??w$KqIh=a<vWUGq(IcT$46XK;+UH@cI#uZ^p| >zzlFbfpygciV04ClF#nRC>*A;9-q-X)m;0NCH%6L=Z!ax4;_Ogx<b0ZWbWRiV=-v)} >z^BidfdHZ+j$HsV=$1(;L9FI&XIKF&|e!^aCo|q9{a56By;N&Nh^;13fncs$QG*1Vg >z(7yB8qn)X~K|5P^nRfQ^94-Im6z%-hp4x@=DaOULF~+4?@kYU<9>x!j_l(Q^gN-YZ >zjf@}Lc^Ov&-HmH?pBmS_e6$<oYG^l}l+$h&{;Cz8yQAGYbWywg%`xpx`Y!G6{B_#B >zX=$1{{&VgA&=l>b0c(t+D8qOVGShe%G|BkcdzA60N}N$#qMK1%6lS=8-N;scftRhq >zbaz|Dl;%z`x}mdDTy<w<do@`l<cagupkHKF?_1KN%6aKo;;8g2+99i5$u_E=GGvXt >zGo{z|Y*8~KQ`B0xSk#^&MV$#B3oXGR>h>8R>P6UvcdJnGnr|~vzh(pRx_dRzz%@iR >zc-TZXyjoxSoc557_Lr7#WED%_WjE!Uv(L%KDTk%s=<U)!ZnX@E$rpi+ED_Xtn`ja_ >zS2V4)NHhyf63w0_ixyt9Ws3{_MDUZbvSoINc<cLU*=j|sY`v|ee0xe;*=9ja`A)pI >zY?~4++J(8wkT@^#ZvE>rG~}rWbIq0Qy)TLOcdv=?61zosUXFPG%2LrGGhIX+*(p1w >z&Jdk4mdMVDiK5Gl$+ByYX)-clpp0ssAng(DWjD`Gvb(R3?Ec7KMpq3J(Pt{lo(~&} >zUYj1s-lyF}AET0p$+|5*NG=kwv-3pX*wdol#6sD>&1Nwm=7@}|Gfxa`ohjqXY?Om) >zNjd1o7jp1Zha8eKP7b|bm%~=|mI((&is4gR%fuB?V#MG&QlHXPjO^M<IO09UsDRpH >zbm(I-rjkvJ^{Xn!nwLdVg-0^!_&zc2ZoVA9c7^ybZ=0MjZ;zaqxk!FAZkbF@O_sJ& >zF0Yg*`I29*>gQhkeyQIp{dfO<nX=ZGTd9Bl>)EqM1JtnCDhQX7Xe;~Y_cb+_@_&48 >ztIXf>sy_F4@h2lX+HE~Tqj=$4{V7Df3E>m<xTxp(i}i0ke{cT><5z6`p3U}5J&YhS >zgqCUykwHX85gA5g9Fc)UMiLoHWGs=vL`D-CPD?eO$bcdviVP_-rpTZoqlyeGGOozL >zA|q?5h87uHWN?wuMTQp{Uu1xh5k`g>8DnISkx@p585w6wHPFaNTdJW(#u^!HOEuca >za9gVJMh4tcjW{yomTJtALAO++jtsk{8h2#iE!D^)LvN|Z9vOUO^pW95#vcg)5&=sU >z0we}V5RfP!VL;-51OkZ!5(*?1NHCCSAmKpbfds@-MFa^65)&jSNK}xpAaOwggG2@i >z4H6q9I7oDm@F4L)0)#}!QiX{B7Q~2$An_0-9>Rpg2?-PuDI`=#tdL+K(L%yysp5qM >z42c*LG9+e5(2%GhVMF4E1P+ND5;`PyNbr#8A>l*fXQ={+L=Xuf5<?`2NEDGUB5_0l >zi9`|!B@#;{m`F5{a3b-vQ~^aIYN<ks#1siC5>+IuNL-P?B9TQxi^LWQE)rcNyhwbJ >z03#8$R3S!UY^j2bL>UP)5@#gPNTiWaBe6z;jYJy>Hxh3o;7G(RRmhQ;TdJTVQAfg# >z#2pDd5_u%_NbHf|Bhg2~kHjB20FWa9IRubnz)~Fq$WeeC2FP)M90<sffE)_Qv49*5 >z$kBit4#@F<91zG6fgBRZF=43=3goD;REGs}Tp$Mqa%3Qf26Aj52M7Ltbo_@$hnu=j >Y{5e#7I|emw+SuPOz_(+7KkwXr2Z!Vh=Kufz > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/ROC b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/ROC >new file mode 100644 >index 0000000000000000000000000000000000000000..748873bed9a167d0226bad2246556c45432880d6 >GIT binary patch >literal 790 >zcmcK1Jt)L+9LMqRd3J8VWKkFtB{CUAc^K$S{uE`Cvi&@iMEWfTEG7@5Vo^r2=mwM$ >z1CBfAJagyy7XyRh_dYfQi{JJCzpj7(8}9RVT01*R<;O|1Pq;V*_TqcGwzt)$I=$nx >z=-sgay;rqh{Iz+q@Aa93a-Rf}I#e+GSqCH2=I|q5LK|D^=(I(L=fxa%_sGd&yE+{l >zma~aTbKbVBFZwpsWyQT*mE@@F+%Ab^&Z%hJtd70}%*{nWZv7s0x1Of&mnzM}>$^No >zt(m7_u{Qm0D*3%xQXWQCYIsDuw^vL?Xhvr`VdaW*#sBFe(iOG;N0gQXk)d%(;qLN$ >zJ@Ga;Qr+lCy}hby9A5lB&hLX2+E-(Py?y`Y!=B!4lZ6b3jED@0jEM}2jEW44jEf8$ >z(~gV`jf{;9j*N~BkBpB5Kq4R^kQhi1BnlD+iGu`+X(J(_kXT4CBpMP9iH8J4A~Fvl >XImASQB2kgBNL=~%x^5f2sLcHdVF6z% > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/ROK b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/ROK >new file mode 100644 >index 0000000000000000000000000000000000000000..312ec40a112d5ab54ea2d92d735735be4b27a44d >GIT binary patch >literal 531 >zcmWHE%1kq2zyNGO5fBCeF(3x91sZ@v_w^4Ilb(tFxa6$<;gP@QhbP(Fe>@eI$at2- >zT=87c=fw;Cf{GW<zhu1P52|=|{94BA_a+r@mhZ@TdtR*KUHhzz52l3`3X2maDCVV4 >zP-=FXpzP;4fq{{UnUMtvGP43914B6n&_agt4h9wmhPnw1Kpv0;vRh{`@-Q&;EMVmE >z@eN_{4h~`P0%C8M5Rh^>2qD2|KcKq)0|Cf~AR6RL5DoGvhz9u<M1y<`qCvg}(IB6L >zXprwgG$;hXG%yrEG$<s%G%z$kG$=$sG$>R+G$>?1G$?dHG$@2X&H;rIhz5lehz5lg >Ph^AeLaRGx;*OChWrb4=L > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Singapore b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Singapore >new file mode 100644 >index 0000000000000000000000000000000000000000..78583666698a0332b822c0cd15daa58abf60eb27 >GIT binary patch >literal 424 >zcmWHE%1kq2zyKUT5fBCeP9O%c6&ip<TXXB;UFm)k4sbn5IJNm{!s&_e9G5(DKZs5I >z%2EIS|9?g%W)@a9R(5s<hQwH)dJxINz>rh`G9q1pkq1OF0Ljb>1|bH9x(N&t3=9Pg >z3^G2xAq>GltZiTp!bS!l(ilWq0<i_iC=?Jv*x_724Pb}=fa(Og?|+?H@L~`R@(73q >qc?Lv-JOrXao&wPzkAY~A=Rn#)9t6?#Krsfo`I5^9=yy9^3oZbMHDSa6 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Turkey b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Turkey >new file mode 100644 >index 0000000000000000000000000000000000000000..9a53b3a39063e86859b12aa755b78cfb38a26709 >GIT binary patch >literal 2166 >zcmd_qe@v8h0LSs~aUAC%)b)e#2L33-Ls3H@It;<Wlc5Ja>4}@+_AJqKI`%DVt8C*I >z%*}N3aoJ>}IZ`4=&bD-ITIsP`!!UYMED2aoYqmKz{nnyi%&zbIskWMb)cUvYv*%vN >zaq!3OKJWOtEt^WkO=qfpg`3l^Z=Qz|`oY>g(b<)iYj#~cZ6DgW!8yF+1*4}iVZK&# >z!tN~$JFkb^?7pHRv+t`L_8UL%a*n>g$QWq5W)7tK?XxQ;%#Vf=#^B&F^W5cr<I^Xu >zI_I|rj0=Y<&EeWK<6<n^`E2eE`}5-K&ZWS5dnE0EIdY}O{^I%(bM$<(F*a<Q<Hz^f >z-+q76{I2DcJ+V2%{9$Iq7Tu>D&(`C1TH+PQyYgi_ealJHSN@if(fX3~R~||DC!ZF9 >zP;Yl&bg`4E{B~Aw$jlm<ZDjXUnz!`sGj8q3GlM&~8@E5+nY^Q+Lfl#RTr#I%JaJdJ >zIhpG{lbGhOPKI{vH$r3klldQBu%~zB7&G>4S2Le)QM0zKQFk{lSNFv3R|Qo?YWDn) >zD$LJRbEZzJurDmb6VqhT<$#<!{EM9T!Bts&Voc8O`B*O4-L4jPyeaQ}s#}({?30Vu >zzpF~0JfO;!98~42o>livPpFF0M^(j*$5bTm85tR0rYa}b$;I!@Q4fq($*SI3x#XQ0 >zvU+EstmzVR=_bE?up?hR6ulyAH~gxW6%NX1t)rryrOtBSS*xz#%V6ELZ-VvS{$Tyk >zKyby^hl4AR^#x<+&R7k5$F0VruUZecwg!zo?bah}U$j<j+i0zhoDRlgb=I2PMysj% >zpw;waiM95Vg+^N{mGXGg{>zo_`}0ckX88Z@<((3^>GJu6$Scy{NRhW$qzf^x#4|;R >z{8=Jfh{#gUZM-6K{{H%3-@|WX4RKMg?`U*24{=dkQm*eZ{;NJ7eSUxD{vhK2yp<09 >zPIoIm{qcwTqe?ZsJ#Y!x4zeFty&+^r$d-^jA)7*Wg=`Dim#f|wvNL3B$lhG_=8)YX >z+e7w;Y!KNYvPEQ%$R?3pBHKjviEI?vsjJ>9vR7oY$ZnDCBKt))jO-ZQE%UkQJp-FY >zc8zQs**CIrWar4%UG?5MY~EGx9@##!e^=cAqytC`kRBjSK)QgmfkPjVMj)L)T7mQe >zX@;xr2GS0sA4o%xjvy^TdV(|s=?c;oq%TNgkj}X3)*!t>nuBx)X%EsLq(MlBkQO05 >zLYjnh32773C!|qGr(AWbkY2g!W+B}|+J*EBX&BNmq-99YkftGBL)wP)4QU+GIal2} >zq<2X3Ty^)5_POf*Aq_-2h_n#tA<{&oi%1)hJ|c}oI*GIr=_S%kSKUpdo!F+o>*D_y >O(99|w*XjjjnZE%*@2d&` > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/UCT b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/UCT >new file mode 100644 >index 0000000000000000000000000000000000000000..40147b9e8349c50b9b5459d34a8bf683c91b182f >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<U33UzuGC~OJgPFnd17-@c0bD?H47dQf)dy|> > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska >new file mode 100644 >index 0000000000000000000000000000000000000000..6c8bdf226900d7f4c6a4d47338e6742d4d6747cd >GIT binary patch >literal 2380 >zcmciCeN2^A0LSs?B5>gbMG2`$^d$2B;sFJrC@%;CA^~!{36V--cUTDoWB5j5I&v#< >zv^kuOj&p3aNjuZ6bS=7Rtxe1kZoP~}>DEk^uJtyH<aWNNw*IL3U!G^r^Euq{@9*nr >zXn8uv`qv59zwmMn>X&=UZv7eCpXZ-Q__=MOsaX6zQ6^_kZE^?RSS75%Qn%x!6cN;& >z?4HwJqJo=N`a^1yRA^D6-<chzoUd%~heu7T@R3Qk>xc8|j&H{N5no;vk^T|?ou|jd >zU2mRqM;#s!cke&$zGqv%nA>u|9bMlpVk+9)_ZHNNd8upN^B1+M1>wuwu|c&eHa$8j >z_Qzti@N%Mzn^>&wJL8n`CqmWzN3Tk|t3W)^J0=%-7m9=}-`R_EZ;Hg#=j^1IuSIg& >zaXWc-My0wA*r`)rskG@fJAL$hm2vT9nK^V+Wu4qAm-M`-#H%$j+b2a%M~+-twnr?h >zi<Y^`%_1-7SGnA|O614Qwezo}h=Q44><2$~iH9aXw+mI0didSb_9F+w)QTfVY<KIl >zD%$&wEUrGURyH4&B}?8?r6oIL=}(tLS>~W!cJZvJh}>>hoE#RbuQl40uYI7_eAX?i >zb{<oYzTF_J8~3T2Lxr-o(5KdR#ml<53gz)y((^~U^5$Na-fzpry7+*-?xQqOKYPh; >z7>*E6Or5nG_g)uIjt<-Fo5#h5p+0+K)%U8Y@0ffl^Mcys+b5eNmD*h9lbf#%C|`1g >z^nKE)TAb;!WyGttT#1y=9O@9yj;Gnrbv-7wstCK)yIi#OU$@)y7KrCt$L)@o8PQpN >z!tM;rQ(gHNWY^Shs(ZeY-J_Fg+l>Laeds;4<BLwYv*&fS>y%gatnXDX4CYHm&>Tl_ >z$gQ5xFz0Q20)dWh%hKPCR&XHD+vW%}-w5+dl)1<7wPFK-{@spvb5B@P<*|zD^!vDe >zYxG;rALS(;tDZ}xz7$pJn?4RcoWCxf|K6HQ{{t^)K)>8mZt#~r0ex1Sx%nyX>MJTo >zHi+!dsJDph5zQvKuuG2KCa_OrqsUH?ts;9xHjC`msJDyk*Qhs)>=@ZHvS(z|$gYuX >zBl|`+j_e%SI<j|U^T_Uz?IZg~8h~`bs9RvvJwTd(bOC7t(g&mwNGFh1AiY4Efpi0D >z2htCuAx7O1q$Nh(6Qn6fSCF<KeL)(7bOvb+(i@~XNOzF-ApJoagmegLkx};uX%f;U >zq)kYlkVYY$LRy9N3TYP7Eu>vYzmSF*b;ppF8FkN)rWtkDkhURxLmG#44rv|IJEVC? >z_mK7>{X-gP)Ez`xXw*GKnrPHrMB0e-5osjSNu-rXFOg;<-9*}n^b=_)(ov+PM%`1S >zsYcyZq^(BXSER8>XOY$-y+xXfbQfta(qE*(NQaRY8+DJ7CL48^kv1E3pOHo*okm)X >z^crb4(ru*OmX3FDP)O*l9%p#iZG0^2LmkQgz2W~v{O_BKx);#-jH;zsIawm3DmyzX >IJ4?9!1Y+B7Z2$lO > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian >new file mode 100644 >index 0000000000000000000000000000000000000000..5696e0f8bedee72515c43f686881a561af339db9 >GIT binary patch >literal 2365 >zcmciCZ%ma{0LSsm-^)cYDj-Bm!Hl7RhrdBt9tc86<UwwrWC#iolmVg)3ox8hdC{a; >z&Wf15=#OjEF}7yX*qNL2g>zkSYhaF=n{(Efu39oj-p=>b){C0&@;rN<&*6@@zpuBZ >z`Na&^zmCWJ!pj*jFZYBu%;$W6p>J}<Z*7zHj=VkjoVs(W-SL0wm9ArzPQc+D8Q7KW >z1hsF{!SxlskcuoFnxE-&r^jgbn>&4;$T{s9x$cDDyrdWWIPF_FeM?5@G2f!Er{#So >zrku!k$K?I}r=17(ejp!g9&)0#?32+Yy-rMCy?iLS&WTOz(ThC=PF&zN9k)7hdE76K >zUUDT<#ZPAFrDvkm!(T?}Wgp&B%R7r@Lf^DXtV)(ET7DOg<SdXYOQ*!6(X%pX)oGFB >z_vqyCA(1@uvtIR6uUI{PL8n}NPo)ljq0>gY)tcV7v>2>a=}n)@j1H+Xiw9&@WunSX >z+9h)`gVkehugr~45V_ZKWZry`c>G+feB%47Vy(*3PmY}vPYuNAb?=`LvUN`9A2_QD >z$}j1s8$MBmYrfG%h5f4N*Bi1p^<z<daYB|v92O;`qq20iMLaw7t={n6K~>g$Qg8g~ >zB~`w4P&-FURmIvpdQ)eLs*JDJ-l|2)JD;bkvTv%Yt5tIIvIw#HY_8mL=Z2{HC{8{< >zGa<Gfn3pe%kBZuc8M$rv9Z^?yTh|{tskWzH);pR8RYSzMZY<uT8fTB|rle}sbYZ`4 >zcIT<)kp|szZHapMXrFw=mn(L5?vSslIMG^FB-@V6i}su(xvO<Xbi{b%?s6@5`&a7D >z+{>!-2e<Bu9amlB*Y)1H<Lb5H^ZNCv{i?fnME9I(P`$NB^uA-ysDQwrfZ&k3J)vRl >zd-(YMHQQY-zrWFO1^fLSbpc`ayU_j;Y41^dU9o<DUt7RZdtbbv%<I}%Y2Iq{I$l?S >zxfc|AUHR+HWxctW6TpY_*TwtaBMUeGz{`2tyxbG!_{$u>IqS~+F@ZgYYHE@3Ap^9U >z5h6oGJ4P-Hl4C{*3=<hAGEiis$WW27B7?P>(IUgOn(-n7Mn;Sb85uJ&Xk^sLu#s^i >z14l-V3>_IeGI(V4$ncTzBLT3Q2v|)BkQg9AK%#(z0f_?=2qY3nD3Dkn!9b#cgae6( >z)dU2Ih}DDyi3t)EBq~T)khma$K_Y{M28j(493(nOc#!xY0YV~VH6cP`gaiqR5)vjP >zPDr4TNFkv@Vub_?i53zrBwkh%FeGAD6EY-bRueQNYDn0SxFLZ<B8P+yi5(I=Bzj2r >zkoZ|m0Fek<O$d<~T1^m<C?a7*;)nzii6jzAB$h}pk!T{}MB<4A6p5(SgcOOX)dUrZ >zs?~%Qi7OIVB(g|ok=P=^MWTy@7l|(tU?jp;6JjLBRug0-%2pF*B+f{nkw_z<Mq-Tw >z8;Q2dR695@B=l~N+Y@#VAD8R1EA;XIiuXVD{`(eg%APJv+EdCh(=yUTN?Ce(T6&rY >F{}YG!e4hXS > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona >new file mode 100644 >index 0000000000000000000000000000000000000000..adf28236a2feb68f177f5b002ea068db59eea997 >GIT binary patch >literal 353 >zcmWHE%1kq2zyK^j5fBCeZXgD+1sZ_Fyk%As=I>^2SkNXjVd1Qo4W~PKCY%?)FLS>C >z>6#0TQZm1OlnVTQ5y8O32!zZ)$jJ2n|Fm}u4FCVHUckum|Nq<x3>;uKkB@H%gRct^ >z2Lo|<2+(i{2qEkw9-vCFlYT(;{0D+K7M=|t8stO}4RR)k200Z(gPaSZK~4tIAZLSV >apwmG#$oU`|<OL87@&+aT-~xKgoC^R+MSyDn > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Central b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Central >new file mode 100644 >index 0000000000000000000000000000000000000000..3dd8f0fa82a60710c0711f35dee93ef5013ca796 >GIT binary patch >literal 3585 >zcmeI!X;77A6u|L=OQ?yOM&c4$mSiHEp=g+zG6aRVAg*Dqh^ag(qNw5HL|RQ{Wu>;@ >zhGvVQk_wrKh~{WcDN2$`xS>(#<C5Xhy*>ZeX~vnF$&Y>LFfYH$oy#!8hx0#iLzBjZ >z$lu1(zQe=(Y9C(vX!|X5jlW*@)it$zegnPY{iAB-z7$#Y;_oIa;-FqVy40*0P%0mL >zFIH<iZk4sJ9P??DkL1&`cg<&)=gQ~#Gt9c;k@7|65R;wLOV+19ZZ>>4LT^kQta9e` >z)L%w+Rhx#l(VP8Rsx9HQb?#j*mDl2|&Z{U_TWi;nt-A}=*QYCFTXvbrFWMv97Z#X; >zp(V0oeYh&jcujW3W|*QelVw-nII}zERsBuFr_7!X6ZM|zv1+eZAHDZTq}ungOCM}= >zMI9Vj*A!2`EQfmhVh#^HEG4b?n;$~A$PvjlrQS=WwEQjeqid5sS}@HVD_g9OfAXd( >z%TLoky)spmXAaXRlH%0K^lti8R3~*hp_M)}DBM&;hRfN`zUG{tul(FpOr`y=RbD-5 >zeyKPqzm^o4s@+9$e)|b^A-i0gWjocyg@yXk+|}xGa+ba_VuAWCcD}yaJxTo@I9^vj >z@{+mMFj`-)lW4A2C(4a;QRe26DEVVgd*jM&FYdKoMwWPq$ASx{#*7P6b4q<xYvkR! >zcHi^rt{zp|Gw6He`MRI3+i0VzyKa@#Gw-Oo%NObTrR$AX!F1gq?`_lYleeYO(iC&g >zD=E@AE#5RqikEwbgc<LsFuAWwbJMh4bMbkwvual7rZlh7Of|pcqg$M~p;{ieuJ7M* >zT={M|rdzGpu3D!yln3UmP!A5gC~YQeGY^Fp%fr#jOk3|w;`iu0<L5e{+tnLw+Lh(# >zM=K*t`}}vcfAJ{QA#;Wf$my*D(}(DwMQv4ZVyc8ptD`zb4wlFISE^9IuF@&wTh-aK >zrG&LOXTmC6(&ffp({*>bJbv_Z6P|rjciZ}gd17Ii?*4%?J(3G_&y3gAld&sxuQAE0 >zcVLE&=-p36T;3v)9VVH`;-wPh6>Fk$W=nKcuzC8!#rm0&J}PETn(nhXNW~5xru)9v >zSoI6<ru$F7q6V~VrQ-&csJNRRIzBX4#h>w&!M=yg;9Vj^T$|0%tdlaVY>643Q6$gi >z&oT*P*2sv=;pVxRLOpUpni|z1OOH+*rp9>9*JC5Qsj*e#b)sJ@mAF4zCwY3Pq;>v! >zLd7Zd{CiO{@jJJfl-gb<XP+?1@m``9?le<EFUZv7)n=Oa0ZEBnU{YLFIyEdyrIvlC >zXZp-nGxIm-wCeF{R^}o-`$)8!lRjO)kn69~69(zIOB$#e9(V9n^R~~_s(srJck;{s >zozJ-4>kf&y-FfRhYPsE?EtfjHmio>+jhyfI-g^I;m^kUx+dc#0B*H$u2HB@?oZW49 >zJpLl?-}hpb{j9SWt8e|1{p)UbLQU6lWKSZy64{r?&P4VmvOAIeiR@5hk0QGi*{6<n >zry_gR(e74czal#p*|W&5MfNSSbCJD^>|SL5B0Ct_!^kd1_A#=Pk-h9_cQdk|9qo=r >z_B67qk$sKqY-DdEyBpcx$PP#LII_!;eU9vOWUo8g-Hz;cN4w*ZJ&){qN4xKlosaB& >zWcMTcA87#60i*?vwg*TPkS-u?K>C0*0_g<O3ZxfEGmvf|?Lhj0Gz94g(h{U6NK+hb >zSCF<KeL)(7bOvb+(i@~XNOzF-ApJoagmegL5z-^1Nl2F*ZJUrjA&o*hg-)w@L9ZCw >zEQW3&?PBN`(lDfBNXw9(IohTnU30W;W9S>wIHYq(>yX|d&12{u(msa%Aq`~cAkspH >z9wJR-=pxcahCVvlMk1X=T8Z=$X(rN5q@4`?L>kJ_QKY2|Jw=+z&{ap<R-~_vwy{WO >zk=7!;MVgCr7illjU!=hd9Y$Kr&|{>@3|&Ur%+O~?+h~SPBduoWHPURP+eo{Sej^P> >zI*zm)={eGLr0b5h?F@Z)w2f!zyrXSBL+_F1Bi%>ZkMtk80gyWYxdo7W0J#Z}yTH-j >z2FQKjXm13DJHgT33JmuGax*a84an`la6ce71j8MH+!Dw=f!q|xU4h&d$bI2xZw%zl >zaJ07ua&I`=n*+H!klTad{y=UJhC2kgMHuc8<R)RbOOV@y;XZM+Hwtp6INDnUxmO(R >z&4S!5$nApMFUSpp+%d>4gWNN6N7u>!2hBeoH1+Jg)5+dF{xKZ`LIQ&PV}gSNf&+r; >F{Ry|ZcJBZH > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana >new file mode 100644 >index 0000000000000000000000000000000000000000..4a92c06593d33d3969756f482e5d3d4b773984ef >GIT binary patch >literal 1675 >zcmdVaT}+K}0LSs?kk@(LFc&RW7jAmD%q$zL)}m8hP9)@yXes=a&Q2uH1yVP-Da?{F >zud{4KTr|uuW;Thu)jw}D*7heCne9CO-+%60xN+k-d!Em8&Q9xG{Ju}1pk!mR^T#p5 >ze8S1G-kjV=y5`b!I@UdY<A-eCH_knA^p$+DJlcKGl_?+Y54%rdzRM?TN9m5re&^}D >zFS;|Y(|I=ik$#?X&FOMl^oz+yoEPelei?3cU)`+Gue%%FH|Gw@?)ECTr><P8rj>4Q >zNkG1>nd`pGnkC;CPIEtfo1#CP{~m6O)ZQ6SIgMfMtL;_k2|<~Wo+dK-&+5#$H7c{C >zUT2M+ud*(e=>>f;YT>aunf+{@@K=}0oU73yca>i*YKRbvQxoKp%8z1c<U|?ByDtJi >z`{lBf^J3YD@j5^1uFAjjRj&x2RRyOy^vdpfwQ5hRUfo`%3X2-`nx-5j{8!}K+ETGD >zu0gIZ_KTviA-N$lL2T$Nki|15isDD9vSfI_D7hFVH+}3Br44g*+2gNjb1+hGY3Wc~ >z^TJvlXjR)%lrG=es46Dk*4uNd)b?<X49;#4!R}i!G&Lkb?I&f`K!MoNv{&xzN)^>L >z#d23$l&C4plDiK(Vu;VahDQ9p8GJi<9X4dx@PF{~yp}nR<9XLF`64{;LbEf{-jA`@ >z30$2?o_Fu2Z)&zb;H0ISbE!F(n{!dX$uRdB<}(hTy+Yvcb1O1mwsRX8{44VdJg;zQ >zxEYxrGC^d9$P|$|TFoSpSt8T4nt37<MP`aj6`3nCS!A}zbggE-$b^v@BU47^j7%Dt >zH8O2v-pIs}nIlt2=8jAr?d-W>`W$BdKmtexND5Yy1CoT*WPzk%HF+S3AekVkAh{sP >zAlV@4Ao(B(AsHblSxrtzQdW}{l9tuvg(QY#hNOn%h9rk%hopz(ha`w(h@^<*h$Lw> >zSt4m#O`b@iR+A}`Dv~RbERrpfE|M>jFp@EnGLkcrwAEydq-`~MBZ*s0=1A&D?nv@T >o_DK3j{>UT1`A?q#qs^ls#XK5f{WIf};}c{3NlEcZ@rk2<0ei4<R{#J2 > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern >new file mode 100644 >index 0000000000000000000000000000000000000000..7553fee37a5d03e9163ee19b1ced730a02345cfb >GIT binary patch >literal 3545 >zcmd_sSy0tw7{~FW;u1<|in&Fm6{0L|xKd(jgnGmUQpxbGKnAsVN+m4AN|bP>tkJ=? >z!Q9a_a=|1E(F`4%HgPS*S5s0GdzBW_I;Z#h-geP=(N%xve?Dg%818=GCn+U!T5r!k >zp2qfnczG_{m+x&}v>!$5LS@CrKdJW?d1U3=U#eB<XJz$*i+auU4`gl3dbMuCL9;%j >zKo$4dWQu)j^~Tn(nT^%?`u#dFo60lw=Bn}LgQ8KoWLsbJVQ!?}^6og<nlVyso7YFS >z$498rDIu~W>{j*B;NN9u6QjyHo{+MdLuyyRuVz=}cJ;}*W9HM6Z*=*-GP8ThR$Z~? >z9kVBEnckcCg83{lTklJoYCeyiq$|DiWPk7=eIPPb4%AOn2ZQ3|;PHX#i&u;s>iUZu >zQa5zfoO9-I+$nt|xzZf%yjvfODK^JFEA@$x#pZ-wpuh92m+vdm^~vf2Ikn+sRb4(q >zP8XypUF4NBnGdS7xzX}NLN|3TwUwNo7^Q3CBh8QfTj~p8!RBJyYx+`?tLD;ghxJc2 >zRp#>19lEx%)LhwJrG73sBxXgay1Hb$T${gK)nygRFH`5LUlViWw;_+H-=kBczT30< >zkKkCj-fXhIUO&m)xG-4%d3=!h>%bk_x3iP+ulH-ua-V6Ce?~WaR+~oRQvvEPX*^b| >zCUK{wY0tf?>8tJKmX>SOEt{8_K(k0S*9)b^iB&qNB13L1%hSOd7MPZAP1CIk(#>si >zAJVNe<4v2%-E~MpxM@4Eg}yz!xoOuWT(xgjYdSP+t~y)`l#XX=Ri|$+%N={ZR-s$I >zk~>#!QJu3r=B}5PsxHZAP1orq`tF#0=AMyn=zBxfnXvA&beQim2@g!x;ni!U`=$Q6 >zM|r+PR3)j%qD+a})=x#}j*^~B+o@g|8K(C$*HxeR1k-o?Nfi^;!}RN2uKG6(G6On( >zrw7#hYzE%=L=UR`)(rl>NXM33k^6SNsPA9$jSP9`aUGYnRfguxR}UmElVNF(so~Mt >zGGh2JHKMNA#79om@l}gWLeNm1ux+LpS=&{QdbdDEAB|Jqc{60pjxH*3idV)K2B>kd >z(K3EcjhfJ@l_Vt}P)RrH<l&f&>f!UjW>RRSp0w|(nd~dpDQl|CBh`!bl)O^&X!%T? >znzr0bEgGYhce^~6KSMnpStw6rcvV_Zj-<y&tMu9w$p~wuGQNzJ%qDdzb91OnuQ{S- >z6b>>ozrL!U%<g2KDyh<0$vz`XO7+t*+B}oBT+a&GYi1|T)w6x4C3`@j%C6ocIqh;( >zPWft?Tc4tyD_SVeACFb@ax>(GouMi>H9_XT=}`?E+~mJT0XO*zH~R<vyPx;_KQ8ik >z{QmtF4FdfBvJXAY-1iplv*l=Sl4rzl`%bX$MEj0SvRmfyG;kkD|Gt5>_6OYt*7F<o >z@!Kc0k$D~2L}V9{ZAA7F*+^t3k*!4b64^{-H<9gh+WkZ})M<AV*-~UrkxfN*71>r~ >zUy+SPb{5%MWN(qpMRph2USxlf4R+ccMz+{#_ZZn^WS5a`M)n!mXk@36tw#15*=%ID >zk?ltI8`*HD-Em~gop#TWO-FX!X}2BOcVy#{okzAF*?VO3k==LN?ML<>X#mmzqy<P1 >zkR~8qK-z%x0cix%38WQBFOX&+-9Xxb^uuWzf^-CF3DOg!DM(k4wjg~$8iRBOX${gF >zq&Y};koF+`K^o+=9YR`!^ayDZx-RjBHu2a#0gXaBg|rIk71AuETS&W{wqHoYoVH^~ >z%aEQSO+&hdv<>MS(m14ZNb8W^A<aX&hqMprAJRaigGdXVwueX)kuD-_MEZy{66qw; >zN~D)aGm&m0?L_*CG}LK3inP>edx|s_=_=Azq_0S0k<KEmMS6=g7wIn2UZlTBgOLs+ >zEq2--BTYuSjI<f)Gty|J(@3k4UL(y$x{b6O={M4Fr|me>a;NP%(sZZoI?{He??~g3 >z&LgcydXF?8=|0kar2ohb;IwxDatk=^J%HQ<PJ0(1w*hh=AU6VXCm^>1axWk^19CSY >zw*zuNAU6bZM<BO^)7}%vP2se61#(+B?R|mV7|5N0+#1Nef!rL(-GSU5$o+xbAjlnp >z+#*hUk03XR)7~Y>ZQ``|338(#cM5W=AomJ#vmkd1a=UnL`V#q{9xs9Rrirn)O@y~k >SRPU&s5#C<CqIyO34E!5Kf4#l{ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii >new file mode 100644 >index 0000000000000000000000000000000000000000..bd855772054f8d41e0158e71c2bf2c04e50e47cc >GIT binary patch >literal 276 >zcmWHE%1kq2zyK^j5fBCeHXsJEc^ZJkZdPZH-HL?~r#o#=TuSt`xY}Fn!N>%J%>V!A >zFflLy$p{9P|NpBp7&-p`FHT@!@$n5|@CXKCmk^+S2nZo;D?3mn*w!CVJ^z8A<Uzqc >h5Djt#m<GB8M1x!dqCqYK(I8hbknSulpgRo>xBx^rPJ#dc > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke >new file mode 100644 >index 0000000000000000000000000000000000000000..cc785da97de0a5614613f9ba6e502d7dc5f525b5 >GIT binary patch >literal 2437 >zcmd_rUrg0y9LMo52q6eaCWd5SS}_9&Y$$E8wFP5`#6Nk!KM+Q0h-E%1kf_n))+8^Q >zrA@&a>LQnGhSpSU3r(rDnlm&BQVB4LS;(VtK}zTJydN*KKlgpv@4U_qC|931-bH24 >zPm{k~i2a0z+hrf#$7uUfzb{Ge{`7aXXLF?9yX%7b=5?PwJ9$u@EeSQ}^Uq7$#M9>c >zw4>54jiw{IPCB~YGC%kZ>kB8=nv0z~^`-r9s?O#r{o|H3s;j<Gcb9opPj#lg?3u29 >zDvsAz=4Y7RoDBJSMx5zOh?Bk><IGk2+po3`nO}N)<kz+q)Bk0QTsz*a1{%Ax*?me~ >z-+EFHF0N5Ghf3vEpT`Whd*qL=5{<7ZQT!i77^#hrfSLgl`0{{^SRJl{N=E76IoH%( >zPxR}Mly6nY8wolz>SGmp;5`X5Z>v#V+jV%yK@)MJLPs9kW=8MdCQ)_e=I$-!GN!7) >z+*4K{V;82IXivI~dpy?MJ0(_PCe2XeM-EGD;CK~#BSzoXeM?Pfy{Yg2{E~`0bWz9e >zJ+3BJj+O^D?NyWVugl~WpP2{K&dEc$yUoMVhb7^WO(wzDs;7i4F<FmRs_d+}D*Lyi >zk~4Ls$vIaio`~7T^T`Iu?N2pNy}MJ-Y@4O>Hdg6bM^e=6qC!1q#~3v?BU3+JF{tKE >zh}YiyHsu`-&;@Bts^ChTEQtHgEcilXq3?)U)X*b^owcUuwHA4%dA%uKx=$9@7nx`C >zPU@1HD)rpd2EC-TP%Vwvte53vs%8Dlb!kGpDm|U6%R&NF*?}azqW7|TVTVUvJmWVj >zD--3V#%{B!AVSpEQ)YGAfUH^dzF8aHD&@0lOu4ULSEe_p%FZ)-UCd^+uKAFz8d|Q_ >z*KgMw+H=*$>I(fzQ<ADKp08i6jZ}dF_G?6tgSU773jUkV@BGv5)8K#j-hcYv{Qi%= >z7V-O!9SjKa`#;<xBi;LO_Zr2kjJ^H&%sj6=nPs1O_L*;=IbO-O@3{c?3f_NT-#hk) >z-TH=Z|1103{r=(+zCFkqkwqe_M3#xH6IrO!t`u1+vQ}iV$ZC=0I_-Lq1tTj)mW-?! >zSv0b0WZB5Nk%c2GN0yGP9a%iGdSv-dyMCkqPFn$_1V{~#A|O>j%7D}XDFjjpq!dUk >zkYXU!KvxdlP!G-)grg!zNjPeP6a}dYQWm5xPFonHGEQ3>j@lr_L8^n42dNKIAdU(l >zCE}<NQY4NlA!XvI6H+LSN+G4<sFl+e3#k@TE~H*a!H|j}CF7_WQZ$aLA!XyJ8&Wuq >z$~kT6klG=|L#pSr<>RQI(-x4Uf=*jPjv69GM5>6C5ve0mNTiZTDUn(t#YC#<wB<zV >z>9hsqsHoGHl%u9dQ8}uLl$E2dNMSiDi<B0rEmB;hx=4AE`Z{fakqSF)iIEyRZIO{G >zBW32OGg4@dN+YG_s5Me-j%p+2=BT&R796R#)0P~mxziRMsX9`2r0z)Jk;)^bM`|yw >hy#I^bhuOad)9qh{q`b$HrzNK(<)x-3rzWR_{RxkBPOAU_ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan >new file mode 100644 >index 0000000000000000000000000000000000000000..e3ea5c3ef1219fdc1b6e6663d2bf3a38c27df689 >GIT binary patch >literal 2188 >zcmdtiZ%oxy9LMn=L|_+4C@EB;f{cOux2tHk!hjL#71N6;njQ_jyF&3zjX@dOf=ssN >znhtX{mT8S@jnr(pim5qkYh}tR`!hVX#e)`gj2^hy_;ucAJ?l}=TKDdp*WKNIyHD=t >z9chehD);{JO0?f_c=g)D=ggh<>iIBd&4JK9@6%_ET*&=HE~p9pb#TC3^bYF8%1e?| >zdRiqtH(jntJFEiUAqkjgRI=`oly6?qsVAdy?TKzZ_4TJs+JQ|veRs3DuJb;9eXQ0@ >zTV0?t>hjGE^HcPV`N<|TCtppUGG=DPC#xC12V~|CV=C+XFLKkVb1M7D=W_GGBkGoR >z&)oXdUX|1EqsiSosBa6NF|!suuW!$I&Eyqq)p?U2Nq(R~=a0N91wYTzvxjy`;c!G1 >z^~a?6*j!c8wOC5`W~#Di)Rb@eQ_ZQZGj}ZiUIp`Jo4MsfYF<*RshIh#t{DBz%%Au` >zFF1SN-1%L<4h{Y)cfG$;-@WGxx#z`=y0Y!4EbQK)?ycV^RZSaIbxFI_R9C5*@c~m? >zv|iT^_nNxYg}Uxot64Obs~5ktTb6uPslwY^Wa+y(s(x))mh~m5`$HwN{IOBBA}d`Y >z4WFpU#JH>szM)qBG}WxiKC4%qxolQX4(P_i!)DD$uU^}I+&nncs@FB`H|zVCY88G* >zHtcFq8;knnp=ek&rFKYjZHa0gYm{hSx{7`ll33!nioKOBn@7J?Eqx12>$%JN;r1-^ >z$l$PUYnU{$=eT|}sLhtP{d#N0X|t`qQ*WERB<&S_s(s{?bYym@j-f-+d8JW3-rpln >zTnwr0T~T@Ry=>LBu1<Em;3+RI{;GudtN#OU-#<Fb^L+o!m%RkvKk>FV#rHox8JFVj >zG<Q#15{`IPD<WPE=K*_`*;5^{|8>uc`}>aki<Mk)&+x0h&svbhAge)^<FxBR7KE&b >z$5|4xCZ}B#vMOX*PP;B-VaUpmr6FrW7Kf}3Sst=JWP!*EktHH)L>7sx5?Lm)PN!Wc >zvQlKJ$Xb!bBCAD~i>wz}FtTD~$;g_KMI)<r+GQi_cG`s_D@T@&tQ}cAvU+6s$oi22 >zAQeDLfYbmf0#XH}3`iZEwh%}qkWwJEK#GA>11Sem52PSSMUavpH9?AkRK;n_g4D%n >z3xia~X-k9D1}P3w9i%)+eUJhn6+%jc)CegOQYEJ?6H+IqEfi8Ir!5syE2LORwUBZl >z^+F1UR17H@QZuAzNY#+CA$4=w!XcG&+R`DlbK2q|)kDgM)DI~jQbDAINDYx9B2`4n >zh}6+(3yD<HX-kRJ(rJr{R1+yDQct9yNJWv7;{UUz0h`*OO>AL!PH}m0X<@jmthlVW >GH1HR^1#Eo) > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain >new file mode 100644 >index 0000000000000000000000000000000000000000..7fc669171f88e8e1fb0c1483bb83e746e5f1c779 >GIT binary patch >literal 2453 >zcmdtjeN5F=9LMnkqQH%ZQ;8v<nU)CgtR#>b8FWLuL3o9$5k`URY6U)Y(?UE3#rVT< >zR*YFDf|Ayni4SWwHq<p-TiG0LO>3b&mt~`eO%k}b^FAy8>5u+w>&t$;e%!&IpEvGR >z-Zfd`A2->2!ozi$hxe(9ANJ?zJ^i7o`=tck^V$z;Z>?YNYndW?3oq&3_WkO^wg^2m >z=l6!8>R53#-KR(Ab%;NrJ^EUhPh1;)Mvi^&5##48<irPg!hbwh2Hs2%VrRSzYW0iY >zXD8&O^>Hesdb*xmI<BVVkLl2iVHLU~TZhY&D*WJK=@{9oZn)H=BQBf}ktdsV)O$T5 >z`mJs$Uu_mQw!I*4+EOcS_SVR$E1e>y=m9w`H%Z)*G*8CPE>zRQ9WpLBQN{f_SI2)D >zt`dgA^o&zKs+or`>sx!ys9C-l^0w`V)a(@jIcM!h;`Zz><Q+@j5p!eSmx;+*B>FGv >zB*zAkG<-@YUv`T-2lnZda}6rB>qVV*v`nQp)#;2^7O2d+7MZninwsxiBNvp7s_euE >z<y~2ys)eD+GAI73$oVcp=8jzud8dDtcYoF|7WFywJ^j1I;`X2Py}P!F{Q8geeJ#7x >zl9E1sf6Z1^kp8kRELg1ye;bs})JEYvcR&_JR*9mcZF1?Ad{O-R8+zF%mCDuFsvmlH >zu_~$b>e9|x>fuGjy37}>mM5fY_lmETdpuf~XP;K(-=s*-%&&xJFiNiU4~kX2Bl3~q >z1ER8JNIp8yCaP+V$<<x!#AB|ry1KPhJ)U|*KT+pZHIW^<)>*7-ulRIbVydb;<I&#G >zXyrYar`LY_i(1!NA)h=OC7$x-%BK&Fi2Cw)+0Z^D)@M)14fV&w#+Zw8Q%R@T<R8<% >zoFmFN{JGv7+o3iOoX}fFed@Wc9{v1zk7{gc)?1I~sivx0y=`ZL3J&_~Yf{Md*S|md >z?+pZYcL)&(yxkoXV&1g~v+oi1yIkgS3s-@8mYb)-Jf&{4A|Zn8H}}7<Z;$y!yS`EW >z!d$>yRY*i1vPNW)$SRR#BI`sJimcRXmWr$uS*+Ep7FjN`USz?@imhhJ$eNKwBdbQc >zY+hJ5XBG~uoMY+8+L6U0t4EfPtlw%1fK<S0N`TY=DFRXjjxr#1;3x!A364@AwcscQ >zQVouBAobuV2vQNGBuGuHrYJ~Nkg_0kK?;LZ1}P0v8>Bc$bvVj{)Q6)$NQJDXL`aRS >zrbtMYILd_72`Lm(DWp_Lt&n0N)k4aJ)C(yXQZb}tNX@LKXh_vK%7)a9qi{&&I7)}q >zj-z-;^^o!*^+O7XRM2Wlh}6((iilLvYRZVzk)x1EC6Q7hwM2@ER1+yDQct9yNJXut >zq)1Jzrl?3&t){F<T{#MiRF<Q(NNqWai&U4RyhweK0wWbhN{rOlYKn|h*=ov+)Y)nZ >zjZ_*bHBxJiVk6b&C^u4Xj)Ef<=O{T+bE_#jQgy2-J5qP6DLhhnr1VJbk>VrON6L@X >jUtDkg|1SRy^Iu`1`R|b8nxB@HmXYGh%uLHn%W(V&DI1f# > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific >new file mode 100644 >index 0000000000000000000000000000000000000000..c0ce4402f60a135017d49933afdbee55916b9be3 >GIT binary patch >literal 2845 >zcmd_rdra0<9LMnoMG+J|nJ5w3NlgR+0Y&jr=52tAs33_MUJ@9lp+cx-NQ*LS#+S@X >zH#(ZNTp60PSrnlyS8J9*bKWAdRHotuE%DOxbl&IR{^;-4d3JuU-=4vr&-;@(yC5&Y >z^N-WPe#7N_W-sqO%Iu@+y%h6yO^BH1qs-RVugiDq!c2X?YfJ0r4^T(E#dD69?Udu* >zujE9XsFRKF%FjDKl*Zb%^2@rHrKzewel1ukr%ETwZ>cln_na6x9XV9aBu`RjyH8im >z5z(r-b%;6_&{dtQ4^ijOTviu$Uso*$>(#}|W9m}%MY+7JMqQ~mEUjzy%hke<<=WhL >z<d5`M<<BwC$@Re{(l&6Ly3uWx-0W1YZnizEZ#Czs+edTtU*DuC@4jU1dp}BfwnS>b >z7rLl+D?97<%La=7{0P%wdXRJ+8)yRJE=a)o@g`7xFM&J1)IpbbN#~|&)8*J96<k+o >zx_(-%y6yN#tJf;k9qUAQUsa^;ELg64WY1I~shPUxh~cVN<S-rDH$(0U4Ao)n5+$s4 >zsJZ)8FA1;jX?pL!A$@kYnR~XL5M44z-}}rL(l;wu_gi#a^-sK{@0;|w8W8fMj)<yK >z5#AOP8C0es8-FlS=N70zwYyDpL#f16Z7{KW=E>mFCrsRiaT1^ZicTo%FGG@x_0Wut >zk{FSthb1)2@PH(p6y8B4oek3?Zk<&l58l?JPJF9I?+P{d*L<KJsJLmyys=(ASa{Nm >zE#D#I(reB5g)hm3!NyFSutX+aZP3XvFRJ8*y*f2`u}a;uSx;)2swTg=$4oi0NYYks >zG*dsBBI$Ehm}#40W%}rBGowUFM))X`IkQzVZ}&D?i9bo!>5+O?pDSwC*Wo(b+n{D| >z_v(im_o_MNP5P1A%_?W%0X?^Bm715<Xy&ioC<|ih%%k}$WMS|&lbf6^xh>@;KVp>R >zAIdWY0llSQXNp;L#wU+$%GHYxhpQze$@=kXuPV%n)JrRx)Usin_42|4swkvI7pHGm >z#lApOl2j)pjpxnE&~37^_K;cCRxVFgRhy@d=E>^PO7rx-6e-OqGHbR(NjpFLY47jg >z^}qA+`6>r^JU-uB;^*)4Rg`%;x%V#asivf5dZtaVH^bhC?46crf6*R~pL=BfdkJdn >zAG#8>@gMg1?8)&Dt3%3w)B!03QVFCKNG+VU7)Ujcav=3U3W8JwDG5>&q$o&Lkg_0k >zK?;LZ1}P0v8>Bc$b)2?5NPV2PKuCp<5+OB0iiA`NDHBpBq)<qukWwMFLW+e{3n>>; >zFQi~jTQQ_$NX?L<p{p7%l#OHS1{4md98x-@c1ZD%>LKNG+WH{{blM6cB}8h76cMQ+ >zQbweXNFk9*BBexXi4+s5CQ?qMo=8EFiXtU-+L|IoMXHLF6{#yySfsK@X_49@#YL)% >zlozQlQeda8Fj8Wttuaz$q{>K{kvb!VMk<Yz8mTo>Y^2&qxsiG!1xG55l-y}+juaiK >zI#PC|?nvR0$|I#mYL65jsXkJEr2fbPIPD4`OW?F?fGmR3t^%?Q$T}bkfvg0w6v$d2 >zi-D{LvK+{IAPeHOD}pSE)2<1!C{DX7$g&{of-DTOGRV>(YlAEfvO37}AnSuH5VAtZ >z5;^S}A&ca+tAs3*)2<V;P{>LlONFczvRKG!A<KoV7qVc;iXltpv}=Yen$xZtvTRPf >yZpgwRD~Bu{vUbSgA*+WhpT}+8|8Dw%>>?)FWsFW65}Obk7o8R#9~&PV7xXtE&6qp@ > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa >new file mode 100644 >index 0000000000000000000000000000000000000000..3e38e97c97ddf5e054fba822cfce1c5ccd422e3f >GIT binary patch >literal 196 >zcmWHE%1kq2zyQoZ5fBCeCLji}IU0b(MAqLNj6ji%6$}jj|HuCTk*NU;EIz&=48g%6 >mKouYmLfBN84IDrtz~Da+<k_C!0MQ^@7zkU#1+>x7kP855a3xUy > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/UTC b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/UTC >new file mode 100644 >index 0000000000000000000000000000000000000000..c3b97f1a199421d6d9625b280316d99b85a4a4e8 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<U2@P=uGC~OJgPFnd17-@c0bD?H47dQg2nTKe > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Universal b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Universal >new file mode 100644 >index 0000000000000000000000000000000000000000..c3b97f1a199421d6d9625b280316d99b85a4a4e8 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<U2@P=uGC~OJgPFnd17-@c0bD?H47dQg2nTKe > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/W-SU b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/W-SU >new file mode 100644 >index 0000000000000000000000000000000000000000..906bd05f344ae9a806c1b20b8e2bfd7061d35fa1 >GIT binary patch >literal 1544 >zcmd^;&r4K60Dxy*f3=#`!F1C#&2)9u(lt%X)va|EQ%iCyup%ju1f!vX6gn&+cBw!L >zJXof*>Y-mAs!LW&1QJ<z=n!ZSL<b9G2%=Q_G2b)M>d+t1JZ8SxdGE1@_kF&GmS(5; >zYpl{IOvX+<*{A#U(sL+j^lIs+_Fl*IOz)TCmTMjRX8K;YPW6joe}BoKJFxOtFyL|y >z55yiF9&nk1LrLDcdjV@>tbJ&Fb^N3|E^?wSZgxd5{zJ^Tb;9FbGj?e_VWdwb-t1Dg >zD`!>G`IBnxnI@Iox<{oPs8H)_HmlT<47EPns?riIDm`jW*~9G8{yAP|ypQu|wmtS| >zzM7Seryph3-AS1pcp-BxKav|d?#PX&`ebfXm&`jjqMRqXRlciNZQ9+g3T%E==-jUg >zza3UZ32n0IO}Q$bYmi$WrmL+JC9-7DBV7-YWNBxbEb9@{-5epebtJ0o-YMxh@?Dju >zJ(ph3TU8NuOID^nQI*rrRFyfPs$SkuJKlAw>f0Ao&DeEWd-1sP)z}(M<`8peNN8Ai >zL}Wzxvhaxc%M!KZieA3t$I=^r?qe)Mq!#NB!5S(=-Z@jG-k)Y))@_OwqR4I1U(1mz >zVi)!mbtbD2iOItD`?(|6l(KMM<X(K9cWY{WqLx{&XE{rKxt`S`E4M&+y*@qlp)pLX >zrungWVC;nO{oAiy`ccELufN{;p~v3)!BL2B5a%G?8Px7U{DU|M@z9`l5#pmk?IgrY >zgW64qpAbj+dpw1>3h~vTb{66-#9fHL5QiZiLtKXV3~?IbHN<U*-w?+ko<m%R_zrR2 >zp!Oc(KE!{6x&cTBkQN|4K$?Jb0ciu$2c!{5Cy-Vky+E3QbYoDr1L?=0ZV1v5q$NmC >zkftDALE3`!1!)Y@8KgBxZ;<97-9g%e^k+~v2<gzEZV}QWq)AAZkTxNGivKxKi;g-c >G-|`bm1(CG? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/WET b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/WET >new file mode 100644 >index 0000000000000000000000000000000000000000..444a1933d72525ab3045980eab2fbf79266cf158 >GIT binary patch >literal 1873 >zcmd7SYfO~|9LMoPjFl|ukH|&2RYYK&;BXBHyo3jafr=afFGLD*NunTP;3d{#&J}aN >zHkNb7#Kl;1ioU>l0qC;JXc}v4tWhyHU1gU!H+6IwThI4->nmT?b9VN5cDD2G|NRBF >zw>D*Z?s*<?e&Nfr&-wDcWa&tQ!ronJkM#RxUAYQxOwqDHj3O%5+w!cx6`AzAq9T4& >zbnw@TzI{P4*UxIjx5HZb*?WqeoU*vnV;29x2}>A|B_4Ro9&PKi$96W@<K+QMD)ieE >z-dszLOR*;(j<J-GVx`>8R_ag5S~VM`r@nYlPmlj8@5rxuX7GEZ^<P$c*Q9)nXOvMl >zXPKSjmQ^%i*<0SXocJNj&Frz<#Xif69aP@@F3bO?TLn|a_S_G(Djcm>(L{k(A6ln1 >z$K$lNDM{=4^X>VP5EVDZ+WO>Q<S$;dl8~=dnsn7lZ~km$!Jk^$%(QK|{-M1vcFM}H >zTvWx80o!=`q&Bs;+vb6{Rax_nwzTb0)w691l$UC2^hQ;CSE+izr`pI8tNm`7w%tv& >z?H}LKj@eM#IUH_v<A2zTeYdTCaK>J$pS4{Ff79+YpIAfP6*VRvvpq#)YI^9rn&YMB >z8%Nc$*s0d(UcEdY(B6-BsO`%Rd*yJE+DEJG)s{rPb|}X>DhsW%DcWAoNU$#dU-m}0 >z$GX!a)qU%l^@J^`=bO*1_vW1Tog20NGZQ*+?2-<S4e8C^5%nGElPBmu`*^}Eh@10x >zLTda~0Z)xT;0bb`z<r!4|K?PYb45-TIa}m(k@H1P7&&9)l#z2rPTJKuYvi<%^F~e_ >zIdkOHk#k2*9yxpD^pW#N5<oIQQb2M*l0dR>b<#lcKoUVRK~h0-L6SkTLDE6;K@vhT >zLQ+C<LXtwVa&^)|@^W<&Lo!2BLvllsL$X8CL-IosL^4EDL~=xuM6yKEMDlcX5=Am~ >zby7ugMUq9bMbbs`MG{6bMp8y{Mv_LdM$$&|c6Aa*GIw=SM{-A!N3uuKNAgD|0GR<~ >z3XnNKCIOiRWEzlpKqdm230G$-khwr61DOqEI*|E5CIp!gWJ-`ZK_&&66=YhFc|j%y >znHg7SYLK~cbtVUy9b|ft`9UTKnIU9~@P9f-q0TP(7$|Q=R$5M)FFnIsk>TSl^j~E| >Bn416q > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Zulu b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Zulu >new file mode 100644 >index 0000000000000000000000000000000000000000..c3b97f1a199421d6d9625b280316d99b85a4a4e8 >GIT binary patch >literal 127 >ucmWHE%1kq2zyORu5fFv}5Ss<U2@P=uGC~OJgPFnd17-@c0bD?H47dQg2nTKe > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab >new file mode 100644 >index 0000000000000000000000000000000000000000..c2e0f8eafc016206bb10d34bca365c5abdf3daac >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab >@@ -0,0 +1,274 @@ >+# ISO 3166 alpha-2 country codes >+# >+# This file is in the public domain, so clarified as of >+# 2009-05-17 by Arthur David Olson. >+# >+# From Paul Eggert (2015-05-02): >+# This file contains a table of two-letter country codes. Columns are >+# separated by a single tab. Lines beginning with '#' are comments. >+# All text uses UTF-8 encoding. The columns of the table are as follows: >+# >+# 1. ISO 3166-1 alpha-2 country code, current as of >+# ISO 3166-1 N905 (2016-11-15). See: Updates on ISO 3166-1 >+# http://isotc.iso.org/livelink/livelink/Open/16944257 >+# 2. The usual English name for the coded region, >+# chosen so that alphabetic sorting of subsets produces helpful lists. >+# This is not the same as the English name in the ISO 3166 tables. >+# >+# The table is sorted by country code. >+# >+# This table is intended as an aid for users, to help them select time >+# zone data appropriate for their practical needs. It is not intended >+# to take or endorse any position on legal or territorial claims. >+# >+#country- >+#code name of country, territory, area, or subdivision >+AD Andorra >+AE United Arab Emirates >+AF Afghanistan >+AG Antigua & Barbuda >+AI Anguilla >+AL Albania >+AM Armenia >+AO Angola >+AQ Antarctica >+AR Argentina >+AS Samoa (American) >+AT Austria >+AU Australia >+AW Aruba >+AX Åland Islands >+AZ Azerbaijan >+BA Bosnia & Herzegovina >+BB Barbados >+BD Bangladesh >+BE Belgium >+BF Burkina Faso >+BG Bulgaria >+BH Bahrain >+BI Burundi >+BJ Benin >+BL St Barthelemy >+BM Bermuda >+BN Brunei >+BO Bolivia >+BQ Caribbean NL >+BR Brazil >+BS Bahamas >+BT Bhutan >+BV Bouvet Island >+BW Botswana >+BY Belarus >+BZ Belize >+CA Canada >+CC Cocos (Keeling) Islands >+CD Congo (Dem. Rep.) >+CF Central African Rep. >+CG Congo (Rep.) >+CH Switzerland >+CI Côte d'Ivoire >+CK Cook Islands >+CL Chile >+CM Cameroon >+CN China >+CO Colombia >+CR Costa Rica >+CU Cuba >+CV Cape Verde >+CW Curaçao >+CX Christmas Island >+CY Cyprus >+CZ Czech Republic >+DE Germany >+DJ Djibouti >+DK Denmark >+DM Dominica >+DO Dominican Republic >+DZ Algeria >+EC Ecuador >+EE Estonia >+EG Egypt >+EH Western Sahara >+ER Eritrea >+ES Spain >+ET Ethiopia >+FI Finland >+FJ Fiji >+FK Falkland Islands >+FM Micronesia >+FO Faroe Islands >+FR France >+GA Gabon >+GB Britain (UK) >+GD Grenada >+GE Georgia >+GF French Guiana >+GG Guernsey >+GH Ghana >+GI Gibraltar >+GL Greenland >+GM Gambia >+GN Guinea >+GP Guadeloupe >+GQ Equatorial Guinea >+GR Greece >+GS South Georgia & the South Sandwich Islands >+GT Guatemala >+GU Guam >+GW Guinea-Bissau >+GY Guyana >+HK Hong Kong >+HM Heard Island & McDonald Islands >+HN Honduras >+HR Croatia >+HT Haiti >+HU Hungary >+ID Indonesia >+IE Ireland >+IL Israel >+IM Isle of Man >+IN India >+IO British Indian Ocean Territory >+IQ Iraq >+IR Iran >+IS Iceland >+IT Italy >+JE Jersey >+JM Jamaica >+JO Jordan >+JP Japan >+KE Kenya >+KG Kyrgyzstan >+KH Cambodia >+KI Kiribati >+KM Comoros >+KN St Kitts & Nevis >+KP Korea (North) >+KR Korea (South) >+KW Kuwait >+KY Cayman Islands >+KZ Kazakhstan >+LA Laos >+LB Lebanon >+LC St Lucia >+LI Liechtenstein >+LK Sri Lanka >+LR Liberia >+LS Lesotho >+LT Lithuania >+LU Luxembourg >+LV Latvia >+LY Libya >+MA Morocco >+MC Monaco >+MD Moldova >+ME Montenegro >+MF St Martin (French) >+MG Madagascar >+MH Marshall Islands >+MK Macedonia >+ML Mali >+MM Myanmar (Burma) >+MN Mongolia >+MO Macau >+MP Northern Mariana Islands >+MQ Martinique >+MR Mauritania >+MS Montserrat >+MT Malta >+MU Mauritius >+MV Maldives >+MW Malawi >+MX Mexico >+MY Malaysia >+MZ Mozambique >+NA Namibia >+NC New Caledonia >+NE Niger >+NF Norfolk Island >+NG Nigeria >+NI Nicaragua >+NL Netherlands >+NO Norway >+NP Nepal >+NR Nauru >+NU Niue >+NZ New Zealand >+OM Oman >+PA Panama >+PE Peru >+PF French Polynesia >+PG Papua New Guinea >+PH Philippines >+PK Pakistan >+PL Poland >+PM St Pierre & Miquelon >+PN Pitcairn >+PR Puerto Rico >+PS Palestine >+PT Portugal >+PW Palau >+PY Paraguay >+QA Qatar >+RE Réunion >+RO Romania >+RS Serbia >+RU Russia >+RW Rwanda >+SA Saudi Arabia >+SB Solomon Islands >+SC Seychelles >+SD Sudan >+SE Sweden >+SG Singapore >+SH St Helena >+SI Slovenia >+SJ Svalbard & Jan Mayen >+SK Slovakia >+SL Sierra Leone >+SM San Marino >+SN Senegal >+SO Somalia >+SR Suriname >+SS South Sudan >+ST Sao Tome & Principe >+SV El Salvador >+SX St Maarten (Dutch) >+SY Syria >+SZ Swaziland >+TC Turks & Caicos Is >+TD Chad >+TF French Southern & Antarctic Lands >+TG Togo >+TH Thailand >+TJ Tajikistan >+TK Tokelau >+TL East Timor >+TM Turkmenistan >+TN Tunisia >+TO Tonga >+TR Turkey >+TT Trinidad & Tobago >+TV Tuvalu >+TW Taiwan >+TZ Tanzania >+UA Ukraine >+UG Uganda >+UM US minor outlying islands >+US United States >+UY Uruguay >+UZ Uzbekistan >+VA Vatican City >+VC St Vincent >+VE Venezuela >+VG Virgin Islands (UK) >+VI Virgin Islands (US) >+VN Vietnam >+VU Vanuatu >+WF Wallis & Futuna >+WS Samoa (western) >+YE Yemen >+YT Mayotte >+ZA South Africa >+ZM Zambia >+ZW Zimbabwe >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/localtime b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/localtime >new file mode 100644 >index 0000000000000000000000000000000000000000..afeeb88d062851fca5523d23a73edaa1d8f5ff6c >GIT binary patch >literal 148 >zcmWHE%1kq2zyORu5fBCeCLji}SsH*u{r~^}ffN|%8W;fS5E4xI0o4hjFiqmJ0h(xM >Gzy$!q_YOt? > >literal 0 >HcmV?d00001 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab >new file mode 100644 >index 0000000000000000000000000000000000000000..2d90ed72f1c647da6e97ac0f70315baa5c8e2b0b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab >@@ -0,0 +1,382 @@ >+# tz zone descriptions >+# >+# This file is in the public domain. >+# >+# From Paul Eggert (2017-10-01): >+# This file contains a table where each row stands for a zone where >+# civil time stamps have agreed since 1970. Columns are separated by >+# a single tab. Lines beginning with '#' are comments. All text uses >+# UTF-8 encoding. The columns of the table are as follows: >+# >+# 1. The countries that overlap the zone, as a comma-separated list >+# of ISO 3166 2-character country codes. See the file 'iso3166.tab'. >+# 2. Latitude and longitude of the zone's principal location >+# in ISO 6709 sign-degrees-minutes-seconds format, >+# either ±DDMM±DDDMM or ±DDMMSS±DDDMMSS, >+# first latitude (+ is north), then longitude (+ is east). >+# 3. Zone name used in value of TZ environment variable. >+# Please see the theory.html file for how zone names are chosen. >+# If multiple zones overlap a country, each has a row in the >+# table, with each column 1 containing the country code. >+# 4. Comments; present if and only if a country has multiple zones. >+# >+# If a zone covers multiple countries, the most-populous city is used, >+# and that country is listed first in column 1; any other countries >+# are listed alphabetically by country code. The table is sorted >+# first by country code, then (if possible) by an order within the >+# country that (1) makes some geographical sense, and (2) puts the >+# most populous zones first, where that does not contradict (1). >+# >+# This table is intended as an aid for users, to help them select time >+# zone data entries appropriate for their practical needs. It is not >+# intended to take or endorse any position on legal or territorial claims. >+# >+#country- >+#codes coordinates TZ comments >+AD +4230+00131 Europe/Andorra >+AE,OM +2518+05518 Asia/Dubai >+AF +3431+06912 Asia/Kabul >+AL +4120+01950 Europe/Tirane >+AM +4011+04430 Asia/Yerevan >+AQ -6617+11031 Antarctica/Casey Casey >+AQ -6835+07758 Antarctica/Davis Davis >+AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville >+AQ -6736+06253 Antarctica/Mawson Mawson >+AQ -6448-06406 Antarctica/Palmer Palmer >+AQ -6734-06808 Antarctica/Rothera Rothera >+AQ -690022+0393524 Antarctica/Syowa Syowa >+AQ -720041+0023206 Antarctica/Troll Troll >+AQ -7824+10654 Antarctica/Vostok Vostok >+AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF) >+AR -3124-06411 America/Argentina/Cordoba Argentina (most areas: CB, CC, CN, ER, FM, MN, SE, SF) >+AR -2447-06525 America/Argentina/Salta Salta (SA, LP, NQ, RN) >+AR -2411-06518 America/Argentina/Jujuy Jujuy (JY) >+AR -2649-06513 America/Argentina/Tucuman Tucumán (TM) >+AR -2828-06547 America/Argentina/Catamarca Catamarca (CT); Chubut (CH) >+AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR) >+AR -3132-06831 America/Argentina/San_Juan San Juan (SJ) >+AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ) >+AR -3319-06621 America/Argentina/San_Luis San Luis (SL) >+AR -5138-06913 America/Argentina/Rio_Gallegos Santa Cruz (SC) >+AR -5448-06818 America/Argentina/Ushuaia Tierra del Fuego (TF) >+AS,UM -1416-17042 Pacific/Pago_Pago Samoa, Midway >+AT +4813+01620 Europe/Vienna >+AU -3133+15905 Australia/Lord_Howe Lord Howe Island >+AU -5430+15857 Antarctica/Macquarie Macquarie Island >+AU -4253+14719 Australia/Hobart Tasmania (most areas) >+AU -3956+14352 Australia/Currie Tasmania (King Island) >+AU -3749+14458 Australia/Melbourne Victoria >+AU -3352+15113 Australia/Sydney New South Wales (most areas) >+AU -3157+14127 Australia/Broken_Hill New South Wales (Yancowinna) >+AU -2728+15302 Australia/Brisbane Queensland (most areas) >+AU -2016+14900 Australia/Lindeman Queensland (Whitsunday Islands) >+AU -3455+13835 Australia/Adelaide South Australia >+AU -1228+13050 Australia/Darwin Northern Territory >+AU -3157+11551 Australia/Perth Western Australia (most areas) >+AU -3143+12852 Australia/Eucla Western Australia (Eucla) >+AZ +4023+04951 Asia/Baku >+BB +1306-05937 America/Barbados >+BD +2343+09025 Asia/Dhaka >+BE +5050+00420 Europe/Brussels >+BG +4241+02319 Europe/Sofia >+BM +3217-06446 Atlantic/Bermuda >+BN +0456+11455 Asia/Brunei >+BO -1630-06809 America/La_Paz >+BR -0351-03225 America/Noronha Atlantic islands >+BR -0127-04829 America/Belem Pará (east); Amapá >+BR -0343-03830 America/Fortaleza Brazil (northeast: MA, PI, CE, RN, PB) >+BR -0803-03454 America/Recife Pernambuco >+BR -0712-04812 America/Araguaina Tocantins >+BR -0940-03543 America/Maceio Alagoas, Sergipe >+BR -1259-03831 America/Bahia Bahia >+BR -2332-04637 America/Sao_Paulo Brazil (southeast: GO, DF, MG, ES, RJ, SP, PR, SC, RS) >+BR -2027-05437 America/Campo_Grande Mato Grosso do Sul >+BR -1535-05605 America/Cuiaba Mato Grosso >+BR -0226-05452 America/Santarem Pará (west) >+BR -0846-06354 America/Porto_Velho Rondônia >+BR +0249-06040 America/Boa_Vista Roraima >+BR -0308-06001 America/Manaus Amazonas (east) >+BR -0640-06952 America/Eirunepe Amazonas (west) >+BR -0958-06748 America/Rio_Branco Acre >+BS +2505-07721 America/Nassau >+BT +2728+08939 Asia/Thimphu >+BY +5354+02734 Europe/Minsk >+BZ +1730-08812 America/Belize >+CA +4734-05243 America/St_Johns Newfoundland; Labrador (southeast) >+CA +4439-06336 America/Halifax Atlantic - NS (most areas); PE >+CA +4612-05957 America/Glace_Bay Atlantic - NS (Cape Breton) >+CA +4606-06447 America/Moncton Atlantic - New Brunswick >+CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas) >+CA +5125-05707 America/Blanc-Sablon AST - QC (Lower North Shore) >+CA +4339-07923 America/Toronto Eastern - ON, QC (most areas) >+CA +4901-08816 America/Nipigon Eastern - ON, QC (no DST 1967-73) >+CA +4823-08915 America/Thunder_Bay Eastern - ON (Thunder Bay) >+CA +6344-06828 America/Iqaluit Eastern - NU (most east areas) >+CA +6608-06544 America/Pangnirtung Eastern - NU (Pangnirtung) >+CA +484531-0913718 America/Atikokan EST - ON (Atikokan); NU (Coral H) >+CA +4953-09709 America/Winnipeg Central - ON (west); Manitoba >+CA +4843-09434 America/Rainy_River Central - ON (Rainy R, Ft Frances) >+CA +744144-0944945 America/Resolute Central - NU (Resolute) >+CA +624900-0920459 America/Rankin_Inlet Central - NU (central) >+CA +5024-10439 America/Regina CST - SK (most areas) >+CA +5017-10750 America/Swift_Current CST - SK (midwest) >+CA +5333-11328 America/Edmonton Mountain - AB; BC (E); SK (W) >+CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west) >+CA +6227-11421 America/Yellowknife Mountain - NT (central) >+CA +682059-1334300 America/Inuvik Mountain - NT (west) >+CA +4906-11631 America/Creston MST - BC (Creston) >+CA +5946-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John) >+CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson) >+CA +4916-12307 America/Vancouver Pacific - BC (most areas) >+CA +6043-13503 America/Whitehorse Pacific - Yukon (south) >+CA +6404-13925 America/Dawson Pacific - Yukon (north) >+CC -1210+09655 Indian/Cocos >+CH,DE,LI +4723+00832 Europe/Zurich Swiss time >+CI,BF,GM,GN,ML,MR,SH,SL,SN,TG +0519-00402 Africa/Abidjan >+CK -2114-15946 Pacific/Rarotonga >+CL -3327-07040 America/Santiago Chile (most areas) >+CL -5309-07055 America/Punta_Arenas Region of Magallanes >+CL -2709-10926 Pacific/Easter Easter Island >+CN +3114+12128 Asia/Shanghai Beijing Time >+CN +4348+08735 Asia/Urumqi Xinjiang Time >+CO +0436-07405 America/Bogota >+CR +0956-08405 America/Costa_Rica >+CU +2308-08222 America/Havana >+CV +1455-02331 Atlantic/Cape_Verde >+CW,AW,BQ,SX +1211-06900 America/Curacao >+CX -1025+10543 Indian/Christmas >+CY +3510+03322 Asia/Nicosia Cyprus (most areas) >+CY +3507+03357 Asia/Famagusta Northern Cyprus >+CZ,SK +5005+01426 Europe/Prague >+DE +5230+01322 Europe/Berlin Germany (most areas) >+DK +5540+01235 Europe/Copenhagen >+DO +1828-06954 America/Santo_Domingo >+DZ +3647+00303 Africa/Algiers >+EC -0210-07950 America/Guayaquil Ecuador (mainland) >+EC -0054-08936 Pacific/Galapagos Galápagos Islands >+EE +5925+02445 Europe/Tallinn >+EG +3003+03115 Africa/Cairo >+EH +2709-01312 Africa/El_Aaiun >+ES +4024-00341 Europe/Madrid Spain (mainland) >+ES +3553-00519 Africa/Ceuta Ceuta, Melilla >+ES +2806-01524 Atlantic/Canary Canary Islands >+FI,AX +6010+02458 Europe/Helsinki >+FJ -1808+17825 Pacific/Fiji >+FK -5142-05751 Atlantic/Stanley >+FM +0725+15147 Pacific/Chuuk Chuuk/Truk, Yap >+FM +0658+15813 Pacific/Pohnpei Pohnpei/Ponape >+FM +0519+16259 Pacific/Kosrae Kosrae >+FO +6201-00646 Atlantic/Faroe >+FR +4852+00220 Europe/Paris >+GB,GG,IM,JE +513030-0000731 Europe/London >+GE +4143+04449 Asia/Tbilisi >+GF +0456-05220 America/Cayenne >+GH +0533-00013 Africa/Accra >+GI +3608-00521 Europe/Gibraltar >+GL +6411-05144 America/Godthab Greenland (most areas) >+GL +7646-01840 America/Danmarkshavn National Park (east coast) >+GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit >+GL +7634-06847 America/Thule Thule/Pituffik >+GR +3758+02343 Europe/Athens >+GS -5416-03632 Atlantic/South_Georgia >+GT +1438-09031 America/Guatemala >+GU,MP +1328+14445 Pacific/Guam >+GW +1151-01535 Africa/Bissau >+GY +0648-05810 America/Guyana >+HK +2217+11409 Asia/Hong_Kong >+HN +1406-08713 America/Tegucigalpa >+HT +1832-07220 America/Port-au-Prince >+HU +4730+01905 Europe/Budapest >+ID -0610+10648 Asia/Jakarta Java, Sumatra >+ID -0002+10920 Asia/Pontianak Borneo (west, central) >+ID -0507+11924 Asia/Makassar Borneo (east, south); Sulawesi/Celebes, Bali, Nusa Tengarra; Timor (west) >+ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya); Malukus/Moluccas >+IE +5320-00615 Europe/Dublin >+IL +314650+0351326 Asia/Jerusalem >+IN +2232+08822 Asia/Kolkata >+IO -0720+07225 Indian/Chagos >+IQ +3321+04425 Asia/Baghdad >+IR +3540+05126 Asia/Tehran >+IS +6409-02151 Atlantic/Reykjavik >+IT,SM,VA +4154+01229 Europe/Rome >+JM +175805-0764736 America/Jamaica >+JO +3157+03556 Asia/Amman >+JP +353916+1394441 Asia/Tokyo >+KE,DJ,ER,ET,KM,MG,SO,TZ,UG,YT -0117+03649 Africa/Nairobi >+KG +4254+07436 Asia/Bishkek >+KI +0125+17300 Pacific/Tarawa Gilbert Islands >+KI -0308-17105 Pacific/Enderbury Phoenix Islands >+KI +0152-15720 Pacific/Kiritimati Line Islands >+KP +3901+12545 Asia/Pyongyang >+KR +3733+12658 Asia/Seoul >+KZ +4315+07657 Asia/Almaty Kazakhstan (most areas) >+KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda >+KZ +5017+05710 Asia/Aqtobe Aqtöbe/Aktobe >+KZ +4431+05016 Asia/Aqtau MangghystaÅ«/Mankistau >+KZ +4707+05156 Asia/Atyrau AtyraÅ«/Atirau/Gur'yev >+KZ +5113+05121 Asia/Oral West Kazakhstan >+LB +3353+03530 Asia/Beirut >+LK +0656+07951 Asia/Colombo >+LR +0618-01047 Africa/Monrovia >+LT +5441+02519 Europe/Vilnius >+LU +4936+00609 Europe/Luxembourg >+LV +5657+02406 Europe/Riga >+LY +3254+01311 Africa/Tripoli >+MA +3339-00735 Africa/Casablanca >+MC +4342+00723 Europe/Monaco >+MD +4700+02850 Europe/Chisinau >+MH +0709+17112 Pacific/Majuro Marshall Islands (most areas) >+MH +0905+16720 Pacific/Kwajalein Kwajalein >+MM +1647+09610 Asia/Yangon >+MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas) >+MN +4801+09139 Asia/Hovd Bayan-Ölgii, Govi-Altai, Hovd, Uvs, Zavkhan >+MN +4804+11430 Asia/Choibalsan Dornod, Sükhbaatar >+MO +2214+11335 Asia/Macau >+MQ +1436-06105 America/Martinique >+MT +3554+01431 Europe/Malta >+MU -2010+05730 Indian/Mauritius >+MV +0410+07330 Indian/Maldives >+MX +1924-09909 America/Mexico_City Central Time >+MX +2105-08646 America/Cancun Eastern Standard Time - Quintana Roo >+MX +2058-08937 America/Merida Central Time - Campeche, Yucatán >+MX +2540-10019 America/Monterrey Central Time - Durango; Coahuila, Nuevo León, Tamaulipas (most areas) >+MX +2550-09730 America/Matamoros Central Time US - Coahuila, Nuevo León, Tamaulipas (US border) >+MX +2313-10625 America/Mazatlan Mountain Time - Baja California Sur, Nayarit, Sinaloa >+MX +2838-10605 America/Chihuahua Mountain Time - Chihuahua (most areas) >+MX +2934-10425 America/Ojinaga Mountain Time US - Chihuahua (US border) >+MX +2904-11058 America/Hermosillo Mountain Standard Time - Sonora >+MX +3232-11701 America/Tijuana Pacific Time US - Baja California >+MX +2048-10515 America/Bahia_Banderas Central Time - BahÃÂa de Banderas >+MY +0310+10142 Asia/Kuala_Lumpur Malaysia (peninsula) >+MY +0133+11020 Asia/Kuching Sabah, Sarawak >+MZ,BI,BW,CD,MW,RW,ZM,ZW -2558+03235 Africa/Maputo Central Africa Time >+NA -2234+01706 Africa/Windhoek >+NC -2216+16627 Pacific/Noumea >+NF -2903+16758 Pacific/Norfolk >+NG,AO,BJ,CD,CF,CG,CM,GA,GQ,NE +0627+00324 Africa/Lagos West Africa Time >+NI +1209-08617 America/Managua >+NL +5222+00454 Europe/Amsterdam >+NO,SJ +5955+01045 Europe/Oslo >+NP +2743+08519 Asia/Kathmandu >+NR -0031+16655 Pacific/Nauru >+NU -1901-16955 Pacific/Niue >+NZ,AQ -3652+17446 Pacific/Auckland New Zealand time >+NZ -4357-17633 Pacific/Chatham Chatham Islands >+PA,KY +0858-07932 America/Panama >+PE -1203-07703 America/Lima >+PF -1732-14934 Pacific/Tahiti Society Islands >+PF -0900-13930 Pacific/Marquesas Marquesas Islands >+PF -2308-13457 Pacific/Gambier Gambier Islands >+PG -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas) >+PG -0613+15534 Pacific/Bougainville Bougainville >+PH +1435+12100 Asia/Manila >+PK +2452+06703 Asia/Karachi >+PL +5215+02100 Europe/Warsaw >+PM +4703-05620 America/Miquelon >+PN -2504-13005 Pacific/Pitcairn >+PR +182806-0660622 America/Puerto_Rico >+PS +3130+03428 Asia/Gaza Gaza Strip >+PS +313200+0350542 Asia/Hebron West Bank >+PT +3843-00908 Europe/Lisbon Portugal (mainland) >+PT +3238-01654 Atlantic/Madeira Madeira Islands >+PT +3744-02540 Atlantic/Azores Azores >+PW +0720+13429 Pacific/Palau >+PY -2516-05740 America/Asuncion >+QA,BH +2517+05132 Asia/Qatar >+RE,TF -2052+05528 Indian/Reunion Réunion, Crozet, Scattered Islands >+RO +4426+02606 Europe/Bucharest >+RS,BA,HR,ME,MK,SI +4450+02030 Europe/Belgrade >+RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad >+RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area >+RU +4457+03406 Europe/Simferopol MSK+00 - Crimea >+RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd >+RU +5836+04939 Europe/Kirov MSK+00 - Kirov >+RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan >+RU +5134+04602 Europe/Saratov MSK+01 - Saratov >+RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk >+RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia >+RU +5651+06036 Asia/Yekaterinburg MSK+02 - Urals >+RU +5500+07324 Asia/Omsk MSK+03 - Omsk >+RU +5502+08255 Asia/Novosibirsk MSK+04 - Novosibirsk >+RU +5322+08345 Asia/Barnaul MSK+04 - Altai >+RU +5630+08458 Asia/Tomsk MSK+04 - Tomsk >+RU +5345+08707 Asia/Novokuznetsk MSK+04 - Kemerovo >+RU +5601+09250 Asia/Krasnoyarsk MSK+04 - Krasnoyarsk area >+RU +5216+10420 Asia/Irkutsk MSK+05 - Irkutsk, Buryatia >+RU +5203+11328 Asia/Chita MSK+06 - Zabaykalsky >+RU +6200+12940 Asia/Yakutsk MSK+06 - Lena River >+RU +623923+1353314 Asia/Khandyga MSK+06 - Tomponsky, Ust-Maysky >+RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River >+RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky >+RU +5934+15048 Asia/Magadan MSK+08 - Magadan >+RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island >+RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); North Kuril Is >+RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka >+RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea >+SA,KW,YE +2438+04643 Asia/Riyadh >+SB -0932+16012 Pacific/Guadalcanal >+SC -0440+05528 Indian/Mahe >+SD +1536+03232 Africa/Khartoum >+SE +5920+01803 Europe/Stockholm >+SG +0117+10351 Asia/Singapore >+SR +0550-05510 America/Paramaribo >+SS +0451+03137 Africa/Juba >+ST +0020+00644 Africa/Sao_Tome >+SV +1342-08912 America/El_Salvador >+SY +3330+03618 Asia/Damascus >+TC +2128-07108 America/Grand_Turk >+TD +1207+01503 Africa/Ndjamena >+TF -492110+0701303 Indian/Kerguelen Kerguelen, St Paul Island, Amsterdam Island >+TH,KH,LA,VN +1345+10031 Asia/Bangkok Indochina (most areas) >+TJ +3835+06848 Asia/Dushanbe >+TK -0922-17114 Pacific/Fakaofo >+TL -0833+12535 Asia/Dili >+TM +3757+05823 Asia/Ashgabat >+TN +3648+01011 Africa/Tunis >+TO -2110-17510 Pacific/Tongatapu >+TR +4101+02858 Europe/Istanbul >+TT,AG,AI,BL,DM,GD,GP,KN,LC,MF,MS,VC,VG,VI +1039-06131 America/Port_of_Spain >+TV -0831+17913 Pacific/Funafuti >+TW +2503+12130 Asia/Taipei >+UA +5026+03031 Europe/Kiev Ukraine (most areas) >+UA +4837+02218 Europe/Uzhgorod Ruthenia >+UA +4750+03510 Europe/Zaporozhye Zaporozh'ye/Zaporizhia; Lugansk/Luhansk (east) >+UM +1917+16637 Pacific/Wake Wake Island >+US +404251-0740023 America/New_York Eastern (most areas) >+US +421953-0830245 America/Detroit Eastern - MI (most areas) >+US +381515-0854534 America/Kentucky/Louisville Eastern - KY (Louisville area) >+US +364947-0845057 America/Kentucky/Monticello Eastern - KY (Wayne) >+US +394606-0860929 America/Indiana/Indianapolis Eastern - IN (most areas) >+US +384038-0873143 America/Indiana/Vincennes Eastern - IN (Da, Du, K, Mn) >+US +410305-0863611 America/Indiana/Winamac Eastern - IN (Pulaski) >+US +382232-0862041 America/Indiana/Marengo Eastern - IN (Crawford) >+US +382931-0871643 America/Indiana/Petersburg Eastern - IN (Pike) >+US +384452-0850402 America/Indiana/Vevay Eastern - IN (Switzerland) >+US +415100-0873900 America/Chicago Central (most areas) >+US +375711-0864541 America/Indiana/Tell_City Central - IN (Perry) >+US +411745-0863730 America/Indiana/Knox Central - IN (Starke) >+US +450628-0873651 America/Menominee Central - MI (Wisconsin border) >+US +470659-1011757 America/North_Dakota/Center Central - ND (Oliver) >+US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural) >+US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer) >+US +394421-1045903 America/Denver Mountain (most areas) >+US +433649-1161209 America/Boise Mountain - ID (south); OR (east) >+US +332654-1120424 America/Phoenix MST - Arizona (except Navajo) >+US +340308-1181434 America/Los_Angeles Pacific >+US +611305-1495401 America/Anchorage Alaska (most areas) >+US +581807-1342511 America/Juneau Alaska - Juneau area >+US +571035-1351807 America/Sitka Alaska - Sitka area >+US +550737-1313435 America/Metlakatla Alaska - Annette Island >+US +593249-1394338 America/Yakutat Alaska - Yakutat >+US +643004-1652423 America/Nome Alaska (west) >+US +515248-1763929 America/Adak Aleutian Islands >+US,UM +211825-1575130 Pacific/Honolulu Hawaii >+UY -345433-0561245 America/Montevideo >+UZ +3940+06648 Asia/Samarkand Uzbekistan (west) >+UZ +4120+06918 Asia/Tashkent Uzbekistan (east) >+VE +1030-06656 America/Caracas >+VN +1045+10640 Asia/Ho_Chi_Minh Vietnam (south) >+VU -1740+16825 Pacific/Efate >+WF -1318-17610 Pacific/Wallis >+WS -1350-17144 Pacific/Apia >+ZA,LS,SZ -2615+02800 Africa/Johannesburg >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/get_current_time_chrono.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/get_current_time_chrono.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..cf884a10ed9d988de04587c80805288b878dca7e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/get_current_time_chrono.inc >@@ -0,0 +1,29 @@ >+// 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 <chrono> >+#include <cstdint> >+ >+namespace absl { >+namespace time_internal { >+ >+static int64_t GetCurrentTimeNanosFromSystem() { >+ return std::chrono::duration_cast<std::chrono::nanoseconds>( >+ std::chrono::system_clock::now() - >+ std::chrono::system_clock::from_time_t(0)) >+ .count(); >+} >+ >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/get_current_time_posix.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/get_current_time_posix.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..65474ca6da1e5078c5b11a91a53372aaa5fd48ce >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/get_current_time_posix.inc >@@ -0,0 +1,22 @@ >+#include "absl/time/clock.h" >+ >+#include <sys/time.h> >+#include <ctime> >+#include <cstdint> >+ >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+namespace time_internal { >+ >+static int64_t GetCurrentTimeNanosFromSystem() { >+ const int64_t kNanosPerSecond = 1000 * 1000 * 1000; >+ struct timespec ts; >+ ABSL_RAW_CHECK(clock_gettime(CLOCK_REALTIME, &ts) == 0, >+ "Failed to read real-time clock."); >+ return (int64_t{ts.tv_sec} * kNanosPerSecond + >+ int64_t{ts.tv_nsec}); >+} >+ >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/test_util.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/test_util.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..bbbef7da70c469f8d4db55d9dbd0c05f61059b6b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/test_util.cc >@@ -0,0 +1,129 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/internal/test_util.h" >+ >+#include <algorithm> >+#include <cstddef> >+#include <cstring> >+ >+#include "absl/base/internal/raw_logging.h" >+#include "absl/time/internal/cctz/include/cctz/zone_info_source.h" >+ >+namespace cctz = absl::time_internal::cctz; >+ >+namespace absl { >+namespace time_internal { >+ >+#if GTEST_USES_SIMPLE_RE >+extern const char kZoneAbbrRE[] = ".*"; // just punt >+#else >+extern const char kZoneAbbrRE[] = "[A-Za-z]{3,4}|[-+][0-9]{2}([0-9]{2})?"; >+#endif >+ >+TimeZone LoadTimeZone(const std::string& name) { >+ TimeZone tz; >+ ABSL_RAW_CHECK(LoadTimeZone(name, &tz), name.c_str()); >+ return tz; >+} >+ >+} // namespace time_internal >+} // namespace absl >+ >+namespace absl { >+namespace time_internal { >+namespace cctz_extension { >+namespace { >+ >+// Embed the zoneinfo data for time zones used during tests and benchmarks. >+// The data was generated using "xxd -i zoneinfo-file". There is no need >+// to update the data as long as the tests do not depend on recent changes >+// (and the past rules remain the same). >+#include "absl/time/internal/zoneinfo.inc" >+ >+const struct ZoneInfo { >+ const char* name; >+ const char* data; >+ std::size_t length; >+} kZoneInfo[] = { >+ // The three real time zones used by :time_test and :time_benchmark. >+ {"America/Los_Angeles", // >+ reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len}, >+ {"America/New_York", // >+ reinterpret_cast<char*>(America_New_York), America_New_York_len}, >+ {"Australia/Sydney", // >+ reinterpret_cast<char*>(Australia_Sydney), Australia_Sydney_len}, >+ >+ // Other zones named in tests but which should fail to load. >+ {"Invalid/TimeZone", nullptr, 0}, >+ {"", nullptr, 0}, >+ >+ // Also allow for loading the local time zone under TZ=US/Pacific. >+ {"US/Pacific", // >+ reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len}, >+ >+ // Allows use of the local time zone from a system-specific location. >+#ifdef _MSC_VER >+ {"localtime", // >+ reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len}, >+#else >+ {"/etc/localtime", // >+ reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len}, >+#endif >+}; >+ >+class TestZoneInfoSource : public cctz::ZoneInfoSource { >+ public: >+ TestZoneInfoSource(const char* data, std::size_t size) >+ : data_(data), end_(data + size) {} >+ >+ std::size_t Read(void* ptr, std::size_t size) override { >+ const std::size_t len = std::min<std::size_t>(size, end_ - data_); >+ memcpy(ptr, data_, len); >+ data_ += len; >+ return len; >+ } >+ >+ int Skip(std::size_t offset) override { >+ data_ += std::min<std::size_t>(offset, end_ - data_); >+ return 0; >+ } >+ >+ private: >+ const char* data_; >+ const char* const end_; >+}; >+ >+std::unique_ptr<cctz::ZoneInfoSource> TestFactory( >+ const std::string& name, >+ const std::function<std::unique_ptr<cctz::ZoneInfoSource>( >+ const std::string& name)>& /*fallback_factory*/) { >+ for (const ZoneInfo& zoneinfo : kZoneInfo) { >+ if (name == zoneinfo.name) { >+ if (zoneinfo.data == nullptr) return nullptr; >+ return std::unique_ptr<cctz::ZoneInfoSource>( >+ new TestZoneInfoSource(zoneinfo.data, zoneinfo.length)); >+ } >+ } >+ ABSL_RAW_LOG(FATAL, "Unexpected time zone \"%s\" in test", name.c_str()); >+ return nullptr; >+} >+ >+} // namespace >+ >+ZoneInfoSourceFactory zone_info_source_factory = TestFactory; >+ >+} // namespace cctz_extension >+} // namespace time_internal >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/test_util.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/test_util.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8fd5fb9fd0382e8c4423749d609cc269e5e399d6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/test_util.h >@@ -0,0 +1,55 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#ifndef ABSL_TIME_INTERNAL_TEST_UTIL_H_ >+#define ABSL_TIME_INTERNAL_TEST_UTIL_H_ >+ >+#include <string> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/time/time.h" >+ >+// This helper is a macro so that failed expectations show up with the >+// correct line numbers. >+// >+// This is for internal testing of the Base Time library itself. This is not >+// part of a public API. >+#define ABSL_INTERNAL_EXPECT_TIME(bd, y, m, d, h, min, s, off, isdst) \ >+ do { \ >+ EXPECT_EQ(y, bd.year); \ >+ EXPECT_EQ(m, bd.month); \ >+ EXPECT_EQ(d, bd.day); \ >+ EXPECT_EQ(h, bd.hour); \ >+ EXPECT_EQ(min, bd.minute); \ >+ EXPECT_EQ(s, bd.second); \ >+ EXPECT_EQ(off, bd.offset); \ >+ EXPECT_EQ(isdst, bd.is_dst); \ >+ EXPECT_THAT(bd.zone_abbr, \ >+ testing::MatchesRegex(absl::time_internal::kZoneAbbrRE)); \ >+ } while (0) >+ >+namespace absl { >+namespace time_internal { >+ >+// A regular expression that matches all zone abbreviations (%Z). >+extern const char kZoneAbbrRE[]; >+ >+// Loads the named timezone, but dies on any failure. >+absl::TimeZone LoadTimeZone(const std::string& name); >+ >+} // namespace time_internal >+} // namespace absl >+ >+#endif // ABSL_TIME_INTERNAL_TEST_UTIL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/zoneinfo.inc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/zoneinfo.inc >new file mode 100644 >index 0000000000000000000000000000000000000000..bfed82990dd5ba7f12d8d3169a5708690e36fa87 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/internal/zoneinfo.inc >@@ -0,0 +1,729 @@ >+unsigned char America_Los_Angeles[] = { >+ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, >+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, >+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00, >+ 0x9e, 0xa6, 0x48, 0xa0, 0x9f, 0xbb, 0x15, 0x90, 0xa0, 0x86, 0x2a, 0xa0, >+ 0xa1, 0x9a, 0xf7, 0x90, 0xcb, 0x89, 0x1a, 0xa0, 0xd2, 0x23, 0xf4, 0x70, >+ 0xd2, 0x61, 0x26, 0x10, 0xd6, 0xfe, 0x74, 0x5c, 0xd8, 0x80, 0xad, 0x90, >+ 0xda, 0xfe, 0xc3, 0x90, 0xdb, 0xc0, 0x90, 0x10, 0xdc, 0xde, 0xa5, 0x90, >+ 0xdd, 0xa9, 0xac, 0x90, 0xde, 0xbe, 0x87, 0x90, 0xdf, 0x89, 0x8e, 0x90, >+ 0xe0, 0x9e, 0x69, 0x90, 0xe1, 0x69, 0x70, 0x90, 0xe2, 0x7e, 0x4b, 0x90, >+ 0xe3, 0x49, 0x52, 0x90, 0xe4, 0x5e, 0x2d, 0x90, 0xe5, 0x29, 0x34, 0x90, >+ 0xe6, 0x47, 0x4a, 0x10, 0xe7, 0x12, 0x51, 0x10, 0xe8, 0x27, 0x2c, 0x10, >+ 0xe8, 0xf2, 0x33, 0x10, 0xea, 0x07, 0x0e, 0x10, 0xea, 0xd2, 0x15, 0x10, >+ 0xeb, 0xe6, 0xf0, 0x10, 0xec, 0xb1, 0xf7, 0x10, 0xed, 0xc6, 0xd2, 0x10, >+ 0xee, 0x91, 0xd9, 0x10, 0xef, 0xaf, 0xee, 0x90, 0xf0, 0x71, 0xbb, 0x10, >+ 0xf1, 0x8f, 0xd0, 0x90, 0xf2, 0x7f, 0xc1, 0x90, 0xf3, 0x6f, 0xb2, 0x90, >+ 0xf4, 0x5f, 0xa3, 0x90, 0xf5, 0x4f, 0x94, 0x90, 0xf6, 0x3f, 0x85, 0x90, >+ 0xf7, 0x2f, 0x76, 0x90, 0xf8, 0x28, 0xa2, 0x10, 0xf9, 0x0f, 0x58, 0x90, >+ 0xfa, 0x08, 0x84, 0x10, 0xfa, 0xf8, 0x83, 0x20, 0xfb, 0xe8, 0x66, 0x10, >+ 0xfc, 0xd8, 0x65, 0x20, 0xfd, 0xc8, 0x48, 0x10, 0xfe, 0xb8, 0x47, 0x20, >+ 0xff, 0xa8, 0x2a, 0x10, 0x00, 0x98, 0x29, 0x20, 0x01, 0x88, 0x0c, 0x10, >+ 0x02, 0x78, 0x0b, 0x20, 0x03, 0x71, 0x28, 0x90, 0x04, 0x61, 0x27, 0xa0, >+ 0x05, 0x51, 0x0a, 0x90, 0x06, 0x41, 0x09, 0xa0, 0x07, 0x30, 0xec, 0x90, >+ 0x07, 0x8d, 0x43, 0xa0, 0x09, 0x10, 0xce, 0x90, 0x09, 0xad, 0xbf, 0x20, >+ 0x0a, 0xf0, 0xb0, 0x90, 0x0b, 0xe0, 0xaf, 0xa0, 0x0c, 0xd9, 0xcd, 0x10, >+ 0x0d, 0xc0, 0x91, 0xa0, 0x0e, 0xb9, 0xaf, 0x10, 0x0f, 0xa9, 0xae, 0x20, >+ 0x10, 0x99, 0x91, 0x10, 0x11, 0x89, 0x90, 0x20, 0x12, 0x79, 0x73, 0x10, >+ 0x13, 0x69, 0x72, 0x20, 0x14, 0x59, 0x55, 0x10, 0x15, 0x49, 0x54, 0x20, >+ 0x16, 0x39, 0x37, 0x10, 0x17, 0x29, 0x36, 0x20, 0x18, 0x22, 0x53, 0x90, >+ 0x19, 0x09, 0x18, 0x20, 0x1a, 0x02, 0x35, 0x90, 0x1a, 0xf2, 0x34, 0xa0, >+ 0x1b, 0xe2, 0x17, 0x90, 0x1c, 0xd2, 0x16, 0xa0, 0x1d, 0xc1, 0xf9, 0x90, >+ 0x1e, 0xb1, 0xf8, 0xa0, 0x1f, 0xa1, 0xdb, 0x90, 0x20, 0x76, 0x2b, 0x20, >+ 0x21, 0x81, 0xbd, 0x90, 0x22, 0x56, 0x0d, 0x20, 0x23, 0x6a, 0xda, 0x10, >+ 0x24, 0x35, 0xef, 0x20, 0x25, 0x4a, 0xbc, 0x10, 0x26, 0x15, 0xd1, 0x20, >+ 0x27, 0x2a, 0x9e, 0x10, 0x27, 0xfe, 0xed, 0xa0, 0x29, 0x0a, 0x80, 0x10, >+ 0x29, 0xde, 0xcf, 0xa0, 0x2a, 0xea, 0x62, 0x10, 0x2b, 0xbe, 0xb1, 0xa0, >+ 0x2c, 0xd3, 0x7e, 0x90, 0x2d, 0x9e, 0x93, 0xa0, 0x2e, 0xb3, 0x60, 0x90, >+ 0x2f, 0x7e, 0x75, 0xa0, 0x30, 0x93, 0x42, 0x90, 0x31, 0x67, 0x92, 0x20, >+ 0x32, 0x73, 0x24, 0x90, 0x33, 0x47, 0x74, 0x20, 0x34, 0x53, 0x06, 0x90, >+ 0x35, 0x27, 0x56, 0x20, 0x36, 0x32, 0xe8, 0x90, 0x37, 0x07, 0x38, 0x20, >+ 0x38, 0x1c, 0x05, 0x10, 0x38, 0xe7, 0x1a, 0x20, 0x39, 0xfb, 0xe7, 0x10, >+ 0x3a, 0xc6, 0xfc, 0x20, 0x3b, 0xdb, 0xc9, 0x10, 0x3c, 0xb0, 0x18, 0xa0, >+ 0x3d, 0xbb, 0xab, 0x10, 0x3e, 0x8f, 0xfa, 0xa0, 0x3f, 0x9b, 0x8d, 0x10, >+ 0x40, 0x6f, 0xdc, 0xa0, 0x41, 0x84, 0xa9, 0x90, 0x42, 0x4f, 0xbe, 0xa0, >+ 0x43, 0x64, 0x8b, 0x90, 0x44, 0x2f, 0xa0, 0xa0, 0x45, 0x44, 0x6d, 0x90, >+ 0x45, 0xf3, 0xd3, 0x20, 0x47, 0x2d, 0x8a, 0x10, 0x47, 0xd3, 0xb5, 0x20, >+ 0x49, 0x0d, 0x6c, 0x10, 0x49, 0xb3, 0x97, 0x20, 0x4a, 0xed, 0x4e, 0x10, >+ 0x4b, 0x9c, 0xb3, 0xa0, 0x4c, 0xd6, 0x6a, 0x90, 0x4d, 0x7c, 0x95, 0xa0, >+ 0x4e, 0xb6, 0x4c, 0x90, 0x4f, 0x5c, 0x77, 0xa0, 0x50, 0x96, 0x2e, 0x90, >+ 0x51, 0x3c, 0x59, 0xa0, 0x52, 0x76, 0x10, 0x90, 0x53, 0x1c, 0x3b, 0xa0, >+ 0x54, 0x55, 0xf2, 0x90, 0x54, 0xfc, 0x1d, 0xa0, 0x56, 0x35, 0xd4, 0x90, >+ 0x56, 0xe5, 0x3a, 0x20, 0x58, 0x1e, 0xf1, 0x10, 0x58, 0xc5, 0x1c, 0x20, >+ 0x59, 0xfe, 0xd3, 0x10, 0x5a, 0xa4, 0xfe, 0x20, 0x5b, 0xde, 0xb5, 0x10, >+ 0x5c, 0x84, 0xe0, 0x20, 0x5d, 0xbe, 0x97, 0x10, 0x5e, 0x64, 0xc2, 0x20, >+ 0x5f, 0x9e, 0x79, 0x10, 0x60, 0x4d, 0xde, 0xa0, 0x61, 0x87, 0x95, 0x90, >+ 0x62, 0x2d, 0xc0, 0xa0, 0x63, 0x67, 0x77, 0x90, 0x64, 0x0d, 0xa2, 0xa0, >+ 0x65, 0x47, 0x59, 0x90, 0x65, 0xed, 0x84, 0xa0, 0x67, 0x27, 0x3b, 0x90, >+ 0x67, 0xcd, 0x66, 0xa0, 0x69, 0x07, 0x1d, 0x90, 0x69, 0xad, 0x48, 0xa0, >+ 0x6a, 0xe6, 0xff, 0x90, 0x6b, 0x96, 0x65, 0x20, 0x6c, 0xd0, 0x1c, 0x10, >+ 0x6d, 0x76, 0x47, 0x20, 0x6e, 0xaf, 0xfe, 0x10, 0x6f, 0x56, 0x29, 0x20, >+ 0x70, 0x8f, 0xe0, 0x10, 0x71, 0x36, 0x0b, 0x20, 0x72, 0x6f, 0xc2, 0x10, >+ 0x73, 0x15, 0xed, 0x20, 0x74, 0x4f, 0xa4, 0x10, 0x74, 0xff, 0x09, 0xa0, >+ 0x76, 0x38, 0xc0, 0x90, 0x76, 0xde, 0xeb, 0xa0, 0x78, 0x18, 0xa2, 0x90, >+ 0x78, 0xbe, 0xcd, 0xa0, 0x79, 0xf8, 0x84, 0x90, 0x7a, 0x9e, 0xaf, 0xa0, >+ 0x7b, 0xd8, 0x66, 0x90, 0x7c, 0x7e, 0x91, 0xa0, 0x7d, 0xb8, 0x48, 0x90, >+ 0x7e, 0x5e, 0x73, 0xa0, 0x7f, 0x98, 0x2a, 0x90, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0xff, 0xff, 0x91, 0x26, 0x00, 0x00, 0xff, 0xff, 0x9d, 0x90, >+ 0x01, 0x04, 0xff, 0xff, 0x8f, 0x80, 0x00, 0x08, 0xff, 0xff, 0x9d, 0x90, >+ 0x01, 0x0c, 0xff, 0xff, 0x9d, 0x90, 0x01, 0x10, 0x4c, 0x4d, 0x54, 0x00, >+ 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, >+ 0x50, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, >+ 0x00, 0x01, 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0xbb, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xf8, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x04, >+ 0x1a, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xa6, 0x48, 0xa0, 0xff, 0xff, >+ 0xff, 0xff, 0x9f, 0xbb, 0x15, 0x90, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x86, >+ 0x2a, 0xa0, 0xff, 0xff, 0xff, 0xff, 0xa1, 0x9a, 0xf7, 0x90, 0xff, 0xff, >+ 0xff, 0xff, 0xcb, 0x89, 0x1a, 0xa0, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x23, >+ 0xf4, 0x70, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x61, 0x26, 0x10, 0xff, 0xff, >+ 0xff, 0xff, 0xd6, 0xfe, 0x74, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x80, >+ 0xad, 0x90, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfe, 0xc3, 0x90, 0xff, 0xff, >+ 0xff, 0xff, 0xdb, 0xc0, 0x90, 0x10, 0xff, 0xff, 0xff, 0xff, 0xdc, 0xde, >+ 0xa5, 0x90, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xa9, 0xac, 0x90, 0xff, 0xff, >+ 0xff, 0xff, 0xde, 0xbe, 0x87, 0x90, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x89, >+ 0x8e, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x9e, 0x69, 0x90, 0xff, 0xff, >+ 0xff, 0xff, 0xe1, 0x69, 0x70, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe2, 0x7e, >+ 0x4b, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x49, 0x52, 0x90, 0xff, 0xff, >+ 0xff, 0xff, 0xe4, 0x5e, 0x2d, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe5, 0x29, >+ 0x34, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x47, 0x4a, 0x10, 0xff, 0xff, >+ 0xff, 0xff, 0xe7, 0x12, 0x51, 0x10, 0xff, 0xff, 0xff, 0xff, 0xe8, 0x27, >+ 0x2c, 0x10, 0xff, 0xff, 0xff, 0xff, 0xe8, 0xf2, 0x33, 0x10, 0xff, 0xff, >+ 0xff, 0xff, 0xea, 0x07, 0x0e, 0x10, 0xff, 0xff, 0xff, 0xff, 0xea, 0xd2, >+ 0x15, 0x10, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xe6, 0xf0, 0x10, 0xff, 0xff, >+ 0xff, 0xff, 0xec, 0xb1, 0xf7, 0x10, 0xff, 0xff, 0xff, 0xff, 0xed, 0xc6, >+ 0xd2, 0x10, 0xff, 0xff, 0xff, 0xff, 0xee, 0x91, 0xd9, 0x10, 0xff, 0xff, >+ 0xff, 0xff, 0xef, 0xaf, 0xee, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x71, >+ 0xbb, 0x10, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8f, 0xd0, 0x90, 0xff, 0xff, >+ 0xff, 0xff, 0xf2, 0x7f, 0xc1, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x6f, >+ 0xb2, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x5f, 0xa3, 0x90, 0xff, 0xff, >+ 0xff, 0xff, 0xf5, 0x4f, 0x94, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x3f, >+ 0x85, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x2f, 0x76, 0x90, 0xff, 0xff, >+ 0xff, 0xff, 0xf8, 0x28, 0xa2, 0x10, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0f, >+ 0x58, 0x90, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x08, 0x84, 0x10, 0xff, 0xff, >+ 0xff, 0xff, 0xfa, 0xf8, 0x83, 0x20, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xe8, >+ 0x66, 0x10, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xd8, 0x65, 0x20, 0xff, 0xff, >+ 0xff, 0xff, 0xfd, 0xc8, 0x48, 0x10, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xb8, >+ 0x47, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa8, 0x2a, 0x10, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x98, 0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, >+ 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x78, 0x0b, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x03, 0x71, 0x28, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x61, >+ 0x27, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x05, 0x51, 0x0a, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x06, 0x41, 0x09, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30, >+ 0xec, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x8d, 0x43, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x09, 0x10, 0xce, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0xad, >+ 0xbf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xf0, 0xb0, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x0b, 0xe0, 0xaf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xd9, >+ 0xcd, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xc0, 0x91, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x0e, 0xb9, 0xaf, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xa9, >+ 0xae, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x91, 0x10, 0x00, 0x00, >+ 0x00, 0x00, 0x11, 0x89, 0x90, 0x20, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79, >+ 0x73, 0x10, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x72, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x14, 0x59, 0x55, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49, >+ 0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x37, 0x10, 0x00, 0x00, >+ 0x00, 0x00, 0x17, 0x29, 0x36, 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22, >+ 0x53, 0x90, 0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x18, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x1a, 0x02, 0x35, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xf2, >+ 0x34, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe2, 0x17, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x1c, 0xd2, 0x16, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xc1, >+ 0xf9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xb1, 0xf8, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x1f, 0xa1, 0xdb, 0x90, 0x00, 0x00, 0x00, 0x00, 0x20, 0x76, >+ 0x2b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0xbd, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x22, 0x56, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6a, >+ 0xda, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xef, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x25, 0x4a, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x26, 0x15, >+ 0xd1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2a, 0x9e, 0x10, 0x00, 0x00, >+ 0x00, 0x00, 0x27, 0xfe, 0xed, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0a, >+ 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x29, 0xde, 0xcf, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x2a, 0xea, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2b, 0xbe, >+ 0xb1, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd3, 0x7e, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x2d, 0x9e, 0x93, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xb3, >+ 0x60, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x7e, 0x75, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x30, 0x93, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x31, 0x67, >+ 0x92, 0x20, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73, 0x24, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x33, 0x47, 0x74, 0x20, 0x00, 0x00, 0x00, 0x00, 0x34, 0x53, >+ 0x06, 0x90, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x56, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x36, 0x32, 0xe8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07, >+ 0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x05, 0x10, 0x00, 0x00, >+ 0x00, 0x00, 0x38, 0xe7, 0x1a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x39, 0xfb, >+ 0xe7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xc6, 0xfc, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x3b, 0xdb, 0xc9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb0, >+ 0x18, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xbb, 0xab, 0x10, 0x00, 0x00, >+ 0x00, 0x00, 0x3e, 0x8f, 0xfa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x9b, >+ 0x8d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6f, 0xdc, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x41, 0x84, 0xa9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4f, >+ 0xbe, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x8b, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x44, 0x2f, 0xa0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, >+ 0x6d, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf3, 0xd3, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x47, 0x2d, 0x8a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xd3, >+ 0xb5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0d, 0x6c, 0x10, 0x00, 0x00, >+ 0x00, 0x00, 0x49, 0xb3, 0x97, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xed, >+ 0x4e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x9c, 0xb3, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x4c, 0xd6, 0x6a, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x7c, >+ 0x95, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xb6, 0x4c, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x4f, 0x5c, 0x77, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, >+ 0x2e, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3c, 0x59, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x52, 0x76, 0x10, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x1c, >+ 0x3b, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xf2, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x54, 0xfc, 0x1d, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, >+ 0xd4, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xe5, 0x3a, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x58, 0x1e, 0xf1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xc5, >+ 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x59, 0xfe, 0xd3, 0x10, 0x00, 0x00, >+ 0x00, 0x00, 0x5a, 0xa4, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xde, >+ 0xb5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x84, 0xe0, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x5d, 0xbe, 0x97, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x64, >+ 0xc2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9e, 0x79, 0x10, 0x00, 0x00, >+ 0x00, 0x00, 0x60, 0x4d, 0xde, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, >+ 0x95, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2d, 0xc0, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x63, 0x67, 0x77, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0d, >+ 0xa2, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x59, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x65, 0xed, 0x84, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, >+ 0x3b, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xcd, 0x66, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x69, 0x07, 0x1d, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xad, >+ 0x48, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xe6, 0xff, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x6b, 0x96, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xd0, >+ 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x76, 0x47, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x6e, 0xaf, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x56, >+ 0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0xe0, 0x10, 0x00, 0x00, >+ 0x00, 0x00, 0x71, 0x36, 0x0b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6f, >+ 0xc2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15, 0xed, 0x20, 0x00, 0x00, >+ 0x00, 0x00, 0x74, 0x4f, 0xa4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x74, 0xff, >+ 0x09, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38, 0xc0, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x76, 0xde, 0xeb, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x18, >+ 0xa2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0xbe, 0xcd, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x79, 0xf8, 0x84, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x9e, >+ 0xaf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x7b, 0xd8, 0x66, 0x90, 0x00, 0x00, >+ 0x00, 0x00, 0x7c, 0x7e, 0x91, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xb8, >+ 0x48, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5e, 0x73, 0xa0, 0x00, 0x00, >+ 0x00, 0x00, 0x7f, 0x98, 0x2a, 0x90, 0x00, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0xff, 0xff, 0x91, 0x26, 0x00, 0x00, 0xff, 0xff, 0x9d, 0x90, 0x01, >+ 0x04, 0xff, 0xff, 0x8f, 0x80, 0x00, 0x08, 0xff, 0xff, 0x9d, 0x90, 0x01, >+ 0x0c, 0xff, 0xff, 0x9d, 0x90, 0x01, 0x10, 0x4c, 0x4d, 0x54, 0x00, 0x50, >+ 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, >+ 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, >+ 0x01, 0x0a, 0x50, 0x53, 0x54, 0x38, 0x50, 0x44, 0x54, 0x2c, 0x4d, 0x33, >+ 0x2e, 0x32, 0x2e, 0x30, 0x2c, 0x4d, 0x31, 0x31, 0x2e, 0x31, 0x2e, 0x30, >+ 0x0a >+}; >+unsigned int America_Los_Angeles_len = 2845; >+unsigned char America_New_York[] = { >+ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, >+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, >+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00, >+ 0x9e, 0xa6, 0x1e, 0x70, 0x9f, 0xba, 0xeb, 0x60, 0xa0, 0x86, 0x00, 0x70, >+ 0xa1, 0x9a, 0xcd, 0x60, 0xa2, 0x65, 0xe2, 0x70, 0xa3, 0x83, 0xe9, 0xe0, >+ 0xa4, 0x6a, 0xae, 0x70, 0xa5, 0x35, 0xa7, 0x60, 0xa6, 0x53, 0xca, 0xf0, >+ 0xa7, 0x15, 0x89, 0x60, 0xa8, 0x33, 0xac, 0xf0, 0xa8, 0xfe, 0xa5, 0xe0, >+ 0xaa, 0x13, 0x8e, 0xf0, 0xaa, 0xde, 0x87, 0xe0, 0xab, 0xf3, 0x70, 0xf0, >+ 0xac, 0xbe, 0x69, 0xe0, 0xad, 0xd3, 0x52, 0xf0, 0xae, 0x9e, 0x4b, 0xe0, >+ 0xaf, 0xb3, 0x34, 0xf0, 0xb0, 0x7e, 0x2d, 0xe0, 0xb1, 0x9c, 0x51, 0x70, >+ 0xb2, 0x67, 0x4a, 0x60, 0xb3, 0x7c, 0x33, 0x70, 0xb4, 0x47, 0x2c, 0x60, >+ 0xb5, 0x5c, 0x15, 0x70, 0xb6, 0x27, 0x0e, 0x60, 0xb7, 0x3b, 0xf7, 0x70, >+ 0xb8, 0x06, 0xf0, 0x60, 0xb9, 0x1b, 0xd9, 0x70, 0xb9, 0xe6, 0xd2, 0x60, >+ 0xbb, 0x04, 0xf5, 0xf0, 0xbb, 0xc6, 0xb4, 0x60, 0xbc, 0xe4, 0xd7, 0xf0, >+ 0xbd, 0xaf, 0xd0, 0xe0, 0xbe, 0xc4, 0xb9, 0xf0, 0xbf, 0x8f, 0xb2, 0xe0, >+ 0xc0, 0xa4, 0x9b, 0xf0, 0xc1, 0x6f, 0x94, 0xe0, 0xc2, 0x84, 0x7d, 0xf0, >+ 0xc3, 0x4f, 0x76, 0xe0, 0xc4, 0x64, 0x5f, 0xf0, 0xc5, 0x2f, 0x58, 0xe0, >+ 0xc6, 0x4d, 0x7c, 0x70, 0xc7, 0x0f, 0x3a, 0xe0, 0xc8, 0x2d, 0x5e, 0x70, >+ 0xc8, 0xf8, 0x57, 0x60, 0xca, 0x0d, 0x40, 0x70, 0xca, 0xd8, 0x39, 0x60, >+ 0xcb, 0x88, 0xf0, 0x70, 0xd2, 0x23, 0xf4, 0x70, 0xd2, 0x60, 0xfb, 0xe0, >+ 0xd3, 0x75, 0xe4, 0xf0, 0xd4, 0x40, 0xdd, 0xe0, 0xd5, 0x55, 0xc6, 0xf0, >+ 0xd6, 0x20, 0xbf, 0xe0, 0xd7, 0x35, 0xa8, 0xf0, 0xd8, 0x00, 0xa1, 0xe0, >+ 0xd9, 0x15, 0x8a, 0xf0, 0xd9, 0xe0, 0x83, 0xe0, 0xda, 0xfe, 0xa7, 0x70, >+ 0xdb, 0xc0, 0x65, 0xe0, 0xdc, 0xde, 0x89, 0x70, 0xdd, 0xa9, 0x82, 0x60, >+ 0xde, 0xbe, 0x6b, 0x70, 0xdf, 0x89, 0x64, 0x60, 0xe0, 0x9e, 0x4d, 0x70, >+ 0xe1, 0x69, 0x46, 0x60, 0xe2, 0x7e, 0x2f, 0x70, 0xe3, 0x49, 0x28, 0x60, >+ 0xe4, 0x5e, 0x11, 0x70, 0xe5, 0x57, 0x2e, 0xe0, 0xe6, 0x47, 0x2d, 0xf0, >+ 0xe7, 0x37, 0x10, 0xe0, 0xe8, 0x27, 0x0f, 0xf0, 0xe9, 0x16, 0xf2, 0xe0, >+ 0xea, 0x06, 0xf1, 0xf0, 0xea, 0xf6, 0xd4, 0xe0, 0xeb, 0xe6, 0xd3, 0xf0, >+ 0xec, 0xd6, 0xb6, 0xe0, 0xed, 0xc6, 0xb5, 0xf0, 0xee, 0xbf, 0xd3, 0x60, >+ 0xef, 0xaf, 0xd2, 0x70, 0xf0, 0x9f, 0xb5, 0x60, 0xf1, 0x8f, 0xb4, 0x70, >+ 0xf2, 0x7f, 0x97, 0x60, 0xf3, 0x6f, 0x96, 0x70, 0xf4, 0x5f, 0x79, 0x60, >+ 0xf5, 0x4f, 0x78, 0x70, 0xf6, 0x3f, 0x5b, 0x60, 0xf7, 0x2f, 0x5a, 0x70, >+ 0xf8, 0x28, 0x77, 0xe0, 0xf9, 0x0f, 0x3c, 0x70, 0xfa, 0x08, 0x59, 0xe0, >+ 0xfa, 0xf8, 0x58, 0xf0, 0xfb, 0xe8, 0x3b, 0xe0, 0xfc, 0xd8, 0x3a, 0xf0, >+ 0xfd, 0xc8, 0x1d, 0xe0, 0xfe, 0xb8, 0x1c, 0xf0, 0xff, 0xa7, 0xff, 0xe0, >+ 0x00, 0x97, 0xfe, 0xf0, 0x01, 0x87, 0xe1, 0xe0, 0x02, 0x77, 0xe0, 0xf0, >+ 0x03, 0x70, 0xfe, 0x60, 0x04, 0x60, 0xfd, 0x70, 0x05, 0x50, 0xe0, 0x60, >+ 0x06, 0x40, 0xdf, 0x70, 0x07, 0x30, 0xc2, 0x60, 0x07, 0x8d, 0x19, 0x70, >+ 0x09, 0x10, 0xa4, 0x60, 0x09, 0xad, 0x94, 0xf0, 0x0a, 0xf0, 0x86, 0x60, >+ 0x0b, 0xe0, 0x85, 0x70, 0x0c, 0xd9, 0xa2, 0xe0, 0x0d, 0xc0, 0x67, 0x70, >+ 0x0e, 0xb9, 0x84, 0xe0, 0x0f, 0xa9, 0x83, 0xf0, 0x10, 0x99, 0x66, 0xe0, >+ 0x11, 0x89, 0x65, 0xf0, 0x12, 0x79, 0x48, 0xe0, 0x13, 0x69, 0x47, 0xf0, >+ 0x14, 0x59, 0x2a, 0xe0, 0x15, 0x49, 0x29, 0xf0, 0x16, 0x39, 0x0c, 0xe0, >+ 0x17, 0x29, 0x0b, 0xf0, 0x18, 0x22, 0x29, 0x60, 0x19, 0x08, 0xed, 0xf0, >+ 0x1a, 0x02, 0x0b, 0x60, 0x1a, 0xf2, 0x0a, 0x70, 0x1b, 0xe1, 0xed, 0x60, >+ 0x1c, 0xd1, 0xec, 0x70, 0x1d, 0xc1, 0xcf, 0x60, 0x1e, 0xb1, 0xce, 0x70, >+ 0x1f, 0xa1, 0xb1, 0x60, 0x20, 0x76, 0x00, 0xf0, 0x21, 0x81, 0x93, 0x60, >+ 0x22, 0x55, 0xe2, 0xf0, 0x23, 0x6a, 0xaf, 0xe0, 0x24, 0x35, 0xc4, 0xf0, >+ 0x25, 0x4a, 0x91, 0xe0, 0x26, 0x15, 0xa6, 0xf0, 0x27, 0x2a, 0x73, 0xe0, >+ 0x27, 0xfe, 0xc3, 0x70, 0x29, 0x0a, 0x55, 0xe0, 0x29, 0xde, 0xa5, 0x70, >+ 0x2a, 0xea, 0x37, 0xe0, 0x2b, 0xbe, 0x87, 0x70, 0x2c, 0xd3, 0x54, 0x60, >+ 0x2d, 0x9e, 0x69, 0x70, 0x2e, 0xb3, 0x36, 0x60, 0x2f, 0x7e, 0x4b, 0x70, >+ 0x30, 0x93, 0x18, 0x60, 0x31, 0x67, 0x67, 0xf0, 0x32, 0x72, 0xfa, 0x60, >+ 0x33, 0x47, 0x49, 0xf0, 0x34, 0x52, 0xdc, 0x60, 0x35, 0x27, 0x2b, 0xf0, >+ 0x36, 0x32, 0xbe, 0x60, 0x37, 0x07, 0x0d, 0xf0, 0x38, 0x1b, 0xda, 0xe0, >+ 0x38, 0xe6, 0xef, 0xf0, 0x39, 0xfb, 0xbc, 0xe0, 0x3a, 0xc6, 0xd1, 0xf0, >+ 0x3b, 0xdb, 0x9e, 0xe0, 0x3c, 0xaf, 0xee, 0x70, 0x3d, 0xbb, 0x80, 0xe0, >+ 0x3e, 0x8f, 0xd0, 0x70, 0x3f, 0x9b, 0x62, 0xe0, 0x40, 0x6f, 0xb2, 0x70, >+ 0x41, 0x84, 0x7f, 0x60, 0x42, 0x4f, 0x94, 0x70, 0x43, 0x64, 0x61, 0x60, >+ 0x44, 0x2f, 0x76, 0x70, 0x45, 0x44, 0x43, 0x60, 0x45, 0xf3, 0xa8, 0xf0, >+ 0x47, 0x2d, 0x5f, 0xe0, 0x47, 0xd3, 0x8a, 0xf0, 0x49, 0x0d, 0x41, 0xe0, >+ 0x49, 0xb3, 0x6c, 0xf0, 0x4a, 0xed, 0x23, 0xe0, 0x4b, 0x9c, 0x89, 0x70, >+ 0x4c, 0xd6, 0x40, 0x60, 0x4d, 0x7c, 0x6b, 0x70, 0x4e, 0xb6, 0x22, 0x60, >+ 0x4f, 0x5c, 0x4d, 0x70, 0x50, 0x96, 0x04, 0x60, 0x51, 0x3c, 0x2f, 0x70, >+ 0x52, 0x75, 0xe6, 0x60, 0x53, 0x1c, 0x11, 0x70, 0x54, 0x55, 0xc8, 0x60, >+ 0x54, 0xfb, 0xf3, 0x70, 0x56, 0x35, 0xaa, 0x60, 0x56, 0xe5, 0x0f, 0xf0, >+ 0x58, 0x1e, 0xc6, 0xe0, 0x58, 0xc4, 0xf1, 0xf0, 0x59, 0xfe, 0xa8, 0xe0, >+ 0x5a, 0xa4, 0xd3, 0xf0, 0x5b, 0xde, 0x8a, 0xe0, 0x5c, 0x84, 0xb5, 0xf0, >+ 0x5d, 0xbe, 0x6c, 0xe0, 0x5e, 0x64, 0x97, 0xf0, 0x5f, 0x9e, 0x4e, 0xe0, >+ 0x60, 0x4d, 0xb4, 0x70, 0x61, 0x87, 0x6b, 0x60, 0x62, 0x2d, 0x96, 0x70, >+ 0x63, 0x67, 0x4d, 0x60, 0x64, 0x0d, 0x78, 0x70, 0x65, 0x47, 0x2f, 0x60, >+ 0x65, 0xed, 0x5a, 0x70, 0x67, 0x27, 0x11, 0x60, 0x67, 0xcd, 0x3c, 0x70, >+ 0x69, 0x06, 0xf3, 0x60, 0x69, 0xad, 0x1e, 0x70, 0x6a, 0xe6, 0xd5, 0x60, >+ 0x6b, 0x96, 0x3a, 0xf0, 0x6c, 0xcf, 0xf1, 0xe0, 0x6d, 0x76, 0x1c, 0xf0, >+ 0x6e, 0xaf, 0xd3, 0xe0, 0x6f, 0x55, 0xfe, 0xf0, 0x70, 0x8f, 0xb5, 0xe0, >+ 0x71, 0x35, 0xe0, 0xf0, 0x72, 0x6f, 0x97, 0xe0, 0x73, 0x15, 0xc2, 0xf0, >+ 0x74, 0x4f, 0x79, 0xe0, 0x74, 0xfe, 0xdf, 0x70, 0x76, 0x38, 0x96, 0x60, >+ 0x76, 0xde, 0xc1, 0x70, 0x78, 0x18, 0x78, 0x60, 0x78, 0xbe, 0xa3, 0x70, >+ 0x79, 0xf8, 0x5a, 0x60, 0x7a, 0x9e, 0x85, 0x70, 0x7b, 0xd8, 0x3c, 0x60, >+ 0x7c, 0x7e, 0x67, 0x70, 0x7d, 0xb8, 0x1e, 0x60, 0x7e, 0x5e, 0x49, 0x70, >+ 0x7f, 0x98, 0x00, 0x60, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0xff, 0xff, 0xba, 0x9e, 0x00, 0x00, 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x04, >+ 0xff, 0xff, 0xb9, 0xb0, 0x00, 0x08, 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x0c, >+ 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x10, 0x4c, 0x4d, 0x54, 0x00, 0x45, 0x44, >+ 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50, >+ 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, >+ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, >+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, >+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xf8, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x03, 0xf0, 0x90, >+ 0xff, 0xff, 0xff, 0xff, 0x9e, 0xa6, 0x1e, 0x70, 0xff, 0xff, 0xff, 0xff, >+ 0x9f, 0xba, 0xeb, 0x60, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x86, 0x00, 0x70, >+ 0xff, 0xff, 0xff, 0xff, 0xa1, 0x9a, 0xcd, 0x60, 0xff, 0xff, 0xff, 0xff, >+ 0xa2, 0x65, 0xe2, 0x70, 0xff, 0xff, 0xff, 0xff, 0xa3, 0x83, 0xe9, 0xe0, >+ 0xff, 0xff, 0xff, 0xff, 0xa4, 0x6a, 0xae, 0x70, 0xff, 0xff, 0xff, 0xff, >+ 0xa5, 0x35, 0xa7, 0x60, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x53, 0xca, 0xf0, >+ 0xff, 0xff, 0xff, 0xff, 0xa7, 0x15, 0x89, 0x60, 0xff, 0xff, 0xff, 0xff, >+ 0xa8, 0x33, 0xac, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xa8, 0xfe, 0xa5, 0xe0, >+ 0xff, 0xff, 0xff, 0xff, 0xaa, 0x13, 0x8e, 0xf0, 0xff, 0xff, 0xff, 0xff, >+ 0xaa, 0xde, 0x87, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xab, 0xf3, 0x70, 0xf0, >+ 0xff, 0xff, 0xff, 0xff, 0xac, 0xbe, 0x69, 0xe0, 0xff, 0xff, 0xff, 0xff, >+ 0xad, 0xd3, 0x52, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xae, 0x9e, 0x4b, 0xe0, >+ 0xff, 0xff, 0xff, 0xff, 0xaf, 0xb3, 0x34, 0xf0, 0xff, 0xff, 0xff, 0xff, >+ 0xb0, 0x7e, 0x2d, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xb1, 0x9c, 0x51, 0x70, >+ 0xff, 0xff, 0xff, 0xff, 0xb2, 0x67, 0x4a, 0x60, 0xff, 0xff, 0xff, 0xff, >+ 0xb3, 0x7c, 0x33, 0x70, 0xff, 0xff, 0xff, 0xff, 0xb4, 0x47, 0x2c, 0x60, >+ 0xff, 0xff, 0xff, 0xff, 0xb5, 0x5c, 0x15, 0x70, 0xff, 0xff, 0xff, 0xff, >+ 0xb6, 0x27, 0x0e, 0x60, 0xff, 0xff, 0xff, 0xff, 0xb7, 0x3b, 0xf7, 0x70, >+ 0xff, 0xff, 0xff, 0xff, 0xb8, 0x06, 0xf0, 0x60, 0xff, 0xff, 0xff, 0xff, >+ 0xb9, 0x1b, 0xd9, 0x70, 0xff, 0xff, 0xff, 0xff, 0xb9, 0xe6, 0xd2, 0x60, >+ 0xff, 0xff, 0xff, 0xff, 0xbb, 0x04, 0xf5, 0xf0, 0xff, 0xff, 0xff, 0xff, >+ 0xbb, 0xc6, 0xb4, 0x60, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe4, 0xd7, 0xf0, >+ 0xff, 0xff, 0xff, 0xff, 0xbd, 0xaf, 0xd0, 0xe0, 0xff, 0xff, 0xff, 0xff, >+ 0xbe, 0xc4, 0xb9, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x8f, 0xb2, 0xe0, >+ 0xff, 0xff, 0xff, 0xff, 0xc0, 0xa4, 0x9b, 0xf0, 0xff, 0xff, 0xff, 0xff, >+ 0xc1, 0x6f, 0x94, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xc2, 0x84, 0x7d, 0xf0, >+ 0xff, 0xff, 0xff, 0xff, 0xc3, 0x4f, 0x76, 0xe0, 0xff, 0xff, 0xff, 0xff, >+ 0xc4, 0x64, 0x5f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xc5, 0x2f, 0x58, 0xe0, >+ 0xff, 0xff, 0xff, 0xff, 0xc6, 0x4d, 0x7c, 0x70, 0xff, 0xff, 0xff, 0xff, >+ 0xc7, 0x0f, 0x3a, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x2d, 0x5e, 0x70, >+ 0xff, 0xff, 0xff, 0xff, 0xc8, 0xf8, 0x57, 0x60, 0xff, 0xff, 0xff, 0xff, >+ 0xca, 0x0d, 0x40, 0x70, 0xff, 0xff, 0xff, 0xff, 0xca, 0xd8, 0x39, 0x60, >+ 0xff, 0xff, 0xff, 0xff, 0xcb, 0x88, 0xf0, 0x70, 0xff, 0xff, 0xff, 0xff, >+ 0xd2, 0x23, 0xf4, 0x70, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x60, 0xfb, 0xe0, >+ 0xff, 0xff, 0xff, 0xff, 0xd3, 0x75, 0xe4, 0xf0, 0xff, 0xff, 0xff, 0xff, >+ 0xd4, 0x40, 0xdd, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x55, 0xc6, 0xf0, >+ 0xff, 0xff, 0xff, 0xff, 0xd6, 0x20, 0xbf, 0xe0, 0xff, 0xff, 0xff, 0xff, >+ 0xd7, 0x35, 0xa8, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x00, 0xa1, 0xe0, >+ 0xff, 0xff, 0xff, 0xff, 0xd9, 0x15, 0x8a, 0xf0, 0xff, 0xff, 0xff, 0xff, >+ 0xd9, 0xe0, 0x83, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfe, 0xa7, 0x70, >+ 0xff, 0xff, 0xff, 0xff, 0xdb, 0xc0, 0x65, 0xe0, 0xff, 0xff, 0xff, 0xff, >+ 0xdc, 0xde, 0x89, 0x70, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xa9, 0x82, 0x60, >+ 0xff, 0xff, 0xff, 0xff, 0xde, 0xbe, 0x6b, 0x70, 0xff, 0xff, 0xff, 0xff, >+ 0xdf, 0x89, 0x64, 0x60, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x9e, 0x4d, 0x70, >+ 0xff, 0xff, 0xff, 0xff, 0xe1, 0x69, 0x46, 0x60, 0xff, 0xff, 0xff, 0xff, >+ 0xe2, 0x7e, 0x2f, 0x70, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x49, 0x28, 0x60, >+ 0xff, 0xff, 0xff, 0xff, 0xe4, 0x5e, 0x11, 0x70, 0xff, 0xff, 0xff, 0xff, >+ 0xe5, 0x57, 0x2e, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x47, 0x2d, 0xf0, >+ 0xff, 0xff, 0xff, 0xff, 0xe7, 0x37, 0x10, 0xe0, 0xff, 0xff, 0xff, 0xff, >+ 0xe8, 0x27, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x16, 0xf2, 0xe0, >+ 0xff, 0xff, 0xff, 0xff, 0xea, 0x06, 0xf1, 0xf0, 0xff, 0xff, 0xff, 0xff, >+ 0xea, 0xf6, 0xd4, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xe6, 0xd3, 0xf0, >+ 0xff, 0xff, 0xff, 0xff, 0xec, 0xd6, 0xb6, 0xe0, 0xff, 0xff, 0xff, 0xff, >+ 0xed, 0xc6, 0xb5, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xee, 0xbf, 0xd3, 0x60, >+ 0xff, 0xff, 0xff, 0xff, 0xef, 0xaf, 0xd2, 0x70, 0xff, 0xff, 0xff, 0xff, >+ 0xf0, 0x9f, 0xb5, 0x60, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8f, 0xb4, 0x70, >+ 0xff, 0xff, 0xff, 0xff, 0xf2, 0x7f, 0x97, 0x60, 0xff, 0xff, 0xff, 0xff, >+ 0xf3, 0x6f, 0x96, 0x70, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x5f, 0x79, 0x60, >+ 0xff, 0xff, 0xff, 0xff, 0xf5, 0x4f, 0x78, 0x70, 0xff, 0xff, 0xff, 0xff, >+ 0xf6, 0x3f, 0x5b, 0x60, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x2f, 0x5a, 0x70, >+ 0xff, 0xff, 0xff, 0xff, 0xf8, 0x28, 0x77, 0xe0, 0xff, 0xff, 0xff, 0xff, >+ 0xf9, 0x0f, 0x3c, 0x70, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x08, 0x59, 0xe0, >+ 0xff, 0xff, 0xff, 0xff, 0xfa, 0xf8, 0x58, 0xf0, 0xff, 0xff, 0xff, 0xff, >+ 0xfb, 0xe8, 0x3b, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xd8, 0x3a, 0xf0, >+ 0xff, 0xff, 0xff, 0xff, 0xfd, 0xc8, 0x1d, 0xe0, 0xff, 0xff, 0xff, 0xff, >+ 0xfe, 0xb8, 0x1c, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7, 0xff, 0xe0, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, >+ 0x01, 0x87, 0xe1, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x02, 0x77, 0xe0, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x70, 0xfe, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x04, 0x60, 0xfd, 0x70, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0xe0, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0xdf, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x07, 0x30, 0xc2, 0x60, 0x00, 0x00, 0x00, 0x00, 0x07, 0x8d, 0x19, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0xa4, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x09, 0xad, 0x94, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xf0, 0x86, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe0, 0x85, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x0c, 0xd9, 0xa2, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xc0, 0x67, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb9, 0x84, 0xe0, 0x00, 0x00, 0x00, 0x00, >+ 0x0f, 0xa9, 0x83, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x66, 0xe0, >+ 0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x65, 0xf0, 0x00, 0x00, 0x00, 0x00, >+ 0x12, 0x79, 0x48, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x47, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x59, 0x2a, 0xe0, 0x00, 0x00, 0x00, 0x00, >+ 0x15, 0x49, 0x29, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x0c, 0xe0, >+ 0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x0b, 0xf0, 0x00, 0x00, 0x00, 0x00, >+ 0x18, 0x22, 0x29, 0x60, 0x00, 0x00, 0x00, 0x00, 0x19, 0x08, 0xed, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x0b, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x1a, 0xf2, 0x0a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe1, 0xed, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x1c, 0xd1, 0xec, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x1d, 0xc1, 0xcf, 0x60, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xb1, 0xce, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0xa1, 0xb1, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x20, 0x76, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0x93, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x22, 0x55, 0xe2, 0xf0, 0x00, 0x00, 0x00, 0x00, >+ 0x23, 0x6a, 0xaf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xc4, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x25, 0x4a, 0x91, 0xe0, 0x00, 0x00, 0x00, 0x00, >+ 0x26, 0x15, 0xa6, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2a, 0x73, 0xe0, >+ 0x00, 0x00, 0x00, 0x00, 0x27, 0xfe, 0xc3, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x29, 0x0a, 0x55, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x29, 0xde, 0xa5, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x2a, 0xea, 0x37, 0xe0, 0x00, 0x00, 0x00, 0x00, >+ 0x2b, 0xbe, 0x87, 0x70, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd3, 0x54, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x2d, 0x9e, 0x69, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x2e, 0xb3, 0x36, 0x60, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x7e, 0x4b, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x93, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x31, 0x67, 0x67, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x32, 0x72, 0xfa, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x49, 0xf0, 0x00, 0x00, 0x00, 0x00, >+ 0x34, 0x52, 0xdc, 0x60, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x2b, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x36, 0x32, 0xbe, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x37, 0x07, 0x0d, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b, 0xda, 0xe0, >+ 0x00, 0x00, 0x00, 0x00, 0x38, 0xe6, 0xef, 0xf0, 0x00, 0x00, 0x00, 0x00, >+ 0x39, 0xfb, 0xbc, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xc6, 0xd1, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x3b, 0xdb, 0x9e, 0xe0, 0x00, 0x00, 0x00, 0x00, >+ 0x3c, 0xaf, 0xee, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xbb, 0x80, 0xe0, >+ 0x00, 0x00, 0x00, 0x00, 0x3e, 0x8f, 0xd0, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x3f, 0x9b, 0x62, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6f, 0xb2, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0x7f, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x42, 0x4f, 0x94, 0x70, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x61, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x44, 0x2f, 0x76, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x45, 0x44, 0x43, 0x60, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf3, 0xa8, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x47, 0x2d, 0x5f, 0xe0, 0x00, 0x00, 0x00, 0x00, >+ 0x47, 0xd3, 0x8a, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0d, 0x41, 0xe0, >+ 0x00, 0x00, 0x00, 0x00, 0x49, 0xb3, 0x6c, 0xf0, 0x00, 0x00, 0x00, 0x00, >+ 0x4a, 0xed, 0x23, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x9c, 0x89, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x4c, 0xd6, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x4d, 0x7c, 0x6b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xb6, 0x22, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x4f, 0x5c, 0x4d, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x50, 0x96, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3c, 0x2f, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x75, 0xe6, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x53, 0x1c, 0x11, 0x70, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xc8, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x54, 0xfb, 0xf3, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x56, 0x35, 0xaa, 0x60, 0x00, 0x00, 0x00, 0x00, 0x56, 0xe5, 0x0f, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x58, 0x1e, 0xc6, 0xe0, 0x00, 0x00, 0x00, 0x00, >+ 0x58, 0xc4, 0xf1, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x59, 0xfe, 0xa8, 0xe0, >+ 0x00, 0x00, 0x00, 0x00, 0x5a, 0xa4, 0xd3, 0xf0, 0x00, 0x00, 0x00, 0x00, >+ 0x5b, 0xde, 0x8a, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x84, 0xb5, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x5d, 0xbe, 0x6c, 0xe0, 0x00, 0x00, 0x00, 0x00, >+ 0x5e, 0x64, 0x97, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9e, 0x4e, 0xe0, >+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x4d, 0xb4, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x61, 0x87, 0x6b, 0x60, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2d, 0x96, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x4d, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x64, 0x0d, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x2f, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x65, 0xed, 0x5a, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x67, 0x27, 0x11, 0x60, 0x00, 0x00, 0x00, 0x00, 0x67, 0xcd, 0x3c, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x69, 0x06, 0xf3, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x69, 0xad, 0x1e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xe6, 0xd5, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x6b, 0x96, 0x3a, 0xf0, 0x00, 0x00, 0x00, 0x00, >+ 0x6c, 0xcf, 0xf1, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x76, 0x1c, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x6e, 0xaf, 0xd3, 0xe0, 0x00, 0x00, 0x00, 0x00, >+ 0x6f, 0x55, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0xb5, 0xe0, >+ 0x00, 0x00, 0x00, 0x00, 0x71, 0x35, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00, >+ 0x72, 0x6f, 0x97, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15, 0xc2, 0xf0, >+ 0x00, 0x00, 0x00, 0x00, 0x74, 0x4f, 0x79, 0xe0, 0x00, 0x00, 0x00, 0x00, >+ 0x74, 0xfe, 0xdf, 0x70, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38, 0x96, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x76, 0xde, 0xc1, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x78, 0x18, 0x78, 0x60, 0x00, 0x00, 0x00, 0x00, 0x78, 0xbe, 0xa3, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x79, 0xf8, 0x5a, 0x60, 0x00, 0x00, 0x00, 0x00, >+ 0x7a, 0x9e, 0x85, 0x70, 0x00, 0x00, 0x00, 0x00, 0x7b, 0xd8, 0x3c, 0x60, >+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7e, 0x67, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x7d, 0xb8, 0x1e, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5e, 0x49, 0x70, >+ 0x00, 0x00, 0x00, 0x00, 0x7f, 0x98, 0x00, 0x60, 0x00, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0xff, 0xff, 0xba, 0x9e, 0x00, 0x00, 0xff, >+ 0xff, 0xc7, 0xc0, 0x01, 0x04, 0xff, 0xff, 0xb9, 0xb0, 0x00, 0x08, 0xff, >+ 0xff, 0xc7, 0xc0, 0x01, 0x0c, 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x10, 0x4c, >+ 0x4d, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, >+ 0x57, 0x54, 0x00, 0x45, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, >+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x45, 0x53, 0x54, 0x35, 0x45, 0x44, >+ 0x54, 0x2c, 0x4d, 0x33, 0x2e, 0x32, 0x2e, 0x30, 0x2c, 0x4d, 0x31, 0x31, >+ 0x2e, 0x31, 0x2e, 0x30, 0x0a >+}; >+unsigned int America_New_York_len = 3545; >+unsigned char Australia_Sydney[] = { >+ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, >+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, >+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x00, 0x00, 0x00, >+ 0x9c, 0x4e, 0xa6, 0x9c, 0x9c, 0xbc, 0x20, 0xf0, 0xcb, 0x54, 0xb3, 0x00, >+ 0xcb, 0xc7, 0x57, 0x70, 0xcc, 0xb7, 0x56, 0x80, 0xcd, 0xa7, 0x39, 0x70, >+ 0xce, 0xa0, 0x73, 0x00, 0xcf, 0x87, 0x1b, 0x70, 0x03, 0x70, 0x39, 0x80, >+ 0x04, 0x0d, 0x1c, 0x00, 0x05, 0x50, 0x1b, 0x80, 0x05, 0xf6, 0x38, 0x80, >+ 0x07, 0x2f, 0xfd, 0x80, 0x07, 0xd6, 0x1a, 0x80, 0x09, 0x0f, 0xdf, 0x80, >+ 0x09, 0xb5, 0xfc, 0x80, 0x0a, 0xef, 0xc1, 0x80, 0x0b, 0x9f, 0x19, 0x00, >+ 0x0c, 0xd8, 0xde, 0x00, 0x0d, 0x7e, 0xfb, 0x00, 0x0e, 0xb8, 0xc0, 0x00, >+ 0x0f, 0x5e, 0xdd, 0x00, 0x10, 0x98, 0xa2, 0x00, 0x11, 0x3e, 0xbf, 0x00, >+ 0x12, 0x78, 0x84, 0x00, 0x13, 0x1e, 0xa1, 0x00, 0x14, 0x58, 0x66, 0x00, >+ 0x14, 0xfe, 0x83, 0x00, 0x16, 0x38, 0x48, 0x00, 0x17, 0x0c, 0x89, 0x80, >+ 0x18, 0x21, 0x64, 0x80, 0x18, 0xc7, 0x81, 0x80, 0x1a, 0x01, 0x46, 0x80, >+ 0x1a, 0xa7, 0x63, 0x80, 0x1b, 0xe1, 0x28, 0x80, 0x1c, 0x87, 0x45, 0x80, >+ 0x1d, 0xc1, 0x0a, 0x80, 0x1e, 0x79, 0x9c, 0x80, 0x1f, 0x97, 0xb2, 0x00, >+ 0x20, 0x59, 0x7e, 0x80, 0x21, 0x80, 0xce, 0x80, 0x22, 0x42, 0x9b, 0x00, >+ 0x23, 0x69, 0xeb, 0x00, 0x24, 0x22, 0x7d, 0x00, 0x25, 0x49, 0xcd, 0x00, >+ 0x25, 0xef, 0xea, 0x00, 0x27, 0x29, 0xaf, 0x00, 0x27, 0xcf, 0xcc, 0x00, >+ 0x29, 0x09, 0x91, 0x00, 0x29, 0xaf, 0xae, 0x00, 0x2a, 0xe9, 0x73, 0x00, >+ 0x2b, 0x98, 0xca, 0x80, 0x2c, 0xd2, 0x8f, 0x80, 0x2d, 0x78, 0xac, 0x80, >+ 0x2e, 0xb2, 0x71, 0x80, 0x2f, 0x58, 0x8e, 0x80, 0x30, 0x92, 0x53, 0x80, >+ 0x31, 0x5d, 0x5a, 0x80, 0x32, 0x72, 0x35, 0x80, 0x33, 0x3d, 0x3c, 0x80, >+ 0x34, 0x52, 0x17, 0x80, 0x35, 0x1d, 0x1e, 0x80, 0x36, 0x31, 0xf9, 0x80, >+ 0x36, 0xfd, 0x00, 0x80, 0x38, 0x1b, 0x16, 0x00, 0x38, 0xdc, 0xe2, 0x80, >+ 0x39, 0xa7, 0xe9, 0x80, 0x3a, 0xbc, 0xc4, 0x80, 0x3b, 0xda, 0xda, 0x00, >+ 0x3c, 0xa5, 0xe1, 0x00, 0x3d, 0xba, 0xbc, 0x00, 0x3e, 0x85, 0xc3, 0x00, >+ 0x3f, 0x9a, 0x9e, 0x00, 0x40, 0x65, 0xa5, 0x00, 0x41, 0x83, 0xba, 0x80, >+ 0x42, 0x45, 0x87, 0x00, 0x43, 0x63, 0x9c, 0x80, 0x44, 0x2e, 0xa3, 0x80, >+ 0x45, 0x43, 0x7e, 0x80, 0x46, 0x05, 0x4b, 0x00, 0x47, 0x23, 0x60, 0x80, >+ 0x47, 0xf7, 0xa2, 0x00, 0x48, 0xe7, 0x93, 0x00, 0x49, 0xd7, 0x84, 0x00, >+ 0x4a, 0xc7, 0x75, 0x00, 0x4b, 0xb7, 0x66, 0x00, 0x4c, 0xa7, 0x57, 0x00, >+ 0x4d, 0x97, 0x48, 0x00, 0x4e, 0x87, 0x39, 0x00, 0x4f, 0x77, 0x2a, 0x00, >+ 0x50, 0x70, 0x55, 0x80, 0x51, 0x60, 0x46, 0x80, 0x52, 0x50, 0x37, 0x80, >+ 0x53, 0x40, 0x28, 0x80, 0x54, 0x30, 0x19, 0x80, 0x55, 0x20, 0x0a, 0x80, >+ 0x56, 0x0f, 0xfb, 0x80, 0x56, 0xff, 0xec, 0x80, 0x57, 0xef, 0xdd, 0x80, >+ 0x58, 0xdf, 0xce, 0x80, 0x59, 0xcf, 0xbf, 0x80, 0x5a, 0xbf, 0xb0, 0x80, >+ 0x5b, 0xb8, 0xdc, 0x00, 0x5c, 0xa8, 0xcd, 0x00, 0x5d, 0x98, 0xbe, 0x00, >+ 0x5e, 0x88, 0xaf, 0x00, 0x5f, 0x78, 0xa0, 0x00, 0x60, 0x68, 0x91, 0x00, >+ 0x61, 0x58, 0x82, 0x00, 0x62, 0x48, 0x73, 0x00, 0x63, 0x38, 0x64, 0x00, >+ 0x64, 0x28, 0x55, 0x00, 0x65, 0x18, 0x46, 0x00, 0x66, 0x11, 0x71, 0x80, >+ 0x67, 0x01, 0x62, 0x80, 0x67, 0xf1, 0x53, 0x80, 0x68, 0xe1, 0x44, 0x80, >+ 0x69, 0xd1, 0x35, 0x80, 0x6a, 0xc1, 0x26, 0x80, 0x6b, 0xb1, 0x17, 0x80, >+ 0x6c, 0xa1, 0x08, 0x80, 0x6d, 0x90, 0xf9, 0x80, 0x6e, 0x80, 0xea, 0x80, >+ 0x6f, 0x70, 0xdb, 0x80, 0x70, 0x6a, 0x07, 0x00, 0x71, 0x59, 0xf8, 0x00, >+ 0x72, 0x49, 0xe9, 0x00, 0x73, 0x39, 0xda, 0x00, 0x74, 0x29, 0xcb, 0x00, >+ 0x75, 0x19, 0xbc, 0x00, 0x76, 0x09, 0xad, 0x00, 0x76, 0xf9, 0x9e, 0x00, >+ 0x77, 0xe9, 0x8f, 0x00, 0x78, 0xd9, 0x80, 0x00, 0x79, 0xc9, 0x71, 0x00, >+ 0x7a, 0xb9, 0x62, 0x00, 0x7b, 0xb2, 0x8d, 0x80, 0x7c, 0xa2, 0x7e, 0x80, >+ 0x7d, 0x92, 0x6f, 0x80, 0x7e, 0x82, 0x60, 0x80, 0x7f, 0x72, 0x51, 0x80, >+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, >+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x00, 0x00, >+ 0x8d, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xb0, 0x01, 0x04, 0x00, 0x00, >+ 0x8c, 0xa0, 0x00, 0x09, 0x00, 0x00, 0x9a, 0xb0, 0x01, 0x04, 0x00, 0x00, >+ 0x8c, 0xa0, 0x00, 0x09, 0x4c, 0x4d, 0x54, 0x00, 0x41, 0x45, 0x44, 0x54, >+ 0x00, 0x41, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0e, >+ 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, >+ 0x73, 0x16, 0x7f, 0x3c, 0xff, 0xff, 0xff, 0xff, 0x9c, 0x4e, 0xa6, 0x9c, >+ 0xff, 0xff, 0xff, 0xff, 0x9c, 0xbc, 0x20, 0xf0, 0xff, 0xff, 0xff, 0xff, >+ 0xcb, 0x54, 0xb3, 0x00, 0xff, 0xff, 0xff, 0xff, 0xcb, 0xc7, 0x57, 0x70, >+ 0xff, 0xff, 0xff, 0xff, 0xcc, 0xb7, 0x56, 0x80, 0xff, 0xff, 0xff, 0xff, >+ 0xcd, 0xa7, 0x39, 0x70, 0xff, 0xff, 0xff, 0xff, 0xce, 0xa0, 0x73, 0x00, >+ 0xff, 0xff, 0xff, 0xff, 0xcf, 0x87, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, >+ 0x03, 0x70, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0d, 0x1c, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0x1b, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x05, 0xf6, 0x38, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x2f, 0xfd, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x07, 0xd6, 0x1a, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x09, 0x0f, 0xdf, 0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0xb5, 0xfc, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xef, 0xc1, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x0b, 0x9f, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xd8, 0xde, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x0d, 0x7e, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x0e, 0xb8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x5e, 0xdd, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x98, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x11, 0x3e, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x78, 0x84, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x13, 0x1e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x14, 0x58, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xfe, 0x83, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x16, 0x38, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x17, 0x0c, 0x89, 0x80, 0x00, 0x00, 0x00, 0x00, 0x18, 0x21, 0x64, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x18, 0xc7, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x1a, 0x01, 0x46, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xa7, 0x63, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe1, 0x28, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x1c, 0x87, 0x45, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xc1, 0x0a, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x1e, 0x79, 0x9c, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x1f, 0x97, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x59, 0x7e, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0xce, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x22, 0x42, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x69, 0xeb, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x24, 0x22, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x25, 0x49, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xef, 0xea, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x27, 0x29, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x27, 0xcf, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x09, 0x91, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x29, 0xaf, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x2a, 0xe9, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x98, 0xca, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd2, 0x8f, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x2d, 0x78, 0xac, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xb2, 0x71, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x2f, 0x58, 0x8e, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x30, 0x92, 0x53, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x5d, 0x5a, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x32, 0x72, 0x35, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x33, 0x3d, 0x3c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x34, 0x52, 0x17, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x35, 0x1d, 0x1e, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x36, 0x31, 0xf9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x36, 0xfd, 0x00, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x38, 0xdc, 0xe2, 0x80, 0x00, 0x00, 0x00, 0x00, 0x39, 0xa7, 0xe9, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x3a, 0xbc, 0xc4, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x3b, 0xda, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xa5, 0xe1, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x3d, 0xba, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x3e, 0x85, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x9a, 0x9e, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x65, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x41, 0x83, 0xba, 0x80, 0x00, 0x00, 0x00, 0x00, 0x42, 0x45, 0x87, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x43, 0x63, 0x9c, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x44, 0x2e, 0xa3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x45, 0x43, 0x7e, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x46, 0x05, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x47, 0x23, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x47, 0xf7, 0xa2, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x48, 0xe7, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x49, 0xd7, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xc7, 0x75, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x4b, 0xb7, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x4c, 0xa7, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x97, 0x48, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x4e, 0x87, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x4f, 0x77, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x70, 0x55, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x51, 0x60, 0x46, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x52, 0x50, 0x37, 0x80, 0x00, 0x00, 0x00, 0x00, 0x53, 0x40, 0x28, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x30, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x55, 0x20, 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x56, 0x0f, 0xfb, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x56, 0xff, 0xec, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x57, 0xef, 0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x58, 0xdf, 0xce, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x59, 0xcf, 0xbf, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x5a, 0xbf, 0xb0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xb8, 0xdc, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x5c, 0xa8, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x5d, 0x98, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x88, 0xaf, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x5f, 0x78, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x60, 0x68, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x58, 0x82, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x62, 0x48, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x63, 0x38, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x28, 0x55, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x65, 0x18, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x66, 0x11, 0x71, 0x80, 0x00, 0x00, 0x00, 0x00, 0x67, 0x01, 0x62, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x67, 0xf1, 0x53, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x68, 0xe1, 0x44, 0x80, 0x00, 0x00, 0x00, 0x00, 0x69, 0xd1, 0x35, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x6a, 0xc1, 0x26, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x6b, 0xb1, 0x17, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xa1, 0x08, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x6d, 0x90, 0xf9, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x6e, 0x80, 0xea, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x70, 0xdb, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x6a, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x71, 0x59, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x49, 0xe9, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x73, 0x39, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x74, 0x29, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x19, 0xbc, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x09, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x76, 0xf9, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xe9, 0x8f, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x78, 0xd9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x79, 0xc9, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xb9, 0x62, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x7b, 0xb2, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x7c, 0xa2, 0x7e, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x92, 0x6f, 0x80, >+ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x82, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, >+ 0x7f, 0x72, 0x51, 0x80, 0x00, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, >+ 0x01, 0x02, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, >+ 0x03, 0x04, 0x03, 0x00, 0x00, 0x8d, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x9a, >+ 0xb0, 0x01, 0x04, 0x00, 0x00, 0x8c, 0xa0, 0x00, 0x09, 0x00, 0x00, 0x9a, >+ 0xb0, 0x01, 0x04, 0x00, 0x00, 0x8c, 0xa0, 0x00, 0x09, 0x4c, 0x4d, 0x54, >+ 0x00, 0x41, 0x45, 0x44, 0x54, 0x00, 0x41, 0x45, 0x53, 0x54, 0x00, 0x00, >+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x41, 0x45, >+ 0x53, 0x54, 0x2d, 0x31, 0x30, 0x41, 0x45, 0x44, 0x54, 0x2c, 0x4d, 0x31, >+ 0x30, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x4d, 0x34, 0x2e, 0x31, 0x2e, 0x30, >+ 0x2f, 0x33, 0x0a >+}; >+unsigned int Australia_Sydney_len = 2223; >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..71fd8ee6e7434da9f93e61da2fe36f73c1ccaa60 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time.cc >@@ -0,0 +1,384 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// The implementation of the absl::Time class, which is declared in >+// //absl/time.h. >+// >+// The representation for an absl::Time is an absl::Duration offset from the >+// epoch. We use the traditional Unix epoch (1970-01-01 00:00:00 +0000) >+// for convenience, but this is not exposed in the API and could be changed. >+// >+// NOTE: To keep type verbosity to a minimum, the following variable naming >+// conventions are used throughout this file. >+// >+// cz: A cctz::time_zone >+// tz: An absl::TimeZone >+// cl: A cctz::time_zone::civil_lookup >+// al: A cctz::time_zone::absolute_lookup >+// cd: A cctz::civil_day >+// cs: A cctz::civil_second >+// bd: An absl::Time::Breakdown >+ >+#include "absl/time/time.h" >+ >+#include <cstring> >+#include <ctime> >+#include <limits> >+ >+#include "absl/time/internal/cctz/include/cctz/civil_time.h" >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+ >+namespace cctz = absl::time_internal::cctz; >+namespace absl { >+ >+namespace { >+ >+inline cctz::time_point<cctz::seconds> unix_epoch() { >+ return std::chrono::time_point_cast<cctz::seconds>( >+ std::chrono::system_clock::from_time_t(0)); >+} >+ >+// Floors d to the next unit boundary closer to negative infinity. >+inline int64_t FloorToUnit(absl::Duration d, absl::Duration unit) { >+ absl::Duration rem; >+ int64_t q = absl::IDivDuration(d, unit, &rem); >+ return (q > 0 || >+ rem >= ZeroDuration() || >+ q == std::numeric_limits<int64_t>::min()) ? q : q - 1; >+} >+ >+inline absl::Time::Breakdown InfiniteFutureBreakdown() { >+ absl::Time::Breakdown bd; >+ bd.year = std::numeric_limits<int64_t>::max(); >+ bd.month = 12; >+ bd.day = 31; >+ bd.hour = 23; >+ bd.minute = 59; >+ bd.second = 59; >+ bd.subsecond = absl::InfiniteDuration(); >+ bd.weekday = 4; >+ bd.yearday = 365; >+ bd.offset = 0; >+ bd.is_dst = false; >+ bd.zone_abbr = "-00"; >+ return bd; >+} >+ >+inline Time::Breakdown InfinitePastBreakdown() { >+ Time::Breakdown bd; >+ bd.year = std::numeric_limits<int64_t>::min(); >+ bd.month = 1; >+ bd.day = 1; >+ bd.hour = 0; >+ bd.minute = 0; >+ bd.second = 0; >+ bd.subsecond = -absl::InfiniteDuration(); >+ bd.weekday = 7; >+ bd.yearday = 1; >+ bd.offset = 0; >+ bd.is_dst = false; >+ bd.zone_abbr = "-00"; >+ return bd; >+} >+ >+inline absl::TimeConversion InfiniteFutureTimeConversion() { >+ absl::TimeConversion tc; >+ tc.pre = tc.trans = tc.post = absl::InfiniteFuture(); >+ tc.kind = absl::TimeConversion::UNIQUE; >+ tc.normalized = true; >+ return tc; >+} >+ >+inline TimeConversion InfinitePastTimeConversion() { >+ absl::TimeConversion tc; >+ tc.pre = tc.trans = tc.post = absl::InfinitePast(); >+ tc.kind = absl::TimeConversion::UNIQUE; >+ tc.normalized = true; >+ return tc; >+} >+ >+// Makes a Time from sec, overflowing to InfiniteFuture/InfinitePast as >+// necessary. If sec is min/max, then consult cs+tz to check for overlow. >+Time MakeTimeWithOverflow(const cctz::time_point<cctz::seconds>& sec, >+ const cctz::civil_second& cs, >+ const cctz::time_zone& tz, >+ bool* normalized = nullptr) { >+ const auto max = cctz::time_point<cctz::seconds>::max(); >+ const auto min = cctz::time_point<cctz::seconds>::min(); >+ if (sec == max) { >+ const auto al = tz.lookup(max); >+ if (cs > al.cs) { >+ if (normalized) *normalized = true; >+ return absl::InfiniteFuture(); >+ } >+ } >+ if (sec == min) { >+ const auto al = tz.lookup(min); >+ if (cs < al.cs) { >+ if (normalized) *normalized = true; >+ return absl::InfinitePast(); >+ } >+ } >+ const auto hi = (sec - unix_epoch()).count(); >+ return time_internal::FromUnixDuration(time_internal::MakeDuration(hi)); >+} >+ >+inline absl::TimeConversion::Kind MapKind( >+ const cctz::time_zone::civil_lookup::civil_kind& kind) { >+ switch (kind) { >+ case cctz::time_zone::civil_lookup::UNIQUE: >+ return absl::TimeConversion::UNIQUE; >+ case cctz::time_zone::civil_lookup::SKIPPED: >+ return absl::TimeConversion::SKIPPED; >+ case cctz::time_zone::civil_lookup::REPEATED: >+ return absl::TimeConversion::REPEATED; >+ } >+ return absl::TimeConversion::UNIQUE; >+} >+ >+// Returns Mon=1..Sun=7. >+inline int MapWeekday(const cctz::weekday& wd) { >+ switch (wd) { >+ case cctz::weekday::monday: >+ return 1; >+ case cctz::weekday::tuesday: >+ return 2; >+ case cctz::weekday::wednesday: >+ return 3; >+ case cctz::weekday::thursday: >+ return 4; >+ case cctz::weekday::friday: >+ return 5; >+ case cctz::weekday::saturday: >+ return 6; >+ case cctz::weekday::sunday: >+ return 7; >+ } >+ return 1; >+} >+ >+} // namespace >+ >+absl::Time::Breakdown Time::In(absl::TimeZone tz) const { >+ if (*this == absl::InfiniteFuture()) return absl::InfiniteFutureBreakdown(); >+ if (*this == absl::InfinitePast()) return absl::InfinitePastBreakdown(); >+ >+ const auto tp = unix_epoch() + cctz::seconds(time_internal::GetRepHi(rep_)); >+ const auto al = cctz::time_zone(tz).lookup(tp); >+ const auto cs = al.cs; >+ const auto cd = cctz::civil_day(cs); >+ >+ absl::Time::Breakdown bd; >+ bd.year = cs.year(); >+ bd.month = cs.month(); >+ bd.day = cs.day(); >+ bd.hour = cs.hour(); >+ bd.minute = cs.minute(); >+ bd.second = cs.second(); >+ bd.subsecond = time_internal::MakeDuration(0, time_internal::GetRepLo(rep_)); >+ bd.weekday = MapWeekday(get_weekday(cd)); >+ bd.yearday = get_yearday(cd); >+ bd.offset = al.offset; >+ bd.is_dst = al.is_dst; >+ bd.zone_abbr = al.abbr; >+ return bd; >+} >+ >+absl::Time FromTM(const struct tm& tm, absl::TimeZone tz) { >+ const auto cz = cctz::time_zone(tz); >+ const auto cs = >+ cctz::civil_second(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, >+ tm.tm_hour, tm.tm_min, tm.tm_sec); >+ const auto cl = cz.lookup(cs); >+ const auto tp = tm.tm_isdst == 0 ? cl.post : cl.pre; >+ return MakeTimeWithOverflow(tp, cs, cz); >+} >+ >+struct tm ToTM(absl::Time t, absl::TimeZone tz) { >+ const absl::Time::Breakdown bd = t.In(tz); >+ struct tm tm; >+ std::memset(&tm, 0, sizeof(tm)); >+ tm.tm_sec = bd.second; >+ tm.tm_min = bd.minute; >+ tm.tm_hour = bd.hour; >+ tm.tm_mday = bd.day; >+ tm.tm_mon = bd.month - 1; >+ >+ // Saturates tm.tm_year in cases of over/underflow, accounting for the fact >+ // that tm.tm_year is years since 1900. >+ if (bd.year < std::numeric_limits<int>::min() + 1900) { >+ tm.tm_year = std::numeric_limits<int>::min(); >+ } else if (bd.year > std::numeric_limits<int>::max()) { >+ tm.tm_year = std::numeric_limits<int>::max() - 1900; >+ } else { >+ tm.tm_year = static_cast<int>(bd.year - 1900); >+ } >+ >+ tm.tm_wday = bd.weekday % 7; >+ tm.tm_yday = bd.yearday - 1; >+ tm.tm_isdst = bd.is_dst ? 1 : 0; >+ >+ return tm; >+} >+ >+// >+// Factory functions. >+// >+ >+absl::TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, >+ int min, int sec, TimeZone tz) { >+ // Avoids years that are too extreme for civil_second to normalize. >+ if (year > 300000000000) return InfiniteFutureTimeConversion(); >+ if (year < -300000000000) return InfinitePastTimeConversion(); >+ const auto cz = cctz::time_zone(tz); >+ const auto cs = cctz::civil_second(year, mon, day, hour, min, sec); >+ absl::TimeConversion tc; >+ tc.normalized = year != cs.year() || mon != cs.month() || day != cs.day() || >+ hour != cs.hour() || min != cs.minute() || sec != cs.second(); >+ const auto cl = cz.lookup(cs); >+ // Converts the civil_lookup struct to a TimeConversion. >+ tc.pre = MakeTimeWithOverflow(cl.pre, cs, cz, &tc.normalized); >+ tc.trans = MakeTimeWithOverflow(cl.trans, cs, cz, &tc.normalized); >+ tc.post = MakeTimeWithOverflow(cl.post, cs, cz, &tc.normalized); >+ tc.kind = MapKind(cl.kind); >+ return tc; >+} >+ >+absl::Time FromDateTime(int64_t year, int mon, int day, int hour, int min, >+ int sec, TimeZone tz) { >+ if (year > 300000000000) return InfiniteFuture(); >+ if (year < -300000000000) return InfinitePast(); >+ const auto cz = cctz::time_zone(tz); >+ const auto cs = cctz::civil_second(year, mon, day, hour, min, sec); >+ const auto cl = cz.lookup(cs); >+ return MakeTimeWithOverflow(cl.pre, cs, cz); >+} >+ >+absl::Time TimeFromTimespec(timespec ts) { >+ return time_internal::FromUnixDuration(absl::DurationFromTimespec(ts)); >+} >+ >+absl::Time TimeFromTimeval(timeval tv) { >+ return time_internal::FromUnixDuration(absl::DurationFromTimeval(tv)); >+} >+ >+absl::Time FromUDate(double udate) { >+ return time_internal::FromUnixDuration(absl::Milliseconds(udate)); >+} >+ >+absl::Time FromUniversal(int64_t universal) { >+ return absl::UniversalEpoch() + 100 * absl::Nanoseconds(universal); >+} >+ >+// >+// Conversion to other time types. >+// >+ >+int64_t ToUnixNanos(Time t) { >+ if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 && >+ time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 33 == 0) { >+ return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) * >+ 1000 * 1000 * 1000) + >+ (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) / 4); >+ } >+ return FloorToUnit(time_internal::ToUnixDuration(t), absl::Nanoseconds(1)); >+} >+ >+int64_t ToUnixMicros(Time t) { >+ if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 && >+ time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 43 == 0) { >+ return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) * >+ 1000 * 1000) + >+ (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) / 4000); >+ } >+ return FloorToUnit(time_internal::ToUnixDuration(t), absl::Microseconds(1)); >+} >+ >+int64_t ToUnixMillis(Time t) { >+ if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 && >+ time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 53 == 0) { >+ return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) * 1000) + >+ (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) / >+ (4000 * 1000)); >+ } >+ return FloorToUnit(time_internal::ToUnixDuration(t), absl::Milliseconds(1)); >+} >+ >+int64_t ToUnixSeconds(Time t) { >+ return time_internal::GetRepHi(time_internal::ToUnixDuration(t)); >+} >+ >+time_t ToTimeT(Time t) { return absl::ToTimespec(t).tv_sec; } >+ >+timespec ToTimespec(Time t) { >+ timespec ts; >+ absl::Duration d = time_internal::ToUnixDuration(t); >+ if (!time_internal::IsInfiniteDuration(d)) { >+ ts.tv_sec = time_internal::GetRepHi(d); >+ if (ts.tv_sec == time_internal::GetRepHi(d)) { // no time_t narrowing >+ ts.tv_nsec = time_internal::GetRepLo(d) / 4; // floor >+ return ts; >+ } >+ } >+ if (d >= absl::ZeroDuration()) { >+ ts.tv_sec = std::numeric_limits<time_t>::max(); >+ ts.tv_nsec = 1000 * 1000 * 1000 - 1; >+ } else { >+ ts.tv_sec = std::numeric_limits<time_t>::min(); >+ ts.tv_nsec = 0; >+ } >+ return ts; >+} >+ >+timeval ToTimeval(Time t) { >+ timeval tv; >+ timespec ts = absl::ToTimespec(t); >+ tv.tv_sec = ts.tv_sec; >+ if (tv.tv_sec != ts.tv_sec) { // narrowing >+ if (ts.tv_sec < 0) { >+ tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::min(); >+ tv.tv_usec = 0; >+ } else { >+ tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::max(); >+ tv.tv_usec = 1000 * 1000 - 1; >+ } >+ return tv; >+ } >+ tv.tv_usec = static_cast<int>(ts.tv_nsec / 1000); // suseconds_t >+ return tv; >+} >+ >+double ToUDate(Time t) { >+ return absl::FDivDuration(time_internal::ToUnixDuration(t), >+ absl::Milliseconds(1)); >+} >+ >+int64_t ToUniversal(absl::Time t) { >+ return absl::FloorToUnit(t - absl::UniversalEpoch(), absl::Nanoseconds(100)); >+} >+ >+Time FromChrono(const std::chrono::system_clock::time_point& tp) { >+ return time_internal::FromUnixDuration(time_internal::FromChrono( >+ tp - std::chrono::system_clock::from_time_t(0))); >+} >+ >+std::chrono::system_clock::time_point ToChronoTime(absl::Time t) { >+ using D = std::chrono::system_clock::duration; >+ auto d = time_internal::ToUnixDuration(t); >+ if (d < ZeroDuration()) d = Floor(d, FromChrono(D{1})); >+ return std::chrono::system_clock::from_time_t(0) + >+ time_internal::ToChronoDuration<D>(d); >+} >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time.h >new file mode 100644 >index 0000000000000000000000000000000000000000..c41cb89c5eff1d4daf8ecb16c5b15639702f6462 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time.h >@@ -0,0 +1,1349 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// File: time.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines abstractions for computing with absolute points >+// in time, durations of time, and formatting and parsing time within a given >+// time zone. The following abstractions are defined: >+// >+// * `absl::Time` defines an absolute, specific instance in time >+// * `absl::Duration` defines a signed, fixed-length span of time >+// * `absl::TimeZone` defines geopolitical time zone regions (as collected >+// within the IANA Time Zone database (https://www.iana.org/time-zones)). >+// >+// Example: >+// >+// absl::TimeZone nyc; >+// >+// // LoadTimeZone may fail so it's always better to check for success. >+// if (!absl::LoadTimeZone("America/New_York", &nyc)) { >+// // handle error case >+// } >+// >+// // My flight leaves NYC on Jan 2, 2017 at 03:04:05 >+// absl::Time takeoff = absl::FromDateTime(2017, 1, 2, 3, 4, 5, nyc); >+// absl::Duration flight_duration = absl::Hours(21) + absl::Minutes(35); >+// absl::Time landing = takeoff + flight_duration; >+// >+// absl::TimeZone syd; >+// if (!absl::LoadTimeZone("Australia/Sydney", &syd)) { >+// // handle error case >+// } >+// std::string s = absl::FormatTime( >+// "My flight will land in Sydney on %Y-%m-%d at %H:%M:%S", >+// landing, syd); >+// >+#ifndef ABSL_TIME_TIME_H_ >+#define ABSL_TIME_TIME_H_ >+ >+#if !defined(_MSC_VER) >+#include <sys/time.h> >+#else >+#include <winsock2.h> >+#endif >+#include <chrono> // NOLINT(build/c++11) >+#include <cstdint> >+#include <ctime> >+#include <ostream> >+#include <string> >+#include <type_traits> >+#include <utility> >+ >+#include "absl/base/port.h" // Needed for string vs std::string >+#include "absl/strings/string_view.h" >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+ >+namespace absl { >+ >+class Duration; // Defined below >+class Time; // Defined below >+class TimeZone; // Defined below >+ >+namespace time_internal { >+int64_t IDivDuration(bool satq, Duration num, Duration den, Duration* rem); >+constexpr Time FromUnixDuration(Duration d); >+constexpr Duration ToUnixDuration(Time t); >+constexpr int64_t GetRepHi(Duration d); >+constexpr uint32_t GetRepLo(Duration d); >+constexpr Duration MakeDuration(int64_t hi, uint32_t lo); >+constexpr Duration MakeDuration(int64_t hi, int64_t lo); >+inline Duration MakePosDoubleDuration(double n); >+constexpr int64_t kTicksPerNanosecond = 4; >+constexpr int64_t kTicksPerSecond = 1000 * 1000 * 1000 * kTicksPerNanosecond; >+template <std::intmax_t N> >+constexpr Duration FromInt64(int64_t v, std::ratio<1, N>); >+constexpr Duration FromInt64(int64_t v, std::ratio<60>); >+constexpr Duration FromInt64(int64_t v, std::ratio<3600>); >+template <typename T> >+using EnableIfIntegral = typename std::enable_if< >+ std::is_integral<T>::value || std::is_enum<T>::value, int>::type; >+template <typename T> >+using EnableIfFloat = >+ typename std::enable_if<std::is_floating_point<T>::value, int>::type; >+} // namespace time_internal >+ >+// Duration >+// >+// The `absl::Duration` class represents a signed, fixed-length span of time. >+// A `Duration` is generated using a unit-specific factory function, or is >+// the result of subtracting one `absl::Time` from another. Durations behave >+// like unit-safe integers and they support all the natural integer-like >+// arithmetic operations. Arithmetic overflows and saturates at +/- infinity. >+// `Duration` should be passed by value rather than const reference. >+// >+// Factory functions `Nanoseconds()`, `Microseconds()`, `Milliseconds()`, >+// `Seconds()`, `Minutes()`, `Hours()` and `InfiniteDuration()` allow for >+// creation of constexpr `Duration` values >+// >+// Examples: >+// >+// constexpr absl::Duration ten_ns = absl::Nanoseconds(10); >+// constexpr absl::Duration min = absl::Minutes(1); >+// constexpr absl::Duration hour = absl::Hours(1); >+// absl::Duration dur = 60 * min; // dur == hour >+// absl::Duration half_sec = absl::Milliseconds(500); >+// absl::Duration quarter_sec = 0.25 * absl::Seconds(1); >+// >+// `Duration` values can be easily converted to an integral number of units >+// using the division operator. >+// >+// Example: >+// >+// constexpr absl::Duration dur = absl::Milliseconds(1500); >+// int64_t ns = dur / absl::Nanoseconds(1); // ns == 1500000000 >+// int64_t ms = dur / absl::Milliseconds(1); // ms == 1500 >+// int64_t sec = dur / absl::Seconds(1); // sec == 1 (subseconds truncated) >+// int64_t min = dur / absl::Minutes(1); // min == 0 >+// >+// See the `IDivDuration()` and `FDivDuration()` functions below for details on >+// how to access the fractional parts of the quotient. >+// >+// Alternatively, conversions can be performed using helpers such as >+// `ToInt64Microseconds()` and `ToDoubleSeconds()`. >+class Duration { >+ public: >+ // Value semantics. >+ constexpr Duration() : rep_hi_(0), rep_lo_(0) {} // zero-length duration >+ >+ // Compound assignment operators. >+ Duration& operator+=(Duration d); >+ Duration& operator-=(Duration d); >+ Duration& operator*=(int64_t r); >+ Duration& operator*=(double r); >+ Duration& operator/=(int64_t r); >+ Duration& operator/=(double r); >+ Duration& operator%=(Duration rhs); >+ >+ // Overloads that forward to either the int64_t or double overloads above. >+ template <typename T> >+ Duration& operator*=(T r) { >+ int64_t x = r; >+ return *this *= x; >+ } >+ template <typename T> >+ Duration& operator/=(T r) { >+ int64_t x = r; >+ return *this /= x; >+ } >+ Duration& operator*=(float r) { return *this *= static_cast<double>(r); } >+ Duration& operator/=(float r) { return *this /= static_cast<double>(r); } >+ >+ private: >+ friend constexpr int64_t time_internal::GetRepHi(Duration d); >+ friend constexpr uint32_t time_internal::GetRepLo(Duration d); >+ friend constexpr Duration time_internal::MakeDuration(int64_t hi, >+ uint32_t lo); >+ constexpr Duration(int64_t hi, uint32_t lo) : rep_hi_(hi), rep_lo_(lo) {} >+ int64_t rep_hi_; >+ uint32_t rep_lo_; >+}; >+ >+// Relational Operators >+constexpr bool operator<(Duration lhs, Duration rhs); >+constexpr bool operator>(Duration lhs, Duration rhs) { return rhs < lhs; } >+constexpr bool operator>=(Duration lhs, Duration rhs) { return !(lhs < rhs); } >+constexpr bool operator<=(Duration lhs, Duration rhs) { return !(rhs < lhs); } >+constexpr bool operator==(Duration lhs, Duration rhs); >+constexpr bool operator!=(Duration lhs, Duration rhs) { return !(lhs == rhs); } >+ >+// Additive Operators >+constexpr Duration operator-(Duration d); >+inline Duration operator+(Duration lhs, Duration rhs) { return lhs += rhs; } >+inline Duration operator-(Duration lhs, Duration rhs) { return lhs -= rhs; } >+ >+// Multiplicative Operators >+template <typename T> >+Duration operator*(Duration lhs, T rhs) { >+ return lhs *= rhs; >+} >+template <typename T> >+Duration operator*(T lhs, Duration rhs) { >+ return rhs *= lhs; >+} >+template <typename T> >+Duration operator/(Duration lhs, T rhs) { >+ return lhs /= rhs; >+} >+inline int64_t operator/(Duration lhs, Duration rhs) { >+ return time_internal::IDivDuration(true, lhs, rhs, >+ &lhs); // trunc towards zero >+} >+inline Duration operator%(Duration lhs, Duration rhs) { return lhs %= rhs; } >+ >+// IDivDuration() >+// >+// Divides a numerator `Duration` by a denominator `Duration`, returning the >+// quotient and remainder. The remainder always has the same sign as the >+// numerator. The returned quotient and remainder respect the identity: >+// >+// numerator = denominator * quotient + remainder >+// >+// Returned quotients are capped to the range of `int64_t`, with the difference >+// spilling into the remainder to uphold the above identity. This means that the >+// remainder returned could differ from the remainder returned by >+// `Duration::operator%` for huge quotients. >+// >+// See also the notes on `InfiniteDuration()` below regarding the behavior of >+// division involving zero and infinite durations. >+// >+// Example: >+// >+// constexpr absl::Duration a = >+// absl::Seconds(std::numeric_limits<int64_t>::max()); // big >+// constexpr absl::Duration b = absl::Nanoseconds(1); // small >+// >+// absl::Duration rem = a % b; >+// // rem == absl::ZeroDuration() >+// >+// // Here, q would overflow int64_t, so rem accounts for the difference. >+// int64_t q = absl::IDivDuration(a, b, &rem); >+// // q == std::numeric_limits<int64_t>::max(), rem == a - b * q >+inline int64_t IDivDuration(Duration num, Duration den, Duration* rem) { >+ return time_internal::IDivDuration(true, num, den, >+ rem); // trunc towards zero >+} >+ >+// FDivDuration() >+// >+// Divides a `Duration` numerator into a fractional number of units of a >+// `Duration` denominator. >+// >+// See also the notes on `InfiniteDuration()` below regarding the behavior of >+// division involving zero and infinite durations. >+// >+// Example: >+// >+// double d = absl::FDivDuration(absl::Milliseconds(1500), absl::Seconds(1)); >+// // d == 1.5 >+double FDivDuration(Duration num, Duration den); >+ >+// ZeroDuration() >+// >+// Returns a zero-length duration. This function behaves just like the default >+// constructor, but the name helps make the semantics clear at call sites. >+constexpr Duration ZeroDuration() { return Duration(); } >+ >+// AbsDuration() >+// >+// Returns the absolute value of a duration. >+inline Duration AbsDuration(Duration d) { >+ return (d < ZeroDuration()) ? -d : d; >+} >+ >+// Trunc() >+// >+// Truncates a duration (toward zero) to a multiple of a non-zero unit. >+// >+// Example: >+// >+// absl::Duration d = absl::Nanoseconds(123456789); >+// absl::Duration a = absl::Trunc(d, absl::Microseconds(1)); // 123456us >+Duration Trunc(Duration d, Duration unit); >+ >+// Floor() >+// >+// Floors a duration using the passed duration unit to its largest value not >+// greater than the duration. >+// >+// Example: >+// >+// absl::Duration d = absl::Nanoseconds(123456789); >+// absl::Duration b = absl::Floor(d, absl::Microseconds(1)); // 123456us >+Duration Floor(Duration d, Duration unit); >+ >+// Ceil() >+// >+// Returns the ceiling of a duration using the passed duration unit to its >+// smallest value not less than the duration. >+// >+// Example: >+// >+// absl::Duration d = absl::Nanoseconds(123456789); >+// absl::Duration c = absl::Ceil(d, absl::Microseconds(1)); // 123457us >+Duration Ceil(Duration d, Duration unit); >+ >+// InfiniteDuration() >+// >+// Returns an infinite `Duration`. To get a `Duration` representing negative >+// infinity, use `-InfiniteDuration()`. >+// >+// Duration arithmetic overflows to +/- infinity and saturates. In general, >+// arithmetic with `Duration` infinities is similar to IEEE 754 infinities >+// except where IEEE 754 NaN would be involved, in which case +/- >+// `InfiniteDuration()` is used in place of a "nan" Duration. >+// >+// Examples: >+// >+// constexpr absl::Duration inf = absl::InfiniteDuration(); >+// const absl::Duration d = ... any finite duration ... >+// >+// inf == inf + inf >+// inf == inf + d >+// inf == inf - inf >+// -inf == d - inf >+// >+// inf == d * 1e100 >+// inf == inf / 2 >+// 0 == d / inf >+// INT64_MAX == inf / d >+// >+// // Division by zero returns infinity, or INT64_MIN/MAX where appropriate. >+// inf == d / 0 >+// INT64_MAX == d / absl::ZeroDuration() >+// >+// The examples involving the `/` operator above also apply to `IDivDuration()` >+// and `FDivDuration()`. >+constexpr Duration InfiniteDuration(); >+ >+// Nanoseconds() >+// Microseconds() >+// Milliseconds() >+// Seconds() >+// Minutes() >+// Hours() >+// >+// Factory functions for constructing `Duration` values from an integral number >+// of the unit indicated by the factory function's name. >+// >+// Note: no "Days()" factory function exists because "a day" is ambiguous. Civil >+// days are not always 24 hours long, and a 24-hour duration often does not >+// correspond with a civil day. If a 24-hour duration is needed, use >+// `absl::Hours(24)`. >+// >+// >+// Example: >+// >+// absl::Duration a = absl::Seconds(60); >+// absl::Duration b = absl::Minutes(1); // b == a >+constexpr Duration Nanoseconds(int64_t n); >+constexpr Duration Microseconds(int64_t n); >+constexpr Duration Milliseconds(int64_t n); >+constexpr Duration Seconds(int64_t n); >+constexpr Duration Minutes(int64_t n); >+constexpr Duration Hours(int64_t n); >+ >+// Factory overloads for constructing `Duration` values from a floating-point >+// number of the unit indicated by the factory function's name. These functions >+// exist for convenience, but they are not as efficient as the integral >+// factories, which should be preferred. >+// >+// Example: >+// auto a = absl::Seconds(1.5); // OK >+// auto b = absl::Milliseconds(1500); // BETTER >+template <typename T, time_internal::EnableIfFloat<T> = 0> >+Duration Nanoseconds(T n) { >+ return n * Nanoseconds(1); >+} >+template <typename T, time_internal::EnableIfFloat<T> = 0> >+Duration Microseconds(T n) { >+ return n * Microseconds(1); >+} >+template <typename T, time_internal::EnableIfFloat<T> = 0> >+Duration Milliseconds(T n) { >+ return n * Milliseconds(1); >+} >+template <typename T, time_internal::EnableIfFloat<T> = 0> >+Duration Seconds(T n) { >+ if (n >= 0) { >+ if (n >= std::numeric_limits<int64_t>::max()) return InfiniteDuration(); >+ return time_internal::MakePosDoubleDuration(n); >+ } else { >+ if (n <= std::numeric_limits<int64_t>::min()) return -InfiniteDuration(); >+ return -time_internal::MakePosDoubleDuration(-n); >+ } >+} >+template <typename T, time_internal::EnableIfFloat<T> = 0> >+Duration Minutes(T n) { >+ return n * Minutes(1); >+} >+template <typename T, time_internal::EnableIfFloat<T> = 0> >+Duration Hours(T n) { >+ return n * Hours(1); >+} >+ >+// ToInt64Nanoseconds() >+// ToInt64Microseconds() >+// ToInt64Milliseconds() >+// ToInt64Seconds() >+// ToInt64Minutes() >+// ToInt64Hours() >+// >+// Helper functions that convert a Duration to an integral count of the >+// indicated unit. These functions are shorthand for the `IDivDuration()` >+// function above; see its documentation for details about overflow, etc. >+// >+// Example: >+// >+// absl::Duration d = absl::Milliseconds(1500); >+// int64_t isec = absl::ToInt64Seconds(d); // isec == 1 >+int64_t ToInt64Nanoseconds(Duration d); >+int64_t ToInt64Microseconds(Duration d); >+int64_t ToInt64Milliseconds(Duration d); >+int64_t ToInt64Seconds(Duration d); >+int64_t ToInt64Minutes(Duration d); >+int64_t ToInt64Hours(Duration d); >+ >+// ToDoubleNanoSeconds() >+// ToDoubleMicroseconds() >+// ToDoubleMilliseconds() >+// ToDoubleSeconds() >+// ToDoubleMinutes() >+// ToDoubleHours() >+// >+// Helper functions that convert a Duration to a floating point count of the >+// indicated unit. These functions are shorthand for the `FDivDuration()` >+// function above; see its documentation for details about overflow, etc. >+// >+// Example: >+// >+// absl::Duration d = absl::Milliseconds(1500); >+// double dsec = absl::ToDoubleSeconds(d); // dsec == 1.5 >+double ToDoubleNanoseconds(Duration d); >+double ToDoubleMicroseconds(Duration d); >+double ToDoubleMilliseconds(Duration d); >+double ToDoubleSeconds(Duration d); >+double ToDoubleMinutes(Duration d); >+double ToDoubleHours(Duration d); >+ >+// FromChrono() >+// >+// Converts any of the pre-defined std::chrono durations to an absl::Duration. >+// >+// Example: >+// >+// std::chrono::milliseconds ms(123); >+// absl::Duration d = absl::FromChrono(ms); >+constexpr Duration FromChrono(const std::chrono::nanoseconds& d); >+constexpr Duration FromChrono(const std::chrono::microseconds& d); >+constexpr Duration FromChrono(const std::chrono::milliseconds& d); >+constexpr Duration FromChrono(const std::chrono::seconds& d); >+constexpr Duration FromChrono(const std::chrono::minutes& d); >+constexpr Duration FromChrono(const std::chrono::hours& d); >+ >+// ToChronoNanoseconds() >+// ToChronoMicroseconds() >+// ToChronoMilliseconds() >+// ToChronoSeconds() >+// ToChronoMinutes() >+// ToChronoHours() >+// >+// Converts an absl::Duration to any of the pre-defined std::chrono durations. >+// If overflow would occur, the returned value will saturate at the min/max >+// chrono duration value instead. >+// >+// Example: >+// >+// absl::Duration d = absl::Microseconds(123); >+// auto x = absl::ToChronoMicroseconds(d); >+// auto y = absl::ToChronoNanoseconds(d); // x == y >+// auto z = absl::ToChronoSeconds(absl::InfiniteDuration()); >+// // z == std::chrono::seconds::max() >+std::chrono::nanoseconds ToChronoNanoseconds(Duration d); >+std::chrono::microseconds ToChronoMicroseconds(Duration d); >+std::chrono::milliseconds ToChronoMilliseconds(Duration d); >+std::chrono::seconds ToChronoSeconds(Duration d); >+std::chrono::minutes ToChronoMinutes(Duration d); >+std::chrono::hours ToChronoHours(Duration d); >+ >+// FormatDuration() >+// >+// Returns a std::string representing the duration in the form "72h3m0.5s". >+// Returns "inf" or "-inf" for +/- `InfiniteDuration()`. >+std::string FormatDuration(Duration d); >+ >+// Output stream operator. >+inline std::ostream& operator<<(std::ostream& os, Duration d) { >+ return os << FormatDuration(d); >+} >+ >+// ParseDuration() >+// >+// Parses a duration std::string consisting of a possibly signed sequence of >+// decimal numbers, each with an optional fractional part and a unit >+// suffix. The valid suffixes are "ns", "us" "ms", "s", "m", and "h". >+// Simple examples include "300ms", "-1.5h", and "2h45m". Parses "0" as >+// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`. >+bool ParseDuration(const std::string& dur_string, Duration* d); >+ >+// Support for flag values of type Duration. Duration flags must be specified >+// in a format that is valid input for absl::ParseDuration(). >+bool ParseFlag(const std::string& text, Duration* dst, std::string* error); >+std::string UnparseFlag(Duration d); >+ >+// Time >+// >+// An `absl::Time` represents a specific instant in time. Arithmetic operators >+// are provided for naturally expressing time calculations. Instances are >+// created using `absl::Now()` and the `absl::From*()` factory functions that >+// accept the gamut of other time representations. Formatting and parsing >+// functions are provided for conversion to and from strings. `absl::Time` >+// should be passed by value rather than const reference. >+// >+// `absl::Time` assumes there are 60 seconds in a minute, which means the >+// underlying time scales must be "smeared" to eliminate leap seconds. >+// See https://developers.google.com/time/smear. >+// >+// Even though `absl::Time` supports a wide range of timestamps, exercise >+// caution when using values in the distant past. `absl::Time` uses the >+// Proleptic Gregorian calendar, which extends the Gregorian calendar backward >+// to dates before its introduction in 1582. >+// See https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar >+// for more information. Use the ICU calendar classes to convert a date in >+// some other calendar (http://userguide.icu-project.org/datetime/calendar). >+// >+// Similarly, standardized time zones are a reasonably recent innovation, with >+// the Greenwich prime meridian being established in 1884. The TZ database >+// itself does not profess accurate offsets for timestamps prior to 1970. The >+// breakdown of future timestamps is subject to the whim of regional >+// governments. >+// >+// The `absl::Time` class represents an instant in time as a count of clock >+// ticks of some granularity (resolution) from some starting point (epoch). >+// >+// >+// `absl::Time` uses a resolution that is high enough to avoid loss in >+// precision, and a range that is wide enough to avoid overflow, when >+// converting between tick counts in most Google time scales (i.e., precision >+// of at least one nanosecond, and range +/-100 billion years). Conversions >+// between the time scales are performed by truncating (towards negative >+// infinity) to the nearest representable point. >+// >+// Examples: >+// >+// absl::Time t1 = ...; >+// absl::Time t2 = t1 + absl::Minutes(2); >+// absl::Duration d = t2 - t1; // == absl::Minutes(2) >+// absl::Time::Breakdown bd = t1.In(absl::LocalTimeZone()); >+// >+class Time { >+ public: >+ // Value semantics. >+ >+ // Returns the Unix epoch. However, those reading your code may not know >+ // or expect the Unix epoch as the default value, so make your code more >+ // readable by explicitly initializing all instances before use. >+ // >+ // Example: >+ // absl::Time t = absl::UnixEpoch(); >+ // absl::Time t = absl::Now(); >+ // absl::Time t = absl::TimeFromTimeval(tv); >+ // absl::Time t = absl::InfinitePast(); >+ constexpr Time() {} >+ >+ // Assignment operators. >+ Time& operator+=(Duration d) { >+ rep_ += d; >+ return *this; >+ } >+ Time& operator-=(Duration d) { >+ rep_ -= d; >+ return *this; >+ } >+ >+ // Time::Breakdown >+ // >+ // The calendar and wall-clock (aka "civil time") components of an >+ // `absl::Time` in a certain `absl::TimeZone`. This struct is not >+ // intended to represent an instant in time. So, rather than passing >+ // a `Time::Breakdown` to a function, pass an `absl::Time` and an >+ // `absl::TimeZone`. >+ struct Breakdown { >+ int64_t year; // year (e.g., 2013) >+ int month; // month of year [1:12] >+ int day; // day of month [1:31] >+ int hour; // hour of day [0:23] >+ int minute; // minute of hour [0:59] >+ int second; // second of minute [0:59] >+ Duration subsecond; // [Seconds(0):Seconds(1)) if finite >+ int weekday; // 1==Mon, ..., 7=Sun >+ int yearday; // day of year [1:366] >+ >+ // Note: The following fields exist for backward compatibility >+ // with older APIs. Accessing these fields directly is a sign of >+ // imprudent logic in the calling code. Modern time-related code >+ // should only access this data indirectly by way of FormatTime(). >+ // These fields are undefined for InfiniteFuture() and InfinitePast(). >+ int offset; // seconds east of UTC >+ bool is_dst; // is offset non-standard? >+ const char* zone_abbr; // time-zone abbreviation (e.g., "PST") >+ }; >+ >+ // Time::In() >+ // >+ // Returns the breakdown of this instant in the given TimeZone. >+ Breakdown In(TimeZone tz) const; >+ >+ private: >+ friend constexpr Time time_internal::FromUnixDuration(Duration d); >+ friend constexpr Duration time_internal::ToUnixDuration(Time t); >+ friend constexpr bool operator<(Time lhs, Time rhs); >+ friend constexpr bool operator==(Time lhs, Time rhs); >+ friend Duration operator-(Time lhs, Time rhs); >+ friend constexpr Time UniversalEpoch(); >+ friend constexpr Time InfiniteFuture(); >+ friend constexpr Time InfinitePast(); >+ constexpr explicit Time(Duration rep) : rep_(rep) {} >+ Duration rep_; >+}; >+ >+// Relational Operators >+constexpr bool operator<(Time lhs, Time rhs) { return lhs.rep_ < rhs.rep_; } >+constexpr bool operator>(Time lhs, Time rhs) { return rhs < lhs; } >+constexpr bool operator>=(Time lhs, Time rhs) { return !(lhs < rhs); } >+constexpr bool operator<=(Time lhs, Time rhs) { return !(rhs < lhs); } >+constexpr bool operator==(Time lhs, Time rhs) { return lhs.rep_ == rhs.rep_; } >+constexpr bool operator!=(Time lhs, Time rhs) { return !(lhs == rhs); } >+ >+// Additive Operators >+inline Time operator+(Time lhs, Duration rhs) { return lhs += rhs; } >+inline Time operator+(Duration lhs, Time rhs) { return rhs += lhs; } >+inline Time operator-(Time lhs, Duration rhs) { return lhs -= rhs; } >+inline Duration operator-(Time lhs, Time rhs) { return lhs.rep_ - rhs.rep_; } >+ >+// UnixEpoch() >+// >+// Returns the `absl::Time` representing "1970-01-01 00:00:00.0 +0000". >+constexpr Time UnixEpoch() { return Time(); } >+ >+// UniversalEpoch() >+// >+// Returns the `absl::Time` representing "0001-01-01 00:00:00.0 +0000", the >+// epoch of the ICU Universal Time Scale. >+constexpr Time UniversalEpoch() { >+ // 719162 is the number of days from 0001-01-01 to 1970-01-01, >+ // assuming the Gregorian calendar. >+ return Time(time_internal::MakeDuration(-24 * 719162 * int64_t{3600}, 0U)); >+} >+ >+// InfiniteFuture() >+// >+// Returns an `absl::Time` that is infinitely far in the future. >+constexpr Time InfiniteFuture() { >+ return Time( >+ time_internal::MakeDuration(std::numeric_limits<int64_t>::max(), ~0U)); >+} >+ >+// InfinitePast() >+// >+// Returns an `absl::Time` that is infinitely far in the past. >+constexpr Time InfinitePast() { >+ return Time( >+ time_internal::MakeDuration(std::numeric_limits<int64_t>::min(), ~0U)); >+} >+ >+// TimeConversion >+// >+// An `absl::TimeConversion` represents the conversion of year, month, day, >+// hour, minute, and second values (i.e., a civil time), in a particular >+// `absl::TimeZone`, to a time instant (an absolute time), as returned by >+// `absl::ConvertDateTime()`. (Subseconds must be handled separately.) >+// >+// It is possible, though, for a caller to try to convert values that >+// do not represent an actual or unique instant in time (due to a shift >+// in UTC offset in the `absl::TimeZone`, which results in a discontinuity in >+// the civil-time components). For example, a daylight-saving-time >+// transition skips or repeats civil times---in the United States, March >+// 13, 2011 02:15 never occurred, while November 6, 2011 01:15 occurred >+// twice---so requests for such times are not well-defined. >+// >+// To account for these possibilities, `absl::TimeConversion` is richer >+// than just a single `absl::Time`. When the civil time is skipped or >+// repeated, `absl::ConvertDateTime()` returns times calculated using the >+// pre-transition and post-transition UTC offsets, plus the transition >+// time itself. >+// >+// Examples: >+// >+// absl::TimeZone lax; >+// if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) { ... } >+// >+// // A unique civil time >+// absl::TimeConversion jan01 = >+// absl::ConvertDateTime(2011, 1, 1, 0, 0, 0, lax); >+// // jan01.kind == TimeConversion::UNIQUE >+// // jan01.pre is 2011/01/01 00:00:00 -0800 >+// // jan01.trans is 2011/01/01 00:00:00 -0800 >+// // jan01.post is 2011/01/01 00:00:00 -0800 >+// >+// // A Spring DST transition, when there is a gap in civil time >+// absl::TimeConversion mar13 = >+// absl::ConvertDateTime(2011, 3, 13, 2, 15, 0, lax); >+// // mar13.kind == TimeConversion::SKIPPED >+// // mar13.pre is 2011/03/13 03:15:00 -0700 >+// // mar13.trans is 2011/03/13 03:00:00 -0700 >+// // mar13.post is 2011/03/13 01:15:00 -0800 >+// >+// // A Fall DST transition, when civil times are repeated >+// absl::TimeConversion nov06 = >+// absl::ConvertDateTime(2011, 11, 6, 1, 15, 0, lax); >+// // nov06.kind == TimeConversion::REPEATED >+// // nov06.pre is 2011/11/06 01:15:00 -0700 >+// // nov06.trans is 2011/11/06 01:00:00 -0800 >+// // nov06.post is 2011/11/06 01:15:00 -0800 >+// >+// The input month, day, hour, minute, and second values can also be >+// outside of their valid ranges, in which case they will be "normalized" >+// during the conversion. >+// >+// Example: >+// >+// // "October 32" normalizes to "November 1". >+// absl::TimeZone tz = absl::LocalTimeZone(); >+// absl::TimeConversion tc = >+// absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, tz); >+// // tc.kind == TimeConversion::UNIQUE && tc.normalized == true >+// // tc.pre.In(tz).month == 11 && tc.pre.In(tz).day == 1 >+struct TimeConversion { >+ Time pre; // time calculated using the pre-transition offset >+ Time trans; // when the civil-time discontinuity occurred >+ Time post; // time calculated using the post-transition offset >+ >+ enum Kind { >+ UNIQUE, // the civil time was singular (pre == trans == post) >+ SKIPPED, // the civil time did not exist >+ REPEATED, // the civil time was ambiguous >+ }; >+ Kind kind; >+ >+ bool normalized; // input values were outside their valid ranges >+}; >+ >+// ConvertDateTime() >+// >+// The full generality of a civil time to absl::Time conversion. >+TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, >+ int min, int sec, TimeZone tz); >+ >+// FromDateTime() >+// >+// A convenience wrapper for `absl::ConvertDateTime()` that simply returns the >+// "pre" `absl::Time`. That is, the unique result, or the instant that >+// is correct using the pre-transition offset (as if the transition >+// never happened). This is typically the answer that humans expected when >+// faced with non-unique times, such as near daylight-saving time transitions. >+// >+// Example: >+// >+// absl::TimeZone seattle; >+// if (!absl::LoadTimeZone("America/Los_Angeles", &seattle)) { ... } >+// absl::Time t = absl::FromDateTime(2017, 9, 26, 9, 30, 0, seattle); >+Time FromDateTime(int64_t year, int mon, int day, int hour, int min, int sec, >+ TimeZone tz); >+ >+// FromTM() >+// >+// Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and >+// `tm_sec` fields to an `absl::Time` using the given time zone. See ctime(3) >+// for a description of the expected values of the tm fields. IFF the indicated >+// time instant is not unique (see `absl::ConvertDateTime()` above), the >+// `tm_isdst` field is consulted to select the desired instant (`tm_isdst` > 0 >+// means DST, `tm_isdst` == 0 means no DST, `tm_isdst` < 0 means use the default >+// like `absl::FromDateTime()`). >+Time FromTM(const struct tm& tm, TimeZone tz); >+ >+// ToTM() >+// >+// Converts the given `absl::Time` to a struct tm using the given time zone. >+// See ctime(3) for a description of the values of the tm fields. >+struct tm ToTM(Time t, TimeZone tz); >+ >+// FromUnixNanos() >+// FromUnixMicros() >+// FromUnixMillis() >+// FromUnixSeconds() >+// FromTimeT() >+// FromUDate() >+// FromUniversal() >+// >+// Creates an `absl::Time` from a variety of other representations. >+constexpr Time FromUnixNanos(int64_t ns); >+constexpr Time FromUnixMicros(int64_t us); >+constexpr Time FromUnixMillis(int64_t ms); >+constexpr Time FromUnixSeconds(int64_t s); >+constexpr Time FromTimeT(time_t t); >+Time FromUDate(double udate); >+Time FromUniversal(int64_t universal); >+ >+// ToUnixNanos() >+// ToUnixMicros() >+// ToUnixMillis() >+// ToUnixSeconds() >+// ToTimeT() >+// ToUDate() >+// ToUniversal() >+// >+// Converts an `absl::Time` to a variety of other representations. Note that >+// these operations round down toward negative infinity where necessary to >+// adjust to the resolution of the result type. Beware of possible time_t >+// over/underflow in ToTime{T,val,spec}() on 32-bit platforms. >+int64_t ToUnixNanos(Time t); >+int64_t ToUnixMicros(Time t); >+int64_t ToUnixMillis(Time t); >+int64_t ToUnixSeconds(Time t); >+time_t ToTimeT(Time t); >+double ToUDate(Time t); >+int64_t ToUniversal(Time t); >+ >+// DurationFromTimespec() >+// DurationFromTimeval() >+// ToTimespec() >+// ToTimeval() >+// TimeFromTimespec() >+// TimeFromTimeval() >+// ToTimespec() >+// ToTimeval() >+// >+// Some APIs use a timespec or a timeval as a Duration (e.g., nanosleep(2) >+// and select(2)), while others use them as a Time (e.g. clock_gettime(2) >+// and gettimeofday(2)), so conversion functions are provided for both cases. >+// The "to timespec/val" direction is easily handled via overloading, but >+// for "from timespec/val" the desired type is part of the function name. >+Duration DurationFromTimespec(timespec ts); >+Duration DurationFromTimeval(timeval tv); >+timespec ToTimespec(Duration d); >+timeval ToTimeval(Duration d); >+Time TimeFromTimespec(timespec ts); >+Time TimeFromTimeval(timeval tv); >+timespec ToTimespec(Time t); >+timeval ToTimeval(Time t); >+ >+// FromChrono() >+// >+// Converts a std::chrono::system_clock::time_point to an absl::Time. >+// >+// Example: >+// >+// auto tp = std::chrono::system_clock::from_time_t(123); >+// absl::Time t = absl::FromChrono(tp); >+// // t == absl::FromTimeT(123) >+Time FromChrono(const std::chrono::system_clock::time_point& tp); >+ >+// ToChronoTime() >+// >+// Converts an absl::Time to a std::chrono::system_clock::time_point. If >+// overflow would occur, the returned value will saturate at the min/max time >+// point value instead. >+// >+// Example: >+// >+// absl::Time t = absl::FromTimeT(123); >+// auto tp = absl::ToChronoTime(t); >+// // tp == std::chrono::system_clock::from_time_t(123); >+std::chrono::system_clock::time_point ToChronoTime(Time); >+ >+// RFC3339_full >+// RFC3339_sec >+// >+// FormatTime()/ParseTime() format specifiers for RFC3339 date/time strings, >+// with trailing zeros trimmed or with fractional seconds omitted altogether. >+// >+// Note that RFC3339_sec[] matches an ISO 8601 extended format for date >+// and time with UTC offset. >+extern const char RFC3339_full[]; // %Y-%m-%dT%H:%M:%E*S%Ez >+extern const char RFC3339_sec[]; // %Y-%m-%dT%H:%M:%S%Ez >+ >+// RFC1123_full >+// RFC1123_no_wday >+// >+// FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings. >+extern const char RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z >+extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z >+ >+// FormatTime() >+// >+// Formats the given `absl::Time` in the `absl::TimeZone` according to the >+// provided format std::string. Uses strftime()-like formatting options, with >+// the following extensions: >+// >+// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) >+// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss) >+// - %E#S - Seconds with # digits of fractional precision >+// - %E*S - Seconds with full fractional precision (a literal '*') >+// - %E#f - Fractional seconds with # digits of precision >+// - %E*f - Fractional seconds with full precision (a literal '*') >+// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) >+// >+// Note that %E0S behaves like %S, and %E0f produces no characters. In >+// contrast %E*f always produces at least one digit, which may be '0'. >+// >+// Note that %Y produces as many characters as it takes to fully render the >+// year. A year outside of [-999:9999] when formatted with %E4Y will produce >+// more than four characters, just like %Y. >+// >+// We recommend that format strings include the UTC offset (%z, %Ez, or %E*z) >+// so that the result uniquely identifies a time instant. >+// >+// Example: >+// >+// absl::TimeZone lax; >+// if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) { ... } >+// absl::Time t = absl::FromDateTime(2013, 1, 2, 3, 4, 5, lax); >+// >+// std::string f = absl::FormatTime("%H:%M:%S", t, lax); // "03:04:05" >+// f = absl::FormatTime("%H:%M:%E3S", t, lax); // "03:04:05.000" >+// >+// Note: If the given `absl::Time` is `absl::InfiniteFuture()`, the returned >+// std::string will be exactly "infinite-future". If the given `absl::Time` is >+// `absl::InfinitePast()`, the returned std::string will be exactly "infinite-past". >+// In both cases the given format std::string and `absl::TimeZone` are ignored. >+// >+std::string FormatTime(const std::string& format, Time t, TimeZone tz); >+ >+// Convenience functions that format the given time using the RFC3339_full >+// format. The first overload uses the provided TimeZone, while the second >+// uses LocalTimeZone(). >+std::string FormatTime(Time t, TimeZone tz); >+std::string FormatTime(Time t); >+ >+// Output stream operator. >+inline std::ostream& operator<<(std::ostream& os, Time t) { >+ return os << FormatTime(t); >+} >+ >+// ParseTime() >+// >+// Parses an input std::string according to the provided format std::string and >+// returns the corresponding `absl::Time`. Uses strftime()-like formatting >+// options, with the same extensions as FormatTime(), but with the >+// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez >+// and %E*z also accept the same inputs. >+// >+// %Y consumes as many numeric characters as it can, so the matching data >+// should always be terminated with a non-numeric. %E4Y always consumes >+// exactly four characters, including any sign. >+// >+// Unspecified fields are taken from the default date and time of ... >+// >+// "1970-01-01 00:00:00.0 +0000" >+// >+// For example, parsing a std::string of "15:45" (%H:%M) will return an absl::Time >+// that represents "1970-01-01 15:45:00.0 +0000". >+// >+// Note that since ParseTime() returns time instants, it makes the most sense >+// to parse fully-specified date/time strings that include a UTC offset (%z, >+// %Ez, or %E*z). >+// >+// Note also that `absl::ParseTime()` only heeds the fields year, month, day, >+// hour, minute, (fractional) second, and UTC offset. Other fields, like >+// weekday (%a or %A), while parsed for syntactic validity, are ignored >+// in the conversion. >+// >+// Date and time fields that are out-of-range will be treated as errors >+// rather than normalizing them like `absl::FromDateTime()` does. For example, >+// it is an error to parse the date "Oct 32, 2013" because 32 is out of range. >+// >+// A leap second of ":60" is normalized to ":00" of the following minute >+// with fractional seconds discarded. The following table shows how the >+// given seconds and subseconds will be parsed: >+// >+// "59.x" -> 59.x // exact >+// "60.x" -> 00.0 // normalized >+// "00.x" -> 00.x // exact >+// >+// Errors are indicated by returning false and assigning an error message >+// to the "err" out param if it is non-null. >+// >+// Note: If the input std::string is exactly "infinite-future", the returned >+// `absl::Time` will be `absl::InfiniteFuture()` and `true` will be returned. >+// If the input std::string is "infinite-past", the returned `absl::Time` will be >+// `absl::InfinitePast()` and `true` will be returned. >+// >+bool ParseTime(const std::string& format, const std::string& input, Time* time, >+ std::string* err); >+ >+// Like ParseTime() above, but if the format std::string does not contain a UTC >+// offset specification (%z/%Ez/%E*z) then the input is interpreted in the >+// given TimeZone. This means that the input, by itself, does not identify a >+// unique instant. Being time-zone dependent, it also admits the possibility >+// of ambiguity or non-existence, in which case the "pre" time (as defined >+// for ConvertDateTime()) is returned. For these reasons we recommend that >+// all date/time strings include a UTC offset so they're context independent. >+bool ParseTime(const std::string& format, const std::string& input, TimeZone tz, >+ Time* time, std::string* err); >+ >+// Support for flag values of type Time. Time flags must be specified in a >+// format that matches absl::RFC3339_full. For example: >+// >+// --start_time=2016-01-02T03:04:05.678+08:00 >+// >+// Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required. >+// >+// Additionally, if you'd like to specify a time as a count of >+// seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag >+// and add that duration to absl::UnixEpoch() to get an absl::Time. >+bool ParseFlag(const std::string& text, Time* t, std::string* error); >+std::string UnparseFlag(Time t); >+ >+// TimeZone >+// >+// The `absl::TimeZone` is an opaque, small, value-type class representing a >+// geo-political region within which particular rules are used for converting >+// between absolute and civil times (see https://git.io/v59Ly). `absl::TimeZone` >+// values are named using the TZ identifiers from the IANA Time Zone Database, >+// such as "America/Los_Angeles" or "Australia/Sydney". `absl::TimeZone` values >+// are created from factory functions such as `absl::LoadTimeZone()`. Note: >+// strings like "PST" and "EDT" are not valid TZ identifiers. Prefer to pass by >+// value rather than const reference. >+// >+// For more on the fundamental concepts of time zones, absolute times, and civil >+// times, see https://github.com/google/cctz#fundamental-concepts >+// >+// Examples: >+// >+// absl::TimeZone utc = absl::UTCTimeZone(); >+// absl::TimeZone pst = absl::FixedTimeZone(-8 * 60 * 60); >+// absl::TimeZone loc = absl::LocalTimeZone(); >+// absl::TimeZone lax; >+// if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) { ... } >+// >+// See also: >+// - https://github.com/google/cctz >+// - http://www.iana.org/time-zones >+// - http://en.wikipedia.org/wiki/Zoneinfo >+class TimeZone { >+ public: >+ explicit TimeZone(time_internal::cctz::time_zone tz) : cz_(tz) {} >+ TimeZone() = default; // UTC, but prefer UTCTimeZone() to be explicit. >+ TimeZone(const TimeZone&) = default; >+ TimeZone& operator=(const TimeZone&) = default; >+ >+ explicit operator time_internal::cctz::time_zone() const { return cz_; } >+ >+ std::string name() const { return cz_.name(); } >+ >+ private: >+ friend bool operator==(TimeZone a, TimeZone b) { return a.cz_ == b.cz_; } >+ friend bool operator!=(TimeZone a, TimeZone b) { return a.cz_ != b.cz_; } >+ friend std::ostream& operator<<(std::ostream& os, TimeZone tz) { >+ return os << tz.name(); >+ } >+ >+ time_internal::cctz::time_zone cz_; >+}; >+ >+// LoadTimeZone() >+// >+// Loads the named zone. May perform I/O on the initial load of the named >+// zone. If the name is invalid, or some other kind of error occurs, returns >+// `false` and `*tz` is set to the UTC time zone. >+inline bool LoadTimeZone(const std::string& name, TimeZone* tz) { >+ if (name == "localtime") { >+ *tz = TimeZone(time_internal::cctz::local_time_zone()); >+ return true; >+ } >+ time_internal::cctz::time_zone cz; >+ const bool b = time_internal::cctz::load_time_zone(name, &cz); >+ *tz = TimeZone(cz); >+ return b; >+} >+ >+// FixedTimeZone() >+// >+// Returns a TimeZone that is a fixed offset (seconds east) from UTC. >+// Note: If the absolute value of the offset is greater than 24 hours >+// you'll get UTC (i.e., no offset) instead. >+inline TimeZone FixedTimeZone(int seconds) { >+ return TimeZone( >+ time_internal::cctz::fixed_time_zone(std::chrono::seconds(seconds))); >+} >+ >+// UTCTimeZone() >+// >+// Convenience method returning the UTC time zone. >+inline TimeZone UTCTimeZone() { >+ return TimeZone(time_internal::cctz::utc_time_zone()); >+} >+ >+// LocalTimeZone() >+// >+// Convenience method returning the local time zone, or UTC if there is >+// no configured local zone. Warning: Be wary of using LocalTimeZone(), >+// and particularly so in a server process, as the zone configured for the >+// local machine should be irrelevant. Prefer an explicit zone name. >+inline TimeZone LocalTimeZone() { >+ return TimeZone(time_internal::cctz::local_time_zone()); >+} >+ >+// ============================================================================ >+// Implementation Details Follow >+// ============================================================================ >+ >+namespace time_internal { >+ >+// Creates a Duration with a given representation. >+// REQUIRES: hi,lo is a valid representation of a Duration as specified >+// in time/duration.cc. >+constexpr Duration MakeDuration(int64_t hi, uint32_t lo = 0) { >+ return Duration(hi, lo); >+} >+ >+constexpr Duration MakeDuration(int64_t hi, int64_t lo) { >+ return MakeDuration(hi, static_cast<uint32_t>(lo)); >+} >+ >+// Make a Duration value from a floating-point number, as long as that number >+// is in the range [ 0 .. numeric_limits<int64_t>::max ), that is, as long as >+// it's positive and can be converted to int64_t without risk of UB. >+inline Duration MakePosDoubleDuration(double n) { >+ const int64_t int_secs = static_cast<int64_t>(n); >+ const uint32_t ticks = >+ static_cast<uint32_t>((n - int_secs) * kTicksPerSecond + 0.5); >+ return ticks < kTicksPerSecond >+ ? MakeDuration(int_secs, ticks) >+ : MakeDuration(int_secs + 1, ticks - kTicksPerSecond); >+} >+ >+// Creates a normalized Duration from an almost-normalized (sec,ticks) >+// pair. sec may be positive or negative. ticks must be in the range >+// -kTicksPerSecond < *ticks < kTicksPerSecond. If ticks is negative it >+// will be normalized to a positive value in the resulting Duration. >+constexpr Duration MakeNormalizedDuration(int64_t sec, int64_t ticks) { >+ return (ticks < 0) ? MakeDuration(sec - 1, ticks + kTicksPerSecond) >+ : MakeDuration(sec, ticks); >+} >+// Provide access to the Duration representation. >+constexpr int64_t GetRepHi(Duration d) { return d.rep_hi_; } >+constexpr uint32_t GetRepLo(Duration d) { return d.rep_lo_; } >+constexpr bool IsInfiniteDuration(Duration d) { return GetRepLo(d) == ~0U; } >+ >+// Returns an infinite Duration with the opposite sign. >+// REQUIRES: IsInfiniteDuration(d) >+constexpr Duration OppositeInfinity(Duration d) { >+ return GetRepHi(d) < 0 >+ ? MakeDuration(std::numeric_limits<int64_t>::max(), ~0U) >+ : MakeDuration(std::numeric_limits<int64_t>::min(), ~0U); >+} >+ >+// Returns (-n)-1 (equivalently -(n+1)) without avoidable overflow. >+constexpr int64_t NegateAndSubtractOne(int64_t n) { >+ // Note: Good compilers will optimize this expression to ~n when using >+ // a two's-complement representation (which is required for int64_t). >+ return (n < 0) ? -(n + 1) : (-n) - 1; >+} >+ >+// Map between a Time and a Duration since the Unix epoch. Note that these >+// functions depend on the above mentioned choice of the Unix epoch for the >+// Time representation (and both need to be Time friends). Without this >+// knowledge, we would need to add-in/subtract-out UnixEpoch() respectively. >+constexpr Time FromUnixDuration(Duration d) { return Time(d); } >+constexpr Duration ToUnixDuration(Time t) { return t.rep_; } >+ >+template <std::intmax_t N> >+constexpr Duration FromInt64(int64_t v, std::ratio<1, N>) { >+ static_assert(0 < N && N <= 1000 * 1000 * 1000, "Unsupported ratio"); >+ // Subsecond ratios cannot overflow. >+ return MakeNormalizedDuration( >+ v / N, v % N * kTicksPerNanosecond * 1000 * 1000 * 1000 / N); >+} >+constexpr Duration FromInt64(int64_t v, std::ratio<60>) { >+ return (v <= std::numeric_limits<int64_t>::max() / 60 && >+ v >= std::numeric_limits<int64_t>::min() / 60) >+ ? MakeDuration(v * 60) >+ : v > 0 ? InfiniteDuration() : -InfiniteDuration(); >+} >+constexpr Duration FromInt64(int64_t v, std::ratio<3600>) { >+ return (v <= std::numeric_limits<int64_t>::max() / 3600 && >+ v >= std::numeric_limits<int64_t>::min() / 3600) >+ ? MakeDuration(v * 3600) >+ : v > 0 ? InfiniteDuration() : -InfiniteDuration(); >+} >+ >+// IsValidRep64<T>(0) is true if the expression `int64_t{std::declval<T>()}` is >+// valid. That is, if a T can be assigned to an int64_t without narrowing. >+template <typename T> >+constexpr auto IsValidRep64(int) >+ -> decltype(int64_t{std::declval<T>()}, bool()) { >+ return true; >+} >+template <typename T> >+constexpr auto IsValidRep64(char) -> bool { >+ return false; >+} >+ >+// Converts a std::chrono::duration to an absl::Duration. >+template <typename Rep, typename Period> >+constexpr Duration FromChrono(const std::chrono::duration<Rep, Period>& d) { >+ static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid"); >+ return FromInt64(int64_t{d.count()}, Period{}); >+} >+ >+template <typename Ratio> >+int64_t ToInt64(Duration d, Ratio) { >+ // Note: This may be used on MSVC, which may have a system_clock period of >+ // std::ratio<1, 10 * 1000 * 1000> >+ return ToInt64Seconds(d * Ratio::den / Ratio::num); >+} >+// Fastpath implementations for the 6 common duration units. >+inline int64_t ToInt64(Duration d, std::nano) { >+ return ToInt64Nanoseconds(d); >+} >+inline int64_t ToInt64(Duration d, std::micro) { >+ return ToInt64Microseconds(d); >+} >+inline int64_t ToInt64(Duration d, std::milli) { >+ return ToInt64Milliseconds(d); >+} >+inline int64_t ToInt64(Duration d, std::ratio<1>) { >+ return ToInt64Seconds(d); >+} >+inline int64_t ToInt64(Duration d, std::ratio<60>) { >+ return ToInt64Minutes(d); >+} >+inline int64_t ToInt64(Duration d, std::ratio<3600>) { >+ return ToInt64Hours(d); >+} >+ >+// Converts an absl::Duration to a chrono duration of type T. >+template <typename T> >+T ToChronoDuration(Duration d) { >+ using Rep = typename T::rep; >+ using Period = typename T::period; >+ static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid"); >+ if (time_internal::IsInfiniteDuration(d)) >+ return d < ZeroDuration() ? T::min() : T::max(); >+ const auto v = ToInt64(d, Period{}); >+ if (v > std::numeric_limits<Rep>::max()) return T::max(); >+ if (v < std::numeric_limits<Rep>::min()) return T::min(); >+ return T{v}; >+} >+ >+} // namespace time_internal >+constexpr Duration Nanoseconds(int64_t n) { >+ return time_internal::FromInt64(n, std::nano{}); >+} >+constexpr Duration Microseconds(int64_t n) { >+ return time_internal::FromInt64(n, std::micro{}); >+} >+constexpr Duration Milliseconds(int64_t n) { >+ return time_internal::FromInt64(n, std::milli{}); >+} >+constexpr Duration Seconds(int64_t n) { >+ return time_internal::FromInt64(n, std::ratio<1>{}); >+} >+constexpr Duration Minutes(int64_t n) { >+ return time_internal::FromInt64(n, std::ratio<60>{}); >+} >+constexpr Duration Hours(int64_t n) { >+ return time_internal::FromInt64(n, std::ratio<3600>{}); >+} >+ >+constexpr bool operator<(Duration lhs, Duration rhs) { >+ return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs) >+ ? time_internal::GetRepHi(lhs) < time_internal::GetRepHi(rhs) >+ : time_internal::GetRepHi(lhs) == std::numeric_limits<int64_t>::min() >+ ? time_internal::GetRepLo(lhs) + 1 < >+ time_internal::GetRepLo(rhs) + 1 >+ : time_internal::GetRepLo(lhs) < >+ time_internal::GetRepLo(rhs); >+} >+ >+constexpr bool operator==(Duration lhs, Duration rhs) { >+ return time_internal::GetRepHi(lhs) == time_internal::GetRepHi(rhs) && >+ time_internal::GetRepLo(lhs) == time_internal::GetRepLo(rhs); >+} >+ >+constexpr Duration operator-(Duration d) { >+ // This is a little interesting because of the special cases. >+ // >+ // If rep_lo_ is zero, we have it easy; it's safe to negate rep_hi_, we're >+ // dealing with an integral number of seconds, and the only special case is >+ // the maximum negative finite duration, which can't be negated. >+ // >+ // Infinities stay infinite, and just change direction. >+ // >+ // Finally we're in the case where rep_lo_ is non-zero, and we can borrow >+ // a second's worth of ticks and avoid overflow (as negating int64_t-min + 1 >+ // is safe). >+ return time_internal::GetRepLo(d) == 0 >+ ? time_internal::GetRepHi(d) == std::numeric_limits<int64_t>::min() >+ ? InfiniteDuration() >+ : time_internal::MakeDuration(-time_internal::GetRepHi(d)) >+ : time_internal::IsInfiniteDuration(d) >+ ? time_internal::OppositeInfinity(d) >+ : time_internal::MakeDuration( >+ time_internal::NegateAndSubtractOne( >+ time_internal::GetRepHi(d)), >+ time_internal::kTicksPerSecond - >+ time_internal::GetRepLo(d)); >+} >+ >+constexpr Duration InfiniteDuration() { >+ return time_internal::MakeDuration(std::numeric_limits<int64_t>::max(), ~0U); >+} >+ >+constexpr Duration FromChrono(const std::chrono::nanoseconds& d) { >+ return time_internal::FromChrono(d); >+} >+constexpr Duration FromChrono(const std::chrono::microseconds& d) { >+ return time_internal::FromChrono(d); >+} >+constexpr Duration FromChrono(const std::chrono::milliseconds& d) { >+ return time_internal::FromChrono(d); >+} >+constexpr Duration FromChrono(const std::chrono::seconds& d) { >+ return time_internal::FromChrono(d); >+} >+constexpr Duration FromChrono(const std::chrono::minutes& d) { >+ return time_internal::FromChrono(d); >+} >+constexpr Duration FromChrono(const std::chrono::hours& d) { >+ return time_internal::FromChrono(d); >+} >+ >+constexpr Time FromUnixNanos(int64_t ns) { >+ return time_internal::FromUnixDuration(Nanoseconds(ns)); >+} >+ >+constexpr Time FromUnixMicros(int64_t us) { >+ return time_internal::FromUnixDuration(Microseconds(us)); >+} >+ >+constexpr Time FromUnixMillis(int64_t ms) { >+ return time_internal::FromUnixDuration(Milliseconds(ms)); >+} >+ >+constexpr Time FromUnixSeconds(int64_t s) { >+ return time_internal::FromUnixDuration(Seconds(s)); >+} >+ >+constexpr Time FromTimeT(time_t t) { >+ return time_internal::FromUnixDuration(Seconds(t)); >+} >+ >+} // namespace absl >+ >+#endif // ABSL_TIME_TIME_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..e1009946cd586ef3303e05333922a69903953754 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_benchmark.cc >@@ -0,0 +1,316 @@ >+// Copyright 2018 The Abseil Authors. >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/time.h" >+ >+#if !defined(_WIN32) >+#include <sys/time.h> >+#endif // _WIN32 >+#include <algorithm> >+#include <cmath> >+#include <cstddef> >+#include <cstring> >+#include <ctime> >+#include <memory> >+#include <string> >+ >+#include "absl/time/clock.h" >+#include "absl/time/internal/test_util.h" >+#include "benchmark/benchmark.h" >+ >+namespace { >+ >+// >+// Addition/Subtraction of a duration >+// >+ >+void BM_Time_Arithmetic(benchmark::State& state) { >+ const absl::Duration nano = absl::Nanoseconds(1); >+ const absl::Duration sec = absl::Seconds(1); >+ absl::Time t = absl::UnixEpoch(); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(t += nano); >+ benchmark::DoNotOptimize(t -= sec); >+ } >+} >+BENCHMARK(BM_Time_Arithmetic); >+ >+// >+// Time difference >+// >+ >+void BM_Time_Difference(benchmark::State& state) { >+ absl::Time start = absl::Now(); >+ absl::Time end = start + absl::Nanoseconds(1); >+ absl::Duration diff; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(diff += end - start); >+ } >+} >+BENCHMARK(BM_Time_Difference); >+ >+// >+// ToDateTime >+// >+// In each "ToDateTime" benchmark we switch between two instants >+// separated by at least one transition in order to defeat any >+// internal caching of previous results (e.g., see local_time_hint_). >+// >+// The "UTC" variants use UTC instead of the Google/local time zone. >+// >+ >+void BM_Time_ToDateTime_Absl(benchmark::State& state) { >+ const absl::TimeZone tz = >+ absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ absl::Time t = absl::FromUnixSeconds(1384569027); >+ absl::Time t2 = absl::FromUnixSeconds(1418962578); >+ while (state.KeepRunning()) { >+ std::swap(t, t2); >+ t += absl::Seconds(1); >+ benchmark::DoNotOptimize(t.In(tz)); >+ } >+} >+BENCHMARK(BM_Time_ToDateTime_Absl); >+ >+void BM_Time_ToDateTime_Libc(benchmark::State& state) { >+ // No timezone support, so just use localtime. >+ time_t t = 1384569027; >+ time_t t2 = 1418962578; >+ while (state.KeepRunning()) { >+ std::swap(t, t2); >+ t += 1; >+ struct tm tm; >+#if !defined(_WIN32) >+ benchmark::DoNotOptimize(localtime_r(&t, &tm)); >+#else // _WIN32 >+ benchmark::DoNotOptimize(localtime_s(&tm, &t)); >+#endif // _WIN32 >+ } >+} >+BENCHMARK(BM_Time_ToDateTime_Libc); >+ >+void BM_Time_ToDateTimeUTC_Absl(benchmark::State& state) { >+ const absl::TimeZone tz = absl::UTCTimeZone(); >+ absl::Time t = absl::FromUnixSeconds(1384569027); >+ while (state.KeepRunning()) { >+ t += absl::Seconds(1); >+ benchmark::DoNotOptimize(t.In(tz)); >+ } >+} >+BENCHMARK(BM_Time_ToDateTimeUTC_Absl); >+ >+void BM_Time_ToDateTimeUTC_Libc(benchmark::State& state) { >+ time_t t = 1384569027; >+ while (state.KeepRunning()) { >+ t += 1; >+ struct tm tm; >+#if !defined(_WIN32) >+ benchmark::DoNotOptimize(gmtime_r(&t, &tm)); >+#else // _WIN32 >+ benchmark::DoNotOptimize(gmtime_s(&tm, &t)); >+#endif // _WIN32 >+ } >+} >+BENCHMARK(BM_Time_ToDateTimeUTC_Libc); >+ >+// >+// FromUnixMicros >+// >+ >+void BM_Time_FromUnixMicros(benchmark::State& state) { >+ int i = 0; >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::FromUnixMicros(i)); >+ ++i; >+ } >+} >+BENCHMARK(BM_Time_FromUnixMicros); >+ >+void BM_Time_ToUnixNanos(benchmark::State& state) { >+ const absl::Time t = absl::UnixEpoch() + absl::Seconds(123); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(ToUnixNanos(t)); >+ } >+} >+BENCHMARK(BM_Time_ToUnixNanos); >+ >+void BM_Time_ToUnixMicros(benchmark::State& state) { >+ const absl::Time t = absl::UnixEpoch() + absl::Seconds(123); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(ToUnixMicros(t)); >+ } >+} >+BENCHMARK(BM_Time_ToUnixMicros); >+ >+void BM_Time_ToUnixMillis(benchmark::State& state) { >+ const absl::Time t = absl::UnixEpoch() + absl::Seconds(123); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(ToUnixMillis(t)); >+ } >+} >+BENCHMARK(BM_Time_ToUnixMillis); >+ >+void BM_Time_ToUnixSeconds(benchmark::State& state) { >+ const absl::Time t = absl::UnixEpoch() + absl::Seconds(123); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ToUnixSeconds(t)); >+ } >+} >+BENCHMARK(BM_Time_ToUnixSeconds); >+ >+// >+// FromDateTime >+// >+// In each "FromDateTime" benchmark we switch between two YMDhms >+// values separated by at least one transition in order to defeat any >+// internal caching of previous results (e.g., see time_local_hint_). >+// >+// The "UTC" variants use UTC instead of the Google/local time zone. >+// The "Day0" variants require normalization of the day of month. >+// >+ >+void BM_Time_FromDateTime_Absl(benchmark::State& state) { >+ const absl::TimeZone tz = >+ absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ int i = 0; >+ while (state.KeepRunning()) { >+ if ((i & 1) == 0) { >+ absl::FromDateTime(2014, 12, 18, 20, 16, 18, tz); >+ } else { >+ absl::FromDateTime(2013, 11, 15, 18, 30, 27, tz); >+ } >+ ++i; >+ } >+} >+BENCHMARK(BM_Time_FromDateTime_Absl); >+ >+void BM_Time_FromDateTime_Libc(benchmark::State& state) { >+ // No timezone support, so just use localtime. >+ int i = 0; >+ while (state.KeepRunning()) { >+ struct tm tm; >+ if ((i & 1) == 0) { >+ tm.tm_year = 2014 - 1900; >+ tm.tm_mon = 12 - 1; >+ tm.tm_mday = 18; >+ tm.tm_hour = 20; >+ tm.tm_min = 16; >+ tm.tm_sec = 18; >+ } else { >+ tm.tm_year = 2013 - 1900; >+ tm.tm_mon = 11 - 1; >+ tm.tm_mday = 15; >+ tm.tm_hour = 18; >+ tm.tm_min = 30; >+ tm.tm_sec = 27; >+ } >+ tm.tm_isdst = -1; >+ mktime(&tm); >+ ++i; >+ } >+} >+BENCHMARK(BM_Time_FromDateTime_Libc); >+ >+void BM_Time_FromDateTimeUTC_Absl(benchmark::State& state) { >+ const absl::TimeZone tz = absl::UTCTimeZone(); >+ while (state.KeepRunning()) { >+ FromDateTime(2014, 12, 18, 20, 16, 18, tz); >+ } >+} >+BENCHMARK(BM_Time_FromDateTimeUTC_Absl); >+ >+void BM_Time_FromDateTimeDay0_Absl(benchmark::State& state) { >+ const absl::TimeZone tz = >+ absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ int i = 0; >+ while (state.KeepRunning()) { >+ if ((i & 1) == 0) { >+ absl::FromDateTime(2014, 12, 0, 20, 16, 18, tz); >+ } else { >+ absl::FromDateTime(2013, 11, 0, 18, 30, 27, tz); >+ } >+ ++i; >+ } >+} >+BENCHMARK(BM_Time_FromDateTimeDay0_Absl); >+ >+void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) { >+ // No timezone support, so just use localtime. >+ int i = 0; >+ while (state.KeepRunning()) { >+ struct tm tm; >+ if ((i & 1) == 0) { >+ tm.tm_year = 2014 - 1900; >+ tm.tm_mon = 12 - 1; >+ tm.tm_mday = 0; >+ tm.tm_hour = 20; >+ tm.tm_min = 16; >+ tm.tm_sec = 18; >+ } else { >+ tm.tm_year = 2013 - 1900; >+ tm.tm_mon = 11 - 1; >+ tm.tm_mday = 0; >+ tm.tm_hour = 18; >+ tm.tm_min = 30; >+ tm.tm_sec = 27; >+ } >+ tm.tm_isdst = -1; >+ mktime(&tm); >+ ++i; >+ } >+} >+BENCHMARK(BM_Time_FromDateTimeDay0_Libc); >+ >+// >+// To/FromTimespec >+// >+ >+void BM_Time_ToTimespec(benchmark::State& state) { >+ absl::Time now = absl::Now(); >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::ToTimespec(now)); >+ } >+} >+BENCHMARK(BM_Time_ToTimespec); >+ >+void BM_Time_FromTimespec(benchmark::State& state) { >+ timespec ts = absl::ToTimespec(absl::Now()); >+ while (state.KeepRunning()) { >+ if (++ts.tv_nsec == 1000 * 1000 * 1000) { >+ ++ts.tv_sec; >+ ts.tv_nsec = 0; >+ } >+ benchmark::DoNotOptimize(absl::TimeFromTimespec(ts)); >+ } >+} >+BENCHMARK(BM_Time_FromTimespec); >+ >+// >+// Comparison with InfiniteFuture/Past >+// >+ >+void BM_Time_InfiniteFuture(benchmark::State& state) { >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::InfiniteFuture()); >+ } >+} >+BENCHMARK(BM_Time_InfiniteFuture); >+ >+void BM_Time_InfinitePast(benchmark::State& state) { >+ while (state.KeepRunning()) { >+ benchmark::DoNotOptimize(absl::InfinitePast()); >+ } >+} >+BENCHMARK(BM_Time_InfinitePast); >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_norm_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_norm_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..4436242e4125578e2f15a7873d6c1c6b09ca6ae0 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_norm_test.cc >@@ -0,0 +1,306 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// This file contains tests for FromDateTime() normalization, which is >+// time-zone independent so we just use UTC throughout. >+ >+#include <cstdint> >+#include <limits> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/time/internal/test_util.h" >+#include "absl/time/time.h" >+ >+namespace { >+ >+TEST(TimeNormCase, SimpleOverflow) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ >+ absl::TimeConversion tc = >+ absl::ConvertDateTime(2013, 11, 15, 16, 32, 59 + 1, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ absl::Time::Breakdown bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 16, 33, 0, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11, 15, 16, 59 + 1, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 17, 0, 14, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11, 15, 23 + 1, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 16, 0, 32, 14, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11, 30 + 1, 16, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 12, 1, 16, 32, 14, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 12 + 1, 15, 16, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2014, 1, 15, 16, 32, 14, 0, false); >+} >+ >+TEST(TimeNormCase, SimpleUnderflow) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ >+ absl::TimeConversion tc = ConvertDateTime(2013, 11, 15, 16, 32, 0 - 1, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ absl::Time::Breakdown bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 16, 31, 59, 0, false); >+ >+ tc = ConvertDateTime(2013, 11, 15, 16, 0 - 1, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 15, 59, 14, 0, false); >+ >+ tc = ConvertDateTime(2013, 11, 15, 0 - 1, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 14, 23, 32, 14, 0, false); >+ >+ tc = ConvertDateTime(2013, 11, 1 - 1, 16, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 10, 31, 16, 32, 14, 0, false); >+ >+ tc = ConvertDateTime(2013, 1 - 1, 15, 16, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2012, 12, 15, 16, 32, 14, 0, false); >+} >+ >+TEST(TimeNormCase, MultipleOverflow) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ absl::TimeConversion tc = ConvertDateTime(2013, 12, 31, 23, 59, 59 + 1, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ absl::Time::Breakdown bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2014, 1, 1, 0, 0, 0, 0, false); >+} >+ >+TEST(TimeNormCase, MultipleUnderflow) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ absl::TimeConversion tc = absl::ConvertDateTime(2014, 1, 1, 0, 0, 0 - 1, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ absl::Time::Breakdown bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 12, 31, 23, 59, 59, 0, false); >+} >+ >+TEST(TimeNormCase, OverflowLimits) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ absl::TimeConversion tc; >+ absl::Time::Breakdown bd; >+ >+ const int kintmax = std::numeric_limits<int>::max(); >+ tc = absl::ConvertDateTime(0, kintmax, kintmax, kintmax, kintmax, kintmax, >+ utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 185085715, 11, 27, 12, 21, 7, 0, false); >+ >+ const int kintmin = std::numeric_limits<int>::min(); >+ tc = absl::ConvertDateTime(0, kintmin, kintmin, kintmin, kintmin, kintmin, >+ utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, -185085717, 10, 31, 10, 37, 52, 0, false); >+ >+ const int64_t max_year = std::numeric_limits<int64_t>::max(); >+ tc = absl::ConvertDateTime(max_year, 12, 31, 23, 59, 59, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ EXPECT_EQ(absl::InfiniteFuture(), tc.pre); >+ >+ const int64_t min_year = std::numeric_limits<int64_t>::min(); >+ tc = absl::ConvertDateTime(min_year, 1, 1, 0, 0, 0, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ EXPECT_EQ(absl::InfinitePast(), tc.pre); >+} >+ >+TEST(TimeNormCase, ComplexOverflow) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ >+ absl::TimeConversion tc = >+ ConvertDateTime(2013, 11, 15, 16, 32, 14 + 123456789, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ absl::Time::Breakdown bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2017, 10, 14, 14, 5, 23, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11, 15, 16, 32 + 1234567, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2016, 3, 22, 0, 39, 14, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11, 15, 16 + 123456, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2027, 12, 16, 16, 32, 14, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11, 15 + 1234, 16, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2017, 4, 2, 16, 32, 14, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11 + 123, 15, 16, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2024, 2, 15, 16, 32, 14, 0, false); >+} >+ >+TEST(TimeNormCase, ComplexUnderflow) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ >+ absl::TimeConversion tc = >+ absl::ConvertDateTime(1999, 3, 0, 0, 0, 0, utc); // year 400 >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ absl::Time::Breakdown bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 1999, 2, 28, 0, 0, 0, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11, 15, 16, 32, 14 - 123456789, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2009, 12, 17, 18, 59, 5, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11, 15, 16, 32 - 1234567, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2011, 7, 12, 8, 25, 14, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11, 15, 16 - 123456, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 1999, 10, 16, 16, 32, 14, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11, 15 - 1234, 16, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2010, 6, 30, 16, 32, 14, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11 - 123, 15, 16, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2003, 8, 15, 16, 32, 14, 0, false); >+} >+ >+TEST(TimeNormCase, Mishmash) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ >+ absl::TimeConversion tc = >+ absl::ConvertDateTime(2013, 11 - 123, 15 + 1234, 16 - 123456, >+ 32 + 1234567, 14 - 123456789, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ absl::Time::Breakdown bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 1991, 5, 9, 3, 6, 5, 0, false); >+ >+ tc = absl::ConvertDateTime(2013, 11 + 123, 15 - 1234, 16 + 123456, >+ 32 - 1234567, 14 + 123456789, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2036, 5, 24, 5, 58, 23, 0, false); >+ >+ // Here is a normalization case we got wrong for a while. Because the >+ // day is converted to "1" within a 400-year (146097-day) period, we >+ // didn't need to roll the month and so we didn't mark it as normalized. >+ tc = absl::ConvertDateTime(2013, 11, -146097 + 1, 16, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 1613, 11, 1, 16, 32, 14, 0, false); >+ >+ // Even though the month overflow compensates for the day underflow, >+ // this should still be marked as normalized. >+ tc = absl::ConvertDateTime(2013, 11 + 400 * 12, -146097 + 1, 16, 32, 14, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 1, 16, 32, 14, 0, false); >+} >+ >+TEST(TimeNormCase, LeapYears) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ >+ absl::TimeConversion tc = >+ absl::ConvertDateTime(2013, 2, 28 + 1, 0, 0, 0, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ absl::Time::Breakdown bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 3, 1, 0, 0, 0, 0, false); >+ >+ tc = absl::ConvertDateTime(2012, 2, 28 + 1, 0, 0, 0, utc); >+ EXPECT_FALSE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2012, 2, 29, 0, 0, 0, 0, false); >+ >+ tc = absl::ConvertDateTime(2000, 2, 28 + 1, 0, 0, 0, utc); >+ EXPECT_FALSE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 2000, 2, 29, 0, 0, 0, 0, false); >+ >+ tc = absl::ConvertDateTime(1900, 2, 28 + 1, 0, 0, 0, utc); >+ EXPECT_TRUE(tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ bd = tc.pre.In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 1900, 3, 1, 0, 0, 0, 0, false); >+} >+ >+// Convert all the days from 1970-1-1 to 1970-1-146097 (aka 2369-12-31) >+// and check that they normalize to the expected time. 146097 days span >+// the 400-year Gregorian cycle used during normalization. >+TEST(TimeNormCase, AllTheDays) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ absl::Time exp_time = absl::UnixEpoch(); >+ >+ for (int day = 1; day <= 146097; ++day) { >+ absl::TimeConversion tc = absl::ConvertDateTime(1970, 1, day, 0, 0, 0, utc); >+ EXPECT_EQ(day > 31, tc.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); >+ EXPECT_EQ(exp_time, tc.pre); >+ exp_time += absl::Hours(24); >+ } >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..4f8f58a6ef362d9d8a0227a2708d22df6e0f3993 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_test.cc >@@ -0,0 +1,1088 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/time.h" >+ >+#include <chrono> // NOLINT(build/c++11) >+#include <cstring> >+#include <ctime> >+#include <iomanip> >+#include <limits> >+#include <string> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/time/clock.h" >+#include "absl/time/internal/test_util.h" >+ >+namespace { >+ >+// A gMock matcher to match timespec values. Use this matcher like: >+// timespec ts1, ts2; >+// EXPECT_THAT(ts1, TimespecMatcher(ts2)); >+MATCHER_P(TimespecMatcher, ts, "") { >+ if (ts.tv_sec == arg.tv_sec && ts.tv_nsec == arg.tv_nsec) >+ return true; >+ *result_listener << "expected: {" << ts.tv_sec << ", " << ts.tv_nsec << "} "; >+ *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_nsec << "}"; >+ return false; >+} >+ >+// A gMock matcher to match timeval values. Use this matcher like: >+// timeval tv1, tv2; >+// EXPECT_THAT(tv1, TimevalMatcher(tv2)); >+MATCHER_P(TimevalMatcher, tv, "") { >+ if (tv.tv_sec == arg.tv_sec && tv.tv_usec == arg.tv_usec) >+ return true; >+ *result_listener << "expected: {" << tv.tv_sec << ", " << tv.tv_usec << "} "; >+ *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_usec << "}"; >+ return false; >+} >+ >+TEST(Time, ConstExpr) { >+ constexpr absl::Time t0 = absl::UnixEpoch(); >+ static_assert(t0 == absl::Time(), "UnixEpoch"); >+ constexpr absl::Time t1 = absl::InfiniteFuture(); >+ static_assert(t1 != absl::Time(), "InfiniteFuture"); >+ constexpr absl::Time t2 = absl::InfinitePast(); >+ static_assert(t2 != absl::Time(), "InfinitePast"); >+ constexpr absl::Time t3 = absl::FromUnixNanos(0); >+ static_assert(t3 == absl::Time(), "FromUnixNanos"); >+ constexpr absl::Time t4 = absl::FromUnixMicros(0); >+ static_assert(t4 == absl::Time(), "FromUnixMicros"); >+ constexpr absl::Time t5 = absl::FromUnixMillis(0); >+ static_assert(t5 == absl::Time(), "FromUnixMillis"); >+ constexpr absl::Time t6 = absl::FromUnixSeconds(0); >+ static_assert(t6 == absl::Time(), "FromUnixSeconds"); >+ constexpr absl::Time t7 = absl::FromTimeT(0); >+ static_assert(t7 == absl::Time(), "FromTimeT"); >+} >+ >+TEST(Time, ValueSemantics) { >+ absl::Time a; // Default construction >+ absl::Time b = a; // Copy construction >+ EXPECT_EQ(a, b); >+ absl::Time c(a); // Copy construction (again) >+ EXPECT_EQ(a, b); >+ EXPECT_EQ(a, c); >+ EXPECT_EQ(b, c); >+ b = c; // Assignment >+ EXPECT_EQ(a, b); >+ EXPECT_EQ(a, c); >+ EXPECT_EQ(b, c); >+} >+ >+TEST(Time, UnixEpoch) { >+ absl::Time::Breakdown bd = absl::UnixEpoch().In(absl::UTCTimeZone()); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 1970, 1, 1, 0, 0, 0, 0, false); >+ EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); >+ EXPECT_EQ(4, bd.weekday); // Thursday >+} >+ >+TEST(Time, Breakdown) { >+ absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/New_York"); >+ absl::Time t = absl::UnixEpoch(); >+ >+ // The Unix epoch as seen in NYC. >+ absl::Time::Breakdown bd = t.In(tz); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 1969, 12, 31, 19, 0, 0, -18000, false); >+ EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); >+ EXPECT_EQ(3, bd.weekday); // Wednesday >+ >+ // Just before the epoch. >+ t -= absl::Nanoseconds(1); >+ bd = t.In(tz); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 1969, 12, 31, 18, 59, 59, -18000, false); >+ EXPECT_EQ(absl::Nanoseconds(999999999), bd.subsecond); >+ EXPECT_EQ(3, bd.weekday); // Wednesday >+ >+ // Some time later. >+ t += absl::Hours(24) * 2735; >+ t += absl::Hours(18) + absl::Minutes(30) + absl::Seconds(15) + >+ absl::Nanoseconds(9); >+ bd = t.In(tz); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 1977, 6, 28, 14, 30, 15, -14400, true); >+ EXPECT_EQ(8, bd.subsecond / absl::Nanoseconds(1)); >+ EXPECT_EQ(2, bd.weekday); // Tuesday >+} >+ >+TEST(Time, AdditiveOperators) { >+ const absl::Duration d = absl::Nanoseconds(1); >+ const absl::Time t0; >+ const absl::Time t1 = t0 + d; >+ >+ EXPECT_EQ(d, t1 - t0); >+ EXPECT_EQ(-d, t0 - t1); >+ EXPECT_EQ(t0, t1 - d); >+ >+ absl::Time t(t0); >+ EXPECT_EQ(t0, t); >+ t += d; >+ EXPECT_EQ(t0 + d, t); >+ EXPECT_EQ(d, t - t0); >+ t -= d; >+ EXPECT_EQ(t0, t); >+ >+ // Tests overflow between subseconds and seconds. >+ t = absl::UnixEpoch(); >+ t += absl::Milliseconds(500); >+ EXPECT_EQ(absl::UnixEpoch() + absl::Milliseconds(500), t); >+ t += absl::Milliseconds(600); >+ EXPECT_EQ(absl::UnixEpoch() + absl::Milliseconds(1100), t); >+ t -= absl::Milliseconds(600); >+ EXPECT_EQ(absl::UnixEpoch() + absl::Milliseconds(500), t); >+ t -= absl::Milliseconds(500); >+ EXPECT_EQ(absl::UnixEpoch(), t); >+} >+ >+TEST(Time, RelationalOperators) { >+ constexpr absl::Time t1 = absl::FromUnixNanos(0); >+ constexpr absl::Time t2 = absl::FromUnixNanos(1); >+ constexpr absl::Time t3 = absl::FromUnixNanos(2); >+ >+ static_assert(absl::Time() == t1, ""); >+ static_assert(t1 == t1, ""); >+ static_assert(t2 == t2, ""); >+ static_assert(t3 == t3, ""); >+ >+ static_assert(t1 < t2, ""); >+ static_assert(t2 < t3, ""); >+ static_assert(t1 < t3, ""); >+ >+ static_assert(t1 <= t1, ""); >+ static_assert(t1 <= t2, ""); >+ static_assert(t2 <= t2, ""); >+ static_assert(t2 <= t3, ""); >+ static_assert(t3 <= t3, ""); >+ static_assert(t1 <= t3, ""); >+ >+ static_assert(t2 > t1, ""); >+ static_assert(t3 > t2, ""); >+ static_assert(t3 > t1, ""); >+ >+ static_assert(t2 >= t2, ""); >+ static_assert(t2 >= t1, ""); >+ static_assert(t3 >= t3, ""); >+ static_assert(t3 >= t2, ""); >+ static_assert(t1 >= t1, ""); >+ static_assert(t3 >= t1, ""); >+} >+ >+TEST(Time, Infinity) { >+ constexpr absl::Time ifuture = absl::InfiniteFuture(); >+ constexpr absl::Time ipast = absl::InfinitePast(); >+ >+ static_assert(ifuture == ifuture, ""); >+ static_assert(ipast == ipast, ""); >+ static_assert(ipast < ifuture, ""); >+ static_assert(ifuture > ipast, ""); >+ >+ // Arithmetic saturates >+ EXPECT_EQ(ifuture, ifuture + absl::Seconds(1)); >+ EXPECT_EQ(ifuture, ifuture - absl::Seconds(1)); >+ EXPECT_EQ(ipast, ipast + absl::Seconds(1)); >+ EXPECT_EQ(ipast, ipast - absl::Seconds(1)); >+ >+ EXPECT_EQ(absl::InfiniteDuration(), ifuture - ifuture); >+ EXPECT_EQ(absl::InfiniteDuration(), ifuture - ipast); >+ EXPECT_EQ(-absl::InfiniteDuration(), ipast - ifuture); >+ EXPECT_EQ(-absl::InfiniteDuration(), ipast - ipast); >+ >+ constexpr absl::Time t = absl::UnixEpoch(); // Any finite time. >+ static_assert(t < ifuture, ""); >+ static_assert(t > ipast, ""); >+} >+ >+TEST(Time, FloorConversion) { >+#define TEST_FLOOR_CONVERSION(TO, FROM) \ >+ EXPECT_EQ(1, TO(FROM(1001))); \ >+ EXPECT_EQ(1, TO(FROM(1000))); \ >+ EXPECT_EQ(0, TO(FROM(999))); \ >+ EXPECT_EQ(0, TO(FROM(1))); \ >+ EXPECT_EQ(0, TO(FROM(0))); \ >+ EXPECT_EQ(-1, TO(FROM(-1))); \ >+ EXPECT_EQ(-1, TO(FROM(-999))); \ >+ EXPECT_EQ(-1, TO(FROM(-1000))); \ >+ EXPECT_EQ(-2, TO(FROM(-1001))); >+ >+ TEST_FLOOR_CONVERSION(absl::ToUnixMicros, absl::FromUnixNanos); >+ TEST_FLOOR_CONVERSION(absl::ToUnixMillis, absl::FromUnixMicros); >+ TEST_FLOOR_CONVERSION(absl::ToUnixSeconds, absl::FromUnixMillis); >+ TEST_FLOOR_CONVERSION(absl::ToTimeT, absl::FromUnixMillis); >+ >+#undef TEST_FLOOR_CONVERSION >+ >+ // Tests ToUnixNanos. >+ EXPECT_EQ(1, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(3) / 2)); >+ EXPECT_EQ(1, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(1))); >+ EXPECT_EQ(0, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(1) / 2)); >+ EXPECT_EQ(0, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(0))); >+ EXPECT_EQ(-1, >+ absl::ToUnixNanos(absl::UnixEpoch() - absl::Nanoseconds(1) / 2)); >+ EXPECT_EQ(-1, absl::ToUnixNanos(absl::UnixEpoch() - absl::Nanoseconds(1))); >+ EXPECT_EQ(-2, >+ absl::ToUnixNanos(absl::UnixEpoch() - absl::Nanoseconds(3) / 2)); >+ >+ // Tests ToUniversal, which uses a different epoch than the tests above. >+ EXPECT_EQ(1, >+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(101))); >+ EXPECT_EQ(1, >+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(100))); >+ EXPECT_EQ(0, >+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(99))); >+ EXPECT_EQ(0, >+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(1))); >+ EXPECT_EQ(0, >+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(0))); >+ EXPECT_EQ(-1, >+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-1))); >+ EXPECT_EQ(-1, >+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-99))); >+ EXPECT_EQ( >+ -1, absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-100))); >+ EXPECT_EQ( >+ -2, absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-101))); >+ >+ // Tests ToTimespec()/TimeFromTimespec() >+ const struct { >+ absl::Time t; >+ timespec ts; >+ } to_ts[] = { >+ {absl::FromUnixSeconds(1) + absl::Nanoseconds(1), {1, 1}}, >+ {absl::FromUnixSeconds(1) + absl::Nanoseconds(1) / 2, {1, 0}}, >+ {absl::FromUnixSeconds(1) + absl::Nanoseconds(0), {1, 0}}, >+ {absl::FromUnixSeconds(0) + absl::Nanoseconds(0), {0, 0}}, >+ {absl::FromUnixSeconds(0) - absl::Nanoseconds(1) / 2, {-1, 999999999}}, >+ {absl::FromUnixSeconds(0) - absl::Nanoseconds(1), {-1, 999999999}}, >+ {absl::FromUnixSeconds(-1) + absl::Nanoseconds(1), {-1, 1}}, >+ {absl::FromUnixSeconds(-1) + absl::Nanoseconds(1) / 2, {-1, 0}}, >+ {absl::FromUnixSeconds(-1) + absl::Nanoseconds(0), {-1, 0}}, >+ {absl::FromUnixSeconds(-1) - absl::Nanoseconds(1) / 2, {-2, 999999999}}, >+ }; >+ for (const auto& test : to_ts) { >+ EXPECT_THAT(absl::ToTimespec(test.t), TimespecMatcher(test.ts)); >+ } >+ const struct { >+ timespec ts; >+ absl::Time t; >+ } from_ts[] = { >+ {{1, 1}, absl::FromUnixSeconds(1) + absl::Nanoseconds(1)}, >+ {{1, 0}, absl::FromUnixSeconds(1) + absl::Nanoseconds(0)}, >+ {{0, 0}, absl::FromUnixSeconds(0) + absl::Nanoseconds(0)}, >+ {{0, -1}, absl::FromUnixSeconds(0) - absl::Nanoseconds(1)}, >+ {{-1, 999999999}, absl::FromUnixSeconds(0) - absl::Nanoseconds(1)}, >+ {{-1, 1}, absl::FromUnixSeconds(-1) + absl::Nanoseconds(1)}, >+ {{-1, 0}, absl::FromUnixSeconds(-1) + absl::Nanoseconds(0)}, >+ {{-1, -1}, absl::FromUnixSeconds(-1) - absl::Nanoseconds(1)}, >+ {{-2, 999999999}, absl::FromUnixSeconds(-1) - absl::Nanoseconds(1)}, >+ }; >+ for (const auto& test : from_ts) { >+ EXPECT_EQ(test.t, absl::TimeFromTimespec(test.ts)); >+ } >+ >+ // Tests ToTimeval()/TimeFromTimeval() (same as timespec above) >+ const struct { >+ absl::Time t; >+ timeval tv; >+ } to_tv[] = { >+ {absl::FromUnixSeconds(1) + absl::Microseconds(1), {1, 1}}, >+ {absl::FromUnixSeconds(1) + absl::Microseconds(1) / 2, {1, 0}}, >+ {absl::FromUnixSeconds(1) + absl::Microseconds(0), {1, 0}}, >+ {absl::FromUnixSeconds(0) + absl::Microseconds(0), {0, 0}}, >+ {absl::FromUnixSeconds(0) - absl::Microseconds(1) / 2, {-1, 999999}}, >+ {absl::FromUnixSeconds(0) - absl::Microseconds(1), {-1, 999999}}, >+ {absl::FromUnixSeconds(-1) + absl::Microseconds(1), {-1, 1}}, >+ {absl::FromUnixSeconds(-1) + absl::Microseconds(1) / 2, {-1, 0}}, >+ {absl::FromUnixSeconds(-1) + absl::Microseconds(0), {-1, 0}}, >+ {absl::FromUnixSeconds(-1) - absl::Microseconds(1) / 2, {-2, 999999}}, >+ }; >+ for (const auto& test : to_tv) { >+ EXPECT_THAT(ToTimeval(test.t), TimevalMatcher(test.tv)); >+ } >+ const struct { >+ timeval tv; >+ absl::Time t; >+ } from_tv[] = { >+ {{1, 1}, absl::FromUnixSeconds(1) + absl::Microseconds(1)}, >+ {{1, 0}, absl::FromUnixSeconds(1) + absl::Microseconds(0)}, >+ {{0, 0}, absl::FromUnixSeconds(0) + absl::Microseconds(0)}, >+ {{0, -1}, absl::FromUnixSeconds(0) - absl::Microseconds(1)}, >+ {{-1, 999999}, absl::FromUnixSeconds(0) - absl::Microseconds(1)}, >+ {{-1, 1}, absl::FromUnixSeconds(-1) + absl::Microseconds(1)}, >+ {{-1, 0}, absl::FromUnixSeconds(-1) + absl::Microseconds(0)}, >+ {{-1, -1}, absl::FromUnixSeconds(-1) - absl::Microseconds(1)}, >+ {{-2, 999999}, absl::FromUnixSeconds(-1) - absl::Microseconds(1)}, >+ }; >+ for (const auto& test : from_tv) { >+ EXPECT_EQ(test.t, absl::TimeFromTimeval(test.tv)); >+ } >+ >+ // Tests flooring near negative infinity. >+ const int64_t min_plus_1 = std::numeric_limits<int64_t>::min() + 1; >+ EXPECT_EQ(min_plus_1, absl::ToUnixSeconds(absl::FromUnixSeconds(min_plus_1))); >+ EXPECT_EQ(std::numeric_limits<int64_t>::min(), >+ absl::ToUnixSeconds( >+ absl::FromUnixSeconds(min_plus_1) - absl::Nanoseconds(1) / 2)); >+ >+ // Tests flooring near positive infinity. >+ EXPECT_EQ(std::numeric_limits<int64_t>::max(), >+ absl::ToUnixSeconds(absl::FromUnixSeconds( >+ std::numeric_limits<int64_t>::max()) + absl::Nanoseconds(1) / 2)); >+ EXPECT_EQ(std::numeric_limits<int64_t>::max(), >+ absl::ToUnixSeconds( >+ absl::FromUnixSeconds(std::numeric_limits<int64_t>::max()))); >+ EXPECT_EQ(std::numeric_limits<int64_t>::max() - 1, >+ absl::ToUnixSeconds(absl::FromUnixSeconds( >+ std::numeric_limits<int64_t>::max()) - absl::Nanoseconds(1) / 2)); >+} >+ >+TEST(Time, RoundtripConversion) { >+#define TEST_CONVERSION_ROUND_TRIP(SOURCE, FROM, TO, MATCHER) \ >+ EXPECT_THAT(TO(FROM(SOURCE)), MATCHER(SOURCE)) >+ >+ // FromUnixNanos() and ToUnixNanos() >+ int64_t now_ns = absl::GetCurrentTimeNanos(); >+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixNanos, absl::ToUnixNanos, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixNanos, absl::ToUnixNanos, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixNanos, absl::ToUnixNanos, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(now_ns, absl::FromUnixNanos, absl::ToUnixNanos, >+ testing::Eq) >+ << now_ns; >+ >+ // FromUnixMicros() and ToUnixMicros() >+ int64_t now_us = absl::GetCurrentTimeNanos() / 1000; >+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixMicros, absl::ToUnixMicros, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixMicros, absl::ToUnixMicros, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixMicros, absl::ToUnixMicros, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(now_us, absl::FromUnixMicros, absl::ToUnixMicros, >+ testing::Eq) >+ << now_us; >+ >+ // FromUnixMillis() and ToUnixMillis() >+ int64_t now_ms = absl::GetCurrentTimeNanos() / 1000000; >+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixMillis, absl::ToUnixMillis, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixMillis, absl::ToUnixMillis, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixMillis, absl::ToUnixMillis, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(now_ms, absl::FromUnixMillis, absl::ToUnixMillis, >+ testing::Eq) >+ << now_ms; >+ >+ // FromUnixSeconds() and ToUnixSeconds() >+ int64_t now_s = std::time(nullptr); >+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixSeconds, absl::ToUnixSeconds, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixSeconds, absl::ToUnixSeconds, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixSeconds, absl::ToUnixSeconds, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(now_s, absl::FromUnixSeconds, absl::ToUnixSeconds, >+ testing::Eq) >+ << now_s; >+ >+ // FromTimeT() and ToTimeT() >+ time_t now_time_t = std::time(nullptr); >+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromTimeT, absl::ToTimeT, testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromTimeT, absl::ToTimeT, testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromTimeT, absl::ToTimeT, testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(now_time_t, absl::FromTimeT, absl::ToTimeT, >+ testing::Eq) >+ << now_time_t; >+ >+ // TimeFromTimeval() and ToTimeval() >+ timeval tv; >+ tv.tv_sec = -1; >+ tv.tv_usec = 0; >+ TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval, >+ TimevalMatcher); >+ tv.tv_sec = -1; >+ tv.tv_usec = 999999; >+ TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval, >+ TimevalMatcher); >+ tv.tv_sec = 0; >+ tv.tv_usec = 0; >+ TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval, >+ TimevalMatcher); >+ tv.tv_sec = 0; >+ tv.tv_usec = 1; >+ TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval, >+ TimevalMatcher); >+ tv.tv_sec = 1; >+ tv.tv_usec = 0; >+ TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval, >+ TimevalMatcher); >+ >+ // TimeFromTimespec() and ToTimespec() >+ timespec ts; >+ ts.tv_sec = -1; >+ ts.tv_nsec = 0; >+ TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec, >+ TimespecMatcher); >+ ts.tv_sec = -1; >+ ts.tv_nsec = 999999999; >+ TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec, >+ TimespecMatcher); >+ ts.tv_sec = 0; >+ ts.tv_nsec = 0; >+ TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec, >+ TimespecMatcher); >+ ts.tv_sec = 0; >+ ts.tv_nsec = 1; >+ TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec, >+ TimespecMatcher); >+ ts.tv_sec = 1; >+ ts.tv_nsec = 0; >+ TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec, >+ TimespecMatcher); >+ >+ // FromUDate() and ToUDate() >+ double now_ud = absl::GetCurrentTimeNanos() / 1000000; >+ TEST_CONVERSION_ROUND_TRIP(-1.5, absl::FromUDate, absl::ToUDate, >+ testing::DoubleEq); >+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUDate, absl::ToUDate, >+ testing::DoubleEq); >+ TEST_CONVERSION_ROUND_TRIP(-0.5, absl::FromUDate, absl::ToUDate, >+ testing::DoubleEq); >+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUDate, absl::ToUDate, >+ testing::DoubleEq); >+ TEST_CONVERSION_ROUND_TRIP(0.5, absl::FromUDate, absl::ToUDate, >+ testing::DoubleEq); >+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUDate, absl::ToUDate, >+ testing::DoubleEq); >+ TEST_CONVERSION_ROUND_TRIP(1.5, absl::FromUDate, absl::ToUDate, >+ testing::DoubleEq); >+ TEST_CONVERSION_ROUND_TRIP(now_ud, absl::FromUDate, absl::ToUDate, >+ testing::DoubleEq) >+ << std::fixed << std::setprecision(17) << now_ud; >+ >+ // FromUniversal() and ToUniversal() >+ int64_t now_uni = ((719162LL * (24 * 60 * 60)) * (1000 * 1000 * 10)) + >+ (absl::GetCurrentTimeNanos() / 100); >+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUniversal, absl::ToUniversal, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUniversal, absl::ToUniversal, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUniversal, absl::ToUniversal, >+ testing::Eq); >+ TEST_CONVERSION_ROUND_TRIP(now_uni, absl::FromUniversal, absl::ToUniversal, >+ testing::Eq) >+ << now_uni; >+ >+#undef TEST_CONVERSION_ROUND_TRIP >+} >+ >+template <typename Duration> >+std::chrono::system_clock::time_point MakeChronoUnixTime(const Duration& d) { >+ return std::chrono::system_clock::from_time_t(0) + d; >+} >+ >+TEST(Time, FromChrono) { >+ EXPECT_EQ(absl::FromTimeT(-1), >+ absl::FromChrono(std::chrono::system_clock::from_time_t(-1))); >+ EXPECT_EQ(absl::FromTimeT(0), >+ absl::FromChrono(std::chrono::system_clock::from_time_t(0))); >+ EXPECT_EQ(absl::FromTimeT(1), >+ absl::FromChrono(std::chrono::system_clock::from_time_t(1))); >+ >+ EXPECT_EQ( >+ absl::FromUnixMillis(-1), >+ absl::FromChrono(MakeChronoUnixTime(std::chrono::milliseconds(-1)))); >+ EXPECT_EQ(absl::FromUnixMillis(0), >+ absl::FromChrono(MakeChronoUnixTime(std::chrono::milliseconds(0)))); >+ EXPECT_EQ(absl::FromUnixMillis(1), >+ absl::FromChrono(MakeChronoUnixTime(std::chrono::milliseconds(1)))); >+ >+ // Chrono doesn't define exactly its range and precision (neither does >+ // absl::Time), so let's simply test +/- ~100 years to make sure things work. >+ const auto century_sec = 60 * 60 * 24 * 365 * int64_t{100}; >+ const auto century = std::chrono::seconds(century_sec); >+ const auto chrono_future = MakeChronoUnixTime(century); >+ const auto chrono_past = MakeChronoUnixTime(-century); >+ EXPECT_EQ(absl::FromUnixSeconds(century_sec), >+ absl::FromChrono(chrono_future)); >+ EXPECT_EQ(absl::FromUnixSeconds(-century_sec), absl::FromChrono(chrono_past)); >+ >+ // Roundtrip them both back to chrono. >+ EXPECT_EQ(chrono_future, >+ absl::ToChronoTime(absl::FromUnixSeconds(century_sec))); >+ EXPECT_EQ(chrono_past, >+ absl::ToChronoTime(absl::FromUnixSeconds(-century_sec))); >+} >+ >+TEST(Time, ToChronoTime) { >+ EXPECT_EQ(std::chrono::system_clock::from_time_t(-1), >+ absl::ToChronoTime(absl::FromTimeT(-1))); >+ EXPECT_EQ(std::chrono::system_clock::from_time_t(0), >+ absl::ToChronoTime(absl::FromTimeT(0))); >+ EXPECT_EQ(std::chrono::system_clock::from_time_t(1), >+ absl::ToChronoTime(absl::FromTimeT(1))); >+ >+ EXPECT_EQ(MakeChronoUnixTime(std::chrono::milliseconds(-1)), >+ absl::ToChronoTime(absl::FromUnixMillis(-1))); >+ EXPECT_EQ(MakeChronoUnixTime(std::chrono::milliseconds(0)), >+ absl::ToChronoTime(absl::FromUnixMillis(0))); >+ EXPECT_EQ(MakeChronoUnixTime(std::chrono::milliseconds(1)), >+ absl::ToChronoTime(absl::FromUnixMillis(1))); >+ >+ // Time before the Unix epoch should floor, not trunc. >+ const auto tick = absl::Nanoseconds(1) / 4; >+ EXPECT_EQ(std::chrono::system_clock::from_time_t(0) - >+ std::chrono::system_clock::duration(1), >+ absl::ToChronoTime(absl::UnixEpoch() - tick)); >+} >+ >+TEST(Time, ConvertDateTime) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ const absl::TimeZone goog = >+ absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ const absl::TimeZone nyc = >+ absl::time_internal::LoadTimeZone("America/New_York"); >+ const std::string fmt = "%a, %e %b %Y %H:%M:%S %z (%Z)"; >+ >+ // A simple case of normalization. >+ absl::TimeConversion oct32 = ConvertDateTime(2013, 10, 32, 8, 30, 0, goog); >+ EXPECT_TRUE(oct32.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, oct32.kind); >+ absl::TimeConversion nov01 = ConvertDateTime(2013, 11, 1, 8, 30, 0, goog); >+ EXPECT_FALSE(nov01.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, nov01.kind); >+ EXPECT_EQ(oct32.pre, nov01.pre); >+ EXPECT_EQ("Fri, 1 Nov 2013 08:30:00 -0700 (PDT)", >+ absl::FormatTime(fmt, nov01.pre, goog)); >+ >+ // A Spring DST transition, when there is a gap in civil time >+ // and we prefer the later of the possible interpretations of a >+ // non-existent time. >+ absl::TimeConversion mar13 = ConvertDateTime(2011, 3, 13, 2, 15, 0, nyc); >+ EXPECT_FALSE(mar13.normalized); >+ EXPECT_EQ(absl::TimeConversion::SKIPPED, mar13.kind); >+ EXPECT_EQ("Sun, 13 Mar 2011 03:15:00 -0400 (EDT)", >+ absl::FormatTime(fmt, mar13.pre, nyc)); >+ EXPECT_EQ("Sun, 13 Mar 2011 03:00:00 -0400 (EDT)", >+ absl::FormatTime(fmt, mar13.trans, nyc)); >+ EXPECT_EQ("Sun, 13 Mar 2011 01:15:00 -0500 (EST)", >+ absl::FormatTime(fmt, mar13.post, nyc)); >+ EXPECT_EQ(mar13.pre, absl::FromDateTime(2011, 3, 13, 2, 15, 0, nyc)); >+ >+ // A Fall DST transition, when civil times are repeated and >+ // we prefer the earlier of the possible interpretations of an >+ // ambiguous time. >+ absl::TimeConversion nov06 = ConvertDateTime(2011, 11, 6, 1, 15, 0, nyc); >+ EXPECT_FALSE(nov06.normalized); >+ EXPECT_EQ(absl::TimeConversion::REPEATED, nov06.kind); >+ EXPECT_EQ("Sun, 6 Nov 2011 01:15:00 -0400 (EDT)", >+ absl::FormatTime(fmt, nov06.pre, nyc)); >+ EXPECT_EQ("Sun, 6 Nov 2011 01:00:00 -0500 (EST)", >+ absl::FormatTime(fmt, nov06.trans, nyc)); >+ EXPECT_EQ("Sun, 6 Nov 2011 01:15:00 -0500 (EST)", >+ absl::FormatTime(fmt, nov06.post, nyc)); >+ EXPECT_EQ(nov06.pre, absl::FromDateTime(2011, 11, 6, 1, 15, 0, nyc)); >+ >+ // Check that (time_t) -1 is handled correctly. >+ absl::TimeConversion minus1 = ConvertDateTime(1969, 12, 31, 18, 59, 59, nyc); >+ EXPECT_FALSE(minus1.normalized); >+ EXPECT_EQ(absl::TimeConversion::UNIQUE, minus1.kind); >+ EXPECT_EQ(-1, absl::ToTimeT(minus1.pre)); >+ EXPECT_EQ("Wed, 31 Dec 1969 18:59:59 -0500 (EST)", >+ absl::FormatTime(fmt, minus1.pre, nyc)); >+ EXPECT_EQ("Wed, 31 Dec 1969 23:59:59 +0000 (UTC)", >+ absl::FormatTime(fmt, minus1.pre, utc)); >+} >+ >+// FromDateTime(year, mon, day, hour, min, sec, UTCTimeZone()) has >+// a specialized fastpath implementation which we exercise here. >+TEST(Time, FromDateTimeUTC) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ const std::string fmt = "%a, %e %b %Y %H:%M:%S %z (%Z)"; >+ const int kMax = std::numeric_limits<int>::max(); >+ const int kMin = std::numeric_limits<int>::min(); >+ absl::Time t; >+ >+ // 292091940881 is the last positive year to use the fastpath. >+ t = absl::FromDateTime(292091940881, kMax, kMax, kMax, kMax, kMax, utc); >+ EXPECT_EQ("Fri, 25 Nov 292277026596 12:21:07 +0000 (UTC)", >+ absl::FormatTime(fmt, t, utc)); >+ t = absl::FromDateTime(292091940882, kMax, kMax, kMax, kMax, kMax, utc); >+ EXPECT_EQ("infinite-future", absl::FormatTime(fmt, t, utc)); // no overflow >+ t = absl::FromDateTime( >+ std::numeric_limits<int64_t>::max(), kMax, kMax, kMax, kMax, kMax, utc); >+ EXPECT_EQ("infinite-future", absl::FormatTime(fmt, t, utc)); // no overflow >+ >+ // -292091936940 is the last negative year to use the fastpath. >+ t = absl::FromDateTime(-292091936940, kMin, kMin, kMin, kMin, kMin, utc); >+ EXPECT_EQ("Fri, 1 Nov -292277022657 10:37:52 +0000 (UTC)", >+ absl::FormatTime(fmt, t, utc)); >+ t = absl::FromDateTime(-292091936941, kMin, kMin, kMin, kMin, kMin, utc); >+ EXPECT_EQ("infinite-past", absl::FormatTime(fmt, t, utc)); // no underflow >+ t = absl::FromDateTime( >+ std::numeric_limits<int64_t>::min(), kMin, kMin, kMin, kMin, kMin, utc); >+ EXPECT_EQ("infinite-past", absl::FormatTime(fmt, t, utc)); // no overflow >+ >+ // Check that we're counting leap years correctly. >+ t = absl::FromDateTime(1900, 2, 28, 23, 59, 59, utc); >+ EXPECT_EQ("Wed, 28 Feb 1900 23:59:59 +0000 (UTC)", >+ absl::FormatTime(fmt, t, utc)); >+ t = absl::FromDateTime(1900, 3, 1, 0, 0, 0, utc); >+ EXPECT_EQ("Thu, 1 Mar 1900 00:00:00 +0000 (UTC)", >+ absl::FormatTime(fmt, t, utc)); >+ t = absl::FromDateTime(2000, 2, 29, 23, 59, 59, utc); >+ EXPECT_EQ("Tue, 29 Feb 2000 23:59:59 +0000 (UTC)", >+ absl::FormatTime(fmt, t, utc)); >+ t = absl::FromDateTime(2000, 3, 1, 0, 0, 0, utc); >+ EXPECT_EQ("Wed, 1 Mar 2000 00:00:00 +0000 (UTC)", >+ absl::FormatTime(fmt, t, utc)); >+ >+ // Check normalization. >+ const std::string ymdhms = "%Y-%m-%d %H:%M:%S"; >+ t = absl::FromDateTime(2015, 1, 1, 0, 0, 60, utc); >+ EXPECT_EQ("2015-01-01 00:01:00", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, 1, 1, 0, 60, 0, utc); >+ EXPECT_EQ("2015-01-01 01:00:00", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, 1, 1, 24, 0, 0, utc); >+ EXPECT_EQ("2015-01-02 00:00:00", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, 1, 32, 0, 0, 0, utc); >+ EXPECT_EQ("2015-02-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, 13, 1, 0, 0, 0, utc); >+ EXPECT_EQ("2016-01-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, 13, 32, 60, 60, 60, utc); >+ EXPECT_EQ("2016-02-03 13:01:00", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, 1, 1, 0, 0, -1, utc); >+ EXPECT_EQ("2014-12-31 23:59:59", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, 1, 1, 0, -1, 0, utc); >+ EXPECT_EQ("2014-12-31 23:59:00", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, 1, 1, -1, 0, 0, utc); >+ EXPECT_EQ("2014-12-31 23:00:00", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, 1, -1, 0, 0, 0, utc); >+ EXPECT_EQ("2014-12-30 00:00:00", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, -1, 1, 0, 0, 0, utc); >+ EXPECT_EQ("2014-11-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); >+ t = absl::FromDateTime(2015, -1, -1, -1, -1, -1, utc); >+ EXPECT_EQ("2014-10-29 22:58:59", absl::FormatTime(ymdhms, t, utc)); >+} >+ >+TEST(Time, ToTM) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ >+ // Compares the results of ToTM() to gmtime_r() for lots of times over the >+ // course of a few days. >+ const absl::Time start = absl::FromDateTime(2014, 1, 2, 3, 4, 5, utc); >+ const absl::Time end = absl::FromDateTime(2014, 1, 5, 3, 4, 5, utc); >+ for (absl::Time t = start; t < end; t += absl::Seconds(30)) { >+ const struct tm tm_bt = ToTM(t, utc); >+ const time_t tt = absl::ToTimeT(t); >+ struct tm tm_lc; >+#ifdef _WIN32 >+ gmtime_s(&tm_lc, &tt); >+#else >+ gmtime_r(&tt, &tm_lc); >+#endif >+ EXPECT_EQ(tm_lc.tm_year, tm_bt.tm_year); >+ EXPECT_EQ(tm_lc.tm_mon, tm_bt.tm_mon); >+ EXPECT_EQ(tm_lc.tm_mday, tm_bt.tm_mday); >+ EXPECT_EQ(tm_lc.tm_hour, tm_bt.tm_hour); >+ EXPECT_EQ(tm_lc.tm_min, tm_bt.tm_min); >+ EXPECT_EQ(tm_lc.tm_sec, tm_bt.tm_sec); >+ EXPECT_EQ(tm_lc.tm_wday, tm_bt.tm_wday); >+ EXPECT_EQ(tm_lc.tm_yday, tm_bt.tm_yday); >+ EXPECT_EQ(tm_lc.tm_isdst, tm_bt.tm_isdst); >+ >+ ASSERT_FALSE(HasFailure()); >+ } >+ >+ // Checks that the tm_isdst field is correct when in standard time. >+ const absl::TimeZone nyc = >+ absl::time_internal::LoadTimeZone("America/New_York"); >+ absl::Time t = absl::FromDateTime(2014, 3, 1, 0, 0, 0, nyc); >+ struct tm tm = ToTM(t, nyc); >+ EXPECT_FALSE(tm.tm_isdst); >+ >+ // Checks that the tm_isdst field is correct when in daylight time. >+ t = absl::FromDateTime(2014, 4, 1, 0, 0, 0, nyc); >+ tm = ToTM(t, nyc); >+ EXPECT_TRUE(tm.tm_isdst); >+ >+ // Checks overflow. >+ tm = ToTM(absl::InfiniteFuture(), nyc); >+ EXPECT_EQ(std::numeric_limits<int>::max() - 1900, tm.tm_year); >+ EXPECT_EQ(11, tm.tm_mon); >+ EXPECT_EQ(31, tm.tm_mday); >+ EXPECT_EQ(23, tm.tm_hour); >+ EXPECT_EQ(59, tm.tm_min); >+ EXPECT_EQ(59, tm.tm_sec); >+ EXPECT_EQ(4, tm.tm_wday); >+ EXPECT_EQ(364, tm.tm_yday); >+ EXPECT_FALSE(tm.tm_isdst); >+ >+ // Checks underflow. >+ tm = ToTM(absl::InfinitePast(), nyc); >+ EXPECT_EQ(std::numeric_limits<int>::min(), tm.tm_year); >+ EXPECT_EQ(0, tm.tm_mon); >+ EXPECT_EQ(1, tm.tm_mday); >+ EXPECT_EQ(0, tm.tm_hour); >+ EXPECT_EQ(0, tm.tm_min); >+ EXPECT_EQ(0, tm.tm_sec); >+ EXPECT_EQ(0, tm.tm_wday); >+ EXPECT_EQ(0, tm.tm_yday); >+ EXPECT_FALSE(tm.tm_isdst); >+} >+ >+TEST(Time, FromTM) { >+ const absl::TimeZone nyc = >+ absl::time_internal::LoadTimeZone("America/New_York"); >+ >+ // Verifies that tm_isdst doesn't affect anything when the time is unique. >+ struct tm tm; >+ std::memset(&tm, 0, sizeof(tm)); >+ tm.tm_year = 2014 - 1900; >+ tm.tm_mon = 6 - 1; >+ tm.tm_mday = 28; >+ tm.tm_hour = 1; >+ tm.tm_min = 2; >+ tm.tm_sec = 3; >+ tm.tm_isdst = -1; >+ absl::Time t = FromTM(tm, nyc); >+ EXPECT_EQ("2014-06-28T01:02:03-04:00", absl::FormatTime(t, nyc)); // DST >+ tm.tm_isdst = 0; >+ t = FromTM(tm, nyc); >+ EXPECT_EQ("2014-06-28T01:02:03-04:00", absl::FormatTime(t, nyc)); // DST >+ tm.tm_isdst = 1; >+ t = FromTM(tm, nyc); >+ EXPECT_EQ("2014-06-28T01:02:03-04:00", absl::FormatTime(t, nyc)); // DST >+ >+ // Adjusts tm to refer to an ambiguous time. >+ tm.tm_year = 2014 - 1900; >+ tm.tm_mon = 11 - 1; >+ tm.tm_mday = 2; >+ tm.tm_hour = 1; >+ tm.tm_min = 30; >+ tm.tm_sec = 42; >+ tm.tm_isdst = -1; >+ t = FromTM(tm, nyc); >+ EXPECT_EQ("2014-11-02T01:30:42-04:00", absl::FormatTime(t, nyc)); // DST >+ tm.tm_isdst = 0; >+ t = FromTM(tm, nyc); >+ EXPECT_EQ("2014-11-02T01:30:42-05:00", absl::FormatTime(t, nyc)); // STD >+ tm.tm_isdst = 1; >+ t = FromTM(tm, nyc); >+ EXPECT_EQ("2014-11-02T01:30:42-04:00", absl::FormatTime(t, nyc)); // DST >+ >+ // Adjusts tm to refer to a skipped time. >+ tm.tm_year = 2014 - 1900; >+ tm.tm_mon = 3 - 1; >+ tm.tm_mday = 9; >+ tm.tm_hour = 2; >+ tm.tm_min = 30; >+ tm.tm_sec = 42; >+ tm.tm_isdst = -1; >+ t = FromTM(tm, nyc); >+ EXPECT_EQ("2014-03-09T03:30:42-04:00", absl::FormatTime(t, nyc)); // DST >+ tm.tm_isdst = 0; >+ t = FromTM(tm, nyc); >+ EXPECT_EQ("2014-03-09T01:30:42-05:00", absl::FormatTime(t, nyc)); // STD >+ tm.tm_isdst = 1; >+ t = FromTM(tm, nyc); >+ EXPECT_EQ("2014-03-09T03:30:42-04:00", absl::FormatTime(t, nyc)); // DST >+} >+ >+TEST(Time, TMRoundTrip) { >+ const absl::TimeZone nyc = >+ absl::time_internal::LoadTimeZone("America/New_York"); >+ >+ // Test round-tripping across a skipped transition >+ absl::Time start = absl::FromDateTime(2014, 3, 9, 0, 0, 0, nyc); >+ absl::Time end = absl::FromDateTime(2014, 3, 9, 4, 0, 0, nyc); >+ for (absl::Time t = start; t < end; t += absl::Minutes(1)) { >+ struct tm tm = ToTM(t, nyc); >+ absl::Time rt = FromTM(tm, nyc); >+ EXPECT_EQ(rt, t); >+ } >+ >+ // Test round-tripping across an ambiguous transition >+ start = absl::FromDateTime(2014, 11, 2, 0, 0, 0, nyc); >+ end = absl::FromDateTime(2014, 11, 2, 4, 0, 0, nyc); >+ for (absl::Time t = start; t < end; t += absl::Minutes(1)) { >+ struct tm tm = ToTM(t, nyc); >+ absl::Time rt = FromTM(tm, nyc); >+ EXPECT_EQ(rt, t); >+ } >+ >+ // Test round-tripping of unique instants crossing a day boundary >+ start = absl::FromDateTime(2014, 6, 27, 22, 0, 0, nyc); >+ end = absl::FromDateTime(2014, 6, 28, 4, 0, 0, nyc); >+ for (absl::Time t = start; t < end; t += absl::Minutes(1)) { >+ struct tm tm = ToTM(t, nyc); >+ absl::Time rt = FromTM(tm, nyc); >+ EXPECT_EQ(rt, t); >+ } >+} >+ >+TEST(Time, Range) { >+ // The API's documented range is +/- 100 billion years. >+ const absl::Duration range = absl::Hours(24) * 365.2425 * 100000000000; >+ >+ // Arithmetic and comparison still works at +/-range around base values. >+ absl::Time bases[2] = {absl::UnixEpoch(), absl::Now()}; >+ for (const auto base : bases) { >+ absl::Time bottom = base - range; >+ EXPECT_GT(bottom, bottom - absl::Nanoseconds(1)); >+ EXPECT_LT(bottom, bottom + absl::Nanoseconds(1)); >+ absl::Time top = base + range; >+ EXPECT_GT(top, top - absl::Nanoseconds(1)); >+ EXPECT_LT(top, top + absl::Nanoseconds(1)); >+ absl::Duration full_range = 2 * range; >+ EXPECT_EQ(full_range, top - bottom); >+ EXPECT_EQ(-full_range, bottom - top); >+ } >+} >+ >+TEST(Time, Limits) { >+ // It is an implementation detail that Time().rep_ == ZeroDuration(), >+ // and that the resolution of a Duration is 1/4 of a nanosecond. >+ const absl::Time zero; >+ const absl::Time max = >+ zero + absl::Seconds(std::numeric_limits<int64_t>::max()) + >+ absl::Nanoseconds(999999999) + absl::Nanoseconds(3) / 4; >+ const absl::Time min = >+ zero + absl::Seconds(std::numeric_limits<int64_t>::min()); >+ >+ // Some simple max/min bounds checks. >+ EXPECT_LT(max, absl::InfiniteFuture()); >+ EXPECT_GT(min, absl::InfinitePast()); >+ EXPECT_LT(zero, max); >+ EXPECT_GT(zero, min); >+ EXPECT_GE(absl::UnixEpoch(), min); >+ EXPECT_LT(absl::UnixEpoch(), max); >+ >+ // Check sign of Time differences. >+ EXPECT_LT(absl::ZeroDuration(), max - zero); >+ EXPECT_LT(absl::ZeroDuration(), >+ zero - absl::Nanoseconds(1) / 4 - min); // avoid zero - min >+ >+ // Arithmetic works at max - 0.25ns and min + 0.25ns. >+ EXPECT_GT(max, max - absl::Nanoseconds(1) / 4); >+ EXPECT_LT(min, min + absl::Nanoseconds(1) / 4); >+} >+ >+TEST(Time, ConversionSaturation) { >+ const absl::TimeZone utc = absl::UTCTimeZone(); >+ absl::Time t; >+ >+ const auto max_time_t = std::numeric_limits<time_t>::max(); >+ const auto min_time_t = std::numeric_limits<time_t>::min(); >+ time_t tt = max_time_t - 1; >+ t = absl::FromTimeT(tt); >+ tt = absl::ToTimeT(t); >+ EXPECT_EQ(max_time_t - 1, tt); >+ t += absl::Seconds(1); >+ tt = absl::ToTimeT(t); >+ EXPECT_EQ(max_time_t, tt); >+ t += absl::Seconds(1); // no effect >+ tt = absl::ToTimeT(t); >+ EXPECT_EQ(max_time_t, tt); >+ >+ tt = min_time_t + 1; >+ t = absl::FromTimeT(tt); >+ tt = absl::ToTimeT(t); >+ EXPECT_EQ(min_time_t + 1, tt); >+ t -= absl::Seconds(1); >+ tt = absl::ToTimeT(t); >+ EXPECT_EQ(min_time_t, tt); >+ t -= absl::Seconds(1); // no effect >+ tt = absl::ToTimeT(t); >+ EXPECT_EQ(min_time_t, tt); >+ >+ const auto max_timeval_sec = >+ std::numeric_limits<decltype(timeval::tv_sec)>::max(); >+ const auto min_timeval_sec = >+ std::numeric_limits<decltype(timeval::tv_sec)>::min(); >+ timeval tv; >+ tv.tv_sec = max_timeval_sec; >+ tv.tv_usec = 999998; >+ t = absl::TimeFromTimeval(tv); >+ tv = ToTimeval(t); >+ EXPECT_EQ(max_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(999998, tv.tv_usec); >+ t += absl::Microseconds(1); >+ tv = ToTimeval(t); >+ EXPECT_EQ(max_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(999999, tv.tv_usec); >+ t += absl::Microseconds(1); // no effect >+ tv = ToTimeval(t); >+ EXPECT_EQ(max_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(999999, tv.tv_usec); >+ >+ tv.tv_sec = min_timeval_sec; >+ tv.tv_usec = 1; >+ t = absl::TimeFromTimeval(tv); >+ tv = ToTimeval(t); >+ EXPECT_EQ(min_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(1, tv.tv_usec); >+ t -= absl::Microseconds(1); >+ tv = ToTimeval(t); >+ EXPECT_EQ(min_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(0, tv.tv_usec); >+ t -= absl::Microseconds(1); // no effect >+ tv = ToTimeval(t); >+ EXPECT_EQ(min_timeval_sec, tv.tv_sec); >+ EXPECT_EQ(0, tv.tv_usec); >+ >+ const auto max_timespec_sec = >+ std::numeric_limits<decltype(timespec::tv_sec)>::max(); >+ const auto min_timespec_sec = >+ std::numeric_limits<decltype(timespec::tv_sec)>::min(); >+ timespec ts; >+ ts.tv_sec = max_timespec_sec; >+ ts.tv_nsec = 999999998; >+ t = absl::TimeFromTimespec(ts); >+ ts = absl::ToTimespec(t); >+ EXPECT_EQ(max_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(999999998, ts.tv_nsec); >+ t += absl::Nanoseconds(1); >+ ts = absl::ToTimespec(t); >+ EXPECT_EQ(max_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(999999999, ts.tv_nsec); >+ t += absl::Nanoseconds(1); // no effect >+ ts = absl::ToTimespec(t); >+ EXPECT_EQ(max_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(999999999, ts.tv_nsec); >+ >+ ts.tv_sec = min_timespec_sec; >+ ts.tv_nsec = 1; >+ t = absl::TimeFromTimespec(ts); >+ ts = absl::ToTimespec(t); >+ EXPECT_EQ(min_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(1, ts.tv_nsec); >+ t -= absl::Nanoseconds(1); >+ ts = absl::ToTimespec(t); >+ EXPECT_EQ(min_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(0, ts.tv_nsec); >+ t -= absl::Nanoseconds(1); // no effect >+ ts = absl::ToTimespec(t); >+ EXPECT_EQ(min_timespec_sec, ts.tv_sec); >+ EXPECT_EQ(0, ts.tv_nsec); >+ >+ // Checks how Time::In() saturates on infinities. >+ absl::Time::Breakdown bd = absl::InfiniteFuture().In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, std::numeric_limits<int64_t>::max(), 12, 31, 23, >+ 59, 59, 0, false); >+ EXPECT_EQ(absl::InfiniteDuration(), bd.subsecond); >+ EXPECT_EQ(4, bd.weekday); // Thursday >+ EXPECT_EQ(365, bd.yearday); >+ EXPECT_STREQ("-00", bd.zone_abbr); // artifact of absl::Time::In() >+ bd = absl::InfinitePast().In(utc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, std::numeric_limits<int64_t>::min(), 1, 1, 0, 0, >+ 0, 0, false); >+ EXPECT_EQ(-absl::InfiniteDuration(), bd.subsecond); >+ EXPECT_EQ(7, bd.weekday); // Sunday >+ EXPECT_EQ(1, bd.yearday); >+ EXPECT_STREQ("-00", bd.zone_abbr); // artifact of absl::Time::In() >+ >+ // Approach the maximal Time value from below. >+ t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 6, utc); >+ EXPECT_EQ("292277026596-12-04T15:30:06+00:00", >+ absl::FormatTime(absl::RFC3339_full, t, utc)); >+ t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 7, utc); >+ EXPECT_EQ("292277026596-12-04T15:30:07+00:00", >+ absl::FormatTime(absl::RFC3339_full, t, utc)); >+ EXPECT_EQ( >+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()), t); >+ >+ // Checks that we can also get the maximal Time value for a far-east zone. >+ const absl::TimeZone plus14 = absl::FixedTimeZone(14 * 60 * 60); >+ t = absl::FromDateTime(292277026596, 12, 5, 5, 30, 7, plus14); >+ EXPECT_EQ("292277026596-12-05T05:30:07+14:00", >+ absl::FormatTime(absl::RFC3339_full, t, plus14)); >+ EXPECT_EQ( >+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()), t); >+ >+ // One second later should push us to infinity. >+ t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 8, utc); >+ EXPECT_EQ("infinite-future", absl::FormatTime(absl::RFC3339_full, t, utc)); >+ >+ // Approach the minimal Time value from above. >+ t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 53, utc); >+ EXPECT_EQ("-292277022657-01-27T08:29:53+00:00", >+ absl::FormatTime(absl::RFC3339_full, t, utc)); >+ t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 52, utc); >+ EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", >+ absl::FormatTime(absl::RFC3339_full, t, utc)); >+ EXPECT_EQ( >+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()), t); >+ >+ // Checks that we can also get the minimal Time value for a far-west zone. >+ const absl::TimeZone minus12 = absl::FixedTimeZone(-12 * 60 * 60); >+ t = absl::FromDateTime(-292277022657, 1, 26, 20, 29, 52, minus12); >+ EXPECT_EQ("-292277022657-01-26T20:29:52-12:00", >+ absl::FormatTime(absl::RFC3339_full, t, minus12)); >+ EXPECT_EQ( >+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()), t); >+ >+ // One second before should push us to -infinity. >+ t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 51, utc); >+ EXPECT_EQ("infinite-past", absl::FormatTime(absl::RFC3339_full, t, utc)); >+} >+ >+// In zones with POSIX-style recurring rules we use special logic to >+// handle conversions in the distant future. Here we check the limits >+// of those conversions, particularly with respect to integer overflow. >+TEST(Time, ExtendedConversionSaturation) { >+ const absl::TimeZone syd = >+ absl::time_internal::LoadTimeZone("Australia/Sydney"); >+ const absl::TimeZone nyc = >+ absl::time_internal::LoadTimeZone("America/New_York"); >+ const absl::Time max = >+ absl::FromUnixSeconds(std::numeric_limits<int64_t>::max()); >+ absl::Time::Breakdown bd; >+ absl::Time t; >+ >+ // The maximal time converted in each zone. >+ bd = max.In(syd); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 292277026596, 12, 5, 2, 30, 7, 39600, true); >+ t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 7, syd); >+ EXPECT_EQ(max, t); >+ bd = max.In(nyc); >+ ABSL_INTERNAL_EXPECT_TIME(bd, 292277026596, 12, 4, 10, 30, 7, -18000, false); >+ t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 7, nyc); >+ EXPECT_EQ(max, t); >+ >+ // One second later should push us to infinity. >+ t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 8, syd); >+ EXPECT_EQ(absl::InfiniteFuture(), t); >+ t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 8, nyc); >+ EXPECT_EQ(absl::InfiniteFuture(), t); >+ >+ // And we should stick there. >+ t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 9, syd); >+ EXPECT_EQ(absl::InfiniteFuture(), t); >+ t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 9, nyc); >+ EXPECT_EQ(absl::InfiniteFuture(), t); >+ >+ // All the way up to a saturated date/time, without overflow. >+ t = absl::FromDateTime( >+ std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59, syd); >+ EXPECT_EQ(absl::InfiniteFuture(), t); >+ t = absl::FromDateTime( >+ std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59, nyc); >+ EXPECT_EQ(absl::InfiniteFuture(), t); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_zone_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_zone_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..43d919040445cab663550da3916ef23f0969c45b >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/time/time_zone_test.cc >@@ -0,0 +1,97 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/time/internal/cctz/include/cctz/time_zone.h" >+ >+#include "gtest/gtest.h" >+#include "absl/time/internal/test_util.h" >+#include "absl/time/time.h" >+ >+namespace cctz = absl::time_internal::cctz; >+ >+namespace { >+ >+TEST(TimeZone, ValueSemantics) { >+ absl::TimeZone tz; >+ absl::TimeZone tz2 = tz; // Copy-construct >+ EXPECT_EQ(tz, tz2); >+ tz2 = tz; // Copy-assign >+ EXPECT_EQ(tz, tz2); >+} >+ >+TEST(TimeZone, Equality) { >+ absl::TimeZone a, b; >+ EXPECT_EQ(a, b); >+ EXPECT_EQ(a.name(), b.name()); >+ >+ absl::TimeZone implicit_utc; >+ absl::TimeZone explicit_utc = absl::UTCTimeZone(); >+ EXPECT_EQ(implicit_utc, explicit_utc); >+ EXPECT_EQ(implicit_utc.name(), explicit_utc.name()); >+ >+ absl::TimeZone la = absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ absl::TimeZone nyc = absl::time_internal::LoadTimeZone("America/New_York"); >+ EXPECT_NE(la, nyc); >+} >+ >+TEST(TimeZone, CCTZConversion) { >+ const cctz::time_zone cz = cctz::utc_time_zone(); >+ const absl::TimeZone tz(cz); >+ EXPECT_EQ(cz, cctz::time_zone(tz)); >+} >+ >+TEST(TimeZone, DefaultTimeZones) { >+ absl::TimeZone tz; >+ EXPECT_EQ("UTC", absl::TimeZone().name()); >+ EXPECT_EQ("UTC", absl::UTCTimeZone().name()); >+} >+ >+TEST(TimeZone, FixedTimeZone) { >+ const absl::TimeZone tz = absl::FixedTimeZone(123); >+ const cctz::time_zone cz = cctz::fixed_time_zone(cctz::seconds(123)); >+ EXPECT_EQ(tz, absl::TimeZone(cz)); >+} >+ >+TEST(TimeZone, LocalTimeZone) { >+ const absl::TimeZone local_tz = absl::LocalTimeZone(); >+ absl::TimeZone tz = absl::time_internal::LoadTimeZone("localtime"); >+ EXPECT_EQ(tz, local_tz); >+} >+ >+TEST(TimeZone, NamedTimeZones) { >+ absl::TimeZone nyc = absl::time_internal::LoadTimeZone("America/New_York"); >+ EXPECT_EQ("America/New_York", nyc.name()); >+ absl::TimeZone syd = absl::time_internal::LoadTimeZone("Australia/Sydney"); >+ EXPECT_EQ("Australia/Sydney", syd.name()); >+ absl::TimeZone fixed = absl::FixedTimeZone((((3 * 60) + 25) * 60) + 45); >+ EXPECT_EQ("Fixed/UTC+03:25:45", fixed.name()); >+} >+ >+TEST(TimeZone, Failures) { >+ absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ EXPECT_FALSE(LoadTimeZone("Invalid/TimeZone", &tz)); >+ EXPECT_EQ(absl::UTCTimeZone(), tz); // guaranteed fallback to UTC >+ >+ // Ensures that the load still fails on a subsequent attempt. >+ tz = absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ EXPECT_FALSE(LoadTimeZone("Invalid/TimeZone", &tz)); >+ EXPECT_EQ(absl::UTCTimeZone(), tz); // guaranteed fallback to UTC >+ >+ // Loading an empty std::string timezone should fail. >+ tz = absl::time_internal::LoadTimeZone("America/Los_Angeles"); >+ EXPECT_FALSE(LoadTimeZone("", &tz)); >+ EXPECT_EQ(absl::UTCTimeZone(), tz); // guaranteed fallback to UTC >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..096c119e638cbd35040550bed10b192e7b467401 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/BUILD.bazel >@@ -0,0 +1,280 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+ "ABSL_EXCEPTIONS_FLAG", >+) >+ >+package(default_visibility = ["//visibility:public"]) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+cc_library( >+ name = "any", >+ hdrs = ["any.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":bad_any_cast", >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ "//absl/meta:type_traits", >+ "//absl/utility", >+ ], >+) >+ >+cc_library( >+ name = "bad_any_cast", >+ hdrs = ["bad_any_cast.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":bad_any_cast_impl", >+ "//absl/base:config", >+ ], >+) >+ >+cc_library( >+ name = "bad_any_cast_impl", >+ srcs = [ >+ "bad_any_cast.cc", >+ "bad_any_cast.h", >+ ], >+ copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS, >+ visibility = ["//visibility:private"], >+ deps = [ >+ "//absl/base", >+ "//absl/base:config", >+ ], >+) >+ >+cc_test( >+ name = "any_test", >+ size = "small", >+ srcs = [ >+ "any_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":any", >+ "//absl/base", >+ "//absl/base:config", >+ "//absl/base:exception_testing", >+ "//absl/container:test_instance_tracker", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "any_test_noexceptions", >+ size = "small", >+ srcs = [ >+ "any_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":any", >+ "//absl/base", >+ "//absl/base:config", >+ "//absl/base:exception_testing", >+ "//absl/container:test_instance_tracker", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "any_exception_safety_test", >+ srcs = ["any_exception_safety_test.cc"], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":any", >+ "//absl/base:exception_safety_testing", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_library( >+ name = "span", >+ hdrs = ["span.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/algorithm", >+ "//absl/base:core_headers", >+ "//absl/base:throw_delegate", >+ "//absl/meta:type_traits", >+ ], >+) >+ >+cc_test( >+ name = "span_test", >+ size = "small", >+ srcs = ["span_test.cc"], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":span", >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ "//absl/base:exception_testing", >+ "//absl/container:fixed_array", >+ "//absl/container:inlined_vector", >+ "//absl/strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "span_test_noexceptions", >+ size = "small", >+ srcs = ["span_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":span", >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ "//absl/base:exception_testing", >+ "//absl/container:fixed_array", >+ "//absl/container:inlined_vector", >+ "//absl/strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_library( >+ name = "optional", >+ srcs = ["optional.cc"], >+ hdrs = ["optional.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":bad_optional_access", >+ "//absl/base:config", >+ "//absl/memory", >+ "//absl/meta:type_traits", >+ "//absl/utility", >+ ], >+) >+ >+cc_library( >+ name = "bad_optional_access", >+ srcs = ["bad_optional_access.cc"], >+ hdrs = ["bad_optional_access.h"], >+ copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ "//absl/base", >+ "//absl/base:config", >+ ], >+) >+ >+cc_library( >+ name = "bad_variant_access", >+ srcs = ["bad_variant_access.cc"], >+ hdrs = ["bad_variant_access.h"], >+ copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/base", >+ "//absl/base:config", >+ ], >+) >+ >+cc_test( >+ name = "optional_test", >+ size = "small", >+ srcs = [ >+ "optional_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":optional", >+ "//absl/base", >+ "//absl/base:config", >+ "//absl/meta:type_traits", >+ "//absl/strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "optional_exception_safety_test", >+ srcs = [ >+ "optional_exception_safety_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":optional", >+ "//absl/base:exception_safety_testing", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_library( >+ name = "variant", >+ srcs = ["internal/variant.h"], >+ hdrs = ["variant.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ ":bad_variant_access", >+ "//absl/base:base_internal", >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ "//absl/meta:type_traits", >+ "//absl/utility", >+ ], >+) >+ >+cc_test( >+ name = "variant_test", >+ size = "small", >+ srcs = ["variant_test.cc"], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":variant", >+ "//absl/base:config", >+ "//absl/base:core_headers", >+ "//absl/memory", >+ "//absl/meta:type_traits", >+ "//absl/strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >+ >+cc_test( >+ name = "variant_benchmark", >+ srcs = [ >+ "variant_benchmark.cc", >+ ], >+ copts = ABSL_TEST_COPTS, >+ tags = ["benchmark"], >+ deps = [ >+ ":variant", >+ "//absl/utility", >+ "@com_github_google_benchmark//:benchmark_main", >+ ], >+) >+ >+cc_test( >+ name = "variant_exception_safety_test", >+ size = "small", >+ srcs = [ >+ "variant_exception_safety_test.cc", >+ ], >+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, >+ deps = [ >+ ":variant", >+ "//absl/base:exception_safety_testing", >+ "//absl/memory", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..fd7e89dee34c3b32905a7fa78fbfbfe2abb01e55 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/BUILD.gn >@@ -0,0 +1,172 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("any") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "any.h", >+ ] >+ deps = [ >+ ":bad_any_cast", >+ "../base:config", >+ "../base:core_headers", >+ "../meta:type_traits", >+ "../utility", >+ ] >+} >+ >+source_set("bad_any_cast") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "bad_any_cast.h", >+ ] >+ deps = [ >+ ":bad_any_cast_impl", >+ "../base:config", >+ ] >+} >+ >+source_set("bad_any_cast_impl") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "bad_any_cast.cc", >+ ] >+ public = [ >+ "bad_any_cast.h", >+ ] >+ deps = [ >+ "../base", >+ "../base:config", >+ ] >+ visibility = [] >+ visibility += [ ":*" ] >+} >+ >+source_set("span") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "span.h", >+ ] >+ deps = [ >+ "../algorithm", >+ "../base:core_headers", >+ "../base:throw_delegate", >+ "../meta:type_traits", >+ ] >+} >+ >+source_set("optional") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "optional.cc", >+ ] >+ public = [ >+ "optional.h", >+ ] >+ deps = [ >+ ":bad_optional_access", >+ "../base:config", >+ "../memory", >+ "../meta:type_traits", >+ "../utility", >+ ] >+} >+ >+source_set("bad_optional_access") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "bad_optional_access.cc", >+ ] >+ public = [ >+ "bad_optional_access.h", >+ ] >+ deps = [ >+ "../base", >+ "../base:config", >+ ] >+} >+ >+source_set("bad_variant_access") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "bad_variant_access.cc", >+ ] >+ public = [ >+ "bad_variant_access.h", >+ ] >+ deps = [ >+ "../base", >+ "../base:config", >+ ] >+} >+ >+source_set("variant") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ sources = [ >+ "internal/variant.h", >+ ] >+ public = [ >+ "variant.h", >+ ] >+ deps = [ >+ ":bad_variant_access", >+ "../base:base_internal", >+ "../base:config", >+ "../base:core_headers", >+ "../meta:type_traits", >+ "../utility", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2f2e3a77808933caacf462a3a8b805773ae506ef >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/CMakeLists.txt >@@ -0,0 +1,228 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+list(APPEND TYPES_PUBLIC_HEADERS >+ "any.h" >+ "bad_any_cast.h" >+ "bad_optional_access.h" >+ "optional.h" >+ "span.h" >+ "variant.h" >+) >+ >+ >+# any library >+absl_header_library( >+ TARGET >+ absl_any >+ PUBLIC_LIBRARIES >+ absl::bad_any_cast >+ absl::base >+ absl::meta >+ absl::utility >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+ EXPORT_NAME >+ any >+) >+ >+# span library >+absl_header_library( >+ TARGET >+ absl_span >+ PUBLIC_LIBRARIES >+ absl::utility >+ EXPORT_NAME >+ span >+) >+ >+ >+# bad_any_cast library >+list(APPEND BAD_ANY_CAST_SRC >+ "bad_any_cast.cc" >+ ${TYPES_PUBLIC_HEADERS} >+) >+ >+absl_library( >+ TARGET >+ absl_bad_any_cast >+ SOURCES >+ ${BAD_ANY_CAST_SRC} >+ PUBLIC_LIBRARIES >+ EXPORT_NAME >+ bad_any_cast >+) >+ >+ >+# optional library >+list(APPEND OPTIONAL_SRC >+ "optional.cc" >+) >+ >+absl_library( >+ TARGET >+ absl_optional >+ SOURCES >+ ${OPTIONAL_SRC} >+ PUBLIC_LIBRARIES >+ absl::bad_optional_access >+ absl::base >+ absl::memory >+ absl::meta >+ absl::utility >+ EXPORT_NAME >+ optional >+) >+ >+ >+set(BAD_OPTIONAL_ACCESS_SRC "bad_optional_access.cc") >+set(BAD_OPTIONAL_ACCESS_LIBRARIES absl::base) >+ >+absl_library( >+ TARGET >+ absl_bad_optional_access >+ SOURCES >+ ${BAD_OPTIONAL_ACCESS_SRC} >+ PUBLIC_LIBRARIES >+ ${BAD_OPTIONAL_ACCESS_PUBLIC_LIBRARIES} >+ EXPORT_NAME >+ bad_optional_access >+) >+ >+# variant library >+absl_library( >+ TARGET >+ absl_variant >+ SOURCES >+ "bad_variant_access.h" "bad_variant_access.cc" "variant.h" "internal/variant.h" >+ PUBLIC_LIBRARIES >+ absl::base absl::meta absl::utility >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+ EXPORT_NAME >+ variant >+) >+ >+# >+## TESTS >+# >+ >+ >+# test any_test >+set(ANY_TEST_SRC "any_test.cc") >+set(ANY_TEST_PUBLIC_LIBRARIES absl::base absl::throw_delegate absl::any absl::bad_any_cast test_instance_tracker_lib) >+ >+absl_test( >+ TARGET >+ any_test >+ SOURCES >+ ${ANY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${ANY_TEST_PUBLIC_LIBRARIES} >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+) >+ >+ >+# test any_test_noexceptions >+absl_test( >+ TARGET >+ any_test_noexceptions >+ SOURCES >+ ${ANY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${ANY_TEST_PUBLIC_LIBRARIES} >+) >+ >+# test any_exception_safety_test >+set(ANY_EXCEPTION_SAFETY_TEST_SRC "any_exception_safety_test.cc") >+set(ANY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES >+ absl::any >+ absl::base >+ absl_base_internal_exception_safety_testing >+) >+ >+absl_test( >+ TARGET >+ any_exception_safety_test >+ SOURCES >+ ${ANY_EXCEPTION_SAFETY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${ANY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES} >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+) >+ >+ >+# test span_test >+set(SPAN_TEST_SRC "span_test.cc") >+set(SPAN_TEST_PUBLIC_LIBRARIES absl::base absl::strings absl::throw_delegate absl::span test_instance_tracker_lib) >+ >+absl_test( >+ TARGET >+ span_test >+ SOURCES >+ ${SPAN_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${SPAN_TEST_PUBLIC_LIBRARIES} >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+) >+ >+ >+# test span_test_noexceptions >+absl_test( >+ TARGET >+ span_test_noexceptions >+ SOURCES >+ ${SPAN_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${SPAN_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+ >+# test optional_test >+set(OPTIONAL_TEST_SRC "optional_test.cc") >+set(OPTIONAL_TEST_PUBLIC_LIBRARIES absl::base absl::throw_delegate absl::optional absl_bad_optional_access) >+ >+absl_test( >+ TARGET >+ optional_test >+ SOURCES >+ ${OPTIONAL_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${OPTIONAL_TEST_PUBLIC_LIBRARIES} >+) >+ >+ >+# test optional_exception_safety_test >+set(OPTIONAL_EXCEPTION_SAFETY_TEST_SRC "optional_exception_safety_test.cc") >+set(OPTIONAL_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES >+ absl::optional >+ absl_base_internal_exception_safety_testing >+) >+ >+absl_test( >+ TARGET >+ optional_exception_safety_test >+ SOURCES >+ ${OPTIONAL_EXCEPTION_SAFETY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${OPTIONAL_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES} >+ PRIVATE_COMPILE_FLAGS >+ ${ABSL_EXCEPTIONS_FLAG} >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/any.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/any.h >new file mode 100644 >index 0000000000000000000000000000000000000000..a973c6dab7e611feef430471538d2853a99ef223 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/any.h >@@ -0,0 +1,539 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// any.h >+// ----------------------------------------------------------------------------- >+// >+// This header file define the `absl::any` type for holding a type-safe value >+// of any type. The 'absl::any` type is useful for providing a way to hold >+// something that is, as yet, unspecified. Such unspecified types >+// traditionally are passed between API boundaries until they are later cast to >+// their "destination" types. To cast to such a destination type, use >+// `absl::any_cast()`. Note that when casting an `absl::any`, you must cast it >+// to an explicit type; implicit conversions will throw. >+// >+// Example: >+// >+// auto a = absl::any(65); >+// absl::any_cast<int>(a); // 65 >+// absl::any_cast<char>(a); // throws absl::bad_any_cast >+// absl::any_cast<std::string>(a); // throws absl::bad_any_cast >+// >+// `absl::any` is a C++11 compatible version of the C++17 `std::any` abstraction >+// and is designed to be a drop-in replacement for code compliant with C++17. >+// >+// Traditionally, the behavior of casting to a temporary unspecified type has >+// been accomplished with the `void *` paradigm, where the pointer was to some >+// other unspecified type. `absl::any` provides an "owning" version of `void *` >+// that avoids issues of pointer management. >+// >+// Note: just as in the case of `void *`, use of `absl::any` (and its C++17 >+// version `std::any`) is a code smell indicating that your API might not be >+// constructed correctly. We have seen that most uses of `any` are unwarranted, >+// and `absl::any`, like `std::any`, is difficult to use properly. Before using >+// this abstraction, make sure that you should not instead be rewriting your >+// code to be more specific. >+// >+// Abseil expects to release an `absl::variant` type shortly (a C++11 compatible >+// version of the C++17 `std::variant), which is generally preferred for use >+// over `absl::any`. >+#ifndef ABSL_TYPES_ANY_H_ >+#define ABSL_TYPES_ANY_H_ >+ >+#include "absl/base/config.h" >+#include "absl/utility/utility.h" >+ >+#ifdef ABSL_HAVE_STD_ANY >+ >+#include <any> >+ >+namespace absl { >+using std::any; >+using std::any_cast; >+using std::bad_any_cast; >+using std::make_any; >+} // namespace absl >+ >+#else // ABSL_HAVE_STD_ANY >+ >+#include <algorithm> >+#include <cstddef> >+#include <initializer_list> >+#include <memory> >+#include <stdexcept> >+#include <type_traits> >+#include <typeinfo> >+#include <utility> >+ >+#include "absl/base/macros.h" >+#include "absl/meta/type_traits.h" >+#include "absl/types/bad_any_cast.h" >+ >+// NOTE: This macro is an implementation detail that is undefined at the bottom >+// of the file. It is not intended for expansion directly from user code. >+#ifdef ABSL_ANY_DETAIL_HAS_RTTI >+#error ABSL_ANY_DETAIL_HAS_RTTI cannot be directly set >+#elif !defined(__GNUC__) || defined(__GXX_RTTI) >+#define ABSL_ANY_DETAIL_HAS_RTTI 1 >+#endif // !defined(__GNUC__) || defined(__GXX_RTTI) >+ >+namespace absl { >+ >+namespace any_internal { >+ >+template <typename Type> >+struct TypeTag { >+ constexpr static char dummy_var = 0; >+}; >+ >+template <typename Type> >+constexpr char TypeTag<Type>::dummy_var; >+ >+// FastTypeId<Type>() evaluates at compile/link-time to a unique pointer for the >+// passed in type. These are meant to be good match for keys into maps or >+// straight up comparisons. >+template<typename Type> >+constexpr inline const void* FastTypeId() { >+ return &TypeTag<Type>::dummy_var; >+} >+ >+} // namespace any_internal >+ >+class any; >+ >+// swap() >+// >+// Swaps two `absl::any` values. Equivalent to `x.swap(y) where `x` and `y` are >+// `absl::any` types. >+void swap(any& x, any& y) noexcept; >+ >+// make_any() >+// >+// Constructs an `absl::any` of type `T` with the given arguments. >+template <typename T, typename... Args> >+any make_any(Args&&... args); >+ >+// Overload of `absl::make_any()` for constructing an `absl::any` type from an >+// initializer list. >+template <typename T, typename U, typename... Args> >+any make_any(std::initializer_list<U> il, Args&&... args); >+ >+// any_cast() >+// >+// Statically casts the value of a `const absl::any` type to the given type. >+// This function will throw `absl::bad_any_cast` if the stored value type of the >+// `absl::any` does not match the cast. >+// >+// `any_cast()` can also be used to get a reference to the internal storage iff >+// a reference type is passed as its `ValueType`: >+// >+// Example: >+// >+// absl::any my_any = std::vector<int>(); >+// absl::any_cast<std::vector<int>&>(my_any).push_back(42); >+template <typename ValueType> >+ValueType any_cast(const any& operand); >+ >+// Overload of `any_cast()` to statically cast the value of a non-const >+// `absl::any` type to the given type. This function will throw >+// `absl::bad_any_cast` if the stored value type of the `absl::any` does not >+// match the cast. >+template <typename ValueType> >+ValueType any_cast(any& operand); // NOLINT(runtime/references) >+ >+// Overload of `any_cast()` to statically cast the rvalue of an `absl::any` >+// type. This function will throw `absl::bad_any_cast` if the stored value type >+// of the `absl::any` does not match the cast. >+template <typename ValueType> >+ValueType any_cast(any&& operand); >+ >+// Overload of `any_cast()` to statically cast the value of a const pointer >+// `absl::any` type to the given pointer type, or `nullptr` if the stored value >+// type of the `absl::any` does not match the cast. >+template <typename ValueType> >+const ValueType* any_cast(const any* operand) noexcept; >+ >+// Overload of `any_cast()` to statically cast the value of a pointer >+// `absl::any` type to the given pointer type, or `nullptr` if the stored value >+// type of the `absl::any` does not match the cast. >+template <typename ValueType> >+ValueType* any_cast(any* operand) noexcept; >+ >+// ----------------------------------------------------------------------------- >+// absl::any >+// ----------------------------------------------------------------------------- >+// >+// An `absl::any` object provides the facility to either store an instance of a >+// type, known as the "contained object", or no value. An `absl::any` is used to >+// store values of types that are unknown at compile time. The `absl::any` >+// object, when containing a value, must contain a value type; storing a >+// reference type is neither desired nor supported. >+// >+// An `absl::any` can only store a type that is copy-constructable; move-only >+// types are not allowed within an `any` object. >+// >+// Example: >+// >+// auto a = absl::any(65); // Literal, copyable >+// auto b = absl::any(std::vector<int>()); // Default-initialized, copyable >+// std::unique_ptr<Foo> my_foo; >+// auto c = absl::any(std::move(my_foo)); // Error, not copy-constructable >+// >+// Note that `absl::any` makes use of decayed types (`absl::decay_t` in this >+// context) to remove const-volatile qualifiers (known as "cv qualifiers"), >+// decay functions to function pointers, etc. We essentially "decay" a given >+// type into its essential type. >+// >+// `absl::any` makes use of decayed types when determining the basic type `T` of >+// the value to store in the any's contained object. In the documentation below, >+// we explicitly denote this by using the phrase "a decayed type of `T`". >+// >+// Example: >+// >+// const int a = 4; >+// absl::any foo(a); // Decay ensures we store an "int", not a "const int&". >+// >+// void my_function() {} >+// absl::any bar(my_function); // Decay ensures we store a function pointer. >+// >+// `absl::any` is a C++11 compatible version of the C++17 `std::any` abstraction >+// and is designed to be a drop-in replacement for code compliant with C++17. >+class any { >+ private: >+ template <typename T> >+ struct IsInPlaceType; >+ >+ public: >+ // Constructors >+ >+ // Constructs an empty `absl::any` object (`any::has_value()` will return >+ // `false`). >+ constexpr any() noexcept; >+ >+ // Copy constructs an `absl::any` object with a "contained object" of the >+ // passed type of `other` (or an empty `absl::any` if `other.has_value()` is >+ // `false`. >+ any(const any& other) >+ : obj_(other.has_value() ? other.obj_->Clone() >+ : std::unique_ptr<ObjInterface>()) {} >+ >+ // Move constructs an `absl::any` object with a "contained object" of the >+ // passed type of `other` (or an empty `absl::any` if `other.has_value()` is >+ // `false`). >+ any(any&& other) noexcept = default; >+ >+ // Constructs an `absl::any` object with a "contained object" of the decayed >+ // type of `T`, which is initialized via `std::forward<T>(value)`. >+ // >+ // This constructor will not participate in overload resolution if the >+ // decayed type of `T` is not copy-constructible. >+ template < >+ typename T, typename VT = absl::decay_t<T>, >+ absl::enable_if_t<!absl::disjunction< >+ std::is_same<any, VT>, IsInPlaceType<VT>, >+ absl::negation<std::is_copy_constructible<VT> > >::value>* = nullptr> >+ any(T&& value) : obj_(new Obj<VT>(in_place, std::forward<T>(value))) {} >+ >+ // Constructs an `absl::any` object with a "contained object" of the decayed >+ // type of `T`, which is initialized via `std::forward<T>(value)`. >+ template <typename T, typename... Args, typename VT = absl::decay_t<T>, >+ absl::enable_if_t<absl::conjunction< >+ std::is_copy_constructible<VT>, >+ std::is_constructible<VT, Args...>>::value>* = nullptr> >+ explicit any(in_place_type_t<T> /*tag*/, Args&&... args) >+ : obj_(new Obj<VT>(in_place, std::forward<Args>(args)...)) {} >+ >+ // Constructs an `absl::any` object with a "contained object" of the passed >+ // type `VT` as a decayed type of `T`. `VT` is initialized as if >+ // direct-non-list-initializing an object of type `VT` with the arguments >+ // `initializer_list, std::forward<Args>(args)...`. >+ template < >+ typename T, typename U, typename... Args, typename VT = absl::decay_t<T>, >+ absl::enable_if_t< >+ absl::conjunction<std::is_copy_constructible<VT>, >+ std::is_constructible<VT, std::initializer_list<U>&, >+ Args...>>::value>* = nullptr> >+ explicit any(in_place_type_t<T> /*tag*/, std::initializer_list<U> ilist, >+ Args&&... args) >+ : obj_(new Obj<VT>(in_place, ilist, std::forward<Args>(args)...)) {} >+ >+ // Assignment operators >+ >+ // Copy assigns an `absl::any` object with a "contained object" of the >+ // passed type. >+ any& operator=(const any& rhs) { >+ any(rhs).swap(*this); >+ return *this; >+ } >+ >+ // Move assigns an `absl::any` object with a "contained object" of the >+ // passed type. `rhs` is left in a valid but otherwise unspecified state. >+ any& operator=(any&& rhs) noexcept { >+ any(std::move(rhs)).swap(*this); >+ return *this; >+ } >+ >+ // Assigns an `absl::any` object with a "contained object" of the passed type. >+ template <typename T, typename VT = absl::decay_t<T>, >+ absl::enable_if_t<absl::conjunction< >+ absl::negation<std::is_same<VT, any>>, >+ std::is_copy_constructible<VT>>::value>* = nullptr> >+ any& operator=(T&& rhs) { >+ any tmp(in_place_type_t<VT>(), std::forward<T>(rhs)); >+ tmp.swap(*this); >+ return *this; >+ } >+ >+ // Modifiers >+ >+ // any::emplace() >+ // >+ // Emplaces a value within an `absl::any` object by calling `any::reset()`, >+ // initializing the contained value as if direct-non-list-initializing an >+ // object of type `VT` with the arguments `std::forward<Args>(args)...`, and >+ // returning a reference to the new contained value. >+ // >+ // Note: If an exception is thrown during the call to `VT`'s constructor, >+ // `*this` does not contain a value, and any previously contained value has >+ // been destroyed. >+ template < >+ typename T, typename... Args, typename VT = absl::decay_t<T>, >+ absl::enable_if_t<std::is_copy_constructible<VT>::value && >+ std::is_constructible<VT, Args...>::value>* = nullptr> >+ VT& emplace(Args&&... args) { >+ reset(); // NOTE: reset() is required here even in the world of exceptions. >+ Obj<VT>* const object_ptr = >+ new Obj<VT>(in_place, std::forward<Args>(args)...); >+ obj_ = std::unique_ptr<ObjInterface>(object_ptr); >+ return object_ptr->value; >+ } >+ >+ // Overload of `any::emplace()` to emplace a value within an `absl::any` >+ // object by calling `any::reset()`, initializing the contained value as if >+ // direct-non-list-initializing an object of type `VT` with the arguments >+ // `initializer_list, std::forward<Args>(args)...`, and returning a reference >+ // to the new contained value. >+ // >+ // Note: If an exception is thrown during the call to `VT`'s constructor, >+ // `*this` does not contain a value, and any previously contained value has >+ // been destroyed. The function shall not participate in overload resolution >+ // unless `is_copy_constructible_v<VT>` is `true` and >+ // `is_constructible_v<VT, initializer_list<U>&, Args...>` is `true`. >+ template < >+ typename T, typename U, typename... Args, typename VT = absl::decay_t<T>, >+ absl::enable_if_t<std::is_copy_constructible<VT>::value && >+ std::is_constructible<VT, std::initializer_list<U>&, >+ Args...>::value>* = nullptr> >+ VT& emplace(std::initializer_list<U> ilist, Args&&... args) { >+ reset(); // NOTE: reset() is required here even in the world of exceptions. >+ Obj<VT>* const object_ptr = >+ new Obj<VT>(in_place, ilist, std::forward<Args>(args)...); >+ obj_ = std::unique_ptr<ObjInterface>(object_ptr); >+ return object_ptr->value; >+ } >+ >+ // any::reset() >+ // >+ // Resets the state of the `absl::any` object, destroying the contained object >+ // if present. >+ void reset() noexcept { obj_ = nullptr; } >+ >+ // any::swap() >+ // >+ // Swaps the passed value and the value of this `absl::any` object. >+ void swap(any& other) noexcept { obj_.swap(other.obj_); } >+ >+ // Observers >+ >+ // any::has_value() >+ // >+ // Returns `true` if the `any` object has a contained value, otherwise >+ // returns `false`. >+ bool has_value() const noexcept { return obj_ != nullptr; } >+ >+#if ABSL_ANY_DETAIL_HAS_RTTI >+ // Returns: typeid(T) if *this has a contained object of type T, otherwise >+ // typeid(void). >+ const std::type_info& type() const noexcept { >+ if (has_value()) { >+ return obj_->Type(); >+ } >+ >+ return typeid(void); >+ } >+#endif // ABSL_ANY_DETAIL_HAS_RTTI >+ >+ private: >+ // Tagged type-erased abstraction for holding a cloneable object. >+ class ObjInterface { >+ public: >+ virtual ~ObjInterface() = default; >+ virtual std::unique_ptr<ObjInterface> Clone() const = 0; >+ virtual const void* ObjTypeId() const noexcept = 0; >+#if ABSL_ANY_DETAIL_HAS_RTTI >+ virtual const std::type_info& Type() const noexcept = 0; >+#endif // ABSL_ANY_DETAIL_HAS_RTTI >+ }; >+ >+ // Hold a value of some queryable type, with an ability to Clone it. >+ template <typename T> >+ class Obj : public ObjInterface { >+ public: >+ template <typename... Args> >+ explicit Obj(in_place_t /*tag*/, Args&&... args) >+ : value(std::forward<Args>(args)...) {} >+ >+ std::unique_ptr<ObjInterface> Clone() const final { >+ return std::unique_ptr<ObjInterface>(new Obj(in_place, value)); >+ } >+ >+ const void* ObjTypeId() const noexcept final { return IdForType<T>(); } >+ >+#if ABSL_ANY_DETAIL_HAS_RTTI >+ const std::type_info& Type() const noexcept final { return typeid(T); } >+#endif // ABSL_ANY_DETAIL_HAS_RTTI >+ >+ T value; >+ }; >+ >+ std::unique_ptr<ObjInterface> CloneObj() const { >+ if (!obj_) return nullptr; >+ return obj_->Clone(); >+ } >+ >+ template <typename T> >+ constexpr static const void* IdForType() { >+ // Note: This type dance is to make the behavior consistent with typeid. >+ using NormalizedType = >+ typename std::remove_cv<typename std::remove_reference<T>::type>::type; >+ >+ return any_internal::FastTypeId<NormalizedType>(); >+ } >+ >+ const void* GetObjTypeId() const { >+ return obj_ ? obj_->ObjTypeId() : any_internal::FastTypeId<void>(); >+ } >+ >+ // `absl::any` nonmember functions // >+ >+ // Description at the declaration site (top of file). >+ template <typename ValueType> >+ friend ValueType any_cast(const any& operand); >+ >+ // Description at the declaration site (top of file). >+ template <typename ValueType> >+ friend ValueType any_cast(any& operand); // NOLINT(runtime/references) >+ >+ // Description at the declaration site (top of file). >+ template <typename T> >+ friend const T* any_cast(const any* operand) noexcept; >+ >+ // Description at the declaration site (top of file). >+ template <typename T> >+ friend T* any_cast(any* operand) noexcept; >+ >+ std::unique_ptr<ObjInterface> obj_; >+}; >+ >+// ----------------------------------------------------------------------------- >+// Implementation Details >+// ----------------------------------------------------------------------------- >+ >+constexpr any::any() noexcept = default; >+ >+template <typename T> >+struct any::IsInPlaceType : std::false_type {}; >+ >+template <typename T> >+struct any::IsInPlaceType<in_place_type_t<T>> : std::true_type {}; >+ >+inline void swap(any& x, any& y) noexcept { x.swap(y); } >+ >+// Description at the declaration site (top of file). >+template <typename T, typename... Args> >+any make_any(Args&&... args) { >+ return any(in_place_type_t<T>(), std::forward<Args>(args)...); >+} >+ >+// Description at the declaration site (top of file). >+template <typename T, typename U, typename... Args> >+any make_any(std::initializer_list<U> il, Args&&... args) { >+ return any(in_place_type_t<T>(), il, std::forward<Args>(args)...); >+} >+ >+// Description at the declaration site (top of file). >+template <typename ValueType> >+ValueType any_cast(const any& operand) { >+ using U = typename std::remove_cv< >+ typename std::remove_reference<ValueType>::type>::type; >+ static_assert(std::is_constructible<ValueType, const U&>::value, >+ "Invalid ValueType"); >+ auto* const result = (any_cast<U>)(&operand); >+ if (result == nullptr) { >+ any_internal::ThrowBadAnyCast(); >+ } >+ return static_cast<ValueType>(*result); >+} >+ >+// Description at the declaration site (top of file). >+template <typename ValueType> >+ValueType any_cast(any& operand) { // NOLINT(runtime/references) >+ using U = typename std::remove_cv< >+ typename std::remove_reference<ValueType>::type>::type; >+ static_assert(std::is_constructible<ValueType, U&>::value, >+ "Invalid ValueType"); >+ auto* result = (any_cast<U>)(&operand); >+ if (result == nullptr) { >+ any_internal::ThrowBadAnyCast(); >+ } >+ return static_cast<ValueType>(*result); >+} >+ >+// Description at the declaration site (top of file). >+template <typename ValueType> >+ValueType any_cast(any&& operand) { >+ using U = typename std::remove_cv< >+ typename std::remove_reference<ValueType>::type>::type; >+ static_assert(std::is_constructible<ValueType, U>::value, >+ "Invalid ValueType"); >+ return static_cast<ValueType>(std::move((any_cast<U&>)(operand))); >+} >+ >+// Description at the declaration site (top of file). >+template <typename T> >+const T* any_cast(const any* operand) noexcept { >+ return operand && operand->GetObjTypeId() == any::IdForType<T>() >+ ? std::addressof( >+ static_cast<const any::Obj<T>*>(operand->obj_.get())->value) >+ : nullptr; >+} >+ >+// Description at the declaration site (top of file). >+template <typename T> >+T* any_cast(any* operand) noexcept { >+ return operand && operand->GetObjTypeId() == any::IdForType<T>() >+ ? std::addressof( >+ static_cast<any::Obj<T>*>(operand->obj_.get())->value) >+ : nullptr; >+} >+ >+} // namespace absl >+ >+#undef ABSL_ANY_DETAIL_HAS_RTTI >+ >+#endif // ABSL_HAVE_STD_ANY >+ >+#endif // ABSL_TYPES_ANY_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/any_exception_safety_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/any_exception_safety_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..36955f6c5c376d32fb11a55895ba4ba06fe5a78e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/any_exception_safety_test.cc >@@ -0,0 +1,167 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/types/any.h" >+ >+#include <typeinfo> >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/exception_safety_testing.h" >+ >+using Thrower = testing::ThrowingValue<>; >+using NoThrowMoveThrower = >+ testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>; >+using ThrowerList = std::initializer_list<Thrower>; >+using ThrowerVec = std::vector<Thrower>; >+using ThrowingAlloc = testing::ThrowingAllocator<Thrower>; >+using ThrowingThrowerVec = std::vector<Thrower, ThrowingAlloc>; >+ >+namespace { >+ >+testing::AssertionResult AnyInvariants(absl::any* a) { >+ using testing::AssertionFailure; >+ using testing::AssertionSuccess; >+ >+ if (a->has_value()) { >+ if (a->type() == typeid(void)) { >+ return AssertionFailure() >+ << "A non-empty any should not have type `void`"; >+ } >+ } else { >+ if (a->type() != typeid(void)) { >+ return AssertionFailure() >+ << "An empty any should have type void, but has type " >+ << a->type().name(); >+ } >+ } >+ >+ // Make sure that reset() changes any to a valid state. >+ a->reset(); >+ if (a->has_value()) { >+ return AssertionFailure() << "A reset `any` should be valueless"; >+ } >+ if (a->type() != typeid(void)) { >+ return AssertionFailure() << "A reset `any` should have type() of `void`, " >+ "but instead has type " >+ << a->type().name(); >+ } >+ try { >+ auto unused = absl::any_cast<Thrower>(*a); >+ static_cast<void>(unused); >+ return AssertionFailure() >+ << "A reset `any` should not be able to be any_cast"; >+ } catch (absl::bad_any_cast) { >+ } catch (...) { >+ return AssertionFailure() >+ << "Unexpected exception thrown from absl::any_cast"; >+ } >+ return AssertionSuccess(); >+} >+ >+testing::AssertionResult AnyIsEmpty(absl::any* a) { >+ if (!a->has_value()) { >+ return testing::AssertionSuccess(); >+ } >+ return testing::AssertionFailure() >+ << "a should be empty, but instead has value " >+ << absl::any_cast<Thrower>(*a).Get(); >+} >+ >+TEST(AnyExceptionSafety, Ctors) { >+ Thrower val(1); >+ testing::TestThrowingCtor<absl::any>(val); >+ >+ Thrower copy(val); >+ testing::TestThrowingCtor<absl::any>(copy); >+ >+ testing::TestThrowingCtor<absl::any>(absl::in_place_type_t<Thrower>(), 1); >+ >+ testing::TestThrowingCtor<absl::any>(absl::in_place_type_t<ThrowerVec>(), >+ ThrowerList{val}); >+ >+ testing::TestThrowingCtor<absl::any, >+ absl::in_place_type_t<ThrowingThrowerVec>, >+ ThrowerList, ThrowingAlloc>( >+ absl::in_place_type_t<ThrowingThrowerVec>(), {val}, ThrowingAlloc()); >+} >+ >+TEST(AnyExceptionSafety, Assignment) { >+ auto original = >+ absl::any(absl::in_place_type_t<Thrower>(), 1, testing::nothrow_ctor); >+ auto any_is_strong = [original](absl::any* ap) { >+ return testing::AssertionResult(ap->has_value() && >+ absl::any_cast<Thrower>(original) == >+ absl::any_cast<Thrower>(*ap)); >+ }; >+ auto any_strong_tester = testing::MakeExceptionSafetyTester() >+ .WithInitialValue(original) >+ .WithInvariants(AnyInvariants, any_is_strong); >+ >+ Thrower val(2); >+ absl::any any_val(val); >+ NoThrowMoveThrower mv_val(2); >+ >+ auto assign_any = [&any_val](absl::any* ap) { *ap = any_val; }; >+ auto assign_val = [&val](absl::any* ap) { *ap = val; }; >+ auto move = [&val](absl::any* ap) { *ap = std::move(val); }; >+ auto move_movable = [&mv_val](absl::any* ap) { *ap = std::move(mv_val); }; >+ >+ EXPECT_TRUE(any_strong_tester.Test(assign_any)); >+ EXPECT_TRUE(any_strong_tester.Test(assign_val)); >+ EXPECT_TRUE(any_strong_tester.Test(move)); >+ EXPECT_TRUE(any_strong_tester.Test(move_movable)); >+ >+ auto empty_any_is_strong = [](absl::any* ap) { >+ return testing::AssertionResult{!ap->has_value()}; >+ }; >+ auto strong_empty_any_tester = >+ testing::MakeExceptionSafetyTester() >+ .WithInitialValue(absl::any{}) >+ .WithInvariants(AnyInvariants, empty_any_is_strong); >+ >+ EXPECT_TRUE(strong_empty_any_tester.Test(assign_any)); >+ EXPECT_TRUE(strong_empty_any_tester.Test(assign_val)); >+ EXPECT_TRUE(strong_empty_any_tester.Test(move)); >+} >+// libstdc++ std::any fails this test >+#if !defined(ABSL_HAVE_STD_ANY) >+TEST(AnyExceptionSafety, Emplace) { >+ auto initial_val = >+ absl::any{absl::in_place_type_t<Thrower>(), 1, testing::nothrow_ctor}; >+ auto one_tester = testing::MakeExceptionSafetyTester() >+ .WithInitialValue(initial_val) >+ .WithInvariants(AnyInvariants, AnyIsEmpty); >+ >+ auto emp_thrower = [](absl::any* ap) { ap->emplace<Thrower>(2); }; >+ auto emp_throwervec = [](absl::any* ap) { >+ std::initializer_list<Thrower> il{Thrower(2, testing::nothrow_ctor)}; >+ ap->emplace<ThrowerVec>(il); >+ }; >+ auto emp_movethrower = [](absl::any* ap) { >+ ap->emplace<NoThrowMoveThrower>(2); >+ }; >+ >+ EXPECT_TRUE(one_tester.Test(emp_thrower)); >+ EXPECT_TRUE(one_tester.Test(emp_throwervec)); >+ EXPECT_TRUE(one_tester.Test(emp_movethrower)); >+ >+ auto empty_tester = one_tester.WithInitialValue(absl::any{}); >+ >+ EXPECT_TRUE(empty_tester.Test(emp_thrower)); >+ EXPECT_TRUE(empty_tester.Test(emp_throwervec)); >+} >+#endif // ABSL_HAVE_STD_ANY >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/any_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/any_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..115e78df7af1b1f689420502f5539616e1517b05 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/any_test.cc >@@ -0,0 +1,724 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/types/any.h" >+ >+#include <initializer_list> >+#include <type_traits> >+#include <utility> >+#include <vector> >+ >+#include "gtest/gtest.h" >+#include "absl/base/config.h" >+#include "absl/base/internal/exception_testing.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/container/internal/test_instance_tracker.h" >+ >+namespace { >+using absl::test_internal::CopyableOnlyInstance; >+using absl::test_internal::InstanceTracker; >+ >+template <typename T> >+const T& AsConst(const T& t) { >+ return t; >+} >+ >+struct MoveOnly { >+ MoveOnly() = default; >+ explicit MoveOnly(int value) : value(value) {} >+ MoveOnly(MoveOnly&&) = default; >+ MoveOnly& operator=(MoveOnly&&) = default; >+ >+ int value = 0; >+}; >+ >+struct CopyOnly { >+ CopyOnly() = default; >+ explicit CopyOnly(int value) : value(value) {} >+ CopyOnly(CopyOnly&&) = delete; >+ CopyOnly& operator=(CopyOnly&&) = delete; >+ CopyOnly(const CopyOnly&) = default; >+ CopyOnly& operator=(const CopyOnly&) = default; >+ >+ int value = 0; >+}; >+ >+struct MoveOnlyWithListConstructor { >+ MoveOnlyWithListConstructor() = default; >+ explicit MoveOnlyWithListConstructor(std::initializer_list<int> /*ilist*/, >+ int value) >+ : value(value) {} >+ MoveOnlyWithListConstructor(MoveOnlyWithListConstructor&&) = default; >+ MoveOnlyWithListConstructor& operator=(MoveOnlyWithListConstructor&&) = >+ default; >+ >+ int value = 0; >+}; >+ >+struct IntMoveOnlyCopyOnly { >+ IntMoveOnlyCopyOnly(int value, MoveOnly /*move_only*/, CopyOnly /*copy_only*/) >+ : value(value) {} >+ >+ int value; >+}; >+ >+struct ListMoveOnlyCopyOnly { >+ ListMoveOnlyCopyOnly(std::initializer_list<int> ilist, MoveOnly /*move_only*/, >+ CopyOnly /*copy_only*/) >+ : values(ilist) {} >+ >+ std::vector<int> values; >+}; >+ >+using FunctionType = void(); >+void FunctionToEmplace() {} >+ >+using ArrayType = int[2]; >+using DecayedArray = absl::decay_t<ArrayType>; >+ >+TEST(AnyTest, Noexcept) { >+ static_assert(std::is_nothrow_default_constructible<absl::any>(), ""); >+ static_assert(std::is_nothrow_move_constructible<absl::any>(), ""); >+ static_assert(std::is_nothrow_move_assignable<absl::any>(), ""); >+ static_assert(noexcept(std::declval<absl::any&>().has_value()), ""); >+ static_assert(noexcept(std::declval<absl::any&>().type()), ""); >+ static_assert(noexcept(absl::any_cast<int>(std::declval<absl::any*>())), ""); >+ static_assert( >+ noexcept(std::declval<absl::any&>().swap(std::declval<absl::any&>())), >+ ""); >+ >+ using std::swap; >+ static_assert( >+ noexcept(swap(std::declval<absl::any&>(), std::declval<absl::any&>())), >+ ""); >+} >+ >+TEST(AnyTest, HasValue) { >+ absl::any o; >+ EXPECT_FALSE(o.has_value()); >+ o.emplace<int>(); >+ EXPECT_TRUE(o.has_value()); >+ o.reset(); >+ EXPECT_FALSE(o.has_value()); >+} >+ >+TEST(AnyTest, Type) { >+ absl::any o; >+ EXPECT_EQ(typeid(void), o.type()); >+ o.emplace<int>(5); >+ EXPECT_EQ(typeid(int), o.type()); >+ o.emplace<float>(5.f); >+ EXPECT_EQ(typeid(float), o.type()); >+ o.reset(); >+ EXPECT_EQ(typeid(void), o.type()); >+} >+ >+TEST(AnyTest, EmptyPointerCast) { >+ // pointer-to-unqualified overload >+ { >+ absl::any o; >+ EXPECT_EQ(nullptr, absl::any_cast<int>(&o)); >+ o.emplace<int>(); >+ EXPECT_NE(nullptr, absl::any_cast<int>(&o)); >+ o.reset(); >+ EXPECT_EQ(nullptr, absl::any_cast<int>(&o)); >+ } >+ >+ // pointer-to-const overload >+ { >+ absl::any o; >+ EXPECT_EQ(nullptr, absl::any_cast<int>(&AsConst(o))); >+ o.emplace<int>(); >+ EXPECT_NE(nullptr, absl::any_cast<int>(&AsConst(o))); >+ o.reset(); >+ EXPECT_EQ(nullptr, absl::any_cast<int>(&AsConst(o))); >+ } >+} >+ >+TEST(AnyTest, InPlaceConstruction) { >+ const CopyOnly copy_only{}; >+ absl::any o(absl::in_place_type_t<IntMoveOnlyCopyOnly>(), 5, MoveOnly(), >+ copy_only); >+ IntMoveOnlyCopyOnly& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o); >+ EXPECT_EQ(5, v.value); >+} >+ >+TEST(AnyTest, InPlaceConstructionWithCV) { >+ const CopyOnly copy_only{}; >+ absl::any o(absl::in_place_type_t<const volatile IntMoveOnlyCopyOnly>(), 5, >+ MoveOnly(), copy_only); >+ IntMoveOnlyCopyOnly& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o); >+ EXPECT_EQ(5, v.value); >+} >+ >+TEST(AnyTest, InPlaceConstructionWithFunction) { >+ absl::any o(absl::in_place_type_t<FunctionType>(), FunctionToEmplace); >+ FunctionType*& construction_result = absl::any_cast<FunctionType*&>(o); >+ EXPECT_EQ(&FunctionToEmplace, construction_result); >+} >+ >+TEST(AnyTest, InPlaceConstructionWithArray) { >+ ArrayType ar = {5, 42}; >+ absl::any o(absl::in_place_type_t<ArrayType>(), ar); >+ DecayedArray& construction_result = absl::any_cast<DecayedArray&>(o); >+ EXPECT_EQ(&ar[0], construction_result); >+} >+ >+TEST(AnyTest, InPlaceConstructionIlist) { >+ const CopyOnly copy_only{}; >+ absl::any o(absl::in_place_type_t<ListMoveOnlyCopyOnly>(), {1, 2, 3, 4}, >+ MoveOnly(), copy_only); >+ ListMoveOnlyCopyOnly& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o); >+ std::vector<int> expected_values = {1, 2, 3, 4}; >+ EXPECT_EQ(expected_values, v.values); >+} >+ >+TEST(AnyTest, InPlaceConstructionIlistWithCV) { >+ const CopyOnly copy_only{}; >+ absl::any o(absl::in_place_type_t<const volatile ListMoveOnlyCopyOnly>(), >+ {1, 2, 3, 4}, MoveOnly(), copy_only); >+ ListMoveOnlyCopyOnly& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o); >+ std::vector<int> expected_values = {1, 2, 3, 4}; >+ EXPECT_EQ(expected_values, v.values); >+} >+ >+TEST(AnyTest, InPlaceNoArgs) { >+ absl::any o(absl::in_place_type_t<int>{}); >+ EXPECT_EQ(0, absl::any_cast<int&>(o)); >+} >+ >+template <typename Enabler, typename T, typename... Args> >+struct CanEmplaceAnyImpl : std::false_type {}; >+ >+template <typename T, typename... Args> >+struct CanEmplaceAnyImpl< >+ absl::void_t<decltype( >+ std::declval<absl::any&>().emplace<T>(std::declval<Args>()...))>, >+ T, Args...> : std::true_type {}; >+ >+template <typename T, typename... Args> >+using CanEmplaceAny = CanEmplaceAnyImpl<void, T, Args...>; >+ >+TEST(AnyTest, Emplace) { >+ const CopyOnly copy_only{}; >+ absl::any o; >+ EXPECT_TRUE((std::is_same<decltype(o.emplace<IntMoveOnlyCopyOnly>( >+ 5, MoveOnly(), copy_only)), >+ IntMoveOnlyCopyOnly&>::value)); >+ IntMoveOnlyCopyOnly& emplace_result = >+ o.emplace<IntMoveOnlyCopyOnly>(5, MoveOnly(), copy_only); >+ EXPECT_EQ(5, emplace_result.value); >+ IntMoveOnlyCopyOnly& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o); >+ EXPECT_EQ(5, v.value); >+ EXPECT_EQ(&emplace_result, &v); >+ >+ static_assert(!CanEmplaceAny<int, int, int>::value, ""); >+ static_assert(!CanEmplaceAny<MoveOnly, MoveOnly>::value, ""); >+} >+ >+TEST(AnyTest, EmplaceWithCV) { >+ const CopyOnly copy_only{}; >+ absl::any o; >+ EXPECT_TRUE( >+ (std::is_same<decltype(o.emplace<const volatile IntMoveOnlyCopyOnly>( >+ 5, MoveOnly(), copy_only)), >+ IntMoveOnlyCopyOnly&>::value)); >+ IntMoveOnlyCopyOnly& emplace_result = >+ o.emplace<const volatile IntMoveOnlyCopyOnly>(5, MoveOnly(), copy_only); >+ EXPECT_EQ(5, emplace_result.value); >+ IntMoveOnlyCopyOnly& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o); >+ EXPECT_EQ(5, v.value); >+ EXPECT_EQ(&emplace_result, &v); >+} >+ >+TEST(AnyTest, EmplaceWithFunction) { >+ absl::any o; >+ EXPECT_TRUE( >+ (std::is_same<decltype(o.emplace<FunctionType>(FunctionToEmplace)), >+ FunctionType*&>::value)); >+ FunctionType*& emplace_result = o.emplace<FunctionType>(FunctionToEmplace); >+ EXPECT_EQ(&FunctionToEmplace, emplace_result); >+} >+ >+TEST(AnyTest, EmplaceWithArray) { >+ absl::any o; >+ ArrayType ar = {5, 42}; >+ EXPECT_TRUE( >+ (std::is_same<decltype(o.emplace<ArrayType>(ar)), DecayedArray&>::value)); >+ DecayedArray& emplace_result = o.emplace<ArrayType>(ar); >+ EXPECT_EQ(&ar[0], emplace_result); >+} >+ >+TEST(AnyTest, EmplaceIlist) { >+ const CopyOnly copy_only{}; >+ absl::any o; >+ EXPECT_TRUE((std::is_same<decltype(o.emplace<ListMoveOnlyCopyOnly>( >+ {1, 2, 3, 4}, MoveOnly(), copy_only)), >+ ListMoveOnlyCopyOnly&>::value)); >+ ListMoveOnlyCopyOnly& emplace_result = >+ o.emplace<ListMoveOnlyCopyOnly>({1, 2, 3, 4}, MoveOnly(), copy_only); >+ ListMoveOnlyCopyOnly& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o); >+ EXPECT_EQ(&v, &emplace_result); >+ std::vector<int> expected_values = {1, 2, 3, 4}; >+ EXPECT_EQ(expected_values, v.values); >+ >+ static_assert(!CanEmplaceAny<int, std::initializer_list<int>>::value, ""); >+ static_assert(!CanEmplaceAny<MoveOnlyWithListConstructor, >+ std::initializer_list<int>, int>::value, >+ ""); >+} >+ >+TEST(AnyTest, EmplaceIlistWithCV) { >+ const CopyOnly copy_only{}; >+ absl::any o; >+ EXPECT_TRUE( >+ (std::is_same<decltype(o.emplace<const volatile ListMoveOnlyCopyOnly>( >+ {1, 2, 3, 4}, MoveOnly(), copy_only)), >+ ListMoveOnlyCopyOnly&>::value)); >+ ListMoveOnlyCopyOnly& emplace_result = >+ o.emplace<const volatile ListMoveOnlyCopyOnly>({1, 2, 3, 4}, MoveOnly(), >+ copy_only); >+ ListMoveOnlyCopyOnly& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o); >+ EXPECT_EQ(&v, &emplace_result); >+ std::vector<int> expected_values = {1, 2, 3, 4}; >+ EXPECT_EQ(expected_values, v.values); >+} >+ >+TEST(AnyTest, EmplaceNoArgs) { >+ absl::any o; >+ o.emplace<int>(); >+ EXPECT_EQ(0, absl::any_cast<int>(o)); >+} >+ >+TEST(AnyTest, ConversionConstruction) { >+ { >+ absl::any o = 5; >+ EXPECT_EQ(5, absl::any_cast<int>(o)); >+ } >+ >+ { >+ const CopyOnly copy_only(5); >+ absl::any o = copy_only; >+ EXPECT_EQ(5, absl::any_cast<CopyOnly&>(o).value); >+ } >+ >+ static_assert(!std::is_convertible<MoveOnly, absl::any>::value, ""); >+} >+ >+TEST(AnyTest, ConversionAssignment) { >+ { >+ absl::any o; >+ o = 5; >+ EXPECT_EQ(5, absl::any_cast<int>(o)); >+ } >+ >+ { >+ const CopyOnly copy_only(5); >+ absl::any o; >+ o = copy_only; >+ EXPECT_EQ(5, absl::any_cast<CopyOnly&>(o).value); >+ } >+ >+ static_assert(!std::is_assignable<MoveOnly, absl::any>::value, ""); >+} >+ >+// Suppress MSVC warnings. >+// 4521: multiple copy constructors specified >+// We wrote multiple of them to test that the correct overloads are selected. >+#ifdef _MSC_VER >+#pragma warning( push ) >+#pragma warning( disable : 4521) >+#endif >+ >+// Weird type for testing, only used to make sure we "properly" perfect-forward >+// when being placed into an absl::any (use the l-value constructor if given an >+// l-value rather than use the copy constructor). >+struct WeirdConstructor42 { >+ explicit WeirdConstructor42(int value) : value(value) {} >+ >+ // Copy-constructor >+ WeirdConstructor42(const WeirdConstructor42& other) : value(other.value) {} >+ >+ // L-value "weird" constructor (used when given an l-value) >+ WeirdConstructor42( >+ WeirdConstructor42& /*other*/) // NOLINT(runtime/references) >+ : value(42) {} >+ >+ int value; >+}; >+#ifdef _MSC_VER >+#pragma warning( pop ) >+#endif >+ >+TEST(AnyTest, WeirdConversionConstruction) { >+ { >+ const WeirdConstructor42 source(5); >+ absl::any o = source; // Actual copy >+ EXPECT_EQ(5, absl::any_cast<WeirdConstructor42&>(o).value); >+ } >+ >+ { >+ WeirdConstructor42 source(5); >+ absl::any o = source; // Weird "conversion" >+ EXPECT_EQ(42, absl::any_cast<WeirdConstructor42&>(o).value); >+ } >+} >+ >+TEST(AnyTest, WeirdConversionAssignment) { >+ { >+ const WeirdConstructor42 source(5); >+ absl::any o; >+ o = source; // Actual copy >+ EXPECT_EQ(5, absl::any_cast<WeirdConstructor42&>(o).value); >+ } >+ >+ { >+ WeirdConstructor42 source(5); >+ absl::any o; >+ o = source; // Weird "conversion" >+ EXPECT_EQ(42, absl::any_cast<WeirdConstructor42&>(o).value); >+ } >+} >+ >+struct Value {}; >+ >+TEST(AnyTest, AnyCastValue) { >+ { >+ absl::any o; >+ o.emplace<int>(5); >+ EXPECT_EQ(5, absl::any_cast<int>(o)); >+ EXPECT_EQ(5, absl::any_cast<int>(AsConst(o))); >+ static_assert( >+ std::is_same<decltype(absl::any_cast<Value>(o)), Value>::value, ""); >+ } >+ >+ { >+ absl::any o; >+ o.emplace<int>(5); >+ EXPECT_EQ(5, absl::any_cast<const int>(o)); >+ EXPECT_EQ(5, absl::any_cast<const int>(AsConst(o))); >+ static_assert(std::is_same<decltype(absl::any_cast<const Value>(o)), >+ const Value>::value, >+ ""); >+ } >+} >+ >+TEST(AnyTest, AnyCastReference) { >+ { >+ absl::any o; >+ o.emplace<int>(5); >+ EXPECT_EQ(5, absl::any_cast<int&>(o)); >+ EXPECT_EQ(5, absl::any_cast<const int&>(AsConst(o))); >+ static_assert( >+ std::is_same<decltype(absl::any_cast<Value&>(o)), Value&>::value, ""); >+ } >+ >+ { >+ absl::any o; >+ o.emplace<int>(5); >+ EXPECT_EQ(5, absl::any_cast<const int>(o)); >+ EXPECT_EQ(5, absl::any_cast<const int>(AsConst(o))); >+ static_assert(std::is_same<decltype(absl::any_cast<const Value&>(o)), >+ const Value&>::value, >+ ""); >+ } >+ >+ { >+ absl::any o; >+ o.emplace<int>(5); >+ EXPECT_EQ(5, absl::any_cast<int&&>(std::move(o))); >+ static_assert(std::is_same<decltype(absl::any_cast<Value&&>(std::move(o))), >+ Value&&>::value, >+ ""); >+ } >+ >+ { >+ absl::any o; >+ o.emplace<int>(5); >+ EXPECT_EQ(5, absl::any_cast<const int>(std::move(o))); >+ static_assert( >+ std::is_same<decltype(absl::any_cast<const Value&&>(std::move(o))), >+ const Value&&>::value, >+ ""); >+ } >+} >+ >+TEST(AnyTest, AnyCastPointer) { >+ { >+ absl::any o; >+ EXPECT_EQ(nullptr, absl::any_cast<char>(&o)); >+ o.emplace<int>(5); >+ EXPECT_EQ(nullptr, absl::any_cast<char>(&o)); >+ o.emplace<char>('a'); >+ EXPECT_EQ('a', *absl::any_cast<char>(&o)); >+ static_assert( >+ std::is_same<decltype(absl::any_cast<Value>(&o)), Value*>::value, ""); >+ } >+ >+ { >+ absl::any o; >+ EXPECT_EQ(nullptr, absl::any_cast<const char>(&o)); >+ o.emplace<int>(5); >+ EXPECT_EQ(nullptr, absl::any_cast<const char>(&o)); >+ o.emplace<char>('a'); >+ EXPECT_EQ('a', *absl::any_cast<const char>(&o)); >+ static_assert(std::is_same<decltype(absl::any_cast<const Value>(&o)), >+ const Value*>::value, >+ ""); >+ } >+} >+ >+TEST(AnyTest, MakeAny) { >+ const CopyOnly copy_only{}; >+ auto o = absl::make_any<IntMoveOnlyCopyOnly>(5, MoveOnly(), copy_only); >+ static_assert(std::is_same<decltype(o), absl::any>::value, ""); >+ EXPECT_EQ(5, absl::any_cast<IntMoveOnlyCopyOnly&>(o).value); >+} >+ >+TEST(AnyTest, MakeAnyIList) { >+ const CopyOnly copy_only{}; >+ auto o = >+ absl::make_any<ListMoveOnlyCopyOnly>({1, 2, 3}, MoveOnly(), copy_only); >+ static_assert(std::is_same<decltype(o), absl::any>::value, ""); >+ ListMoveOnlyCopyOnly& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o); >+ std::vector<int> expected_values = {1, 2, 3}; >+ EXPECT_EQ(expected_values, v.values); >+} >+ >+// Test the use of copy constructor and operator= >+TEST(AnyTest, Copy) { >+ InstanceTracker tracker_raii; >+ >+ { >+ absl::any o(absl::in_place_type_t<CopyableOnlyInstance>{}, 123); >+ CopyableOnlyInstance* f1 = absl::any_cast<CopyableOnlyInstance>(&o); >+ >+ absl::any o2(o); >+ const CopyableOnlyInstance* f2 = absl::any_cast<CopyableOnlyInstance>(&o2); >+ EXPECT_EQ(123, f2->value()); >+ EXPECT_NE(f1, f2); >+ >+ absl::any o3; >+ o3 = o2; >+ const CopyableOnlyInstance* f3 = absl::any_cast<CopyableOnlyInstance>(&o3); >+ EXPECT_EQ(123, f3->value()); >+ EXPECT_NE(f2, f3); >+ >+ const absl::any o4(4); >+ // copy construct from const lvalue ref. >+ absl::any o5 = o4; >+ EXPECT_EQ(4, absl::any_cast<int>(o4)); >+ EXPECT_EQ(4, absl::any_cast<int>(o5)); >+ >+ // Copy construct from const rvalue ref. >+ absl::any o6 = std::move(o4); // NOLINT >+ EXPECT_EQ(4, absl::any_cast<int>(o4)); >+ EXPECT_EQ(4, absl::any_cast<int>(o6)); >+ } >+} >+ >+TEST(AnyTest, Move) { >+ InstanceTracker tracker_raii; >+ >+ absl::any any1; >+ any1.emplace<CopyableOnlyInstance>(5); >+ >+ // This is a copy, so copy count increases to 1. >+ absl::any any2 = any1; >+ EXPECT_EQ(5, absl::any_cast<CopyableOnlyInstance&>(any1).value()); >+ EXPECT_EQ(5, absl::any_cast<CopyableOnlyInstance&>(any2).value()); >+ EXPECT_EQ(1, tracker_raii.copies()); >+ >+ // This isn't a copy, so copy count doesn't increase. >+ absl::any any3 = std::move(any2); >+ EXPECT_EQ(5, absl::any_cast<CopyableOnlyInstance&>(any3).value()); >+ EXPECT_EQ(1, tracker_raii.copies()); >+ >+ absl::any any4; >+ any4 = std::move(any3); >+ EXPECT_EQ(5, absl::any_cast<CopyableOnlyInstance&>(any4).value()); >+ EXPECT_EQ(1, tracker_raii.copies()); >+ >+ absl::any tmp4(4); >+ absl::any o4(std::move(tmp4)); // move construct >+ EXPECT_EQ(4, absl::any_cast<int>(o4)); >+ o4 = *&o4; // self assign >+ EXPECT_EQ(4, absl::any_cast<int>(o4)); >+ EXPECT_TRUE(o4.has_value()); >+ >+ absl::any o5; >+ absl::any tmp5(5); >+ o5 = std::move(tmp5); // move assign >+ EXPECT_EQ(5, absl::any_cast<int>(o5)); >+} >+ >+// Reset the ObjectOwner with an object of a different type >+TEST(AnyTest, Reset) { >+ absl::any o; >+ o.emplace<int>(); >+ >+ o.reset(); >+ EXPECT_FALSE(o.has_value()); >+ >+ o.emplace<char>(); >+ EXPECT_TRUE(o.has_value()); >+} >+ >+TEST(AnyTest, ConversionConstructionCausesOneCopy) { >+ InstanceTracker tracker_raii; >+ CopyableOnlyInstance counter(5); >+ absl::any o(counter); >+ EXPECT_EQ(5, absl::any_cast<CopyableOnlyInstance&>(o).value()); >+ EXPECT_EQ(1, tracker_raii.copies()); >+} >+ >+////////////////////////////////// >+// Tests for Exception Behavior // >+////////////////////////////////// >+ >+#if defined(ABSL_HAVE_STD_ANY) >+ >+// If using a std `any` implementation, we can't check for a specific message. >+#define ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(...) \ >+ ABSL_BASE_INTERNAL_EXPECT_FAIL((__VA_ARGS__), absl::bad_any_cast, \ >+ "") >+ >+#else >+ >+// If using the absl `any` implementation, we can rely on a specific message. >+#define ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(...) \ >+ ABSL_BASE_INTERNAL_EXPECT_FAIL((__VA_ARGS__), absl::bad_any_cast, \ >+ "Bad any cast") >+ >+#endif // defined(ABSL_HAVE_STD_ANY) >+ >+TEST(AnyTest, ThrowBadAlloc) { >+ { >+ absl::any a; >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<int&>(a)); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int&>(a)); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<int&&>(absl::any{})); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int&&>(absl::any{})); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<int>(a)); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int>(a)); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<int>(absl::any{})); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int>(absl::any{})); >+ >+ // const absl::any operand >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int&>(AsConst(a))); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<int>(AsConst(a))); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int>(AsConst(a))); >+ } >+ >+ { >+ absl::any a(absl::in_place_type_t<int>{}); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float&>(a)); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float&>(a)); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float&&>(absl::any{})); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST( >+ absl::any_cast<const float&&>(absl::any{})); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float>(a)); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float>(a)); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float>(absl::any{})); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float>(absl::any{})); >+ >+ // const absl::any operand >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float&>(AsConst(a))); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float>(AsConst(a))); >+ ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float>(AsConst(a))); >+ } >+} >+ >+class BadCopy {}; >+ >+struct BadCopyable { >+ BadCopyable() = default; >+ BadCopyable(BadCopyable&&) = default; >+ BadCopyable(const BadCopyable&) { >+#ifdef ABSL_HAVE_EXCEPTIONS >+ throw BadCopy(); >+#else >+ ABSL_RAW_LOG(FATAL, "Bad copy"); >+#endif >+ } >+}; >+ >+#define ABSL_ANY_TEST_EXPECT_BAD_COPY(...) \ >+ ABSL_BASE_INTERNAL_EXPECT_FAIL((__VA_ARGS__), BadCopy, "Bad copy") >+ >+// Test the guarantees regarding exceptions in copy/assign. >+TEST(AnyTest, FailedCopy) { >+ { >+ const BadCopyable bad{}; >+ ABSL_ANY_TEST_EXPECT_BAD_COPY(absl::any{bad}); >+ } >+ >+ { >+ absl::any src(absl::in_place_type_t<BadCopyable>{}); >+ ABSL_ANY_TEST_EXPECT_BAD_COPY(absl::any{src}); >+ } >+ >+ { >+ BadCopyable bad; >+ absl::any target; >+ ABSL_ANY_TEST_EXPECT_BAD_COPY(target = bad); >+ } >+ >+ { >+ BadCopyable bad; >+ absl::any target(absl::in_place_type_t<BadCopyable>{}); >+ ABSL_ANY_TEST_EXPECT_BAD_COPY(target = bad); >+ EXPECT_TRUE(target.has_value()); >+ } >+ >+ { >+ absl::any src(absl::in_place_type_t<BadCopyable>{}); >+ absl::any target; >+ ABSL_ANY_TEST_EXPECT_BAD_COPY(target = src); >+ EXPECT_FALSE(target.has_value()); >+ } >+ >+ { >+ absl::any src(absl::in_place_type_t<BadCopyable>{}); >+ absl::any target(absl::in_place_type_t<BadCopyable>{}); >+ ABSL_ANY_TEST_EXPECT_BAD_COPY(target = src); >+ EXPECT_TRUE(target.has_value()); >+ } >+} >+ >+// Test the guarantees regarding exceptions in emplace. >+TEST(AnyTest, FailedEmplace) { >+ { >+ BadCopyable bad; >+ absl::any target; >+ ABSL_ANY_TEST_EXPECT_BAD_COPY(target.emplace<BadCopyable>(bad)); >+ } >+ >+ { >+ BadCopyable bad; >+ absl::any target(absl::in_place_type_t<int>{}); >+ ABSL_ANY_TEST_EXPECT_BAD_COPY(target.emplace<BadCopyable>(bad)); >+#if defined(ABSL_HAVE_STD_ANY) && defined(__GLIBCXX__) >+ // libstdc++ std::any::emplace() implementation (as of 7.2) has a bug: if an >+ // exception is thrown, *this contains a value. >+#define ABSL_GLIBCXX_ANY_EMPLACE_EXCEPTION_BUG 1 >+#endif >+#if defined(ABSL_HAVE_EXCEPTIONS) && \ >+ !defined(ABSL_GLIBCXX_ANY_EMPLACE_EXCEPTION_BUG) >+ EXPECT_FALSE(target.has_value()); >+#endif >+ } >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_any_cast.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_any_cast.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..2e2fd29a337807066556a2ffc40b3e08dfa67beb >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_any_cast.cc >@@ -0,0 +1,44 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/types/bad_any_cast.h" >+ >+#ifndef ABSL_HAVE_STD_ANY >+ >+#include <cstdlib> >+ >+#include "absl/base/config.h" >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+ >+bad_any_cast::~bad_any_cast() = default; >+ >+const char* bad_any_cast::what() const noexcept { return "Bad any cast"; } >+ >+namespace any_internal { >+ >+void ThrowBadAnyCast() { >+#ifdef ABSL_HAVE_EXCEPTIONS >+ throw bad_any_cast(); >+#else >+ ABSL_RAW_LOG(FATAL, "Bad any cast"); >+ std::abort(); >+#endif >+} >+ >+} // namespace any_internal >+} // namespace absl >+ >+#endif // ABSL_HAVE_STD_ANY >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_any_cast.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_any_cast.h >new file mode 100644 >index 0000000000000000000000000000000000000000..603901324afc30f2bc592eac5ec16f24b1957ad4 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_any_cast.h >@@ -0,0 +1,71 @@ >+// 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. >+// >+// ----------------------------------------------------------------------------- >+// bad_any_cast.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines the `absl::bad_any_cast` type. >+ >+#ifndef ABSL_TYPES_BAD_ANY_CAST_H_ >+#define ABSL_TYPES_BAD_ANY_CAST_H_ >+ >+#include <typeinfo> >+ >+#include "absl/base/config.h" >+ >+#ifdef ABSL_HAVE_STD_ANY >+ >+#include <any> >+ >+namespace absl { >+using std::bad_any_cast; >+} // namespace absl >+ >+#else // ABSL_HAVE_STD_ANY >+ >+namespace absl { >+ >+// ----------------------------------------------------------------------------- >+// bad_any_cast >+// ----------------------------------------------------------------------------- >+// >+// An `absl::bad_any_cast` type is an exception type that is thrown when >+// failing to successfully cast the return value of an `absl::any` object. >+// >+// Example: >+// >+// auto a = absl::any(65); >+// absl::any_cast<int>(a); // 65 >+// try { >+// absl::any_cast<char>(a); >+// } catch(const absl::bad_any_cast& e) { >+// std::cout << "Bad any cast: " << e.what() << '\n'; >+// } >+class bad_any_cast : public std::bad_cast { >+ public: >+ ~bad_any_cast() override; >+ const char* what() const noexcept override; >+}; >+ >+namespace any_internal { >+ >+[[noreturn]] void ThrowBadAnyCast(); >+ >+} // namespace any_internal >+} // namespace absl >+ >+#endif // ABSL_HAVE_STD_ANY >+ >+#endif // ABSL_TYPES_BAD_ANY_CAST_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_optional_access.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_optional_access.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..558707760e9de453f7ccedc998a0ca8f5bbe6446 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_optional_access.cc >@@ -0,0 +1,46 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/types/bad_optional_access.h" >+ >+#ifndef ABSL_HAVE_STD_OPTIONAL >+ >+#include <cstdlib> >+ >+#include "absl/base/config.h" >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+ >+bad_optional_access::~bad_optional_access() = default; >+ >+const char* bad_optional_access::what() const noexcept { >+ return "optional has no value"; >+} >+ >+namespace optional_internal { >+ >+void throw_bad_optional_access() { >+#ifdef ABSL_HAVE_EXCEPTIONS >+ throw bad_optional_access(); >+#else >+ ABSL_RAW_LOG(FATAL, "Bad optional access"); >+ abort(); >+#endif >+} >+ >+} // namespace optional_internal >+} // namespace absl >+ >+#endif // ABSL_HAVE_STD_OPTIONAL >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_optional_access.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_optional_access.h >new file mode 100644 >index 0000000000000000000000000000000000000000..c6c27460a76d309a0739bbf445f2d34be42e1da0 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_optional_access.h >@@ -0,0 +1,74 @@ >+// 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. >+// >+// ----------------------------------------------------------------------------- >+// bad_optional_access.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines the `absl::bad_optional_access` type. >+ >+#ifndef ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_ >+#define ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_ >+ >+#include <stdexcept> >+ >+#include "absl/base/config.h" >+ >+#ifdef ABSL_HAVE_STD_OPTIONAL >+ >+#include <optional> >+ >+namespace absl { >+using std::bad_optional_access; >+} // namespace absl >+ >+#else // ABSL_HAVE_STD_OPTIONAL >+ >+namespace absl { >+ >+// ----------------------------------------------------------------------------- >+// bad_optional_access >+// ----------------------------------------------------------------------------- >+// >+// An `absl::bad_optional_access` type is an exception type that is thrown when >+// attempting to access an `absl::optional` object that does not contain a >+// value. >+// >+// Example: >+// >+// absl::optional<int> o; >+// >+// try { >+// int n = o.value(); >+// } catch(const absl::bad_optional_access& e) { >+// std::cout << "Bad optional access: " << e.what() << '\n'; >+// } >+class bad_optional_access : public std::exception { >+ public: >+ bad_optional_access() = default; >+ ~bad_optional_access() override; >+ const char* what() const noexcept override; >+}; >+ >+namespace optional_internal { >+ >+// throw delegator >+[[noreturn]] void throw_bad_optional_access(); >+ >+} // namespace optional_internal >+} // namespace absl >+ >+#endif // ABSL_HAVE_STD_OPTIONAL >+ >+#endif // ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_variant_access.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_variant_access.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..d27d775617917fbc0683b8efc40daac1ee0dc553 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_variant_access.cc >@@ -0,0 +1,62 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/types/bad_variant_access.h" >+ >+#ifndef ABSL_HAVE_STD_VARIANT >+ >+#include <cstdlib> >+#include <stdexcept> >+ >+#include "absl/base/config.h" >+#include "absl/base/internal/raw_logging.h" >+ >+namespace absl { >+ >+////////////////////////// >+// [variant.bad.access] // >+////////////////////////// >+ >+bad_variant_access::~bad_variant_access() = default; >+ >+const char* bad_variant_access::what() const noexcept { >+ return "Bad variant access"; >+} >+ >+namespace variant_internal { >+ >+void ThrowBadVariantAccess() { >+#ifdef ABSL_HAVE_EXCEPTIONS >+ throw bad_variant_access(); >+#else >+ ABSL_RAW_LOG(FATAL, "Bad variant access"); >+ abort(); // TODO(calabrese) Remove once RAW_LOG FATAL is noreturn. >+#endif >+} >+ >+void Rethrow() { >+#ifdef ABSL_HAVE_EXCEPTIONS >+ throw; >+#else >+ ABSL_RAW_LOG(FATAL, >+ "Internal error in absl::variant implementation. Attempted to " >+ "rethrow an exception when building with exceptions disabled."); >+ abort(); // TODO(calabrese) Remove once RAW_LOG FATAL is noreturn. >+#endif >+} >+ >+} // namespace variant_internal >+} // namespace absl >+ >+#endif // ABSL_HAVE_STD_VARIANT >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_variant_access.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_variant_access.h >new file mode 100644 >index 0000000000000000000000000000000000000000..e7355a5a74c8b624e91652b423896af484365d4e >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/bad_variant_access.h >@@ -0,0 +1,78 @@ >+// 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. >+// >+// ----------------------------------------------------------------------------- >+// bad_variant_access.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines the `absl::bad_variant_access` type. >+ >+#ifndef ABSL_TYPES_BAD_VARIANT_ACCESS_H_ >+#define ABSL_TYPES_BAD_VARIANT_ACCESS_H_ >+ >+#include <stdexcept> >+ >+#include "absl/base/config.h" >+ >+#ifdef ABSL_HAVE_STD_VARIANT >+ >+#include <variant> >+ >+namespace absl { >+using std::bad_variant_access; >+} // namespace absl >+ >+#else // ABSL_HAVE_STD_VARIANT >+ >+namespace absl { >+ >+// ----------------------------------------------------------------------------- >+// bad_variant_access >+// ----------------------------------------------------------------------------- >+// >+// An `absl::bad_variant_access` type is an exception type that is thrown in >+// the following cases: >+// >+// * Calling `absl::get(absl::variant) with an index or type that does not >+// match the currently selected alternative type >+// * Calling `absl::visit on an `absl::variant` that is in the >+// `variant::valueless_by_exception` state. >+// >+// Example: >+// >+// absl::variant<int, std::string> v; >+// v = 1; >+// try { >+// absl::get<std::string>(v); >+// } catch(const absl::bad_variant_access& e) { >+// std::cout << "Bad variant access: " << e.what() << '\n'; >+// } >+class bad_variant_access : public std::exception { >+ public: >+ bad_variant_access() noexcept = default; >+ ~bad_variant_access() override; >+ const char* what() const noexcept override; >+}; >+ >+namespace variant_internal { >+ >+[[noreturn]] void ThrowBadVariantAccess(); >+[[noreturn]] void Rethrow(); >+ >+} // namespace variant_internal >+} // namespace absl >+ >+#endif // ABSL_HAVE_STD_VARIANT >+ >+#endif // ABSL_TYPES_BAD_VARIANT_ACCESS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/internal/variant.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/internal/variant.h >new file mode 100644 >index 0000000000000000000000000000000000000000..7708e67cb14f416ade16719e2369aaf648bb6283 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/internal/variant.h >@@ -0,0 +1,1615 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// Implementation details of absl/types/variant.h, pulled into a >+// separate file to avoid cluttering the top of the API header with >+// implementation details. >+ >+#ifndef ABSL_TYPES_variant_internal_H_ >+#define ABSL_TYPES_variant_internal_H_ >+ >+#include <cassert> >+#include <cstddef> >+#include <cstdlib> >+#include <memory> >+#include <stdexcept> >+#include <tuple> >+#include <type_traits> >+ >+#include "absl/base/config.h" >+#include "absl/base/internal/identity.h" >+#include "absl/base/internal/inline_variable.h" >+#include "absl/base/internal/invoke.h" >+#include "absl/base/macros.h" >+#include "absl/base/optimization.h" >+#include "absl/meta/type_traits.h" >+#include "absl/types/bad_variant_access.h" >+#include "absl/utility/utility.h" >+ >+namespace absl { >+ >+template <class... Types> >+class variant; >+ >+ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, -1); >+ >+template <class T> >+struct variant_size; >+ >+template <std::size_t I, class T> >+struct variant_alternative; >+ >+namespace variant_internal { >+ >+// NOTE: See specializations below for details. >+template <std::size_t I, class T> >+struct VariantAlternativeSfinae {}; >+ >+// Requires: I < variant_size_v<T>. >+// >+// Value: The Ith type of Types... >+template <std::size_t I, class T0, class... Tn> >+struct VariantAlternativeSfinae<I, variant<T0, Tn...>> >+ : VariantAlternativeSfinae<I - 1, variant<Tn...>> {}; >+ >+// Value: T0 >+template <class T0, class... Ts> >+struct VariantAlternativeSfinae<0, variant<T0, Ts...>> { >+ using type = T0; >+}; >+ >+template <std::size_t I, class T> >+using VariantAlternativeSfinaeT = typename VariantAlternativeSfinae<I, T>::type; >+ >+// NOTE: Requires T to be a reference type. >+template <class T, class U> >+struct GiveQualsTo; >+ >+template <class T, class U> >+struct GiveQualsTo<T&, U> { >+ using type = U&; >+}; >+ >+template <class T, class U> >+struct GiveQualsTo<T&&, U> { >+ using type = U&&; >+}; >+ >+template <class T, class U> >+struct GiveQualsTo<const T&, U> { >+ using type = const U&; >+}; >+ >+template <class T, class U> >+struct GiveQualsTo<const T&&, U> { >+ using type = const U&&; >+}; >+ >+template <class T, class U> >+struct GiveQualsTo<volatile T&, U> { >+ using type = volatile U&; >+}; >+ >+template <class T, class U> >+struct GiveQualsTo<volatile T&&, U> { >+ using type = volatile U&&; >+}; >+ >+template <class T, class U> >+struct GiveQualsTo<volatile const T&, U> { >+ using type = volatile const U&; >+}; >+ >+template <class T, class U> >+struct GiveQualsTo<volatile const T&&, U> { >+ using type = volatile const U&&; >+}; >+ >+template <class T, class U> >+using GiveQualsToT = typename GiveQualsTo<T, U>::type; >+ >+// Convenience alias, since size_t integral_constant is used a lot in this file. >+template <std::size_t I> >+using SizeT = std::integral_constant<std::size_t, I>; >+ >+using NPos = SizeT<variant_npos>; >+ >+template <class Variant, class T, class = void> >+struct IndexOfConstructedType {}; >+ >+template <std::size_t I, class Variant> >+struct VariantAccessResultImpl; >+ >+template <std::size_t I, template <class...> class Variantemplate, class... T> >+struct VariantAccessResultImpl<I, Variantemplate<T...>&> { >+ using type = typename absl::variant_alternative<I, variant<T...>>::type&; >+}; >+ >+template <std::size_t I, template <class...> class Variantemplate, class... T> >+struct VariantAccessResultImpl<I, const Variantemplate<T...>&> { >+ using type = >+ const typename absl::variant_alternative<I, variant<T...>>::type&; >+}; >+ >+template <std::size_t I, template <class...> class Variantemplate, class... T> >+struct VariantAccessResultImpl<I, Variantemplate<T...>&&> { >+ using type = typename absl::variant_alternative<I, variant<T...>>::type&&; >+}; >+ >+template <std::size_t I, template <class...> class Variantemplate, class... T> >+struct VariantAccessResultImpl<I, const Variantemplate<T...>&&> { >+ using type = >+ const typename absl::variant_alternative<I, variant<T...>>::type&&; >+}; >+ >+template <std::size_t I, class Variant> >+using VariantAccessResult = >+ typename VariantAccessResultImpl<I, Variant&&>::type; >+ >+// NOTE: This is used instead of std::array to reduce instantiation overhead. >+template <class T, std::size_t Size> >+struct SimpleArray { >+ static_assert(Size != 0, ""); >+ T value[Size]; >+}; >+ >+template <class T> >+struct AccessedType { >+ using type = T; >+}; >+ >+template <class T> >+using AccessedTypeT = typename AccessedType<T>::type; >+ >+template <class T, std::size_t Size> >+struct AccessedType<SimpleArray<T, Size>> { >+ using type = AccessedTypeT<T>; >+}; >+ >+template <class T> >+constexpr T AccessSimpleArray(const T& value) { >+ return value; >+} >+ >+template <class T, std::size_t Size, class... SizeT> >+constexpr AccessedTypeT<T> AccessSimpleArray(const SimpleArray<T, Size>& table, >+ std::size_t head_index, >+ SizeT... tail_indices) { >+ return AccessSimpleArray(table.value[head_index], tail_indices...); >+} >+ >+// Note: Intentionally is an alias. >+template <class T> >+using AlwaysZero = SizeT<0>; >+ >+template <class Op, class... Vs> >+struct VisitIndicesResultImpl { >+ using type = absl::result_of_t<Op(AlwaysZero<Vs>...)>; >+}; >+ >+template <class Op, class... Vs> >+using VisitIndicesResultT = typename VisitIndicesResultImpl<Op, Vs...>::type; >+ >+template <class ReturnType, class FunctionObject, class EndIndices, >+ std::size_t... BoundIndices> >+struct MakeVisitationMatrix; >+ >+template <class ReturnType, class FunctionObject, std::size_t... Indices> >+constexpr ReturnType call_with_indices(FunctionObject&& function) { >+ static_assert( >+ std::is_same<ReturnType, decltype(std::declval<FunctionObject>()( >+ SizeT<Indices>()...))>::value, >+ "Not all visitation overloads have the same return type."); >+ return absl::forward<FunctionObject>(function)(SizeT<Indices>()...); >+} >+ >+template <class ReturnType, class FunctionObject, std::size_t... BoundIndices> >+struct MakeVisitationMatrix<ReturnType, FunctionObject, index_sequence<>, >+ BoundIndices...> { >+ using ResultType = ReturnType (*)(FunctionObject&&); >+ static constexpr ResultType Run() { >+ return &call_with_indices<ReturnType, FunctionObject, >+ (BoundIndices - 1)...>; >+ } >+}; >+ >+template <class ReturnType, class FunctionObject, class EndIndices, >+ class CurrIndices, std::size_t... BoundIndices> >+struct MakeVisitationMatrixImpl; >+ >+template <class ReturnType, class FunctionObject, std::size_t... EndIndices, >+ std::size_t... CurrIndices, std::size_t... BoundIndices> >+struct MakeVisitationMatrixImpl< >+ ReturnType, FunctionObject, index_sequence<EndIndices...>, >+ index_sequence<CurrIndices...>, BoundIndices...> { >+ using ResultType = SimpleArray< >+ typename MakeVisitationMatrix<ReturnType, FunctionObject, >+ index_sequence<EndIndices...>>::ResultType, >+ sizeof...(CurrIndices)>; >+ >+ static constexpr ResultType Run() { >+ return {{MakeVisitationMatrix<ReturnType, FunctionObject, >+ index_sequence<EndIndices...>, >+ BoundIndices..., CurrIndices>::Run()...}}; >+ } >+}; >+ >+template <class ReturnType, class FunctionObject, std::size_t HeadEndIndex, >+ std::size_t... TailEndIndices, std::size_t... BoundIndices> >+struct MakeVisitationMatrix<ReturnType, FunctionObject, >+ index_sequence<HeadEndIndex, TailEndIndices...>, >+ BoundIndices...> >+ : MakeVisitationMatrixImpl< >+ ReturnType, FunctionObject, index_sequence<TailEndIndices...>, >+ absl::make_index_sequence<HeadEndIndex>, BoundIndices...> {}; >+ >+struct UnreachableSwitchCase { >+ template <class Op> >+ [[noreturn]] static VisitIndicesResultT<Op, std::size_t> Run( >+ Op&& /*ignored*/) { >+#if ABSL_HAVE_BUILTIN(__builtin_unreachable) || \ >+ (defined(__GNUC__) && !defined(__clang__)) >+ __builtin_unreachable(); >+#elif defined(_MSC_VER) >+ __assume(false); >+#else >+ // Try to use assert of false being identified as an unreachable intrinsic. >+ // NOTE: We use assert directly to increase chances of exploiting an assume >+ // intrinsic. >+ assert(false); // NOLINT >+ >+ // Hack to silence potential no return warning -- cause an infinite loop. >+ return Run(absl::forward<Op>(op)); >+#endif // Checks for __builtin_unreachable >+ } >+}; >+ >+template <class Op, std::size_t I> >+struct ReachableSwitchCase { >+ static VisitIndicesResultT<Op, std::size_t> Run(Op&& op) { >+ return absl::base_internal::Invoke(absl::forward<Op>(op), SizeT<I>()); >+ } >+}; >+ >+// The number 33 is just a guess at a reasonable maximum to our switch. It is >+// not based on any analysis. The reason it is a power of 2 plus 1 instead of a >+// power of 2 is because the number was picked to correspond to a power of 2 >+// amount of "normal" alternatives, plus one for the possibility of the user >+// providing "monostate" in addition to the more natural alternatives. >+ABSL_INTERNAL_INLINE_CONSTEXPR(std::size_t, MaxUnrolledVisitCases, 33); >+ >+// Note: The default-definition is for unreachable cases. >+template <bool IsReachable> >+struct PickCaseImpl { >+ template <class Op, std::size_t I> >+ using Apply = UnreachableSwitchCase; >+}; >+ >+template <> >+struct PickCaseImpl</*IsReachable =*/true> { >+ template <class Op, std::size_t I> >+ using Apply = ReachableSwitchCase<Op, I>; >+}; >+ >+// Note: This form of dance with template aliases is to make sure that we >+// instantiate a number of templates proportional to the number of variant >+// alternatives rather than a number of templates proportional to our >+// maximum unrolled amount of visitation cases (aliases are effectively >+// "free" whereas other template instantiations are costly). >+template <class Op, std::size_t I, std::size_t EndIndex> >+using PickCase = typename PickCaseImpl<(I < EndIndex)>::template Apply<Op, I>; >+ >+template <class ReturnType> >+[[noreturn]] ReturnType TypedThrowBadVariantAccess() { >+ absl::variant_internal::ThrowBadVariantAccess(); >+} >+ >+// Given N variant sizes, determine the number of cases there would need to be >+// in a single switch-statement that would cover every possibility in the >+// corresponding N-ary visit operation. >+template <std::size_t... NumAlternatives> >+struct NumCasesOfSwitch; >+ >+template <std::size_t HeadNumAlternatives, std::size_t... TailNumAlternatives> >+struct NumCasesOfSwitch<HeadNumAlternatives, TailNumAlternatives...> { >+ static constexpr std::size_t value = >+ (HeadNumAlternatives + 1) * >+ NumCasesOfSwitch<TailNumAlternatives...>::value; >+}; >+ >+template <> >+struct NumCasesOfSwitch<> { >+ static constexpr std::size_t value = 1; >+}; >+ >+// A switch statement optimizes better than the table of function pointers. >+template <std::size_t EndIndex> >+struct VisitIndicesSwitch { >+ static_assert(EndIndex <= MaxUnrolledVisitCases, >+ "Maximum unrolled switch size exceeded."); >+ >+ template <class Op> >+ static VisitIndicesResultT<Op, std::size_t> Run(Op&& op, std::size_t i) { >+ switch (i) { >+ case 0: >+ return PickCase<Op, 0, EndIndex>::Run(absl::forward<Op>(op)); >+ case 1: >+ return PickCase<Op, 1, EndIndex>::Run(absl::forward<Op>(op)); >+ case 2: >+ return PickCase<Op, 2, EndIndex>::Run(absl::forward<Op>(op)); >+ case 3: >+ return PickCase<Op, 3, EndIndex>::Run(absl::forward<Op>(op)); >+ case 4: >+ return PickCase<Op, 4, EndIndex>::Run(absl::forward<Op>(op)); >+ case 5: >+ return PickCase<Op, 5, EndIndex>::Run(absl::forward<Op>(op)); >+ case 6: >+ return PickCase<Op, 6, EndIndex>::Run(absl::forward<Op>(op)); >+ case 7: >+ return PickCase<Op, 7, EndIndex>::Run(absl::forward<Op>(op)); >+ case 8: >+ return PickCase<Op, 8, EndIndex>::Run(absl::forward<Op>(op)); >+ case 9: >+ return PickCase<Op, 9, EndIndex>::Run(absl::forward<Op>(op)); >+ case 10: >+ return PickCase<Op, 10, EndIndex>::Run(absl::forward<Op>(op)); >+ case 11: >+ return PickCase<Op, 11, EndIndex>::Run(absl::forward<Op>(op)); >+ case 12: >+ return PickCase<Op, 12, EndIndex>::Run(absl::forward<Op>(op)); >+ case 13: >+ return PickCase<Op, 13, EndIndex>::Run(absl::forward<Op>(op)); >+ case 14: >+ return PickCase<Op, 14, EndIndex>::Run(absl::forward<Op>(op)); >+ case 15: >+ return PickCase<Op, 15, EndIndex>::Run(absl::forward<Op>(op)); >+ case 16: >+ return PickCase<Op, 16, EndIndex>::Run(absl::forward<Op>(op)); >+ case 17: >+ return PickCase<Op, 17, EndIndex>::Run(absl::forward<Op>(op)); >+ case 18: >+ return PickCase<Op, 18, EndIndex>::Run(absl::forward<Op>(op)); >+ case 19: >+ return PickCase<Op, 19, EndIndex>::Run(absl::forward<Op>(op)); >+ case 20: >+ return PickCase<Op, 20, EndIndex>::Run(absl::forward<Op>(op)); >+ case 21: >+ return PickCase<Op, 21, EndIndex>::Run(absl::forward<Op>(op)); >+ case 22: >+ return PickCase<Op, 22, EndIndex>::Run(absl::forward<Op>(op)); >+ case 23: >+ return PickCase<Op, 23, EndIndex>::Run(absl::forward<Op>(op)); >+ case 24: >+ return PickCase<Op, 24, EndIndex>::Run(absl::forward<Op>(op)); >+ case 25: >+ return PickCase<Op, 25, EndIndex>::Run(absl::forward<Op>(op)); >+ case 26: >+ return PickCase<Op, 26, EndIndex>::Run(absl::forward<Op>(op)); >+ case 27: >+ return PickCase<Op, 27, EndIndex>::Run(absl::forward<Op>(op)); >+ case 28: >+ return PickCase<Op, 28, EndIndex>::Run(absl::forward<Op>(op)); >+ case 29: >+ return PickCase<Op, 29, EndIndex>::Run(absl::forward<Op>(op)); >+ case 30: >+ return PickCase<Op, 30, EndIndex>::Run(absl::forward<Op>(op)); >+ case 31: >+ return PickCase<Op, 31, EndIndex>::Run(absl::forward<Op>(op)); >+ case 32: >+ return PickCase<Op, 32, EndIndex>::Run(absl::forward<Op>(op)); >+ default: >+ ABSL_ASSERT(i == variant_npos); >+ return absl::base_internal::Invoke(absl::forward<Op>(op), NPos()); >+ } >+ } >+}; >+ >+template <std::size_t... EndIndices> >+struct VisitIndicesFallback { >+ template <class Op, class... SizeT> >+ static VisitIndicesResultT<Op, SizeT...> Run(Op&& op, SizeT... indices) { >+ return AccessSimpleArray( >+ MakeVisitationMatrix<VisitIndicesResultT<Op, SizeT...>, Op, >+ index_sequence<(EndIndices + 1)...>>::Run(), >+ (indices + 1)...)(absl::forward<Op>(op)); >+ } >+}; >+ >+// Take an N-dimensional series of indices and convert them into a single index >+// without loss of information. The purpose of this is to be able to convert an >+// N-ary visit operation into a single switch statement. >+template <std::size_t...> >+struct FlattenIndices; >+ >+template <std::size_t HeadSize, std::size_t... TailSize> >+struct FlattenIndices<HeadSize, TailSize...> { >+ template<class... SizeType> >+ static constexpr std::size_t Run(std::size_t head, SizeType... tail) { >+ return head + HeadSize * FlattenIndices<TailSize...>::Run(tail...); >+ } >+}; >+ >+template <> >+struct FlattenIndices<> { >+ static constexpr std::size_t Run() { return 0; } >+}; >+ >+// Take a single "flattened" index (flattened by FlattenIndices) and determine >+// the value of the index of one of the logically represented dimensions. >+template <std::size_t I, std::size_t IndexToGet, std::size_t HeadSize, >+ std::size_t... TailSize> >+struct UnflattenIndex { >+ static constexpr std::size_t value = >+ UnflattenIndex<I / HeadSize, IndexToGet - 1, TailSize...>::value; >+}; >+ >+template <std::size_t I, std::size_t HeadSize, std::size_t... TailSize> >+struct UnflattenIndex<I, 0, HeadSize, TailSize...> { >+ static constexpr std::size_t value = (I % HeadSize); >+}; >+ >+// The backend for converting an N-ary visit operation into a unary visit. >+template <class IndexSequence, std::size_t... EndIndices> >+struct VisitIndicesVariadicImpl; >+ >+template <std::size_t... N, std::size_t... EndIndices> >+struct VisitIndicesVariadicImpl<absl::index_sequence<N...>, EndIndices...> { >+ // A type that can take an N-ary function object and converts it to a unary >+ // function object that takes a single, flattened index, and "unflattens" it >+ // into its individual dimensions when forwarding to the wrapped object. >+ template <class Op> >+ struct FlattenedOp { >+ template <std::size_t I> >+ VisitIndicesResultT<Op, decltype(EndIndices)...> operator()( >+ SizeT<I> /*index*/) && { >+ return base_internal::Invoke( >+ absl::forward<Op>(op), >+ SizeT<UnflattenIndex<I, N, (EndIndices + 1)...>::value - >+ std::size_t{1}>()...); >+ } >+ >+ Op&& op; >+ }; >+ >+ template <class Op, class... SizeType> >+ static VisitIndicesResultT<Op, decltype(EndIndices)...> Run( >+ Op&& op, SizeType... i) { >+ return VisitIndicesSwitch<NumCasesOfSwitch<EndIndices...>::value>::Run( >+ FlattenedOp<Op>{absl::forward<Op>(op)}, >+ FlattenIndices<(EndIndices + std::size_t{1})...>::Run( >+ (i + std::size_t{1})...)); >+ } >+}; >+ >+template <std::size_t... EndIndices> >+struct VisitIndicesVariadic >+ : VisitIndicesVariadicImpl<absl::make_index_sequence<sizeof...(EndIndices)>, >+ EndIndices...> {}; >+ >+// This implementation will flatten N-ary visit operations into a single switch >+// statement when the number of cases would be less than our maximum specified >+// switch-statement size. >+// TODO(calabrese) >+// Based on benchmarks, determine whether the function table approach actually >+// does optimize better than a chain of switch statements and possibly update >+// the implementation accordingly. Also consider increasing the maximum switch >+// size. >+template <std::size_t... EndIndices> >+struct VisitIndices >+ : absl::conditional_t<(NumCasesOfSwitch<EndIndices...>::value <= >+ MaxUnrolledVisitCases), >+ VisitIndicesVariadic<EndIndices...>, >+ VisitIndicesFallback<EndIndices...>> {}; >+ >+template <std::size_t EndIndex> >+struct VisitIndices<EndIndex> >+ : absl::conditional_t<(EndIndex <= MaxUnrolledVisitCases), >+ VisitIndicesSwitch<EndIndex>, >+ VisitIndicesFallback<EndIndex>> {}; >+ >+// Suppress bogus warning on MSVC: MSVC complains that the `reinterpret_cast` >+// below is returning the address of a temporary or local object. >+#ifdef _MSC_VER >+#pragma warning(push) >+#pragma warning(disable : 4172) >+#endif // _MSC_VER >+ >+// TODO(calabrese) std::launder >+// TODO(calabrese) constexpr >+// NOTE: DO NOT REMOVE the `inline` keyword as it is necessary to work around a >+// MSVC bug. See https://github.com/abseil/abseil-cpp/issues/129 for details. >+template <class Self, std::size_t I> >+inline VariantAccessResult<I, Self> AccessUnion(Self&& self, SizeT<I> /*i*/) { >+ return reinterpret_cast<VariantAccessResult<I, Self>>(self); >+} >+ >+#ifdef _MSC_VER >+#pragma warning(pop) >+#endif // _MSC_VER >+ >+template <class T> >+void DeducedDestroy(T& self) { // NOLINT >+ self.~T(); >+} >+ >+// NOTE: This type exists as a single entity for variant and its bases to >+// befriend. It contains helper functionality that manipulates the state of the >+// variant, such as the implementation of things like assignment and emplace >+// operations. >+struct VariantCoreAccess { >+ template <class VariantType> >+ static typename VariantType::Variant& Derived(VariantType& self) { // NOLINT >+ return static_cast<typename VariantType::Variant&>(self); >+ } >+ >+ template <class VariantType> >+ static const typename VariantType::Variant& Derived( >+ const VariantType& self) { // NOLINT >+ return static_cast<const typename VariantType::Variant&>(self); >+ } >+ >+ template <class VariantType> >+ static void Destroy(VariantType& self) { // NOLINT >+ Derived(self).destroy(); >+ self.index_ = absl::variant_npos; >+ } >+ >+ template <class Variant> >+ static void SetIndex(Variant& self, std::size_t i) { // NOLINT >+ self.index_ = i; >+ } >+ >+ template <class Variant> >+ static void InitFrom(Variant& self, Variant&& other) { // NOLINT >+ VisitIndices<absl::variant_size<Variant>::value>::Run( >+ InitFromVisitor<Variant, Variant&&>{&self, >+ std::forward<Variant>(other)}, >+ other.index()); >+ self.index_ = other.index(); >+ } >+ >+ // Access a variant alternative, assuming the index is correct. >+ template <std::size_t I, class Variant> >+ static VariantAccessResult<I, Variant> Access(Variant&& self) { >+ // This cast instead of invocation of AccessUnion with an rvalue is a >+ // workaround for msvc. Without this there is a runtime failure when dealing >+ // with rvalues. >+ // TODO(calabrese) Reduce test case and find a simpler workaround. >+ return static_cast<VariantAccessResult<I, Variant>>( >+ variant_internal::AccessUnion(self.state_, SizeT<I>())); >+ } >+ >+ // Access a variant alternative, throwing if the index is incorrect. >+ template <std::size_t I, class Variant> >+ static VariantAccessResult<I, Variant> CheckedAccess(Variant&& self) { >+ if (ABSL_PREDICT_FALSE(self.index_ != I)) { >+ TypedThrowBadVariantAccess<VariantAccessResult<I, Variant>>(); >+ } >+ >+ return Access<I>(absl::forward<Variant>(self)); >+ } >+ >+ // The implementation of the move-assignment operation for a variant. >+ template <class VType> >+ struct MoveAssignVisitor { >+ using DerivedType = typename VType::Variant; >+ template <std::size_t NewIndex> >+ void operator()(SizeT<NewIndex> /*new_i*/) const { >+ if (left->index_ == NewIndex) { >+ Access<NewIndex>(*left) = std::move(Access<NewIndex>(*right)); >+ } else { >+ Derived(*left).template emplace<NewIndex>( >+ std::move(Access<NewIndex>(*right))); >+ } >+ } >+ >+ void operator()(SizeT<absl::variant_npos> /*new_i*/) const { >+ Destroy(*left); >+ } >+ >+ VType* left; >+ VType* right; >+ }; >+ >+ template <class VType> >+ static MoveAssignVisitor<VType> MakeMoveAssignVisitor(VType* left, >+ VType* other) { >+ return {left, other}; >+ } >+ >+ // The implementation of the assignment operation for a variant. >+ template <class VType> >+ struct CopyAssignVisitor { >+ using DerivedType = typename VType::Variant; >+ template <std::size_t NewIndex> >+ void operator()(SizeT<NewIndex> /*new_i*/) const { >+ using New = >+ typename absl::variant_alternative<NewIndex, DerivedType>::type; >+ >+ if (left->index_ == NewIndex) { >+ Access<NewIndex>(*left) = Access<NewIndex>(*right); >+ } else if (std::is_nothrow_copy_constructible<New>::value || >+ !std::is_nothrow_move_constructible<New>::value) { >+ Derived(*left).template emplace<NewIndex>(Access<NewIndex>(*right)); >+ } else { >+ Derived(*left) = DerivedType(Derived(*right)); >+ } >+ } >+ >+ void operator()(SizeT<absl::variant_npos> /*new_i*/) const { >+ Destroy(*left); >+ } >+ >+ VType* left; >+ const VType* right; >+ }; >+ >+ template <class VType> >+ static CopyAssignVisitor<VType> MakeCopyAssignVisitor(VType* left, >+ const VType& other) { >+ return {left, &other}; >+ } >+ >+ // The implementation of conversion-assignment operations for variant. >+ template <class Left, class QualifiedNew> >+ struct ConversionAssignVisitor { >+ using NewIndex = >+ variant_internal::IndexOfConstructedType<Left, QualifiedNew>; >+ >+ void operator()(SizeT<NewIndex::value> /*old_i*/ >+ ) const { >+ Access<NewIndex::value>(*left) = absl::forward<QualifiedNew>(other); >+ } >+ >+ template <std::size_t OldIndex> >+ void operator()(SizeT<OldIndex> /*old_i*/ >+ ) const { >+ using New = >+ typename absl::variant_alternative<NewIndex::value, Left>::type; >+ if (std::is_nothrow_constructible<New, QualifiedNew>::value || >+ !std::is_nothrow_move_constructible<New>::value) { >+ left->template emplace<NewIndex::value>( >+ absl::forward<QualifiedNew>(other)); >+ } else { >+ // the standard says "equivalent to >+ // operator=(variant(std::forward<T>(t)))", but we use `emplace` here >+ // because the variant's move assignment operator could be deleted. >+ left->template emplace<NewIndex::value>( >+ New(absl::forward<QualifiedNew>(other))); >+ } >+ } >+ >+ Left* left; >+ QualifiedNew&& other; >+ }; >+ >+ template <class Left, class QualifiedNew> >+ static ConversionAssignVisitor<Left, QualifiedNew> >+ MakeConversionAssignVisitor(Left* left, QualifiedNew&& qual) { >+ return {left, absl::forward<QualifiedNew>(qual)}; >+ } >+ >+ // Backend for operations for `emplace()` which destructs `*self` then >+ // construct a new alternative with `Args...`. >+ template <std::size_t NewIndex, class Self, class... Args> >+ static typename absl::variant_alternative<NewIndex, Self>::type& Replace( >+ Self* self, Args&&... args) { >+ Destroy(*self); >+ using New = typename absl::variant_alternative<NewIndex, Self>::type; >+ New* const result = ::new (static_cast<void*>(&self->state_)) >+ New(absl::forward<Args>(args)...); >+ self->index_ = NewIndex; >+ return *result; >+ } >+ >+ template <class LeftVariant, class QualifiedRightVariant> >+ struct InitFromVisitor { >+ template <std::size_t NewIndex> >+ void operator()(SizeT<NewIndex> /*new_i*/) const { >+ using Alternative = >+ typename variant_alternative<NewIndex, LeftVariant>::type; >+ ::new (static_cast<void*>(&left->state_)) Alternative( >+ Access<NewIndex>(std::forward<QualifiedRightVariant>(right))); >+ } >+ >+ void operator()(SizeT<absl::variant_npos> /*new_i*/) const { >+ // This space intentionally left blank. >+ } >+ LeftVariant* left; >+ QualifiedRightVariant&& right; >+ }; >+}; >+ >+template <class Expected, class... T> >+struct IndexOfImpl; >+ >+template <class Expected> >+struct IndexOfImpl<Expected> { >+ using IndexFromEnd = SizeT<0>; >+ using MatchedIndexFromEnd = IndexFromEnd; >+ using MultipleMatches = std::false_type; >+}; >+ >+template <class Expected, class Head, class... Tail> >+struct IndexOfImpl<Expected, Head, Tail...> : IndexOfImpl<Expected, Tail...> { >+ using IndexFromEnd = >+ SizeT<IndexOfImpl<Expected, Tail...>::IndexFromEnd::value + 1>; >+}; >+ >+template <class Expected, class... Tail> >+struct IndexOfImpl<Expected, Expected, Tail...> >+ : IndexOfImpl<Expected, Tail...> { >+ using IndexFromEnd = >+ SizeT<IndexOfImpl<Expected, Tail...>::IndexFromEnd::value + 1>; >+ using MatchedIndexFromEnd = IndexFromEnd; >+ using MultipleMatches = std::integral_constant< >+ bool, IndexOfImpl<Expected, Tail...>::MatchedIndexFromEnd::value != 0>; >+}; >+ >+template <class Expected, class... Types> >+struct IndexOfMeta { >+ using Results = IndexOfImpl<Expected, Types...>; >+ static_assert(!Results::MultipleMatches::value, >+ "Attempted to access a variant by specifying a type that " >+ "matches more than one alternative."); >+ static_assert(Results::MatchedIndexFromEnd::value != 0, >+ "Attempted to access a variant by specifying a type that does " >+ "not match any alternative."); >+ using type = SizeT<sizeof...(Types) - Results::MatchedIndexFromEnd::value>; >+}; >+ >+template <class Expected, class... Types> >+using IndexOf = typename IndexOfMeta<Expected, Types...>::type; >+ >+template <class Variant, class T, std::size_t CurrIndex> >+struct UnambiguousIndexOfImpl; >+ >+// Terminating case encountered once we've checked all of the alternatives >+template <class T, std::size_t CurrIndex> >+struct UnambiguousIndexOfImpl<variant<>, T, CurrIndex> : SizeT<CurrIndex> {}; >+ >+// Case where T is not Head >+template <class Head, class... Tail, class T, std::size_t CurrIndex> >+struct UnambiguousIndexOfImpl<variant<Head, Tail...>, T, CurrIndex> >+ : UnambiguousIndexOfImpl<variant<Tail...>, T, CurrIndex + 1>::type {}; >+ >+// Case where T is Head >+template <class Head, class... Tail, std::size_t CurrIndex> >+struct UnambiguousIndexOfImpl<variant<Head, Tail...>, Head, CurrIndex> >+ : SizeT<UnambiguousIndexOfImpl<variant<Tail...>, Head, 0>::value == >+ sizeof...(Tail) >+ ? CurrIndex >+ : CurrIndex + sizeof...(Tail) + 1> {}; >+ >+template <class Variant, class T> >+struct UnambiguousIndexOf; >+ >+struct NoMatch { >+ struct type {}; >+}; >+ >+template <class... Alts, class T> >+struct UnambiguousIndexOf<variant<Alts...>, T> >+ : std::conditional<UnambiguousIndexOfImpl<variant<Alts...>, T, 0>::value != >+ sizeof...(Alts), >+ UnambiguousIndexOfImpl<variant<Alts...>, T, 0>, >+ NoMatch>::type::type {}; >+ >+template <class T, std::size_t /*Dummy*/> >+using UnambiguousTypeOfImpl = T; >+ >+template <class Variant, class T> >+using UnambiguousTypeOfT = >+ UnambiguousTypeOfImpl<T, UnambiguousIndexOf<Variant, T>::value>; >+ >+template <class H, class... T> >+class VariantStateBase; >+ >+// This is an implementation of the "imaginary function" that is described in >+// [variant.ctor] >+// It is used in order to determine which alternative to construct during >+// initialization from some type T. >+template <class Variant, std::size_t I = 0> >+struct ImaginaryFun; >+ >+template <std::size_t I> >+struct ImaginaryFun<variant<>, I> { >+ static void Run() = delete; >+}; >+ >+template <class H, class... T, std::size_t I> >+struct ImaginaryFun<variant<H, T...>, I> : ImaginaryFun<variant<T...>, I + 1> { >+ using ImaginaryFun<variant<T...>, I + 1>::Run; >+ >+ // NOTE: const& and && are used instead of by-value due to lack of guaranteed >+ // move elision of C++17. This may have other minor differences, but tests >+ // pass. >+ static SizeT<I> Run(const H&); >+ static SizeT<I> Run(H&&); >+}; >+ >+// The following metafunctions are used in constructor and assignment >+// constraints. >+template <class Self, class T> >+struct IsNeitherSelfNorInPlace : std::true_type {}; >+ >+template <class Self> >+struct IsNeitherSelfNorInPlace<Self, Self> : std::false_type {}; >+ >+template <class Self, class T> >+struct IsNeitherSelfNorInPlace<Self, in_place_type_t<T>> : std::false_type {}; >+ >+template <class Self, std::size_t I> >+struct IsNeitherSelfNorInPlace<Self, in_place_index_t<I>> : std::false_type {}; >+ >+template <class Variant, class T, class = void> >+struct ConversionIsPossibleImpl : std::false_type {}; >+ >+template <class Variant, class T> >+struct ConversionIsPossibleImpl< >+ Variant, T, void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>()))>> >+ : std::true_type {}; >+ >+template <class Variant, class T> >+struct ConversionIsPossible : ConversionIsPossibleImpl<Variant, T>::type {}; >+ >+template <class Variant, class T> >+struct IndexOfConstructedType< >+ Variant, T, void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>()))>> >+ : decltype(ImaginaryFun<Variant>::Run(std::declval<T>())) {}; >+ >+template <std::size_t... Is> >+struct ContainsVariantNPos >+ : absl::negation<std::is_same< // NOLINT >+ absl::integer_sequence<bool, 0 <= Is...>, >+ absl::integer_sequence<bool, Is != absl::variant_npos...>>> {}; >+ >+template <class Op, class... QualifiedVariants> >+using RawVisitResult = >+ absl::result_of_t<Op(VariantAccessResult<0, QualifiedVariants>...)>; >+ >+// NOTE: The spec requires that all return-paths yield the same type and is not >+// SFINAE-friendly, so we can deduce the return type by examining the first >+// result. If it's not callable, then we get an error, but are compliant and >+// fast to compile. >+// TODO(calabrese) Possibly rewrite in a way that yields better compile errors >+// at the cost of longer compile-times. >+template <class Op, class... QualifiedVariants> >+struct VisitResultImpl { >+ using type = >+ absl::result_of_t<Op(VariantAccessResult<0, QualifiedVariants>...)>; >+}; >+ >+// Done in two steps intentionally so that we don't cause substitution to fail. >+template <class Op, class... QualifiedVariants> >+using VisitResult = typename VisitResultImpl<Op, QualifiedVariants...>::type; >+ >+template <class Op, class... QualifiedVariants> >+struct PerformVisitation { >+ using ReturnType = VisitResult<Op, QualifiedVariants...>; >+ >+ template <std::size_t... Is> >+ constexpr ReturnType operator()(SizeT<Is>... indices) const { >+ return Run(typename ContainsVariantNPos<Is...>::type{}, >+ absl::index_sequence_for<QualifiedVariants...>(), indices...); >+ } >+ >+ template <std::size_t... TupIs, std::size_t... Is> >+ constexpr ReturnType Run(std::false_type /*has_valueless*/, >+ index_sequence<TupIs...>, SizeT<Is>...) const { >+ return absl::base_internal::Invoke( >+ absl::forward<Op>(op), >+ VariantCoreAccess::Access<Is>( >+ absl::forward<QualifiedVariants>(std::get<TupIs>(variant_tup)))...); >+ } >+ >+ template <std::size_t... TupIs, std::size_t... Is> >+ [[noreturn]] ReturnType Run(std::true_type /*has_valueless*/, >+ index_sequence<TupIs...>, SizeT<Is>...) const { >+ absl::variant_internal::ThrowBadVariantAccess(); >+ } >+ >+ // TODO(calabrese) Avoid using a tuple, which causes lots of instantiations >+ // Attempts using lambda variadic captures fail on current GCC. >+ std::tuple<QualifiedVariants&&...> variant_tup; >+ Op&& op; >+}; >+ >+template <class... T> >+union Union; >+ >+// We want to allow for variant<> to be trivial. For that, we need the default >+// constructor to be trivial, which means we can't define it ourselves. >+// Instead, we use a non-default constructor that takes NoopConstructorTag >+// that doesn't affect the triviality of the types. >+struct NoopConstructorTag {}; >+ >+template <std::size_t I> >+struct EmplaceTag {}; >+ >+template <> >+union Union<> { >+ constexpr explicit Union(NoopConstructorTag) noexcept {} >+}; >+ >+// Suppress bogus warning on MSVC: MSVC complains that Union<T...> has a defined >+// deleted destructor from the `std::is_destructible` check below. >+#ifdef _MSC_VER >+#pragma warning(push) >+#pragma warning(disable : 4624) >+#endif // _MSC_VER >+ >+template <class Head, class... Tail> >+union Union<Head, Tail...> { >+ using TailUnion = Union<Tail...>; >+ >+ explicit constexpr Union(NoopConstructorTag /*tag*/) noexcept >+ : tail(NoopConstructorTag()) {} >+ >+ template <class... P> >+ explicit constexpr Union(EmplaceTag<0>, P&&... args) >+ : head(absl::forward<P>(args)...) {} >+ >+ template <std::size_t I, class... P> >+ explicit constexpr Union(EmplaceTag<I>, P&&... args) >+ : tail(EmplaceTag<I - 1>{}, absl::forward<P>(args)...) {} >+ >+ Head head; >+ TailUnion tail; >+}; >+ >+#ifdef _MSC_VER >+#pragma warning(pop) >+#endif // _MSC_VER >+ >+// TODO(calabrese) Just contain a Union in this union (certain configs fail). >+template <class... T> >+union DestructibleUnionImpl; >+ >+template <> >+union DestructibleUnionImpl<> { >+ constexpr explicit DestructibleUnionImpl(NoopConstructorTag) noexcept {} >+}; >+ >+template <class Head, class... Tail> >+union DestructibleUnionImpl<Head, Tail...> { >+ using TailUnion = DestructibleUnionImpl<Tail...>; >+ >+ explicit constexpr DestructibleUnionImpl(NoopConstructorTag /*tag*/) noexcept >+ : tail(NoopConstructorTag()) {} >+ >+ template <class... P> >+ explicit constexpr DestructibleUnionImpl(EmplaceTag<0>, P&&... args) >+ : head(absl::forward<P>(args)...) {} >+ >+ template <std::size_t I, class... P> >+ explicit constexpr DestructibleUnionImpl(EmplaceTag<I>, P&&... args) >+ : tail(EmplaceTag<I - 1>{}, absl::forward<P>(args)...) {} >+ >+ ~DestructibleUnionImpl() {} >+ >+ Head head; >+ TailUnion tail; >+}; >+ >+// This union type is destructible even if one or more T are not trivially >+// destructible. In the case that all T are trivially destructible, then so is >+// this resultant type. >+template <class... T> >+using DestructibleUnion = >+ absl::conditional_t<std::is_destructible<Union<T...>>::value, Union<T...>, >+ DestructibleUnionImpl<T...>>; >+ >+// Deepest base, containing the actual union and the discriminator >+template <class H, class... T> >+class VariantStateBase { >+ protected: >+ using Variant = variant<H, T...>; >+ >+ template <class LazyH = H, >+ class ConstructibleH = absl::enable_if_t< >+ std::is_default_constructible<LazyH>::value, LazyH>> >+ constexpr VariantStateBase() noexcept( >+ std::is_nothrow_default_constructible<ConstructibleH>::value) >+ : state_(EmplaceTag<0>()), index_(0) {} >+ >+ template <std::size_t I, class... P> >+ explicit constexpr VariantStateBase(EmplaceTag<I> tag, P&&... args) >+ : state_(tag, absl::forward<P>(args)...), index_(I) {} >+ >+ explicit constexpr VariantStateBase(NoopConstructorTag) >+ : state_(NoopConstructorTag()), index_(variant_npos) {} >+ >+ void destroy() {} // Does nothing (shadowed in child if non-trivial) >+ >+ DestructibleUnion<H, T...> state_; >+ std::size_t index_; >+}; >+ >+using absl::internal::identity; >+ >+// OverloadSet::Overload() is a unary function which is overloaded to >+// take any of the element types of the variant, by reference-to-const. >+// The return type of the overload on T is identity<T>, so that you >+// can statically determine which overload was called. >+// >+// Overload() is not defined, so it can only be called in unevaluated >+// contexts. >+template <typename... Ts> >+struct OverloadSet; >+ >+template <typename T, typename... Ts> >+struct OverloadSet<T, Ts...> : OverloadSet<Ts...> { >+ using Base = OverloadSet<Ts...>; >+ static identity<T> Overload(const T&); >+ using Base::Overload; >+}; >+ >+template <> >+struct OverloadSet<> { >+ // For any case not handled above. >+ static void Overload(...); >+}; >+ >+template <class T> >+using LessThanResult = decltype(std::declval<T>() < std::declval<T>()); >+ >+template <class T> >+using GreaterThanResult = decltype(std::declval<T>() > std::declval<T>()); >+ >+template <class T> >+using LessThanOrEqualResult = decltype(std::declval<T>() <= std::declval<T>()); >+ >+template <class T> >+using GreaterThanOrEqualResult = >+ decltype(std::declval<T>() >= std::declval<T>()); >+ >+template <class T> >+using EqualResult = decltype(std::declval<T>() == std::declval<T>()); >+ >+template <class T> >+using NotEqualResult = decltype(std::declval<T>() != std::declval<T>()); >+ >+using type_traits_internal::is_detected_convertible; >+ >+template <class... T> >+using RequireAllHaveEqualT = absl::enable_if_t< >+ absl::conjunction<is_detected_convertible<bool, EqualResult, T>...>::value, >+ bool>; >+ >+template <class... T> >+using RequireAllHaveNotEqualT = >+ absl::enable_if_t<absl::conjunction<is_detected_convertible< >+ bool, NotEqualResult, T>...>::value, >+ bool>; >+ >+template <class... T> >+using RequireAllHaveLessThanT = >+ absl::enable_if_t<absl::conjunction<is_detected_convertible< >+ bool, LessThanResult, T>...>::value, >+ bool>; >+ >+template <class... T> >+using RequireAllHaveLessThanOrEqualT = >+ absl::enable_if_t<absl::conjunction<is_detected_convertible< >+ bool, LessThanOrEqualResult, T>...>::value, >+ bool>; >+ >+template <class... T> >+using RequireAllHaveGreaterThanOrEqualT = >+ absl::enable_if_t<absl::conjunction<is_detected_convertible< >+ bool, GreaterThanOrEqualResult, T>...>::value, >+ bool>; >+ >+template <class... T> >+using RequireAllHaveGreaterThanT = >+ absl::enable_if_t<absl::conjunction<is_detected_convertible< >+ bool, GreaterThanResult, T>...>::value, >+ bool>; >+ >+// Helper template containing implementations details of variant that can't go >+// in the private section. For convenience, this takes the variant type as a >+// single template parameter. >+template <typename T> >+struct VariantHelper; >+ >+template <typename... Ts> >+struct VariantHelper<variant<Ts...>> { >+ // Type metafunction which returns the element type selected if >+ // OverloadSet::Overload() is well-formed when called with argument type U. >+ template <typename U> >+ using BestMatch = decltype( >+ variant_internal::OverloadSet<Ts...>::Overload(std::declval<U>())); >+ >+ // Type metafunction which returns true if OverloadSet::Overload() is >+ // well-formed when called with argument type U. >+ // CanAccept can't be just an alias because there is a MSVC bug on parameter >+ // pack expansion involving decltype. >+ template <typename U> >+ struct CanAccept : >+ std::integral_constant<bool, !std::is_void<BestMatch<U>>::value> {}; >+ >+ // Type metafunction which returns true if Other is an instantiation of >+ // variant, and variants's converting constructor from Other will be >+ // well-formed. We will use this to remove constructors that would be >+ // ill-formed from the overload set. >+ template <typename Other> >+ struct CanConvertFrom; >+ >+ template <typename... Us> >+ struct CanConvertFrom<variant<Us...>> >+ : public absl::conjunction<CanAccept<Us>...> {}; >+}; >+ >+// A type with nontrivial copy ctor and trivial move ctor. >+struct TrivialMoveOnly { >+ TrivialMoveOnly(TrivialMoveOnly&&) = default; >+}; >+ >+// Trait class to detect whether a type is trivially move constructible. >+// A union's defaulted copy/move constructor is deleted if any variant member's >+// copy/move constructor is nontrivial. >+template <typename T> >+struct IsTriviallyMoveConstructible: >+ std::is_move_constructible<Union<T, TrivialMoveOnly>> {}; >+ >+// To guarantee triviality of all special-member functions that can be trivial, >+// we use a chain of conditional bases for each one. >+// The order of inheritance of bases from child to base are logically: >+// >+// variant >+// VariantCopyAssignBase >+// VariantMoveAssignBase >+// VariantCopyBase >+// VariantMoveBase >+// VariantStateBaseDestructor >+// VariantStateBase >+// >+// Note that there is a separate branch at each base that is dependent on >+// whether or not that corresponding special-member-function can be trivial in >+// the resultant variant type. >+ >+template <class... T> >+class VariantStateBaseDestructorNontrivial; >+ >+template <class... T> >+class VariantMoveBaseNontrivial; >+ >+template <class... T> >+class VariantCopyBaseNontrivial; >+ >+template <class... T> >+class VariantMoveAssignBaseNontrivial; >+ >+template <class... T> >+class VariantCopyAssignBaseNontrivial; >+ >+// Base that is dependent on whether or not the destructor can be trivial. >+template <class... T> >+using VariantStateBaseDestructor = >+ absl::conditional_t<std::is_destructible<Union<T...>>::value, >+ VariantStateBase<T...>, >+ VariantStateBaseDestructorNontrivial<T...>>; >+ >+// Base that is dependent on whether or not the move-constructor can be >+// implicitly generated by the compiler (trivial or deleted). >+// Previously we were using `std::is_move_constructible<Union<T...>>` to check >+// whether all Ts have trivial move constructor, but it ran into a GCC bug: >+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84866 >+// So we have to use a different approach (i.e. `HasTrivialMoveConstructor`) to >+// work around the bug. >+template <class... T> >+using VariantMoveBase = absl::conditional_t< >+ absl::disjunction< >+ absl::negation<absl::conjunction<std::is_move_constructible<T>...>>, >+ absl::conjunction<IsTriviallyMoveConstructible<T>...>>::value, >+ VariantStateBaseDestructor<T...>, VariantMoveBaseNontrivial<T...>>; >+ >+// Base that is dependent on whether or not the copy-constructor can be trivial. >+template <class... T> >+using VariantCopyBase = absl::conditional_t< >+ absl::disjunction< >+ absl::negation<absl::conjunction<std::is_copy_constructible<T>...>>, >+ std::is_copy_constructible<Union<T...>>>::value, >+ VariantMoveBase<T...>, VariantCopyBaseNontrivial<T...>>; >+ >+// Base that is dependent on whether or not the move-assign can be trivial. >+template <class... T> >+using VariantMoveAssignBase = absl::conditional_t< >+ absl::disjunction<absl::conjunction<std::is_move_assignable<Union<T...>>, >+ std::is_move_constructible<Union<T...>>, >+ std::is_destructible<Union<T...>>>, >+ absl::negation<absl::conjunction< >+ std::is_move_constructible<T>..., >+ std::is_move_assignable<T>...>>>::value, >+ VariantCopyBase<T...>, VariantMoveAssignBaseNontrivial<T...>>; >+ >+// Base that is dependent on whether or not the copy-assign can be trivial. >+template <class... T> >+using VariantCopyAssignBase = absl::conditional_t< >+ absl::disjunction<absl::conjunction<std::is_copy_assignable<Union<T...>>, >+ std::is_copy_constructible<Union<T...>>, >+ std::is_destructible<Union<T...>>>, >+ absl::negation<absl::conjunction< >+ std::is_copy_constructible<T>..., >+ std::is_copy_assignable<T>...>>>::value, >+ VariantMoveAssignBase<T...>, VariantCopyAssignBaseNontrivial<T...>>; >+ >+template <class... T> >+using VariantBase = VariantCopyAssignBase<T...>; >+ >+template <class... T> >+class VariantStateBaseDestructorNontrivial : protected VariantStateBase<T...> { >+ private: >+ using Base = VariantStateBase<T...>; >+ >+ protected: >+ using Base::Base; >+ >+ VariantStateBaseDestructorNontrivial() = default; >+ VariantStateBaseDestructorNontrivial(VariantStateBaseDestructorNontrivial&&) = >+ default; >+ VariantStateBaseDestructorNontrivial( >+ const VariantStateBaseDestructorNontrivial&) = default; >+ VariantStateBaseDestructorNontrivial& operator=( >+ VariantStateBaseDestructorNontrivial&&) = default; >+ VariantStateBaseDestructorNontrivial& operator=( >+ const VariantStateBaseDestructorNontrivial&) = default; >+ >+ struct Destroyer { >+ template <std::size_t I> >+ void operator()(SizeT<I> i) const { >+ using Alternative = >+ typename absl::variant_alternative<I, variant<T...>>::type; >+ variant_internal::AccessUnion(self->state_, i).~Alternative(); >+ } >+ >+ void operator()(SizeT<absl::variant_npos> /*i*/) const { >+ // This space intentionally left blank >+ } >+ >+ VariantStateBaseDestructorNontrivial* self; >+ }; >+ >+ void destroy() { VisitIndices<sizeof...(T)>::Run(Destroyer{this}, index_); } >+ >+ ~VariantStateBaseDestructorNontrivial() { destroy(); } >+ >+ protected: >+ using Base::index_; >+ using Base::state_; >+}; >+ >+template <class... T> >+class VariantMoveBaseNontrivial : protected VariantStateBaseDestructor<T...> { >+ private: >+ using Base = VariantStateBaseDestructor<T...>; >+ >+ protected: >+ using Base::Base; >+ >+ struct Construct { >+ template <std::size_t I> >+ void operator()(SizeT<I> i) const { >+ using Alternative = >+ typename absl::variant_alternative<I, variant<T...>>::type; >+ ::new (static_cast<void*>(&self->state_)) Alternative( >+ variant_internal::AccessUnion(absl::move(other->state_), i)); >+ } >+ >+ void operator()(SizeT<absl::variant_npos> /*i*/) const {} >+ >+ VariantMoveBaseNontrivial* self; >+ VariantMoveBaseNontrivial* other; >+ }; >+ >+ VariantMoveBaseNontrivial() = default; >+ VariantMoveBaseNontrivial(VariantMoveBaseNontrivial&& other) noexcept( >+ absl::conjunction<std::is_nothrow_move_constructible<T>...>::value) >+ : Base(NoopConstructorTag()) { >+ VisitIndices<sizeof...(T)>::Run(Construct{this, &other}, other.index_); >+ index_ = other.index_; >+ } >+ >+ VariantMoveBaseNontrivial(VariantMoveBaseNontrivial const&) = default; >+ >+ VariantMoveBaseNontrivial& operator=(VariantMoveBaseNontrivial&&) = default; >+ VariantMoveBaseNontrivial& operator=(VariantMoveBaseNontrivial const&) = >+ default; >+ >+ protected: >+ using Base::index_; >+ using Base::state_; >+}; >+ >+template <class... T> >+class VariantCopyBaseNontrivial : protected VariantMoveBase<T...> { >+ private: >+ using Base = VariantMoveBase<T...>; >+ >+ protected: >+ using Base::Base; >+ >+ VariantCopyBaseNontrivial() = default; >+ VariantCopyBaseNontrivial(VariantCopyBaseNontrivial&&) = default; >+ >+ struct Construct { >+ template <std::size_t I> >+ void operator()(SizeT<I> i) const { >+ using Alternative = >+ typename absl::variant_alternative<I, variant<T...>>::type; >+ ::new (static_cast<void*>(&self->state_)) >+ Alternative(variant_internal::AccessUnion(other->state_, i)); >+ } >+ >+ void operator()(SizeT<absl::variant_npos> /*i*/) const {} >+ >+ VariantCopyBaseNontrivial* self; >+ const VariantCopyBaseNontrivial* other; >+ }; >+ >+ VariantCopyBaseNontrivial(VariantCopyBaseNontrivial const& other) >+ : Base(NoopConstructorTag()) { >+ VisitIndices<sizeof...(T)>::Run(Construct{this, &other}, other.index_); >+ index_ = other.index_; >+ } >+ >+ VariantCopyBaseNontrivial& operator=(VariantCopyBaseNontrivial&&) = default; >+ VariantCopyBaseNontrivial& operator=(VariantCopyBaseNontrivial const&) = >+ default; >+ >+ protected: >+ using Base::index_; >+ using Base::state_; >+}; >+ >+template <class... T> >+class VariantMoveAssignBaseNontrivial : protected VariantCopyBase<T...> { >+ friend struct VariantCoreAccess; >+ >+ private: >+ using Base = VariantCopyBase<T...>; >+ >+ protected: >+ using Base::Base; >+ >+ VariantMoveAssignBaseNontrivial() = default; >+ VariantMoveAssignBaseNontrivial(VariantMoveAssignBaseNontrivial&&) = default; >+ VariantMoveAssignBaseNontrivial(const VariantMoveAssignBaseNontrivial&) = >+ default; >+ VariantMoveAssignBaseNontrivial& operator=( >+ VariantMoveAssignBaseNontrivial const&) = default; >+ >+ VariantMoveAssignBaseNontrivial& >+ operator=(VariantMoveAssignBaseNontrivial&& other) noexcept( >+ absl::conjunction<std::is_nothrow_move_constructible<T>..., >+ std::is_nothrow_move_assignable<T>...>::value) { >+ VisitIndices<sizeof...(T)>::Run( >+ VariantCoreAccess::MakeMoveAssignVisitor(this, &other), other.index_); >+ return *this; >+ } >+ >+ protected: >+ using Base::index_; >+ using Base::state_; >+}; >+ >+template <class... T> >+class VariantCopyAssignBaseNontrivial : protected VariantMoveAssignBase<T...> { >+ friend struct VariantCoreAccess; >+ >+ private: >+ using Base = VariantMoveAssignBase<T...>; >+ >+ protected: >+ using Base::Base; >+ >+ VariantCopyAssignBaseNontrivial() = default; >+ VariantCopyAssignBaseNontrivial(VariantCopyAssignBaseNontrivial&&) = default; >+ VariantCopyAssignBaseNontrivial(const VariantCopyAssignBaseNontrivial&) = >+ default; >+ VariantCopyAssignBaseNontrivial& operator=( >+ VariantCopyAssignBaseNontrivial&&) = default; >+ >+ VariantCopyAssignBaseNontrivial& operator=( >+ const VariantCopyAssignBaseNontrivial& other) { >+ VisitIndices<sizeof...(T)>::Run( >+ VariantCoreAccess::MakeCopyAssignVisitor(this, other), other.index_); >+ return *this; >+ } >+ >+ protected: >+ using Base::index_; >+ using Base::state_; >+}; >+ >+//////////////////////////////////////// >+// Visitors for Comparison Operations // >+//////////////////////////////////////// >+ >+template <class... Types> >+struct EqualsOp { >+ const variant<Types...>* v; >+ const variant<Types...>* w; >+ >+ constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const { >+ return true; >+ } >+ >+ template <std::size_t I> >+ constexpr bool operator()(SizeT<I> /*v_i*/) const { >+ return VariantCoreAccess::Access<I>(*v) == VariantCoreAccess::Access<I>(*w); >+ } >+}; >+ >+template <class... Types> >+struct NotEqualsOp { >+ const variant<Types...>* v; >+ const variant<Types...>* w; >+ >+ constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const { >+ return false; >+ } >+ >+ template <std::size_t I> >+ constexpr bool operator()(SizeT<I> /*v_i*/) const { >+ return VariantCoreAccess::Access<I>(*v) != VariantCoreAccess::Access<I>(*w); >+ } >+}; >+ >+template <class... Types> >+struct LessThanOp { >+ const variant<Types...>* v; >+ const variant<Types...>* w; >+ >+ constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const { >+ return false; >+ } >+ >+ template <std::size_t I> >+ constexpr bool operator()(SizeT<I> /*v_i*/) const { >+ return VariantCoreAccess::Access<I>(*v) < VariantCoreAccess::Access<I>(*w); >+ } >+}; >+ >+template <class... Types> >+struct GreaterThanOp { >+ const variant<Types...>* v; >+ const variant<Types...>* w; >+ >+ constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const { >+ return false; >+ } >+ >+ template <std::size_t I> >+ constexpr bool operator()(SizeT<I> /*v_i*/) const { >+ return VariantCoreAccess::Access<I>(*v) > VariantCoreAccess::Access<I>(*w); >+ } >+}; >+ >+template <class... Types> >+struct LessThanOrEqualsOp { >+ const variant<Types...>* v; >+ const variant<Types...>* w; >+ >+ constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const { >+ return true; >+ } >+ >+ template <std::size_t I> >+ constexpr bool operator()(SizeT<I> /*v_i*/) const { >+ return VariantCoreAccess::Access<I>(*v) <= VariantCoreAccess::Access<I>(*w); >+ } >+}; >+ >+template <class... Types> >+struct GreaterThanOrEqualsOp { >+ const variant<Types...>* v; >+ const variant<Types...>* w; >+ >+ constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const { >+ return true; >+ } >+ >+ template <std::size_t I> >+ constexpr bool operator()(SizeT<I> /*v_i*/) const { >+ return VariantCoreAccess::Access<I>(*v) >= VariantCoreAccess::Access<I>(*w); >+ } >+}; >+ >+// Precondition: v.index() == w.index(); >+template <class... Types> >+struct SwapSameIndex { >+ variant<Types...>* v; >+ variant<Types...>* w; >+ template <std::size_t I> >+ void operator()(SizeT<I>) const { >+ using std::swap; >+ swap(VariantCoreAccess::Access<I>(*v), VariantCoreAccess::Access<I>(*w)); >+ } >+ >+ void operator()(SizeT<variant_npos>) const {} >+}; >+ >+// TODO(calabrese) do this from a different namespace for proper adl usage >+template <class... Types> >+struct Swap { >+ variant<Types...>* v; >+ variant<Types...>* w; >+ >+ void generic_swap() const { >+ variant<Types...> tmp(std::move(*w)); >+ VariantCoreAccess::Destroy(*w); >+ VariantCoreAccess::InitFrom(*w, std::move(*v)); >+ VariantCoreAccess::Destroy(*v); >+ VariantCoreAccess::InitFrom(*v, std::move(tmp)); >+ } >+ >+ void operator()(SizeT<absl::variant_npos> /*w_i*/) const { >+ if (!v->valueless_by_exception()) { >+ generic_swap(); >+ } >+ } >+ >+ template <std::size_t Wi> >+ void operator()(SizeT<Wi> /*w_i*/) { >+ if (v->index() == Wi) { >+ VisitIndices<sizeof...(Types)>::Run(SwapSameIndex<Types...>{v, w}, Wi); >+ } else { >+ generic_swap(); >+ } >+ } >+}; >+ >+template <typename Variant, typename = void, typename... Ts> >+struct VariantHashBase { >+ VariantHashBase() = delete; >+ VariantHashBase(const VariantHashBase&) = delete; >+ VariantHashBase(VariantHashBase&&) = delete; >+ VariantHashBase& operator=(const VariantHashBase&) = delete; >+ VariantHashBase& operator=(VariantHashBase&&) = delete; >+}; >+ >+struct VariantHashVisitor { >+ template <typename T> >+ size_t operator()(const T& t) { >+ return std::hash<T>{}(t); >+ } >+}; >+ >+template <typename Variant, typename... Ts> >+struct VariantHashBase<Variant, >+ absl::enable_if_t<absl::conjunction< >+ type_traits_internal::IsHashEnabled<Ts>...>::value>, >+ Ts...> { >+ using argument_type = Variant; >+ using result_type = size_t; >+ size_t operator()(const Variant& var) const { >+ if (var.valueless_by_exception()) { >+ return 239799884; >+ } >+ size_t result = VisitIndices<variant_size<Variant>::value>::Run( >+ PerformVisitation<VariantHashVisitor, const Variant&>{ >+ std::forward_as_tuple(var), VariantHashVisitor{}}, >+ var.index()); >+ // Combine the index and the hash result in order to distinguish >+ // std::variant<int, int> holding the same value as different alternative. >+ return result ^ var.index(); >+ } >+}; >+ >+} // namespace variant_internal >+} // namespace absl >+ >+#endif // ABSL_TYPES_variant_internal_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..ef2729041990bbe162fe20d8f28bf9407b755089 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional.cc >@@ -0,0 +1,24 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/types/optional.h" >+ >+#ifndef ABSL_HAVE_STD_OPTIONAL >+namespace absl { >+ >+nullopt_t::init_t nullopt_t::init; >+extern const nullopt_t nullopt{nullopt_t::init}; >+ >+} // namespace absl >+#endif // ABSL_HAVE_STD_OPTIONAL >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional.h >new file mode 100644 >index 0000000000000000000000000000000000000000..c837cddeef48942647e7f8292d0163750946b2b6 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional.h >@@ -0,0 +1,1141 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// optional.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines the `absl::optional` type for holding a value which >+// may or may not be present. This type is useful for providing value semantics >+// for operations that may either wish to return or hold "something-or-nothing". >+// >+// Example: >+// >+// // A common way to signal operation failure is to provide an output >+// // parameter and a bool return type: >+// bool AcquireResource(const Input&, Resource * out); >+// >+// // Providing an absl::optional return type provides a cleaner API: >+// absl::optional<Resource> AcquireResource(const Input&); >+// >+// `absl::optional` is a C++11 compatible version of the C++17 `std::optional` >+// abstraction and is designed to be a drop-in replacement for code compliant >+// with C++17. >+#ifndef ABSL_TYPES_OPTIONAL_H_ >+#define ABSL_TYPES_OPTIONAL_H_ >+ >+#include "absl/base/config.h" >+#include "absl/utility/utility.h" >+ >+#ifdef ABSL_HAVE_STD_OPTIONAL >+ >+#include <optional> >+ >+namespace absl { >+using std::bad_optional_access; >+using std::optional; >+using std::make_optional; >+using std::nullopt_t; >+using std::nullopt; >+} // namespace absl >+ >+#else // ABSL_HAVE_STD_OPTIONAL >+ >+#include <cassert> >+#include <functional> >+#include <initializer_list> >+#include <new> >+#include <type_traits> >+#include <utility> >+ >+#include "absl/memory/memory.h" >+#include "absl/meta/type_traits.h" >+#include "absl/types/bad_optional_access.h" >+ >+// ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS >+// >+// Inheriting constructors is supported in GCC 4.8+, Clang 3.3+ and MSVC 2015. >+// __cpp_inheriting_constructors is a predefined macro and a recommended way to >+// check for this language feature, but GCC doesn't support it until 5.0 and >+// Clang doesn't support it until 3.6. >+// Also, MSVC 2015 has a bug: it doesn't inherit the constexpr template >+// constructor. For example, the following code won't work on MSVC 2015 Update3: >+// struct Base { >+// int t; >+// template <typename T> >+// constexpr Base(T t_) : t(t_) {} >+// }; >+// struct Foo : Base { >+// using Base::Base; >+// } >+// constexpr Foo foo(0); // doesn't work on MSVC 2015 >+#if defined(__clang__) >+#if __has_feature(cxx_inheriting_constructors) >+#define ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS 1 >+#endif >+#elif (defined(__GNUC__) && \ >+ (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 8)) || \ >+ (__cpp_inheriting_constructors >= 200802) || \ >+ (defined(_MSC_VER) && _MSC_VER >= 1910) >+#define ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS 1 >+#endif >+ >+namespace absl { >+ >+// ----------------------------------------------------------------------------- >+// absl::optional >+// ----------------------------------------------------------------------------- >+// >+// A value of type `absl::optional<T>` holds either a value of `T` or an >+// "empty" value. When it holds a value of `T`, it stores it as a direct >+// sub-object, so `sizeof(optional<T>)` is approximately >+// `sizeof(T) + sizeof(bool)`. >+// >+// This implementation is based on the specification in the latest draft of the >+// C++17 `std::optional` specification as of May 2017, section 20.6. >+// >+// Differences between `absl::optional<T>` and `std::optional<T>` include: >+// >+// * `constexpr` is not used for non-const member functions. >+// (dependency on some differences between C++11 and C++14.) >+// * `absl::nullopt` and `absl::in_place` are not declared `constexpr`. We >+// need the inline variable support in C++17 for external linkage. >+// * Throws `absl::bad_optional_access` instead of >+// `std::bad_optional_access`. >+// * `optional::swap()` and `absl::swap()` relies on >+// `std::is_(nothrow_)swappable()`, which has been introduced in C++17. >+// As a workaround, we assume `is_swappable()` is always `true` >+// and `is_nothrow_swappable()` is the same as `std::is_trivial()`. >+// * `make_optional()` cannot be declared `constexpr` due to the absence of >+// guaranteed copy elision. >+// * The move constructor's `noexcept` specification is stronger, i.e. if the >+// default allocator is non-throwing (via setting >+// `ABSL_ALLOCATOR_NOTHROW`), it evaluates to `noexcept(true)`, because >+// we assume >+// a) move constructors should only throw due to allocation failure and >+// b) if T's move constructor allocates, it uses the same allocation >+// function as the default allocator. >+template <typename T> >+class optional; >+ >+// nullopt_t >+// >+// Class type for `absl::nullopt` used to indicate an `absl::optional<T>` type >+// that does not contain a value. >+struct nullopt_t { >+ struct init_t {}; >+ static init_t init; >+ >+ // It must not be default-constructible to avoid ambiguity for opt = {}. >+ // Note the non-const reference, which is to eliminate ambiguity for code >+ // like: >+ // >+ // struct S { int value; }; >+ // >+ // void Test() { >+ // optional<S> opt; >+ // opt = {{}}; >+ // } >+ explicit constexpr nullopt_t(init_t& /*unused*/) {} >+}; >+ >+// nullopt >+// >+// A tag constant of type `absl::nullopt_t` used to indicate an empty >+// `absl::optional` in certain functions, such as construction or assignment. >+extern const nullopt_t nullopt; >+ >+namespace optional_internal { >+ >+struct empty_struct {}; >+// This class stores the data in optional<T>. >+// It is specialized based on whether T is trivially destructible. >+// This is the specialization for non trivially destructible type. >+template <typename T, bool = std::is_trivially_destructible<T>::value> >+class optional_data_dtor_base { >+ struct dummy_type { >+ static_assert(sizeof(T) % sizeof(empty_struct) == 0, ""); >+ // Use an array to avoid GCC 6 placement-new warning. >+ empty_struct data[sizeof(T) / sizeof(empty_struct)]; >+ }; >+ >+ protected: >+ // Whether there is data or not. >+ bool engaged_; >+ // Data storage >+ union { >+ dummy_type dummy_; >+ T data_; >+ }; >+ >+ void destruct() noexcept { >+ if (engaged_) { >+ data_.~T(); >+ engaged_ = false; >+ } >+ } >+ >+ // dummy_ must be initialized for constexpr constructor. >+ constexpr optional_data_dtor_base() noexcept : engaged_(false), dummy_{{}} {} >+ >+ template <typename... Args> >+ constexpr explicit optional_data_dtor_base(in_place_t, Args&&... args) >+ : engaged_(true), data_(absl::forward<Args>(args)...) {} >+ >+ ~optional_data_dtor_base() { destruct(); } >+}; >+ >+// Specialization for trivially destructible type. >+template <typename T> >+class optional_data_dtor_base<T, true> { >+ struct dummy_type { >+ static_assert(sizeof(T) % sizeof(empty_struct) == 0, ""); >+ // Use array to avoid GCC 6 placement-new warning. >+ empty_struct data[sizeof(T) / sizeof(empty_struct)]; >+ }; >+ >+ protected: >+ // Whether there is data or not. >+ bool engaged_; >+ // Data storage >+ union { >+ dummy_type dummy_; >+ T data_; >+ }; >+ void destruct() noexcept { engaged_ = false; } >+ >+ // dummy_ must be initialized for constexpr constructor. >+ constexpr optional_data_dtor_base() noexcept : engaged_(false), dummy_{{}} {} >+ >+ template <typename... Args> >+ constexpr explicit optional_data_dtor_base(in_place_t, Args&&... args) >+ : engaged_(true), data_(absl::forward<Args>(args)...) {} >+}; >+ >+template <typename T> >+class optional_data_base : public optional_data_dtor_base<T> { >+ protected: >+ using base = optional_data_dtor_base<T>; >+#if ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS >+ using base::base; >+#else >+ optional_data_base() = default; >+ >+ template <typename... Args> >+ constexpr explicit optional_data_base(in_place_t t, Args&&... args) >+ : base(t, absl::forward<Args>(args)...) {} >+#endif >+ >+ template <typename... Args> >+ void construct(Args&&... args) { >+ // Use dummy_'s address to work around casting cv-qualified T* to void*. >+ ::new (static_cast<void*>(&this->dummy_)) T(std::forward<Args>(args)...); >+ this->engaged_ = true; >+ } >+ >+ template <typename U> >+ void assign(U&& u) { >+ if (this->engaged_) { >+ this->data_ = std::forward<U>(u); >+ } else { >+ construct(std::forward<U>(u)); >+ } >+ } >+}; >+ >+// TODO(absl-team): Add another class using >+// std::is_trivially_move_constructible trait when available to match >+// http://cplusplus.github.io/LWG/lwg-defects.html#2900, for types that >+// have trivial move but nontrivial copy. >+// Also, we should be checking is_trivially_copyable here, which is not >+// supported now, so we use is_trivially_* traits instead. >+template <typename T, bool = absl::is_trivially_copy_constructible<T>::value&& >+ absl::is_trivially_copy_assignable< >+ typename std::remove_cv<T>::type>::value&& >+ std::is_trivially_destructible<T>::value> >+class optional_data; >+ >+// Trivially copyable types >+template <typename T> >+class optional_data<T, true> : public optional_data_base<T> { >+ protected: >+#if ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS >+ using optional_data_base<T>::optional_data_base; >+#else >+ optional_data() = default; >+ >+ template <typename... Args> >+ constexpr explicit optional_data(in_place_t t, Args&&... args) >+ : optional_data_base<T>(t, absl::forward<Args>(args)...) {} >+#endif >+}; >+ >+template <typename T> >+class optional_data<T, false> : public optional_data_base<T> { >+ protected: >+#if ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS >+ using optional_data_base<T>::optional_data_base; >+#else >+ template <typename... Args> >+ constexpr explicit optional_data(in_place_t t, Args&&... args) >+ : optional_data_base<T>(t, absl::forward<Args>(args)...) {} >+#endif >+ >+ optional_data() = default; >+ >+ optional_data(const optional_data& rhs) { >+ if (rhs.engaged_) { >+ this->construct(rhs.data_); >+ } >+ } >+ >+ optional_data(optional_data&& rhs) noexcept( >+ absl::default_allocator_is_nothrow::value || >+ std::is_nothrow_move_constructible<T>::value) { >+ if (rhs.engaged_) { >+ this->construct(std::move(rhs.data_)); >+ } >+ } >+ >+ optional_data& operator=(const optional_data& rhs) { >+ if (rhs.engaged_) { >+ this->assign(rhs.data_); >+ } else { >+ this->destruct(); >+ } >+ return *this; >+ } >+ >+ optional_data& operator=(optional_data&& rhs) noexcept( >+ std::is_nothrow_move_assignable<T>::value&& >+ std::is_nothrow_move_constructible<T>::value) { >+ if (rhs.engaged_) { >+ this->assign(std::move(rhs.data_)); >+ } else { >+ this->destruct(); >+ } >+ return *this; >+ } >+}; >+ >+// Ordered by level of restriction, from low to high. >+// Copyable implies movable. >+enum class copy_traits { copyable = 0, movable = 1, non_movable = 2 }; >+ >+// Base class for enabling/disabling copy/move constructor. >+template <copy_traits> >+class optional_ctor_base; >+ >+template <> >+class optional_ctor_base<copy_traits::copyable> { >+ public: >+ constexpr optional_ctor_base() = default; >+ optional_ctor_base(const optional_ctor_base&) = default; >+ optional_ctor_base(optional_ctor_base&&) = default; >+ optional_ctor_base& operator=(const optional_ctor_base&) = default; >+ optional_ctor_base& operator=(optional_ctor_base&&) = default; >+}; >+ >+template <> >+class optional_ctor_base<copy_traits::movable> { >+ public: >+ constexpr optional_ctor_base() = default; >+ optional_ctor_base(const optional_ctor_base&) = delete; >+ optional_ctor_base(optional_ctor_base&&) = default; >+ optional_ctor_base& operator=(const optional_ctor_base&) = default; >+ optional_ctor_base& operator=(optional_ctor_base&&) = default; >+}; >+ >+template <> >+class optional_ctor_base<copy_traits::non_movable> { >+ public: >+ constexpr optional_ctor_base() = default; >+ optional_ctor_base(const optional_ctor_base&) = delete; >+ optional_ctor_base(optional_ctor_base&&) = delete; >+ optional_ctor_base& operator=(const optional_ctor_base&) = default; >+ optional_ctor_base& operator=(optional_ctor_base&&) = default; >+}; >+ >+// Base class for enabling/disabling copy/move assignment. >+template <copy_traits> >+class optional_assign_base; >+ >+template <> >+class optional_assign_base<copy_traits::copyable> { >+ public: >+ constexpr optional_assign_base() = default; >+ optional_assign_base(const optional_assign_base&) = default; >+ optional_assign_base(optional_assign_base&&) = default; >+ optional_assign_base& operator=(const optional_assign_base&) = default; >+ optional_assign_base& operator=(optional_assign_base&&) = default; >+}; >+ >+template <> >+class optional_assign_base<copy_traits::movable> { >+ public: >+ constexpr optional_assign_base() = default; >+ optional_assign_base(const optional_assign_base&) = default; >+ optional_assign_base(optional_assign_base&&) = default; >+ optional_assign_base& operator=(const optional_assign_base&) = delete; >+ optional_assign_base& operator=(optional_assign_base&&) = default; >+}; >+ >+template <> >+class optional_assign_base<copy_traits::non_movable> { >+ public: >+ constexpr optional_assign_base() = default; >+ optional_assign_base(const optional_assign_base&) = default; >+ optional_assign_base(optional_assign_base&&) = default; >+ optional_assign_base& operator=(const optional_assign_base&) = delete; >+ optional_assign_base& operator=(optional_assign_base&&) = delete; >+}; >+ >+template <typename T> >+constexpr copy_traits get_ctor_copy_traits() { >+ return std::is_copy_constructible<T>::value >+ ? copy_traits::copyable >+ : std::is_move_constructible<T>::value ? copy_traits::movable >+ : copy_traits::non_movable; >+} >+ >+template <typename T> >+constexpr copy_traits get_assign_copy_traits() { >+ return std::is_copy_assignable<T>::value && >+ std::is_copy_constructible<T>::value >+ ? copy_traits::copyable >+ : std::is_move_assignable<T>::value && >+ std::is_move_constructible<T>::value >+ ? copy_traits::movable >+ : copy_traits::non_movable; >+} >+ >+// Whether T is constructible or convertible from optional<U>. >+template <typename T, typename U> >+struct is_constructible_convertible_from_optional >+ : std::integral_constant< >+ bool, std::is_constructible<T, optional<U>&>::value || >+ std::is_constructible<T, optional<U>&&>::value || >+ std::is_constructible<T, const optional<U>&>::value || >+ std::is_constructible<T, const optional<U>&&>::value || >+ std::is_convertible<optional<U>&, T>::value || >+ std::is_convertible<optional<U>&&, T>::value || >+ std::is_convertible<const optional<U>&, T>::value || >+ std::is_convertible<const optional<U>&&, T>::value> {}; >+ >+// Whether T is constructible or convertible or assignable from optional<U>. >+template <typename T, typename U> >+struct is_constructible_convertible_assignable_from_optional >+ : std::integral_constant< >+ bool, is_constructible_convertible_from_optional<T, U>::value || >+ std::is_assignable<T&, optional<U>&>::value || >+ std::is_assignable<T&, optional<U>&&>::value || >+ std::is_assignable<T&, const optional<U>&>::value || >+ std::is_assignable<T&, const optional<U>&&>::value> {}; >+ >+// Helper function used by [optional.relops], [optional.comp_with_t], >+// for checking whether an expression is convertible to bool. >+bool convertible_to_bool(bool); >+ >+// Base class for std::hash<absl::optional<T>>: >+// If std::hash<std::remove_const_t<T>> is enabled, it provides operator() to >+// compute the hash; Otherwise, it is disabled. >+// Reference N4659 23.14.15 [unord.hash]. >+template <typename T, typename = size_t> >+struct optional_hash_base { >+ optional_hash_base() = delete; >+ optional_hash_base(const optional_hash_base&) = delete; >+ optional_hash_base(optional_hash_base&&) = delete; >+ optional_hash_base& operator=(const optional_hash_base&) = delete; >+ optional_hash_base& operator=(optional_hash_base&&) = delete; >+}; >+ >+template <typename T> >+struct optional_hash_base<T, decltype(std::hash<absl::remove_const_t<T> >()( >+ std::declval<absl::remove_const_t<T> >()))> { >+ using argument_type = absl::optional<T>; >+ using result_type = size_t; >+ size_t operator()(const absl::optional<T>& opt) const { >+ if (opt) { >+ return std::hash<absl::remove_const_t<T> >()(*opt); >+ } else { >+ return static_cast<size_t>(0x297814aaad196e6dULL); >+ } >+ } >+}; >+ >+} // namespace optional_internal >+ >+// ----------------------------------------------------------------------------- >+// absl::optional class definition >+// ----------------------------------------------------------------------------- >+ >+template <typename T> >+class optional : private optional_internal::optional_data<T>, >+ private optional_internal::optional_ctor_base< >+ optional_internal::get_ctor_copy_traits<T>()>, >+ private optional_internal::optional_assign_base< >+ optional_internal::get_assign_copy_traits<T>()> { >+ using data_base = optional_internal::optional_data<T>; >+ >+ public: >+ typedef T value_type; >+ >+ // Constructors >+ >+ // Constructs an `optional` holding an empty value, NOT a default constructed >+ // `T`. >+ constexpr optional() noexcept {} >+ >+ // Constructs an `optional` initialized with `nullopt` to hold an empty value. >+ constexpr optional(nullopt_t) noexcept {} // NOLINT(runtime/explicit) >+ >+ // Copy constructor, standard semantics >+ optional(const optional& src) = default; >+ >+ // Move constructor, standard semantics >+ optional(optional&& src) = default; >+ >+ // Constructs a non-empty `optional` direct-initialized value of type `T` from >+ // the arguments `std::forward<Args>(args)...` within the `optional`. >+ // (The `in_place_t` is a tag used to indicate that the contained object >+ // should be constructed in-place.) >+ // >+ // TODO(absl-team): Add std::is_constructible<T, Args&&...> SFINAE. >+ template <typename... Args> >+ constexpr explicit optional(in_place_t, Args&&... args) >+ : data_base(in_place_t(), absl::forward<Args>(args)...) {} >+ >+ // Constructs a non-empty `optional` direct-initialized value of type `T` from >+ // the arguments of an initializer_list and `std::forward<Args>(args)...`. >+ // (The `in_place_t` is a tag used to indicate that the contained object >+ // should be constructed in-place.) >+ template <typename U, typename... Args, >+ typename = typename std::enable_if<std::is_constructible< >+ T, std::initializer_list<U>&, Args&&...>::value>::type> >+ constexpr explicit optional(in_place_t, std::initializer_list<U> il, >+ Args&&... args) >+ : data_base(in_place_t(), il, absl::forward<Args>(args)...) { >+ } >+ >+ // Value constructor (implicit) >+ template < >+ typename U = T, >+ typename std::enable_if< >+ absl::conjunction<absl::negation<std::is_same< >+ in_place_t, typename std::decay<U>::type> >, >+ absl::negation<std::is_same< >+ optional<T>, typename std::decay<U>::type> >, >+ std::is_convertible<U&&, T>, >+ std::is_constructible<T, U&&> >::value, >+ bool>::type = false> >+ constexpr optional(U&& v) : data_base(in_place_t(), absl::forward<U>(v)) {} >+ >+ // Value constructor (explicit) >+ template < >+ typename U = T, >+ typename std::enable_if< >+ absl::conjunction<absl::negation<std::is_same< >+ in_place_t, typename std::decay<U>::type>>, >+ absl::negation<std::is_same< >+ optional<T>, typename std::decay<U>::type>>, >+ absl::negation<std::is_convertible<U&&, T>>, >+ std::is_constructible<T, U&&>>::value, >+ bool>::type = false> >+ explicit constexpr optional(U&& v) >+ : data_base(in_place_t(), absl::forward<U>(v)) {} >+ >+ // Converting copy constructor (implicit) >+ template <typename U, >+ typename std::enable_if< >+ absl::conjunction< >+ absl::negation<std::is_same<T, U> >, >+ std::is_constructible<T, const U&>, >+ absl::negation< >+ optional_internal:: >+ is_constructible_convertible_from_optional<T, U> >, >+ std::is_convertible<const U&, T> >::value, >+ bool>::type = false> >+ optional(const optional<U>& rhs) { >+ if (rhs) { >+ this->construct(*rhs); >+ } >+ } >+ >+ // Converting copy constructor (explicit) >+ template <typename U, >+ typename std::enable_if< >+ absl::conjunction< >+ absl::negation<std::is_same<T, U>>, >+ std::is_constructible<T, const U&>, >+ absl::negation< >+ optional_internal:: >+ is_constructible_convertible_from_optional<T, U>>, >+ absl::negation<std::is_convertible<const U&, T>>>::value, >+ bool>::type = false> >+ explicit optional(const optional<U>& rhs) { >+ if (rhs) { >+ this->construct(*rhs); >+ } >+ } >+ >+ // Converting move constructor (implicit) >+ template <typename U, >+ typename std::enable_if< >+ absl::conjunction< >+ absl::negation<std::is_same<T, U> >, >+ std::is_constructible<T, U&&>, >+ absl::negation< >+ optional_internal:: >+ is_constructible_convertible_from_optional<T, U> >, >+ std::is_convertible<U&&, T> >::value, >+ bool>::type = false> >+ optional(optional<U>&& rhs) { >+ if (rhs) { >+ this->construct(std::move(*rhs)); >+ } >+ } >+ >+ // Converting move constructor (explicit) >+ template < >+ typename U, >+ typename std::enable_if< >+ absl::conjunction< >+ absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>, >+ absl::negation< >+ optional_internal::is_constructible_convertible_from_optional< >+ T, U>>, >+ absl::negation<std::is_convertible<U&&, T>>>::value, >+ bool>::type = false> >+ explicit optional(optional<U>&& rhs) { >+ if (rhs) { >+ this->construct(std::move(*rhs)); >+ } >+ } >+ >+ // Destructor. Trivial if `T` is trivially destructible. >+ ~optional() = default; >+ >+ // Assignment Operators >+ >+ // Assignment from `nullopt` >+ // >+ // Example: >+ // >+ // struct S { int value; }; >+ // optional<S> opt = absl::nullopt; // Could also use opt = { }; >+ optional& operator=(nullopt_t) noexcept { >+ this->destruct(); >+ return *this; >+ } >+ >+ // Copy assignment operator, standard semantics >+ optional& operator=(const optional& src) = default; >+ >+ // Move assignment operator, standard semantics >+ optional& operator=(optional&& src) = default; >+ >+ // Value assignment operators >+ template < >+ typename U = T, >+ typename = typename std::enable_if<absl::conjunction< >+ absl::negation< >+ std::is_same<optional<T>, typename std::decay<U>::type>>, >+ absl::negation< >+ absl::conjunction<std::is_scalar<T>, >+ std::is_same<T, typename std::decay<U>::type>>>, >+ std::is_constructible<T, U>, std::is_assignable<T&, U>>::value>::type> >+ optional& operator=(U&& v) { >+ this->assign(std::forward<U>(v)); >+ return *this; >+ } >+ >+ template < >+ typename U, >+ typename = typename std::enable_if<absl::conjunction< >+ absl::negation<std::is_same<T, U>>, >+ std::is_constructible<T, const U&>, std::is_assignable<T&, const U&>, >+ absl::negation< >+ optional_internal:: >+ is_constructible_convertible_assignable_from_optional< >+ T, U>>>::value>::type> >+ optional& operator=(const optional<U>& rhs) { >+ if (rhs) { >+ this->assign(*rhs); >+ } else { >+ this->destruct(); >+ } >+ return *this; >+ } >+ >+ template <typename U, >+ typename = typename std::enable_if<absl::conjunction< >+ absl::negation<std::is_same<T, U>>, std::is_constructible<T, U>, >+ std::is_assignable<T&, U>, >+ absl::negation< >+ optional_internal:: >+ is_constructible_convertible_assignable_from_optional< >+ T, U>>>::value>::type> >+ optional& operator=(optional<U>&& rhs) { >+ if (rhs) { >+ this->assign(std::move(*rhs)); >+ } else { >+ this->destruct(); >+ } >+ return *this; >+ } >+ >+ // Modifiers >+ >+ // optional::reset() >+ // >+ // Destroys the inner `T` value of an `absl::optional` if one is present. >+ void reset() noexcept { this->destruct(); } >+ >+ // optional::emplace() >+ // >+ // (Re)constructs the underlying `T` in-place with the given forwarded >+ // arguments. >+ // >+ // Example: >+ // >+ // optional<Foo> opt; >+ // opt.emplace(arg1,arg2,arg3); // Constructs Foo(arg1,arg2,arg3) >+ // >+ // If the optional is non-empty, and the `args` refer to subobjects of the >+ // current object, then behaviour is undefined, because the current object >+ // will be destructed before the new object is constructed with `args`. >+ template <typename... Args, >+ typename = typename std::enable_if< >+ std::is_constructible<T, Args&&...>::value>::type> >+ T& emplace(Args&&... args) { >+ this->destruct(); >+ this->construct(std::forward<Args>(args)...); >+ return reference(); >+ } >+ >+ // Emplace reconstruction overload for an initializer list and the given >+ // forwarded arguments. >+ // >+ // Example: >+ // >+ // struct Foo { >+ // Foo(std::initializer_list<int>); >+ // }; >+ // >+ // optional<Foo> opt; >+ // opt.emplace({1,2,3}); // Constructs Foo({1,2,3}) >+ template <typename U, typename... Args, >+ typename = typename std::enable_if<std::is_constructible< >+ T, std::initializer_list<U>&, Args&&...>::value>::type> >+ T& emplace(std::initializer_list<U> il, Args&&... args) { >+ this->destruct(); >+ this->construct(il, std::forward<Args>(args)...); >+ return reference(); >+ } >+ >+ // Swaps >+ >+ // Swap, standard semantics >+ void swap(optional& rhs) noexcept( >+ std::is_nothrow_move_constructible<T>::value&& >+ std::is_trivial<T>::value) { >+ if (*this) { >+ if (rhs) { >+ using std::swap; >+ swap(**this, *rhs); >+ } else { >+ rhs.construct(std::move(**this)); >+ this->destruct(); >+ } >+ } else { >+ if (rhs) { >+ this->construct(std::move(*rhs)); >+ rhs.destruct(); >+ } else { >+ // No effect (swap(disengaged, disengaged)). >+ } >+ } >+ } >+ >+ // Observers >+ >+ // optional::operator->() >+ // >+ // Accesses the underlying `T` value's member `m` of an `optional`. If the >+ // `optional` is empty, behavior is undefined. >+ // >+ // If you need myOpt->foo in constexpr, use (*myOpt).foo instead. >+ const T* operator->() const { >+ assert(this->engaged_); >+ return std::addressof(this->data_); >+ } >+ T* operator->() { >+ assert(this->engaged_); >+ return std::addressof(this->data_); >+ } >+ >+ // optional::operator*() >+ // >+ // Accesses the underlying `T` value of an `optional`. If the `optional` is >+ // empty, behavior is undefined. >+ constexpr const T& operator*() const & { return reference(); } >+ T& operator*() & { >+ assert(this->engaged_); >+ return reference(); >+ } >+ constexpr const T&& operator*() const && { >+ return absl::move(reference()); >+ } >+ T&& operator*() && { >+ assert(this->engaged_); >+ return std::move(reference()); >+ } >+ >+ // optional::operator bool() >+ // >+ // Returns false if and only if the `optional` is empty. >+ // >+ // if (opt) { >+ // // do something with opt.value(); >+ // } else { >+ // // opt is empty. >+ // } >+ // >+ constexpr explicit operator bool() const noexcept { return this->engaged_; } >+ >+ // optional::has_value() >+ // >+ // Determines whether the `optional` contains a value. Returns `false` if and >+ // only if `*this` is empty. >+ constexpr bool has_value() const noexcept { return this->engaged_; } >+ >+// Suppress bogus warning on MSVC: MSVC complains call to reference() after >+// throw_bad_optional_access() is unreachable. >+#ifdef _MSC_VER >+#pragma warning(push) >+#pragma warning(disable : 4702) >+#endif // _MSC_VER >+ // optional::value() >+ // >+ // Returns a reference to an `optional`s underlying value. The constness >+ // and lvalue/rvalue-ness of the `optional` is preserved to the view of >+ // the `T` sub-object. Throws `absl::bad_optional_access` when the `optional` >+ // is empty. >+ constexpr const T& value() const & { >+ return static_cast<bool>(*this) >+ ? reference() >+ : (optional_internal::throw_bad_optional_access(), reference()); >+ } >+ T& value() & { >+ return static_cast<bool>(*this) >+ ? reference() >+ : (optional_internal::throw_bad_optional_access(), reference()); >+ } >+ T&& value() && { // NOLINT(build/c++11) >+ return std::move( >+ static_cast<bool>(*this) >+ ? reference() >+ : (optional_internal::throw_bad_optional_access(), reference())); >+ } >+ constexpr const T&& value() const && { // NOLINT(build/c++11) >+ return absl::move( >+ static_cast<bool>(*this) >+ ? reference() >+ : (optional_internal::throw_bad_optional_access(), reference())); >+ } >+#ifdef _MSC_VER >+#pragma warning(pop) >+#endif // _MSC_VER >+ >+ // optional::value_or() >+ // >+ // Returns either the value of `T` or a passed default `v` if the `optional` >+ // is empty. >+ template <typename U> >+ constexpr T value_or(U&& v) const& { >+ static_assert(std::is_copy_constructible<value_type>::value, >+ "optional<T>::value_or: T must by copy constructible"); >+ static_assert(std::is_convertible<U&&, value_type>::value, >+ "optional<T>::value_or: U must be convertible to T"); >+ return static_cast<bool>(*this) >+ ? **this >+ : static_cast<T>(absl::forward<U>(v)); >+ } >+ template <typename U> >+ T value_or(U&& v) && { // NOLINT(build/c++11) >+ static_assert(std::is_move_constructible<value_type>::value, >+ "optional<T>::value_or: T must by copy constructible"); >+ static_assert(std::is_convertible<U&&, value_type>::value, >+ "optional<T>::value_or: U must be convertible to T"); >+ return static_cast<bool>(*this) ? std::move(**this) >+ : static_cast<T>(std::forward<U>(v)); >+ } >+ >+ private: >+ // Private accessors for internal storage viewed as reference to T. >+ constexpr const T& reference() const { return this->data_; } >+ T& reference() { return this->data_; } >+ >+ // T constraint checks. You can't have an optional of nullopt_t, in_place_t >+ // or a reference. >+ static_assert( >+ !std::is_same<nullopt_t, typename std::remove_cv<T>::type>::value, >+ "optional<nullopt_t> is not allowed."); >+ static_assert( >+ !std::is_same<in_place_t, typename std::remove_cv<T>::type>::value, >+ "optional<in_place_t> is not allowed."); >+ static_assert(!std::is_reference<T>::value, >+ "optional<reference> is not allowed."); >+}; >+ >+// Non-member functions >+ >+// swap() >+// >+// Performs a swap between two `absl::optional` objects, using standard >+// semantics. >+// >+// NOTE: we assume `is_swappable()` is always `true`. A compile error will >+// result if this is not the case. >+template <typename T, >+ typename std::enable_if<std::is_move_constructible<T>::value, >+ bool>::type = false> >+void swap(optional<T>& a, optional<T>& b) noexcept(noexcept(a.swap(b))) { >+ a.swap(b); >+} >+ >+// make_optional() >+// >+// Creates a non-empty `optional<T>` where the type of `T` is deduced. An >+// `absl::optional` can also be explicitly instantiated with >+// `make_optional<T>(v)`. >+// >+// Note: `make_optional()` constructions may be declared `constexpr` for >+// trivially copyable types `T`. Non-trivial types require copy elision >+// support in C++17 for `make_optional` to support `constexpr` on such >+// non-trivial types. >+// >+// Example: >+// >+// constexpr absl::optional<int> opt = absl::make_optional(1); >+// static_assert(opt.value() == 1, ""); >+template <typename T> >+constexpr optional<typename std::decay<T>::type> make_optional(T&& v) { >+ return optional<typename std::decay<T>::type>(absl::forward<T>(v)); >+} >+ >+template <typename T, typename... Args> >+constexpr optional<T> make_optional(Args&&... args) { >+ return optional<T>(in_place_t(), absl::forward<Args>(args)...); >+} >+ >+template <typename T, typename U, typename... Args> >+constexpr optional<T> make_optional(std::initializer_list<U> il, >+ Args&&... args) { >+ return optional<T>(in_place_t(), il, >+ absl::forward<Args>(args)...); >+} >+ >+// Relational operators [optional.relops] >+ >+// Empty optionals are considered equal to each other and less than non-empty >+// optionals. Supports relations between optional<T> and optional<U>, between >+// optional<T> and U, and between optional<T> and nullopt. >+// >+// Note: We're careful to support T having non-bool relationals. >+ >+// Requires: The expression, e.g. "*x == *y" shall be well-formed and its result >+// shall be convertible to bool. >+// The C++17 (N4606) "Returns:" statements are translated into >+// code in an obvious way here, and the original text retained as function docs. >+// Returns: If bool(x) != bool(y), false; otherwise if bool(x) == false, true; >+// otherwise *x == *y. >+template <typename T, typename U> >+constexpr auto operator==(const optional<T>& x, const optional<U>& y) >+ -> decltype(optional_internal::convertible_to_bool(*x == *y)) { >+ return static_cast<bool>(x) != static_cast<bool>(y) >+ ? false >+ : static_cast<bool>(x) == false ? true >+ : static_cast<bool>(*x == *y); >+} >+ >+// Returns: If bool(x) != bool(y), true; otherwise, if bool(x) == false, false; >+// otherwise *x != *y. >+template <typename T, typename U> >+constexpr auto operator!=(const optional<T>& x, const optional<U>& y) >+ -> decltype(optional_internal::convertible_to_bool(*x != *y)) { >+ return static_cast<bool>(x) != static_cast<bool>(y) >+ ? true >+ : static_cast<bool>(x) == false ? false >+ : static_cast<bool>(*x != *y); >+} >+// Returns: If !y, false; otherwise, if !x, true; otherwise *x < *y. >+template <typename T, typename U> >+constexpr auto operator<(const optional<T>& x, const optional<U>& y) >+ -> decltype(optional_internal::convertible_to_bool(*x < *y)) { >+ return !y ? false : !x ? true : static_cast<bool>(*x < *y); >+} >+// Returns: If !x, false; otherwise, if !y, true; otherwise *x > *y. >+template <typename T, typename U> >+constexpr auto operator>(const optional<T>& x, const optional<U>& y) >+ -> decltype(optional_internal::convertible_to_bool(*x > *y)) { >+ return !x ? false : !y ? true : static_cast<bool>(*x > *y); >+} >+// Returns: If !x, true; otherwise, if !y, false; otherwise *x <= *y. >+template <typename T, typename U> >+constexpr auto operator<=(const optional<T>& x, const optional<U>& y) >+ -> decltype(optional_internal::convertible_to_bool(*x <= *y)) { >+ return !x ? true : !y ? false : static_cast<bool>(*x <= *y); >+} >+// Returns: If !y, true; otherwise, if !x, false; otherwise *x >= *y. >+template <typename T, typename U> >+constexpr auto operator>=(const optional<T>& x, const optional<U>& y) >+ -> decltype(optional_internal::convertible_to_bool(*x >= *y)) { >+ return !y ? true : !x ? false : static_cast<bool>(*x >= *y); >+} >+ >+// Comparison with nullopt [optional.nullops] >+// The C++17 (N4606) "Returns:" statements are used directly here. >+template <typename T> >+constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept { >+ return !x; >+} >+template <typename T> >+constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept { >+ return !x; >+} >+template <typename T> >+constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept { >+ return static_cast<bool>(x); >+} >+template <typename T> >+constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept { >+ return static_cast<bool>(x); >+} >+template <typename T> >+constexpr bool operator<(const optional<T>&, nullopt_t) noexcept { >+ return false; >+} >+template <typename T> >+constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept { >+ return static_cast<bool>(x); >+} >+template <typename T> >+constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept { >+ return !x; >+} >+template <typename T> >+constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept { >+ return true; >+} >+template <typename T> >+constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept { >+ return static_cast<bool>(x); >+} >+template <typename T> >+constexpr bool operator>(nullopt_t, const optional<T>&) noexcept { >+ return false; >+} >+template <typename T> >+constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept { >+ return true; >+} >+template <typename T> >+constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept { >+ return !x; >+} >+ >+// Comparison with T [optional.comp_with_t] >+ >+// Requires: The expression, e.g. "*x == v" shall be well-formed and its result >+// shall be convertible to bool. >+// The C++17 (N4606) "Equivalent to:" statements are used directly here. >+template <typename T, typename U> >+constexpr auto operator==(const optional<T>& x, const U& v) >+ -> decltype(optional_internal::convertible_to_bool(*x == v)) { >+ return static_cast<bool>(x) ? static_cast<bool>(*x == v) : false; >+} >+template <typename T, typename U> >+constexpr auto operator==(const U& v, const optional<T>& x) >+ -> decltype(optional_internal::convertible_to_bool(v == *x)) { >+ return static_cast<bool>(x) ? static_cast<bool>(v == *x) : false; >+} >+template <typename T, typename U> >+constexpr auto operator!=(const optional<T>& x, const U& v) >+ -> decltype(optional_internal::convertible_to_bool(*x != v)) { >+ return static_cast<bool>(x) ? static_cast<bool>(*x != v) : true; >+} >+template <typename T, typename U> >+constexpr auto operator!=(const U& v, const optional<T>& x) >+ -> decltype(optional_internal::convertible_to_bool(v != *x)) { >+ return static_cast<bool>(x) ? static_cast<bool>(v != *x) : true; >+} >+template <typename T, typename U> >+constexpr auto operator<(const optional<T>& x, const U& v) >+ -> decltype(optional_internal::convertible_to_bool(*x < v)) { >+ return static_cast<bool>(x) ? static_cast<bool>(*x < v) : true; >+} >+template <typename T, typename U> >+constexpr auto operator<(const U& v, const optional<T>& x) >+ -> decltype(optional_internal::convertible_to_bool(v < *x)) { >+ return static_cast<bool>(x) ? static_cast<bool>(v < *x) : false; >+} >+template <typename T, typename U> >+constexpr auto operator<=(const optional<T>& x, const U& v) >+ -> decltype(optional_internal::convertible_to_bool(*x <= v)) { >+ return static_cast<bool>(x) ? static_cast<bool>(*x <= v) : true; >+} >+template <typename T, typename U> >+constexpr auto operator<=(const U& v, const optional<T>& x) >+ -> decltype(optional_internal::convertible_to_bool(v <= *x)) { >+ return static_cast<bool>(x) ? static_cast<bool>(v <= *x) : false; >+} >+template <typename T, typename U> >+constexpr auto operator>(const optional<T>& x, const U& v) >+ -> decltype(optional_internal::convertible_to_bool(*x > v)) { >+ return static_cast<bool>(x) ? static_cast<bool>(*x > v) : false; >+} >+template <typename T, typename U> >+constexpr auto operator>(const U& v, const optional<T>& x) >+ -> decltype(optional_internal::convertible_to_bool(v > *x)) { >+ return static_cast<bool>(x) ? static_cast<bool>(v > *x) : true; >+} >+template <typename T, typename U> >+constexpr auto operator>=(const optional<T>& x, const U& v) >+ -> decltype(optional_internal::convertible_to_bool(*x >= v)) { >+ return static_cast<bool>(x) ? static_cast<bool>(*x >= v) : false; >+} >+template <typename T, typename U> >+constexpr auto operator>=(const U& v, const optional<T>& x) >+ -> decltype(optional_internal::convertible_to_bool(v >= *x)) { >+ return static_cast<bool>(x) ? static_cast<bool>(v >= *x) : true; >+} >+ >+} // namespace absl >+ >+namespace std { >+ >+// std::hash specialization for absl::optional. >+template <typename T> >+struct hash<absl::optional<T> > >+ : absl::optional_internal::optional_hash_base<T> {}; >+ >+} // namespace std >+ >+#undef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS >+#undef ABSL_MSVC_CONSTEXPR_BUG_IN_UNION_LIKE_CLASS >+ >+#endif // ABSL_HAVE_STD_OPTIONAL >+ >+#endif // ABSL_TYPES_OPTIONAL_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional_exception_safety_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional_exception_safety_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..d2ef04b8d1b083c755c2306855460aa8f0de81dd >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional_exception_safety_test.cc >@@ -0,0 +1,282 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/types/optional.h" >+ >+#include "gtest/gtest.h" >+#include "absl/base/internal/exception_safety_testing.h" >+ >+namespace absl { >+ >+namespace { >+ >+using ::testing::AssertionFailure; >+using ::testing::AssertionResult; >+using ::testing::AssertionSuccess; >+using ::testing::MakeExceptionSafetyTester; >+ >+using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>; >+using Optional = absl::optional<Thrower>; >+ >+using MoveThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>; >+using MoveOptional = absl::optional<MoveThrower>; >+ >+constexpr int kInitialInteger = 5; >+constexpr int kUpdatedInteger = 10; >+ >+template <typename OptionalT> >+bool ValueThrowsBadOptionalAccess(const OptionalT& optional) try { >+ return (static_cast<void>(optional.value()), false); >+} catch (absl::bad_optional_access) { >+ return true; >+} >+ >+template <typename OptionalT> >+AssertionResult CheckInvariants(OptionalT* optional_ptr) { >+ // Check the current state post-throw for validity >+ auto& optional = *optional_ptr; >+ >+ if (optional.has_value() && ValueThrowsBadOptionalAccess(optional)) { >+ return AssertionFailure() >+ << "Optional with value should not throw bad_optional_access when " >+ "accessing the value."; >+ } >+ if (!optional.has_value() && !ValueThrowsBadOptionalAccess(optional)) { >+ return AssertionFailure() >+ << "Optional without a value should throw bad_optional_access when " >+ "accessing the value."; >+ } >+ >+ // Reset to a known state >+ optional.reset(); >+ >+ // Confirm that the known post-reset state is valid >+ if (optional.has_value()) { >+ return AssertionFailure() >+ << "Optional should not contain a value after being reset."; >+ } >+ if (!ValueThrowsBadOptionalAccess(optional)) { >+ return AssertionFailure() << "Optional should throw bad_optional_access " >+ "when accessing the value after being reset."; >+ } >+ >+ return AssertionSuccess(); >+} >+ >+template <typename OptionalT> >+AssertionResult CheckDisengaged(OptionalT* optional_ptr) { >+ auto& optional = *optional_ptr; >+ >+ if (optional.has_value()) { >+ return AssertionFailure() >+ << "Expected optional to not contain a value but a value was found."; >+ } >+ >+ return AssertionSuccess(); >+} >+ >+template <typename OptionalT> >+AssertionResult CheckEngaged(OptionalT* optional_ptr) { >+ auto& optional = *optional_ptr; >+ >+ if (!optional.has_value()) { >+ return AssertionFailure() >+ << "Expected optional to contain a value but no value was found."; >+ } >+ >+ return AssertionSuccess(); >+} >+ >+TEST(OptionalExceptionSafety, ThrowingConstructors) { >+ auto thrower_nonempty = Optional(Thrower(kInitialInteger)); >+ testing::TestThrowingCtor<Optional>(thrower_nonempty); >+ >+ auto integer_nonempty = absl::optional<int>(kInitialInteger); >+ testing::TestThrowingCtor<Optional>(integer_nonempty); >+ testing::TestThrowingCtor<Optional>(std::move(integer_nonempty)); // NOLINT >+ >+ testing::TestThrowingCtor<Optional>(kInitialInteger); >+ using ThrowerVec = std::vector<Thrower, testing::ThrowingAllocator<Thrower>>; >+ testing::TestThrowingCtor<absl::optional<ThrowerVec>>( >+ absl::in_place, >+ std::initializer_list<Thrower>{Thrower(), Thrower(), Thrower()}, >+ testing::ThrowingAllocator<Thrower>()); >+} >+ >+TEST(OptionalExceptionSafety, NothrowConstructors) { >+ // This constructor is marked noexcept. If it throws, the program will >+ // terminate. >+ testing::TestThrowingCtor<MoveOptional>(MoveOptional(kUpdatedInteger)); >+} >+ >+TEST(OptionalExceptionSafety, Emplace) { >+ // Test the basic guarantee plus test the result of optional::has_value() >+ // is false in all cases >+ auto disengaged_test = MakeExceptionSafetyTester().WithInvariants( >+ CheckInvariants<Optional>, CheckDisengaged<Optional>); >+ auto disengaged_test_empty = disengaged_test.WithInitialValue(Optional()); >+ auto disengaged_test_nonempty = >+ disengaged_test.WithInitialValue(Optional(kInitialInteger)); >+ >+ auto emplace_thrower_directly = [](Optional* optional_ptr) { >+ optional_ptr->emplace(kUpdatedInteger); >+ }; >+ EXPECT_TRUE(disengaged_test_empty.Test(emplace_thrower_directly)); >+ EXPECT_TRUE(disengaged_test_nonempty.Test(emplace_thrower_directly)); >+ >+ auto emplace_thrower_copy = [](Optional* optional_ptr) { >+ auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor); >+ optional_ptr->emplace(thrower); >+ }; >+ EXPECT_TRUE(disengaged_test_empty.Test(emplace_thrower_copy)); >+ EXPECT_TRUE(disengaged_test_nonempty.Test(emplace_thrower_copy)); >+} >+ >+TEST(OptionalExceptionSafety, EverythingThrowsSwap) { >+ // Test the basic guarantee plus test the result of optional::has_value() >+ // remains the same >+ auto test = >+ MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>); >+ auto disengaged_test_empty = test.WithInitialValue(Optional()) >+ .WithInvariants(CheckDisengaged<Optional>); >+ auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger)) >+ .WithInvariants(CheckEngaged<Optional>); >+ >+ auto swap_empty = [](Optional* optional_ptr) { >+ auto empty = Optional(); >+ optional_ptr->swap(empty); >+ }; >+ EXPECT_TRUE(engaged_test_nonempty.Test(swap_empty)); >+ >+ auto swap_nonempty = [](Optional* optional_ptr) { >+ auto nonempty = >+ Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor); >+ optional_ptr->swap(nonempty); >+ }; >+ EXPECT_TRUE(disengaged_test_empty.Test(swap_nonempty)); >+ EXPECT_TRUE(engaged_test_nonempty.Test(swap_nonempty)); >+} >+ >+TEST(OptionalExceptionSafety, NoThrowMoveSwap) { >+ // Tests the nothrow guarantee for optional of T with non-throwing move >+ { >+ auto empty = MoveOptional(); >+ auto nonempty = MoveOptional(kInitialInteger); >+ EXPECT_TRUE(testing::TestNothrowOp([&]() { nonempty.swap(empty); })); >+ } >+ { >+ auto nonempty = MoveOptional(kUpdatedInteger); >+ auto empty = MoveOptional(); >+ EXPECT_TRUE(testing::TestNothrowOp([&]() { empty.swap(nonempty); })); >+ } >+ { >+ auto nonempty_from = MoveOptional(kUpdatedInteger); >+ auto nonempty_to = MoveOptional(kInitialInteger); >+ EXPECT_TRUE( >+ testing::TestNothrowOp([&]() { nonempty_to.swap(nonempty_from); })); >+ } >+} >+ >+TEST(OptionalExceptionSafety, CopyAssign) { >+ // Test the basic guarantee plus test the result of optional::has_value() >+ // remains the same >+ auto test = >+ MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>); >+ auto disengaged_test_empty = test.WithInitialValue(Optional()) >+ .WithInvariants(CheckDisengaged<Optional>); >+ auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger)) >+ .WithInvariants(CheckEngaged<Optional>); >+ >+ auto copyassign_nonempty = [](Optional* optional_ptr) { >+ auto nonempty = >+ Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor); >+ *optional_ptr = nonempty; >+ }; >+ EXPECT_TRUE(disengaged_test_empty.Test(copyassign_nonempty)); >+ EXPECT_TRUE(engaged_test_nonempty.Test(copyassign_nonempty)); >+ >+ auto copyassign_thrower = [](Optional* optional_ptr) { >+ auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor); >+ *optional_ptr = thrower; >+ }; >+ EXPECT_TRUE(disengaged_test_empty.Test(copyassign_thrower)); >+ EXPECT_TRUE(engaged_test_nonempty.Test(copyassign_thrower)); >+} >+ >+TEST(OptionalExceptionSafety, MoveAssign) { >+ // Test the basic guarantee plus test the result of optional::has_value() >+ // remains the same >+ auto test = >+ MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>); >+ auto disengaged_test_empty = test.WithInitialValue(Optional()) >+ .WithInvariants(CheckDisengaged<Optional>); >+ auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger)) >+ .WithInvariants(CheckEngaged<Optional>); >+ >+ auto moveassign_empty = [](Optional* optional_ptr) { >+ auto empty = Optional(); >+ *optional_ptr = std::move(empty); >+ }; >+ EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_empty)); >+ >+ auto moveassign_nonempty = [](Optional* optional_ptr) { >+ auto nonempty = >+ Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor); >+ *optional_ptr = std::move(nonempty); >+ }; >+ EXPECT_TRUE(disengaged_test_empty.Test(moveassign_nonempty)); >+ EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_nonempty)); >+ >+ auto moveassign_thrower = [](Optional* optional_ptr) { >+ auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor); >+ *optional_ptr = std::move(thrower); >+ }; >+ EXPECT_TRUE(disengaged_test_empty.Test(moveassign_thrower)); >+ EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_thrower)); >+} >+ >+TEST(OptionalExceptionSafety, NothrowMoveAssign) { >+ // Tests the nothrow guarantee for optional of T with non-throwing move >+ { >+ auto empty = MoveOptional(); >+ auto nonempty = MoveOptional(kInitialInteger); >+ EXPECT_TRUE(testing::TestNothrowOp([&]() { nonempty = std::move(empty); })); >+ } >+ { >+ auto nonempty = MoveOptional(kInitialInteger); >+ auto empty = MoveOptional(); >+ EXPECT_TRUE(testing::TestNothrowOp([&]() { empty = std::move(nonempty); })); >+ } >+ { >+ auto nonempty_from = MoveOptional(kUpdatedInteger); >+ auto nonempty_to = MoveOptional(kInitialInteger); >+ EXPECT_TRUE(testing::TestNothrowOp( >+ [&]() { nonempty_to = std::move(nonempty_from); })); >+ } >+ { >+ auto thrower = MoveThrower(kUpdatedInteger); >+ auto empty = MoveOptional(); >+ EXPECT_TRUE(testing::TestNothrowOp([&]() { empty = std::move(thrower); })); >+ } >+ { >+ auto thrower = MoveThrower(kUpdatedInteger); >+ auto nonempty = MoveOptional(kInitialInteger); >+ EXPECT_TRUE( >+ testing::TestNothrowOp([&]() { nonempty = std::move(thrower); })); >+ } >+} >+ >+} // namespace >+ >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..179bfd66d2fee0eb9321b0559b2b9dc18910dbb3 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/optional_test.cc >@@ -0,0 +1,1625 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/types/optional.h" >+ >+#include <string> >+#include <type_traits> >+#include <utility> >+ >+#include "gtest/gtest.h" >+#include "absl/base/config.h" >+#include "absl/base/internal/raw_logging.h" >+#include "absl/meta/type_traits.h" >+#include "absl/strings/string_view.h" >+ >+struct Hashable {}; >+ >+namespace std { >+template <> >+struct hash<Hashable> { >+ size_t operator()(const Hashable&) { return 0; } >+}; >+} // namespace std >+ >+struct NonHashable {}; >+ >+namespace { >+ >+std::string TypeQuals(std::string&) { return "&"; } >+std::string TypeQuals(std::string&&) { return "&&"; } >+std::string TypeQuals(const std::string&) { return "c&"; } >+std::string TypeQuals(const std::string&&) { return "c&&"; } >+ >+struct StructorListener { >+ int construct0 = 0; >+ int construct1 = 0; >+ int construct2 = 0; >+ int listinit = 0; >+ int copy = 0; >+ int move = 0; >+ int copy_assign = 0; >+ int move_assign = 0; >+ int destruct = 0; >+ int volatile_copy = 0; >+ int volatile_move = 0; >+ int volatile_copy_assign = 0; >+ int volatile_move_assign = 0; >+}; >+ >+// Suppress MSVC warnings. >+// 4521: multiple copy constructors specified >+// 4522: multiple assignment operators specified >+// We wrote multiple of them to test that the correct overloads are selected. >+#ifdef _MSC_VER >+#pragma warning( push ) >+#pragma warning( disable : 4521) >+#pragma warning( disable : 4522) >+#endif >+struct Listenable { >+ static StructorListener* listener; >+ >+ Listenable() { ++listener->construct0; } >+ explicit Listenable(int /*unused*/) { ++listener->construct1; } >+ Listenable(int /*unused*/, int /*unused*/) { ++listener->construct2; } >+ Listenable(std::initializer_list<int> /*unused*/) { ++listener->listinit; } >+ Listenable(const Listenable& /*unused*/) { ++listener->copy; } >+ Listenable(const volatile Listenable& /*unused*/) { >+ ++listener->volatile_copy; >+ } >+ Listenable(volatile Listenable&& /*unused*/) { ++listener->volatile_move; } >+ Listenable(Listenable&& /*unused*/) { ++listener->move; } >+ Listenable& operator=(const Listenable& /*unused*/) { >+ ++listener->copy_assign; >+ return *this; >+ } >+ Listenable& operator=(Listenable&& /*unused*/) { >+ ++listener->move_assign; >+ return *this; >+ } >+ // use void return type instead of volatile T& to work around GCC warning >+ // when the assignment's returned reference is ignored. >+ void operator=(const volatile Listenable& /*unused*/) volatile { >+ ++listener->volatile_copy_assign; >+ } >+ void operator=(volatile Listenable&& /*unused*/) volatile { >+ ++listener->volatile_move_assign; >+ } >+ ~Listenable() { ++listener->destruct; } >+}; >+#ifdef _MSC_VER >+#pragma warning( pop ) >+#endif >+ >+StructorListener* Listenable::listener = nullptr; >+ >+// ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST is defined to 1 when the standard >+// library implementation doesn't marked initializer_list's default constructor >+// constexpr. The C++11 standard doesn't specify constexpr on it, but C++14 >+// added it. However, libstdc++ 4.7 marked it constexpr. >+#if defined(_LIBCPP_VERSION) && \ >+ (_LIBCPP_STD_VER <= 11 || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)) >+#define ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST 1 >+#endif >+ >+struct ConstexprType { >+ enum CtorTypes { >+ kCtorDefault, >+ kCtorInt, >+ kCtorInitializerList, >+ kCtorConstChar >+ }; >+ constexpr ConstexprType() : x(kCtorDefault) {} >+ constexpr explicit ConstexprType(int i) : x(kCtorInt) {} >+#ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST >+ constexpr ConstexprType(std::initializer_list<int> il) >+ : x(kCtorInitializerList) {} >+#endif >+ constexpr ConstexprType(const char*) // NOLINT(runtime/explicit) >+ : x(kCtorConstChar) {} >+ int x; >+}; >+ >+struct Copyable { >+ Copyable() {} >+ Copyable(const Copyable&) {} >+ Copyable& operator=(const Copyable&) { return *this; } >+}; >+ >+struct MoveableThrow { >+ MoveableThrow() {} >+ MoveableThrow(MoveableThrow&&) {} >+ MoveableThrow& operator=(MoveableThrow&&) { return *this; } >+}; >+ >+struct MoveableNoThrow { >+ MoveableNoThrow() {} >+ MoveableNoThrow(MoveableNoThrow&&) noexcept {} >+ MoveableNoThrow& operator=(MoveableNoThrow&&) noexcept { return *this; } >+}; >+ >+struct NonMovable { >+ NonMovable() {} >+ NonMovable(const NonMovable&) = delete; >+ NonMovable& operator=(const NonMovable&) = delete; >+ NonMovable(NonMovable&&) = delete; >+ NonMovable& operator=(NonMovable&&) = delete; >+}; >+ >+TEST(optionalTest, DefaultConstructor) { >+ absl::optional<int> empty; >+ EXPECT_FALSE(empty); >+ constexpr absl::optional<int> cempty; >+ static_assert(!cempty.has_value(), ""); >+ EXPECT_TRUE( >+ std::is_nothrow_default_constructible<absl::optional<int>>::value); >+} >+ >+TEST(optionalTest, nulloptConstructor) { >+ absl::optional<int> empty(absl::nullopt); >+ EXPECT_FALSE(empty); >+ >+#ifdef ABSL_HAVE_STD_OPTIONAL >+ constexpr absl::optional<int> cempty{absl::nullopt}; >+#else >+ // Creating a temporary absl::nullopt_t object instead of using absl::nullopt >+ // because absl::nullopt cannot be constexpr and have external linkage at the >+ // same time. >+ constexpr absl::optional<int> cempty{absl::nullopt_t(absl::nullopt_t::init)}; >+#endif >+ static_assert(!cempty.has_value(), ""); >+ EXPECT_TRUE((std::is_nothrow_constructible<absl::optional<int>, >+ absl::nullopt_t>::value)); >+} >+ >+TEST(optionalTest, CopyConstructor) { >+ { >+ absl::optional<int> empty, opt42 = 42; >+ absl::optional<int> empty_copy(empty); >+ EXPECT_FALSE(empty_copy); >+ absl::optional<int> opt42_copy(opt42); >+ EXPECT_TRUE(opt42_copy); >+ EXPECT_EQ(42, *opt42_copy); >+ } >+ { >+ absl::optional<const int> empty, opt42 = 42; >+ absl::optional<const int> empty_copy(empty); >+ EXPECT_FALSE(empty_copy); >+ absl::optional<const int> opt42_copy(opt42); >+ EXPECT_TRUE(opt42_copy); >+ EXPECT_EQ(42, *opt42_copy); >+ } >+ { >+ absl::optional<volatile int> empty, opt42 = 42; >+ absl::optional<volatile int> empty_copy(empty); >+ EXPECT_FALSE(empty_copy); >+ absl::optional<volatile int> opt42_copy(opt42); >+ EXPECT_TRUE(opt42_copy); >+ EXPECT_EQ(42, *opt42_copy); >+ } >+ // test copyablility >+ EXPECT_TRUE(std::is_copy_constructible<absl::optional<int>>::value); >+ EXPECT_TRUE(std::is_copy_constructible<absl::optional<Copyable>>::value); >+ EXPECT_FALSE( >+ std::is_copy_constructible<absl::optional<MoveableThrow>>::value); >+ EXPECT_FALSE( >+ std::is_copy_constructible<absl::optional<MoveableNoThrow>>::value); >+ EXPECT_FALSE(std::is_copy_constructible<absl::optional<NonMovable>>::value); >+ >+ EXPECT_FALSE( >+ absl::is_trivially_copy_constructible<absl::optional<Copyable>>::value); >+#if defined(ABSL_HAVE_STD_OPTIONAL) && defined(__GLIBCXX__) >+ // libstdc++ std::optional implementation (as of 7.2) has a bug: when T is >+ // trivially copyable, optional<T> is not trivially copyable (due to one of >+ // its base class is unconditionally nontrivial). >+#define ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG 1 >+#endif >+#ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG >+ EXPECT_TRUE( >+ absl::is_trivially_copy_constructible<absl::optional<int>>::value); >+ EXPECT_TRUE( >+ absl::is_trivially_copy_constructible<absl::optional<const int>>::value); >+#ifndef _MSC_VER >+ // See defect report "Trivial copy/move constructor for class with volatile >+ // member" at >+ // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2094 >+ // A class with non-static data member of volatile-qualified type should still >+ // have a trivial copy constructor if the data member is trivial. >+ // Also a cv-qualified scalar type should be trivially copyable. >+ EXPECT_TRUE(absl::is_trivially_copy_constructible< >+ absl::optional<volatile int>>::value); >+#endif // _MSC_VER >+#endif // ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG >+ >+ // constexpr copy constructor for trivially copyable types >+ { >+ constexpr absl::optional<int> o1; >+ constexpr absl::optional<int> o2 = o1; >+ static_assert(!o2, ""); >+ } >+ { >+ constexpr absl::optional<int> o1 = 42; >+ constexpr absl::optional<int> o2 = o1; >+ static_assert(o2, ""); >+ static_assert(*o2 == 42, ""); >+ } >+ { >+ struct TrivialCopyable { >+ constexpr TrivialCopyable() : x(0) {} >+ constexpr explicit TrivialCopyable(int i) : x(i) {} >+ int x; >+ }; >+ constexpr absl::optional<TrivialCopyable> o1(42); >+ constexpr absl::optional<TrivialCopyable> o2 = o1; >+ static_assert(o2, ""); >+ static_assert((*o2).x == 42, ""); >+#ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG >+ EXPECT_TRUE(absl::is_trivially_copy_constructible< >+ absl::optional<TrivialCopyable>>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible< >+ absl::optional<const TrivialCopyable>>::value); >+#endif >+ // When testing with VS 2017 15.3, there seems to be a bug in MSVC >+ // std::optional when T is volatile-qualified. So skipping this test. >+ // Bug report: >+ // https://connect.microsoft.com/VisualStudio/feedback/details/3142534 >+#if defined(ABSL_HAVE_STD_OPTIONAL) && defined(_MSC_VER) && _MSC_VER >= 1911 >+#define ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG 1 >+#endif >+#ifndef ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG >+ EXPECT_FALSE(std::is_copy_constructible< >+ absl::optional<volatile TrivialCopyable>>::value); >+#endif >+ } >+} >+ >+TEST(optionalTest, MoveConstructor) { >+ absl::optional<int> empty, opt42 = 42; >+ absl::optional<int> empty_move(std::move(empty)); >+ EXPECT_FALSE(empty_move); >+ absl::optional<int> opt42_move(std::move(opt42)); >+ EXPECT_TRUE(opt42_move); >+ EXPECT_EQ(42, opt42_move); >+ // test movability >+ EXPECT_TRUE(std::is_move_constructible<absl::optional<int>>::value); >+ EXPECT_TRUE(std::is_move_constructible<absl::optional<Copyable>>::value); >+ EXPECT_TRUE(std::is_move_constructible<absl::optional<MoveableThrow>>::value); >+ EXPECT_TRUE( >+ std::is_move_constructible<absl::optional<MoveableNoThrow>>::value); >+ EXPECT_FALSE(std::is_move_constructible<absl::optional<NonMovable>>::value); >+ // test noexcept >+ EXPECT_TRUE(std::is_nothrow_move_constructible<absl::optional<int>>::value); >+#ifndef ABSL_HAVE_STD_OPTIONAL >+ EXPECT_EQ( >+ absl::default_allocator_is_nothrow::value, >+ std::is_nothrow_move_constructible<absl::optional<MoveableThrow>>::value); >+#endif >+ EXPECT_TRUE(std::is_nothrow_move_constructible< >+ absl::optional<MoveableNoThrow>>::value); >+} >+ >+TEST(optionalTest, Destructor) { >+ struct Trivial {}; >+ >+ struct NonTrivial { >+ NonTrivial(const NonTrivial&) {} >+ NonTrivial& operator=(const NonTrivial&) { return *this; } >+ ~NonTrivial() {} >+ }; >+ >+ EXPECT_TRUE(std::is_trivially_destructible<absl::optional<int>>::value); >+ EXPECT_TRUE(std::is_trivially_destructible<absl::optional<Trivial>>::value); >+ EXPECT_FALSE( >+ std::is_trivially_destructible<absl::optional<NonTrivial>>::value); >+} >+ >+TEST(optionalTest, InPlaceConstructor) { >+ constexpr absl::optional<ConstexprType> opt0{absl::in_place_t()}; >+ static_assert(opt0, ""); >+ static_assert((*opt0).x == ConstexprType::kCtorDefault, ""); >+ constexpr absl::optional<ConstexprType> opt1{absl::in_place_t(), 1}; >+ static_assert(opt1, ""); >+ static_assert((*opt1).x == ConstexprType::kCtorInt, ""); >+#ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST >+ constexpr absl::optional<ConstexprType> opt2{absl::in_place_t(), {1, 2}}; >+ static_assert(opt2, ""); >+ static_assert((*opt2).x == ConstexprType::kCtorInitializerList, ""); >+#endif >+ >+ // TODO(absl-team): uncomment these when std::is_constructible<T, Args&&...> >+ // SFINAE is added to optional::optional(absl::in_place_t, Args&&...). >+ // struct I { >+ // I(absl::in_place_t); >+ // }; >+ >+ // EXPECT_FALSE((std::is_constructible<absl::optional<I>, >+ // absl::in_place_t>::value)); >+ // EXPECT_FALSE((std::is_constructible<absl::optional<I>, const >+ // absl::in_place_t&>::value)); >+} >+ >+// template<U=T> optional(U&&); >+TEST(optionalTest, ValueConstructor) { >+ constexpr absl::optional<int> opt0(0); >+ static_assert(opt0, ""); >+ static_assert(*opt0 == 0, ""); >+ EXPECT_TRUE((std::is_convertible<int, absl::optional<int>>::value)); >+ // Copy initialization ( = "abc") won't work due to optional(optional&&) >+ // is not constexpr. Use list initialization instead. This invokes >+ // absl::optional<ConstexprType>::absl::optional<U>(U&&), with U = const char >+ // (&) [4], which direct-initializes the ConstexprType value held by the >+ // optional via ConstexprType::ConstexprType(const char*). >+ constexpr absl::optional<ConstexprType> opt1 = {"abc"}; >+ static_assert(opt1, ""); >+ static_assert(ConstexprType::kCtorConstChar == (*opt1).x, ""); >+ EXPECT_TRUE( >+ (std::is_convertible<const char*, absl::optional<ConstexprType>>::value)); >+ // direct initialization >+ constexpr absl::optional<ConstexprType> opt2{2}; >+ static_assert(opt2, ""); >+ static_assert(ConstexprType::kCtorInt == (*opt2).x, ""); >+ EXPECT_FALSE( >+ (std::is_convertible<int, absl::optional<ConstexprType>>::value)); >+ >+ // this invokes absl::optional<int>::optional(int&&) >+ // NOTE: this has different behavior than assignment, e.g. >+ // "opt3 = {};" clears the optional rather than setting the value to 0 >+ // According to C++17 standard N4659 [over.ics.list] 16.3.3.1.5, (9.2)- "if >+ // the initializer list has no elements, the implicit conversion is the >+ // identity conversion", so `optional(int&&)` should be a better match than >+ // `optional(optional&&)` which is a user-defined conversion. >+ // Note: GCC 7 has a bug with this overload selection when compiled with >+ // `-std=c++17`. >+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 7 && \ >+ __cplusplus == 201703L >+#define ABSL_GCC7_OVER_ICS_LIST_BUG 1 >+#endif >+#ifndef ABSL_GCC7_OVER_ICS_LIST_BUG >+ constexpr absl::optional<int> opt3({}); >+ static_assert(opt3, ""); >+ static_assert(*opt3 == 0, ""); >+#endif >+ >+ // this invokes the move constructor with a default constructed optional >+ // because non-template function is a better match than template function. >+ absl::optional<ConstexprType> opt4({}); >+ EXPECT_FALSE(opt4); >+} >+ >+struct Implicit {}; >+ >+struct Explicit {}; >+ >+struct Convert { >+ Convert(const Implicit&) // NOLINT(runtime/explicit) >+ : implicit(true), move(false) {} >+ Convert(Implicit&&) // NOLINT(runtime/explicit) >+ : implicit(true), move(true) {} >+ explicit Convert(const Explicit&) : implicit(false), move(false) {} >+ explicit Convert(Explicit&&) : implicit(false), move(true) {} >+ >+ bool implicit; >+ bool move; >+}; >+ >+struct ConvertFromOptional { >+ ConvertFromOptional(const Implicit&) // NOLINT(runtime/explicit) >+ : implicit(true), move(false), from_optional(false) {} >+ ConvertFromOptional(Implicit&&) // NOLINT(runtime/explicit) >+ : implicit(true), move(true), from_optional(false) {} >+ ConvertFromOptional( >+ const absl::optional<Implicit>&) // NOLINT(runtime/explicit) >+ : implicit(true), move(false), from_optional(true) {} >+ ConvertFromOptional(absl::optional<Implicit>&&) // NOLINT(runtime/explicit) >+ : implicit(true), move(true), from_optional(true) {} >+ explicit ConvertFromOptional(const Explicit&) >+ : implicit(false), move(false), from_optional(false) {} >+ explicit ConvertFromOptional(Explicit&&) >+ : implicit(false), move(true), from_optional(false) {} >+ explicit ConvertFromOptional(const absl::optional<Explicit>&) >+ : implicit(false), move(false), from_optional(true) {} >+ explicit ConvertFromOptional(absl::optional<Explicit>&&) >+ : implicit(false), move(true), from_optional(true) {} >+ >+ bool implicit; >+ bool move; >+ bool from_optional; >+}; >+ >+TEST(optionalTest, ConvertingConstructor) { >+ absl::optional<Implicit> i_empty; >+ absl::optional<Implicit> i(absl::in_place); >+ absl::optional<Explicit> e_empty; >+ absl::optional<Explicit> e(absl::in_place); >+ { >+ // implicitly constructing absl::optional<Convert> from >+ // absl::optional<Implicit> >+ absl::optional<Convert> empty = i_empty; >+ EXPECT_FALSE(empty); >+ absl::optional<Convert> opt_copy = i; >+ EXPECT_TRUE(opt_copy); >+ EXPECT_TRUE(opt_copy->implicit); >+ EXPECT_FALSE(opt_copy->move); >+ absl::optional<Convert> opt_move = absl::optional<Implicit>(absl::in_place); >+ EXPECT_TRUE(opt_move); >+ EXPECT_TRUE(opt_move->implicit); >+ EXPECT_TRUE(opt_move->move); >+ } >+ { >+ // explicitly constructing absl::optional<Convert> from >+ // absl::optional<Explicit> >+ absl::optional<Convert> empty(e_empty); >+ EXPECT_FALSE(empty); >+ absl::optional<Convert> opt_copy(e); >+ EXPECT_TRUE(opt_copy); >+ EXPECT_FALSE(opt_copy->implicit); >+ EXPECT_FALSE(opt_copy->move); >+ EXPECT_FALSE((std::is_convertible<const absl::optional<Explicit>&, >+ absl::optional<Convert>>::value)); >+ absl::optional<Convert> opt_move{absl::optional<Explicit>(absl::in_place)}; >+ EXPECT_TRUE(opt_move); >+ EXPECT_FALSE(opt_move->implicit); >+ EXPECT_TRUE(opt_move->move); >+ EXPECT_FALSE((std::is_convertible<absl::optional<Explicit>&&, >+ absl::optional<Convert>>::value)); >+ } >+ { >+ // implicitly constructing absl::optional<ConvertFromOptional> from >+ // absl::optional<Implicit> via >+ // ConvertFromOptional(absl::optional<Implicit>&&) check that >+ // ConvertFromOptional(Implicit&&) is NOT called >+ static_assert( >+ std::is_convertible<absl::optional<Implicit>, >+ absl::optional<ConvertFromOptional>>::value, >+ ""); >+ absl::optional<ConvertFromOptional> opt0 = i_empty; >+ EXPECT_TRUE(opt0); >+ EXPECT_TRUE(opt0->implicit); >+ EXPECT_FALSE(opt0->move); >+ EXPECT_TRUE(opt0->from_optional); >+ absl::optional<ConvertFromOptional> opt1 = absl::optional<Implicit>(); >+ EXPECT_TRUE(opt1); >+ EXPECT_TRUE(opt1->implicit); >+ EXPECT_TRUE(opt1->move); >+ EXPECT_TRUE(opt1->from_optional); >+ } >+ { >+ // implicitly constructing absl::optional<ConvertFromOptional> from >+ // absl::optional<Explicit> via >+ // ConvertFromOptional(absl::optional<Explicit>&&) check that >+ // ConvertFromOptional(Explicit&&) is NOT called >+ absl::optional<ConvertFromOptional> opt0(e_empty); >+ EXPECT_TRUE(opt0); >+ EXPECT_FALSE(opt0->implicit); >+ EXPECT_FALSE(opt0->move); >+ EXPECT_TRUE(opt0->from_optional); >+ EXPECT_FALSE( >+ (std::is_convertible<const absl::optional<Explicit>&, >+ absl::optional<ConvertFromOptional>>::value)); >+ absl::optional<ConvertFromOptional> opt1{absl::optional<Explicit>()}; >+ EXPECT_TRUE(opt1); >+ EXPECT_FALSE(opt1->implicit); >+ EXPECT_TRUE(opt1->move); >+ EXPECT_TRUE(opt1->from_optional); >+ EXPECT_FALSE( >+ (std::is_convertible<absl::optional<Explicit>&&, >+ absl::optional<ConvertFromOptional>>::value)); >+ } >+} >+ >+TEST(optionalTest, StructorBasic) { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ { >+ absl::optional<Listenable> empty; >+ EXPECT_FALSE(empty); >+ absl::optional<Listenable> opt0(absl::in_place); >+ EXPECT_TRUE(opt0); >+ absl::optional<Listenable> opt1(absl::in_place, 1); >+ EXPECT_TRUE(opt1); >+ absl::optional<Listenable> opt2(absl::in_place, 1, 2); >+ EXPECT_TRUE(opt2); >+ } >+ EXPECT_EQ(1, listener.construct0); >+ EXPECT_EQ(1, listener.construct1); >+ EXPECT_EQ(1, listener.construct2); >+ EXPECT_EQ(3, listener.destruct); >+} >+ >+TEST(optionalTest, CopyMoveStructor) { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ absl::optional<Listenable> original(absl::in_place); >+ EXPECT_EQ(1, listener.construct0); >+ EXPECT_EQ(0, listener.copy); >+ EXPECT_EQ(0, listener.move); >+ absl::optional<Listenable> copy(original); >+ EXPECT_EQ(1, listener.construct0); >+ EXPECT_EQ(1, listener.copy); >+ EXPECT_EQ(0, listener.move); >+ absl::optional<Listenable> move(std::move(original)); >+ EXPECT_EQ(1, listener.construct0); >+ EXPECT_EQ(1, listener.copy); >+ EXPECT_EQ(1, listener.move); >+} >+ >+TEST(optionalTest, ListInit) { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ absl::optional<Listenable> listinit1(absl::in_place, {1}); >+ absl::optional<Listenable> listinit2(absl::in_place, {1, 2}); >+ EXPECT_EQ(2, listener.listinit); >+} >+ >+TEST(optionalTest, AssignFromNullopt) { >+ absl::optional<int> opt(1); >+ opt = absl::nullopt; >+ EXPECT_FALSE(opt); >+ >+ StructorListener listener; >+ Listenable::listener = &listener; >+ absl::optional<Listenable> opt1(absl::in_place); >+ opt1 = absl::nullopt; >+ EXPECT_FALSE(opt1); >+ EXPECT_EQ(1, listener.construct0); >+ EXPECT_EQ(1, listener.destruct); >+ >+ EXPECT_TRUE(( >+ std::is_nothrow_assignable<absl::optional<int>, absl::nullopt_t>::value)); >+ EXPECT_TRUE((std::is_nothrow_assignable<absl::optional<Listenable>, >+ absl::nullopt_t>::value)); >+} >+ >+TEST(optionalTest, CopyAssignment) { >+ const absl::optional<int> empty, opt1 = 1, opt2 = 2; >+ absl::optional<int> empty_to_opt1, opt1_to_opt2, opt2_to_empty; >+ >+ EXPECT_FALSE(empty_to_opt1); >+ empty_to_opt1 = empty; >+ EXPECT_FALSE(empty_to_opt1); >+ empty_to_opt1 = opt1; >+ EXPECT_TRUE(empty_to_opt1); >+ EXPECT_EQ(1, empty_to_opt1.value()); >+ >+ EXPECT_FALSE(opt1_to_opt2); >+ opt1_to_opt2 = opt1; >+ EXPECT_TRUE(opt1_to_opt2); >+ EXPECT_EQ(1, opt1_to_opt2.value()); >+ opt1_to_opt2 = opt2; >+ EXPECT_TRUE(opt1_to_opt2); >+ EXPECT_EQ(2, opt1_to_opt2.value()); >+ >+ EXPECT_FALSE(opt2_to_empty); >+ opt2_to_empty = opt2; >+ EXPECT_TRUE(opt2_to_empty); >+ EXPECT_EQ(2, opt2_to_empty.value()); >+ opt2_to_empty = empty; >+ EXPECT_FALSE(opt2_to_empty); >+ >+ EXPECT_FALSE(std::is_copy_assignable<absl::optional<const int>>::value); >+ EXPECT_TRUE(std::is_copy_assignable<absl::optional<Copyable>>::value); >+ EXPECT_FALSE(std::is_copy_assignable<absl::optional<MoveableThrow>>::value); >+ EXPECT_FALSE(std::is_copy_assignable<absl::optional<MoveableNoThrow>>::value); >+ EXPECT_FALSE(std::is_copy_assignable<absl::optional<NonMovable>>::value); >+ >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<volatile int>::value); >+ >+ struct Trivial { >+ int i; >+ }; >+ struct NonTrivial { >+ NonTrivial& operator=(const NonTrivial&) { return *this; } >+ int i; >+ }; >+ >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value); >+ EXPECT_FALSE(std::is_copy_assignable<const Trivial>::value); >+ EXPECT_FALSE(std::is_copy_assignable<volatile Trivial>::value); >+ EXPECT_TRUE(std::is_copy_assignable<NonTrivial>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<NonTrivial>::value); >+ >+ // std::optional doesn't support volatile nontrivial types. >+#ifndef ABSL_HAVE_STD_OPTIONAL >+ { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ >+ absl::optional<volatile Listenable> empty, set(absl::in_place); >+ EXPECT_EQ(1, listener.construct0); >+ absl::optional<volatile Listenable> empty_to_empty, empty_to_set, >+ set_to_empty(absl::in_place), set_to_set(absl::in_place); >+ EXPECT_EQ(3, listener.construct0); >+ empty_to_empty = empty; // no effect >+ empty_to_set = set; // copy construct >+ set_to_empty = empty; // destruct >+ set_to_set = set; // copy assign >+ EXPECT_EQ(1, listener.volatile_copy); >+ EXPECT_EQ(0, listener.volatile_move); >+ EXPECT_EQ(1, listener.destruct); >+ EXPECT_EQ(1, listener.volatile_copy_assign); >+ } >+#endif // ABSL_HAVE_STD_OPTIONAL >+} >+ >+TEST(optionalTest, MoveAssignment) { >+ { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ >+ absl::optional<Listenable> empty1, empty2, set1(absl::in_place), >+ set2(absl::in_place); >+ EXPECT_EQ(2, listener.construct0); >+ absl::optional<Listenable> empty_to_empty, empty_to_set, >+ set_to_empty(absl::in_place), set_to_set(absl::in_place); >+ EXPECT_EQ(4, listener.construct0); >+ empty_to_empty = std::move(empty1); >+ empty_to_set = std::move(set1); >+ set_to_empty = std::move(empty2); >+ set_to_set = std::move(set2); >+ EXPECT_EQ(0, listener.copy); >+ EXPECT_EQ(1, listener.move); >+ EXPECT_EQ(1, listener.destruct); >+ EXPECT_EQ(1, listener.move_assign); >+ } >+ // std::optional doesn't support volatile nontrivial types. >+#ifndef ABSL_HAVE_STD_OPTIONAL >+ { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ >+ absl::optional<volatile Listenable> empty1, empty2, set1(absl::in_place), >+ set2(absl::in_place); >+ EXPECT_EQ(2, listener.construct0); >+ absl::optional<volatile Listenable> empty_to_empty, empty_to_set, >+ set_to_empty(absl::in_place), set_to_set(absl::in_place); >+ EXPECT_EQ(4, listener.construct0); >+ empty_to_empty = std::move(empty1); // no effect >+ empty_to_set = std::move(set1); // move construct >+ set_to_empty = std::move(empty2); // destruct >+ set_to_set = std::move(set2); // move assign >+ EXPECT_EQ(0, listener.volatile_copy); >+ EXPECT_EQ(1, listener.volatile_move); >+ EXPECT_EQ(1, listener.destruct); >+ EXPECT_EQ(1, listener.volatile_move_assign); >+ } >+#endif // ABSL_HAVE_STD_OPTIONAL >+ EXPECT_FALSE(std::is_move_assignable<absl::optional<const int>>::value); >+ EXPECT_TRUE(std::is_move_assignable<absl::optional<Copyable>>::value); >+ EXPECT_TRUE(std::is_move_assignable<absl::optional<MoveableThrow>>::value); >+ EXPECT_TRUE(std::is_move_assignable<absl::optional<MoveableNoThrow>>::value); >+ EXPECT_FALSE(std::is_move_assignable<absl::optional<NonMovable>>::value); >+ >+ EXPECT_FALSE( >+ std::is_nothrow_move_assignable<absl::optional<MoveableThrow>>::value); >+ EXPECT_TRUE( >+ std::is_nothrow_move_assignable<absl::optional<MoveableNoThrow>>::value); >+} >+ >+struct NoConvertToOptional { >+ // disable implicit conversion from const NoConvertToOptional& >+ // to absl::optional<NoConvertToOptional>. >+ NoConvertToOptional(const NoConvertToOptional&) = delete; >+}; >+ >+struct CopyConvert { >+ CopyConvert(const NoConvertToOptional&); >+ CopyConvert& operator=(const CopyConvert&) = delete; >+ CopyConvert& operator=(const NoConvertToOptional&); >+}; >+ >+struct CopyConvertFromOptional { >+ CopyConvertFromOptional(const NoConvertToOptional&); >+ CopyConvertFromOptional(const absl::optional<NoConvertToOptional>&); >+ CopyConvertFromOptional& operator=(const CopyConvertFromOptional&) = delete; >+ CopyConvertFromOptional& operator=(const NoConvertToOptional&); >+ CopyConvertFromOptional& operator=( >+ const absl::optional<NoConvertToOptional>&); >+}; >+ >+struct MoveConvert { >+ MoveConvert(NoConvertToOptional&&); >+ MoveConvert& operator=(const MoveConvert&) = delete; >+ MoveConvert& operator=(NoConvertToOptional&&); >+}; >+ >+struct MoveConvertFromOptional { >+ MoveConvertFromOptional(NoConvertToOptional&&); >+ MoveConvertFromOptional(absl::optional<NoConvertToOptional>&&); >+ MoveConvertFromOptional& operator=(const MoveConvertFromOptional&) = delete; >+ MoveConvertFromOptional& operator=(NoConvertToOptional&&); >+ MoveConvertFromOptional& operator=(absl::optional<NoConvertToOptional>&&); >+}; >+ >+// template <typename U = T> absl::optional<T>& operator=(U&& v); >+TEST(optionalTest, ValueAssignment) { >+ absl::optional<int> opt; >+ EXPECT_FALSE(opt); >+ opt = 42; >+ EXPECT_TRUE(opt); >+ EXPECT_EQ(42, opt.value()); >+ opt = absl::nullopt; >+ EXPECT_FALSE(opt); >+ opt = 42; >+ EXPECT_TRUE(opt); >+ EXPECT_EQ(42, opt.value()); >+ opt = 43; >+ EXPECT_TRUE(opt); >+ EXPECT_EQ(43, opt.value()); >+ opt = {}; // this should clear optional >+ EXPECT_FALSE(opt); >+ >+ opt = {44}; >+ EXPECT_TRUE(opt); >+ EXPECT_EQ(44, opt.value()); >+ >+ // U = const NoConvertToOptional& >+ EXPECT_TRUE((std::is_assignable<absl::optional<CopyConvert>&, >+ const NoConvertToOptional&>::value)); >+ // U = const absl::optional<NoConvertToOptional>& >+ EXPECT_TRUE((std::is_assignable<absl::optional<CopyConvertFromOptional>&, >+ const NoConvertToOptional&>::value)); >+ // U = const NoConvertToOptional& triggers SFINAE because >+ // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false >+ EXPECT_FALSE((std::is_assignable<absl::optional<MoveConvert>&, >+ const NoConvertToOptional&>::value)); >+ // U = NoConvertToOptional >+ EXPECT_TRUE((std::is_assignable<absl::optional<MoveConvert>&, >+ NoConvertToOptional&&>::value)); >+ // U = const NoConvertToOptional& triggers SFINAE because >+ // std::is_constructible_v<MoveConvertFromOptional, const >+ // NoConvertToOptional&> is false >+ EXPECT_FALSE((std::is_assignable<absl::optional<MoveConvertFromOptional>&, >+ const NoConvertToOptional&>::value)); >+ // U = NoConvertToOptional >+ EXPECT_TRUE((std::is_assignable<absl::optional<MoveConvertFromOptional>&, >+ NoConvertToOptional&&>::value)); >+ // U = const absl::optional<NoConvertToOptional>& >+ EXPECT_TRUE( >+ (std::is_assignable<absl::optional<CopyConvertFromOptional>&, >+ const absl::optional<NoConvertToOptional>&>::value)); >+ // U = absl::optional<NoConvertToOptional> >+ EXPECT_TRUE( >+ (std::is_assignable<absl::optional<MoveConvertFromOptional>&, >+ absl::optional<NoConvertToOptional>&&>::value)); >+} >+ >+// template <typename U> absl::optional<T>& operator=(const absl::optional<U>& >+// rhs); template <typename U> absl::optional<T>& operator=(absl::optional<U>&& >+// rhs); >+TEST(optionalTest, ConvertingAssignment) { >+ absl::optional<int> opt_i; >+ absl::optional<char> opt_c('c'); >+ opt_i = opt_c; >+ EXPECT_TRUE(opt_i); >+ EXPECT_EQ(*opt_c, *opt_i); >+ opt_i = absl::optional<char>(); >+ EXPECT_FALSE(opt_i); >+ opt_i = absl::optional<char>('d'); >+ EXPECT_TRUE(opt_i); >+ EXPECT_EQ('d', *opt_i); >+ >+ absl::optional<std::string> opt_str; >+ absl::optional<const char*> opt_cstr("abc"); >+ opt_str = opt_cstr; >+ EXPECT_TRUE(opt_str); >+ EXPECT_EQ(std::string("abc"), *opt_str); >+ opt_str = absl::optional<const char*>(); >+ EXPECT_FALSE(opt_str); >+ opt_str = absl::optional<const char*>("def"); >+ EXPECT_TRUE(opt_str); >+ EXPECT_EQ(std::string("def"), *opt_str); >+ >+ // operator=(const absl::optional<U>&) with U = NoConvertToOptional >+ EXPECT_TRUE( >+ (std::is_assignable<absl::optional<CopyConvert>, >+ const absl::optional<NoConvertToOptional>&>::value)); >+ // operator=(const absl::optional<U>&) with U = NoConvertToOptional >+ // triggers SFINAE because >+ // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false >+ EXPECT_FALSE( >+ (std::is_assignable<absl::optional<MoveConvert>&, >+ const absl::optional<NoConvertToOptional>&>::value)); >+ // operator=(absl::optional<U>&&) with U = NoConvertToOptional >+ EXPECT_TRUE( >+ (std::is_assignable<absl::optional<MoveConvert>&, >+ absl::optional<NoConvertToOptional>&&>::value)); >+ // operator=(const absl::optional<U>&) with U = NoConvertToOptional triggers >+ // SFINAE because std::is_constructible_v<MoveConvertFromOptional, const >+ // NoConvertToOptional&> is false. operator=(U&&) with U = const >+ // absl::optional<NoConverToOptional>& triggers SFINAE because >+ // std::is_constructible<MoveConvertFromOptional, >+ // absl::optional<NoConvertToOptional>&&> is true. >+ EXPECT_FALSE( >+ (std::is_assignable<absl::optional<MoveConvertFromOptional>&, >+ const absl::optional<NoConvertToOptional>&>::value)); >+} >+ >+TEST(optionalTest, ResetAndHasValue) { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ absl::optional<Listenable> opt; >+ EXPECT_FALSE(opt); >+ EXPECT_FALSE(opt.has_value()); >+ opt.emplace(); >+ EXPECT_TRUE(opt); >+ EXPECT_TRUE(opt.has_value()); >+ opt.reset(); >+ EXPECT_FALSE(opt); >+ EXPECT_FALSE(opt.has_value()); >+ EXPECT_EQ(1, listener.destruct); >+ opt.reset(); >+ EXPECT_FALSE(opt); >+ EXPECT_FALSE(opt.has_value()); >+ >+ constexpr absl::optional<int> empty; >+ static_assert(!empty.has_value(), ""); >+ constexpr absl::optional<int> nonempty(1); >+ static_assert(nonempty.has_value(), ""); >+} >+ >+TEST(optionalTest, Emplace) { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ absl::optional<Listenable> opt; >+ EXPECT_FALSE(opt); >+ opt.emplace(1); >+ EXPECT_TRUE(opt); >+ opt.emplace(1, 2); >+ EXPECT_EQ(1, listener.construct1); >+ EXPECT_EQ(1, listener.construct2); >+ EXPECT_EQ(1, listener.destruct); >+ >+ absl::optional<std::string> o; >+ EXPECT_TRUE((std::is_same<std::string&, decltype(o.emplace("abc"))>::value)); >+ std::string& ref = o.emplace("abc"); >+ EXPECT_EQ(&ref, &o.value()); >+} >+ >+TEST(optionalTest, ListEmplace) { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ absl::optional<Listenable> opt; >+ EXPECT_FALSE(opt); >+ opt.emplace({1}); >+ EXPECT_TRUE(opt); >+ opt.emplace({1, 2}); >+ EXPECT_EQ(2, listener.listinit); >+ EXPECT_EQ(1, listener.destruct); >+ >+ absl::optional<Listenable> o; >+ EXPECT_TRUE((std::is_same<Listenable&, decltype(o.emplace({1}))>::value)); >+ Listenable& ref = o.emplace({1}); >+ EXPECT_EQ(&ref, &o.value()); >+} >+ >+TEST(optionalTest, Swap) { >+ absl::optional<int> opt_empty, opt1 = 1, opt2 = 2; >+ EXPECT_FALSE(opt_empty); >+ EXPECT_TRUE(opt1); >+ EXPECT_EQ(1, opt1.value()); >+ EXPECT_TRUE(opt2); >+ EXPECT_EQ(2, opt2.value()); >+ swap(opt_empty, opt1); >+ EXPECT_FALSE(opt1); >+ EXPECT_TRUE(opt_empty); >+ EXPECT_EQ(1, opt_empty.value()); >+ EXPECT_TRUE(opt2); >+ EXPECT_EQ(2, opt2.value()); >+ swap(opt_empty, opt1); >+ EXPECT_FALSE(opt_empty); >+ EXPECT_TRUE(opt1); >+ EXPECT_EQ(1, opt1.value()); >+ EXPECT_TRUE(opt2); >+ EXPECT_EQ(2, opt2.value()); >+ swap(opt1, opt2); >+ EXPECT_FALSE(opt_empty); >+ EXPECT_TRUE(opt1); >+ EXPECT_EQ(2, opt1.value()); >+ EXPECT_TRUE(opt2); >+ EXPECT_EQ(1, opt2.value()); >+ >+ EXPECT_TRUE(noexcept(opt1.swap(opt2))); >+ EXPECT_TRUE(noexcept(swap(opt1, opt2))); >+} >+ >+template <int v> >+struct DeletedOpAddr { >+ constexpr static const int value = v; >+ constexpr DeletedOpAddr() = default; >+ constexpr const DeletedOpAddr<v>* operator&() const = delete; // NOLINT >+ DeletedOpAddr<v>* operator&() = delete; // NOLINT >+}; >+ >+// The static_assert featuring a constexpr call to operator->() is commented out >+// to document the fact that the current implementation of absl::optional<T> >+// expects such usecases to be malformed and not compile. >+TEST(optionalTest, OperatorAddr) { >+ constexpr const int v = -1; >+ { // constexpr >+ constexpr const absl::optional<DeletedOpAddr<v>> opt(absl::in_place_t{}); >+ static_assert(opt.has_value(), ""); >+ // static_assert(opt->value == v, ""); >+ static_assert((*opt).value == v, ""); >+ } >+ { // non-constexpr >+ const absl::optional<DeletedOpAddr<v>> opt(absl::in_place_t{}); >+ EXPECT_TRUE(opt.has_value()); >+ EXPECT_TRUE(opt->value == v); >+ EXPECT_TRUE((*opt).value == v); >+ } >+} >+ >+TEST(optionalTest, PointerStuff) { >+ absl::optional<std::string> opt(absl::in_place, "foo"); >+ EXPECT_EQ("foo", *opt); >+ const auto& opt_const = opt; >+ EXPECT_EQ("foo", *opt_const); >+ EXPECT_EQ(opt->size(), 3); >+ EXPECT_EQ(opt_const->size(), 3); >+ >+ constexpr absl::optional<ConstexprType> opt1(1); >+ static_assert((*opt1).x == ConstexprType::kCtorInt, ""); >+} >+ >+// gcc has a bug pre 4.9.1 where it doesn't do correct overload resolution >+// when overloads are const-qualified and *this is an raluve. >+// Skip that test to make the build green again when using the old compiler. >+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59296 is fixed in 4.9.1. >+#if defined(__GNUC__) && !defined(__clang__) >+#define GCC_VERSION (__GNUC__ * 10000 \ >+ + __GNUC_MINOR__ * 100 \ >+ + __GNUC_PATCHLEVEL__) >+#if GCC_VERSION < 40901 >+#define ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG >+#endif >+#endif >+ >+// MSVC has a bug with "cv-qualifiers in class construction", fixed in 2017. See >+// https://docs.microsoft.com/en-us/cpp/cpp-conformance-improvements-2017#bug-fixes >+// The compiler some incorrectly ingores the cv-qualifier when generating a >+// class object via a constructor call. For example: >+// >+// class optional { >+// constexpr T&& value() &&; >+// constexpr const T&& value() const &&; >+// } >+// >+// using COI = const absl::optional<int>; >+// static_assert(2 == COI(2).value(), ""); // const && >+// >+// This should invoke the "const &&" overload but since it ignores the const >+// qualifier it finds the "&&" overload the best candidate. >+#if defined(_MSC_VER) && _MSC_VER < 1910 >+#define ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG >+#endif >+ >+TEST(optionalTest, Value) { >+ using O = absl::optional<std::string>; >+ using CO = const absl::optional<std::string>; >+ using OC = absl::optional<const std::string>; >+ O lvalue(absl::in_place, "lvalue"); >+ CO clvalue(absl::in_place, "clvalue"); >+ OC lvalue_c(absl::in_place, "lvalue_c"); >+ EXPECT_EQ("lvalue", lvalue.value()); >+ EXPECT_EQ("clvalue", clvalue.value()); >+ EXPECT_EQ("lvalue_c", lvalue_c.value()); >+ EXPECT_EQ("xvalue", O(absl::in_place, "xvalue").value()); >+ EXPECT_EQ("xvalue_c", OC(absl::in_place, "xvalue_c").value()); >+#ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG >+ EXPECT_EQ("cxvalue", CO(absl::in_place, "cxvalue").value()); >+#endif >+ EXPECT_EQ("&", TypeQuals(lvalue.value())); >+ EXPECT_EQ("c&", TypeQuals(clvalue.value())); >+ EXPECT_EQ("c&", TypeQuals(lvalue_c.value())); >+ EXPECT_EQ("&&", TypeQuals(O(absl::in_place, "xvalue").value())); >+#if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \ >+ !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG) >+ EXPECT_EQ("c&&", TypeQuals(CO(absl::in_place, "cxvalue").value())); >+#endif >+ EXPECT_EQ("c&&", TypeQuals(OC(absl::in_place, "xvalue_c").value())); >+ >+ // test on volatile type >+ using OV = absl::optional<volatile int>; >+ OV lvalue_v(absl::in_place, 42); >+ EXPECT_EQ(42, lvalue_v.value()); >+ EXPECT_EQ(42, OV(42).value()); >+ EXPECT_TRUE((std::is_same<volatile int&, decltype(lvalue_v.value())>::value)); >+ EXPECT_TRUE((std::is_same<volatile int&&, decltype(OV(42).value())>::value)); >+ >+ // test exception throw on value() >+ absl::optional<int> empty; >+#ifdef ABSL_HAVE_EXCEPTIONS >+ EXPECT_THROW(empty.value(), absl::bad_optional_access); >+#else >+ EXPECT_DEATH(empty.value(), "Bad optional access"); >+#endif >+ >+ // test constexpr value() >+ constexpr absl::optional<int> o1(1); >+ static_assert(1 == o1.value(), ""); // const & >+#if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \ >+ !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG) >+ using COI = const absl::optional<int>; >+ static_assert(2 == COI(2).value(), ""); // const && >+#endif >+} >+ >+TEST(optionalTest, DerefOperator) { >+ using O = absl::optional<std::string>; >+ using CO = const absl::optional<std::string>; >+ using OC = absl::optional<const std::string>; >+ O lvalue(absl::in_place, "lvalue"); >+ CO clvalue(absl::in_place, "clvalue"); >+ OC lvalue_c(absl::in_place, "lvalue_c"); >+ EXPECT_EQ("lvalue", *lvalue); >+ EXPECT_EQ("clvalue", *clvalue); >+ EXPECT_EQ("lvalue_c", *lvalue_c); >+ EXPECT_EQ("xvalue", *O(absl::in_place, "xvalue")); >+ EXPECT_EQ("xvalue_c", *OC(absl::in_place, "xvalue_c")); >+#ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG >+ EXPECT_EQ("cxvalue", *CO(absl::in_place, "cxvalue")); >+#endif >+ EXPECT_EQ("&", TypeQuals(*lvalue)); >+ EXPECT_EQ("c&", TypeQuals(*clvalue)); >+ EXPECT_EQ("&&", TypeQuals(*O(absl::in_place, "xvalue"))); >+#if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \ >+ !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG) >+ EXPECT_EQ("c&&", TypeQuals(*CO(absl::in_place, "cxvalue"))); >+#endif >+ EXPECT_EQ("c&&", TypeQuals(*OC(absl::in_place, "xvalue_c"))); >+ >+ // test on volatile type >+ using OV = absl::optional<volatile int>; >+ OV lvalue_v(absl::in_place, 42); >+ EXPECT_EQ(42, *lvalue_v); >+ EXPECT_EQ(42, *OV(42)); >+ EXPECT_TRUE((std::is_same<volatile int&, decltype(*lvalue_v)>::value)); >+ EXPECT_TRUE((std::is_same<volatile int&&, decltype(*OV(42))>::value)); >+ >+ constexpr absl::optional<int> opt1(1); >+ static_assert(*opt1 == 1, ""); >+#if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \ >+ !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG) >+ using COI = const absl::optional<int>; >+ static_assert(*COI(2) == 2, ""); >+#endif >+} >+ >+TEST(optionalTest, ValueOr) { >+ absl::optional<double> opt_empty, opt_set = 1.2; >+ EXPECT_EQ(42.0, opt_empty.value_or(42)); >+ EXPECT_EQ(1.2, opt_set.value_or(42)); >+ EXPECT_EQ(42.0, absl::optional<double>().value_or(42)); >+ EXPECT_EQ(1.2, absl::optional<double>(1.2).value_or(42)); >+ >+ constexpr absl::optional<double> copt_empty, copt_set = {1.2}; >+ static_assert(42.0 == copt_empty.value_or(42), ""); >+ static_assert(1.2 == copt_set.value_or(42), ""); >+#ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG >+ using COD = const absl::optional<double>; >+ static_assert(42.0 == COD().value_or(42), ""); >+ static_assert(1.2 == COD(1.2).value_or(42), ""); >+#endif >+} >+ >+// make_optional cannot be constexpr until C++17 >+TEST(optionalTest, make_optional) { >+ auto opt_int = absl::make_optional(42); >+ EXPECT_TRUE((std::is_same<decltype(opt_int), absl::optional<int>>::value)); >+ EXPECT_EQ(42, opt_int); >+ >+ StructorListener listener; >+ Listenable::listener = &listener; >+ >+ absl::optional<Listenable> opt0 = absl::make_optional<Listenable>(); >+ EXPECT_EQ(1, listener.construct0); >+ absl::optional<Listenable> opt1 = absl::make_optional<Listenable>(1); >+ EXPECT_EQ(1, listener.construct1); >+ absl::optional<Listenable> opt2 = absl::make_optional<Listenable>(1, 2); >+ EXPECT_EQ(1, listener.construct2); >+ absl::optional<Listenable> opt3 = absl::make_optional<Listenable>({1}); >+ absl::optional<Listenable> opt4 = absl::make_optional<Listenable>({1, 2}); >+ EXPECT_EQ(2, listener.listinit); >+ >+ // Constexpr tests on trivially copyable types >+ // optional<T> has trivial copy/move ctors when T is trivially copyable. >+ // For nontrivial types with constexpr constructors, we need copy elision in >+ // C++17 for make_optional to be constexpr. >+ { >+ constexpr absl::optional<int> c_opt = absl::make_optional(42); >+ static_assert(c_opt.value() == 42, ""); >+ } >+ { >+ struct TrivialCopyable { >+ constexpr TrivialCopyable() : x(0) {} >+ constexpr explicit TrivialCopyable(int i) : x(i) {} >+ int x; >+ }; >+ >+ constexpr TrivialCopyable v; >+ constexpr absl::optional<TrivialCopyable> c_opt0 = absl::make_optional(v); >+ static_assert((*c_opt0).x == 0, ""); >+ constexpr absl::optional<TrivialCopyable> c_opt1 = >+ absl::make_optional<TrivialCopyable>(); >+ static_assert((*c_opt1).x == 0, ""); >+ constexpr absl::optional<TrivialCopyable> c_opt2 = >+ absl::make_optional<TrivialCopyable>(42); >+ static_assert((*c_opt2).x == 42, ""); >+ } >+} >+ >+template <typename T, typename U> >+void optionalTest_Comparisons_EXPECT_LESS(T x, U y) { >+ EXPECT_FALSE(x == y); >+ EXPECT_TRUE(x != y); >+ EXPECT_TRUE(x < y); >+ EXPECT_FALSE(x > y); >+ EXPECT_TRUE(x <= y); >+ EXPECT_FALSE(x >= y); >+} >+ >+template <typename T, typename U> >+void optionalTest_Comparisons_EXPECT_SAME(T x, U y) { >+ EXPECT_TRUE(x == y); >+ EXPECT_FALSE(x != y); >+ EXPECT_FALSE(x < y); >+ EXPECT_FALSE(x > y); >+ EXPECT_TRUE(x <= y); >+ EXPECT_TRUE(x >= y); >+} >+ >+template <typename T, typename U> >+void optionalTest_Comparisons_EXPECT_GREATER(T x, U y) { >+ EXPECT_FALSE(x == y); >+ EXPECT_TRUE(x != y); >+ EXPECT_FALSE(x < y); >+ EXPECT_TRUE(x > y); >+ EXPECT_FALSE(x <= y); >+ EXPECT_TRUE(x >= y); >+} >+ >+ >+template <typename T, typename U, typename V> >+void TestComparisons() { >+ absl::optional<T> ae, a2{2}, a4{4}; >+ absl::optional<U> be, b2{2}, b4{4}; >+ V v3 = 3; >+ >+ // LHS: absl::nullopt, ae, a2, v3, a4 >+ // RHS: absl::nullopt, be, b2, v3, b4 >+ >+ // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,absl::nullopt); >+ optionalTest_Comparisons_EXPECT_SAME(absl::nullopt, be); >+ optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b2); >+ // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,v3); >+ optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b4); >+ >+ optionalTest_Comparisons_EXPECT_SAME(ae, absl::nullopt); >+ optionalTest_Comparisons_EXPECT_SAME(ae, be); >+ optionalTest_Comparisons_EXPECT_LESS(ae, b2); >+ optionalTest_Comparisons_EXPECT_LESS(ae, v3); >+ optionalTest_Comparisons_EXPECT_LESS(ae, b4); >+ >+ optionalTest_Comparisons_EXPECT_GREATER(a2, absl::nullopt); >+ optionalTest_Comparisons_EXPECT_GREATER(a2, be); >+ optionalTest_Comparisons_EXPECT_SAME(a2, b2); >+ optionalTest_Comparisons_EXPECT_LESS(a2, v3); >+ optionalTest_Comparisons_EXPECT_LESS(a2, b4); >+ >+ // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(v3,absl::nullopt); >+ optionalTest_Comparisons_EXPECT_GREATER(v3, be); >+ optionalTest_Comparisons_EXPECT_GREATER(v3, b2); >+ optionalTest_Comparisons_EXPECT_SAME(v3, v3); >+ optionalTest_Comparisons_EXPECT_LESS(v3, b4); >+ >+ optionalTest_Comparisons_EXPECT_GREATER(a4, absl::nullopt); >+ optionalTest_Comparisons_EXPECT_GREATER(a4, be); >+ optionalTest_Comparisons_EXPECT_GREATER(a4, b2); >+ optionalTest_Comparisons_EXPECT_GREATER(a4, v3); >+ optionalTest_Comparisons_EXPECT_SAME(a4, b4); >+} >+ >+struct Int1 { >+ Int1() = default; >+ Int1(int i) : i(i) {} // NOLINT(runtime/explicit) >+ int i; >+}; >+ >+struct Int2 { >+ Int2() = default; >+ Int2(int i) : i(i) {} // NOLINT(runtime/explicit) >+ int i; >+}; >+ >+// comparison between Int1 and Int2 >+constexpr bool operator==(const Int1& lhs, const Int2& rhs) { >+ return lhs.i == rhs.i; >+} >+constexpr bool operator!=(const Int1& lhs, const Int2& rhs) { >+ return !(lhs == rhs); >+} >+constexpr bool operator<(const Int1& lhs, const Int2& rhs) { >+ return lhs.i < rhs.i; >+} >+constexpr bool operator<=(const Int1& lhs, const Int2& rhs) { >+ return lhs < rhs || lhs == rhs; >+} >+constexpr bool operator>(const Int1& lhs, const Int2& rhs) { >+ return !(lhs <= rhs); >+} >+constexpr bool operator>=(const Int1& lhs, const Int2& rhs) { >+ return !(lhs < rhs); >+} >+ >+TEST(optionalTest, Comparisons) { >+ TestComparisons<int, int, int>(); >+ TestComparisons<const int, int, int>(); >+ TestComparisons<Int1, int, int>(); >+ TestComparisons<int, Int2, int>(); >+ TestComparisons<Int1, Int2, int>(); >+ >+ // compare absl::optional<std::string> with const char* >+ absl::optional<std::string> opt_str = "abc"; >+ const char* cstr = "abc"; >+ EXPECT_TRUE(opt_str == cstr); >+ // compare absl::optional<std::string> with absl::optional<const char*> >+ absl::optional<const char*> opt_cstr = cstr; >+ EXPECT_TRUE(opt_str == opt_cstr); >+ // compare absl::optional<std::string> with absl::optional<absl::string_view> >+ absl::optional<absl::string_view> e1; >+ absl::optional<std::string> e2; >+ EXPECT_TRUE(e1 == e2); >+} >+ >+ >+TEST(optionalTest, SwapRegression) { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ >+ { >+ absl::optional<Listenable> a; >+ absl::optional<Listenable> b(absl::in_place); >+ a.swap(b); >+ } >+ >+ EXPECT_EQ(1, listener.construct0); >+ EXPECT_EQ(1, listener.move); >+ EXPECT_EQ(2, listener.destruct); >+ >+ { >+ absl::optional<Listenable> a(absl::in_place); >+ absl::optional<Listenable> b; >+ a.swap(b); >+ } >+ >+ EXPECT_EQ(2, listener.construct0); >+ EXPECT_EQ(2, listener.move); >+ EXPECT_EQ(4, listener.destruct); >+} >+ >+TEST(optionalTest, BigStringLeakCheck) { >+ constexpr size_t n = 1 << 16; >+ >+ using OS = absl::optional<std::string>; >+ >+ OS a; >+ OS b = absl::nullopt; >+ OS c = std::string(n, 'c'); >+ std::string sd(n, 'd'); >+ OS d = sd; >+ OS e(absl::in_place, n, 'e'); >+ OS f; >+ f.emplace(n, 'f'); >+ >+ OS ca(a); >+ OS cb(b); >+ OS cc(c); >+ OS cd(d); >+ OS ce(e); >+ >+ OS oa; >+ OS ob = absl::nullopt; >+ OS oc = std::string(n, 'c'); >+ std::string sod(n, 'd'); >+ OS od = sod; >+ OS oe(absl::in_place, n, 'e'); >+ OS of; >+ of.emplace(n, 'f'); >+ >+ OS ma(std::move(oa)); >+ OS mb(std::move(ob)); >+ OS mc(std::move(oc)); >+ OS md(std::move(od)); >+ OS me(std::move(oe)); >+ OS mf(std::move(of)); >+ >+ OS aa1; >+ OS ab1 = absl::nullopt; >+ OS ac1 = std::string(n, 'c'); >+ std::string sad1(n, 'd'); >+ OS ad1 = sad1; >+ OS ae1(absl::in_place, n, 'e'); >+ OS af1; >+ af1.emplace(n, 'f'); >+ >+ OS aa2; >+ OS ab2 = absl::nullopt; >+ OS ac2 = std::string(n, 'c'); >+ std::string sad2(n, 'd'); >+ OS ad2 = sad2; >+ OS ae2(absl::in_place, n, 'e'); >+ OS af2; >+ af2.emplace(n, 'f'); >+ >+ aa1 = af2; >+ ab1 = ae2; >+ ac1 = ad2; >+ ad1 = ac2; >+ ae1 = ab2; >+ af1 = aa2; >+ >+ OS aa3; >+ OS ab3 = absl::nullopt; >+ OS ac3 = std::string(n, 'c'); >+ std::string sad3(n, 'd'); >+ OS ad3 = sad3; >+ OS ae3(absl::in_place, n, 'e'); >+ OS af3; >+ af3.emplace(n, 'f'); >+ >+ aa3 = absl::nullopt; >+ ab3 = absl::nullopt; >+ ac3 = absl::nullopt; >+ ad3 = absl::nullopt; >+ ae3 = absl::nullopt; >+ af3 = absl::nullopt; >+ >+ OS aa4; >+ OS ab4 = absl::nullopt; >+ OS ac4 = std::string(n, 'c'); >+ std::string sad4(n, 'd'); >+ OS ad4 = sad4; >+ OS ae4(absl::in_place, n, 'e'); >+ OS af4; >+ af4.emplace(n, 'f'); >+ >+ aa4 = OS(absl::in_place, n, 'a'); >+ ab4 = OS(absl::in_place, n, 'b'); >+ ac4 = OS(absl::in_place, n, 'c'); >+ ad4 = OS(absl::in_place, n, 'd'); >+ ae4 = OS(absl::in_place, n, 'e'); >+ af4 = OS(absl::in_place, n, 'f'); >+ >+ OS aa5; >+ OS ab5 = absl::nullopt; >+ OS ac5 = std::string(n, 'c'); >+ std::string sad5(n, 'd'); >+ OS ad5 = sad5; >+ OS ae5(absl::in_place, n, 'e'); >+ OS af5; >+ af5.emplace(n, 'f'); >+ >+ std::string saa5(n, 'a'); >+ std::string sab5(n, 'a'); >+ std::string sac5(n, 'a'); >+ std::string sad52(n, 'a'); >+ std::string sae5(n, 'a'); >+ std::string saf5(n, 'a'); >+ >+ aa5 = saa5; >+ ab5 = sab5; >+ ac5 = sac5; >+ ad5 = sad52; >+ ae5 = sae5; >+ af5 = saf5; >+ >+ OS aa6; >+ OS ab6 = absl::nullopt; >+ OS ac6 = std::string(n, 'c'); >+ std::string sad6(n, 'd'); >+ OS ad6 = sad6; >+ OS ae6(absl::in_place, n, 'e'); >+ OS af6; >+ af6.emplace(n, 'f'); >+ >+ aa6 = std::string(n, 'a'); >+ ab6 = std::string(n, 'b'); >+ ac6 = std::string(n, 'c'); >+ ad6 = std::string(n, 'd'); >+ ae6 = std::string(n, 'e'); >+ af6 = std::string(n, 'f'); >+ >+ OS aa7; >+ OS ab7 = absl::nullopt; >+ OS ac7 = std::string(n, 'c'); >+ std::string sad7(n, 'd'); >+ OS ad7 = sad7; >+ OS ae7(absl::in_place, n, 'e'); >+ OS af7; >+ af7.emplace(n, 'f'); >+ >+ aa7.emplace(n, 'A'); >+ ab7.emplace(n, 'B'); >+ ac7.emplace(n, 'C'); >+ ad7.emplace(n, 'D'); >+ ae7.emplace(n, 'E'); >+ af7.emplace(n, 'F'); >+} >+ >+TEST(optionalTest, MoveAssignRegression) { >+ StructorListener listener; >+ Listenable::listener = &listener; >+ >+ { >+ absl::optional<Listenable> a; >+ Listenable b; >+ a = std::move(b); >+ } >+ >+ EXPECT_EQ(1, listener.construct0); >+ EXPECT_EQ(1, listener.move); >+ EXPECT_EQ(2, listener.destruct); >+} >+ >+TEST(optionalTest, ValueType) { >+ EXPECT_TRUE((std::is_same<absl::optional<int>::value_type, int>::value)); >+ EXPECT_TRUE( >+ (std::is_same<absl::optional<std::string>::value_type, std::string>::value)); >+ EXPECT_FALSE( >+ (std::is_same<absl::optional<int>::value_type, absl::nullopt_t>::value)); >+} >+ >+template <typename T> >+struct is_hash_enabled_for { >+ template <typename U, typename = decltype(std::hash<U>()(std::declval<U>()))> >+ static std::true_type test(int); >+ >+ template <typename U> >+ static std::false_type test(...); >+ >+ static constexpr bool value = decltype(test<T>(0))::value; >+}; >+ >+TEST(optionalTest, Hash) { >+ std::hash<absl::optional<int>> hash; >+ std::set<size_t> hashcodes; >+ hashcodes.insert(hash(absl::nullopt)); >+ for (int i = 0; i < 100; ++i) { >+ hashcodes.insert(hash(i)); >+ } >+ EXPECT_GT(hashcodes.size(), 90); >+ >+ static_assert(is_hash_enabled_for<absl::optional<int>>::value, ""); >+ static_assert(is_hash_enabled_for<absl::optional<Hashable>>::value, ""); >+ >+#if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \ >+ _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11) >+ // For MSVC and libc++ (< 4.0 and c++14), std::hash primary template has a >+ // static_assert to catch any user-defined type that doesn't provide a hash >+ // specialization. So instantiating std::hash<absl::optional<T>> will result >+ // in a hard error which is not SFINAE friendly. >+#define ABSL_STD_HASH_NOT_SFINAE_FRIENDLY 1 >+#endif >+ >+#ifndef ABSL_STD_HASH_NOT_SFINAE_FRIENDLY >+ static_assert(!is_hash_enabled_for<absl::optional<NonHashable>>::value, ""); >+#endif >+ >+ // libstdc++ std::optional is missing remove_const_t, i.e. it's using >+ // std::hash<T> rather than std::hash<std::remove_const_t<T>>. >+ // Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82262 >+#ifndef __GLIBCXX__ >+ static_assert(is_hash_enabled_for<absl::optional<const int>>::value, ""); >+ static_assert(is_hash_enabled_for<absl::optional<const Hashable>>::value, ""); >+ std::hash<absl::optional<const int>> c_hash; >+ for (int i = 0; i < 100; ++i) { >+ EXPECT_EQ(hash(i), c_hash(i)); >+ } >+#endif >+} >+ >+struct MoveMeNoThrow { >+ MoveMeNoThrow() : x(0) {} >+ [[noreturn]] MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) { >+ ABSL_RAW_LOG(FATAL, "Should not be called."); >+ abort(); >+ } >+ MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {} >+ int x; >+}; >+ >+struct MoveMeThrow { >+ MoveMeThrow() : x(0) {} >+ MoveMeThrow(const MoveMeThrow& other) : x(other.x) {} >+ MoveMeThrow(MoveMeThrow&& other) : x(other.x) {} >+ int x; >+}; >+ >+TEST(optionalTest, NoExcept) { >+ static_assert( >+ std::is_nothrow_move_constructible<absl::optional<MoveMeNoThrow>>::value, >+ ""); >+#ifndef ABSL_HAVE_STD_OPTIONAL >+ static_assert(absl::default_allocator_is_nothrow::value == >+ std::is_nothrow_move_constructible< >+ absl::optional<MoveMeThrow>>::value, >+ ""); >+#endif >+ std::vector<absl::optional<MoveMeNoThrow>> v; >+ for (int i = 0; i < 10; ++i) v.emplace_back(); >+} >+ >+struct AnyLike { >+ AnyLike(AnyLike&&) = default; >+ AnyLike(const AnyLike&) = default; >+ >+ template <typename ValueType, >+ typename T = typename std::decay<ValueType>::type, >+ typename std::enable_if< >+ !absl::disjunction< >+ std::is_same<AnyLike, T>, >+ absl::negation<std::is_copy_constructible<T>>>::value, >+ int>::type = 0> >+ AnyLike(ValueType&&) {} // NOLINT(runtime/explicit) >+ >+ AnyLike& operator=(AnyLike&&) = default; >+ AnyLike& operator=(const AnyLike&) = default; >+ >+ template <typename ValueType, >+ typename T = typename std::decay<ValueType>::type> >+ typename std::enable_if< >+ absl::conjunction<absl::negation<std::is_same<AnyLike, T>>, >+ std::is_copy_constructible<T>>::value, >+ AnyLike&>::type >+ operator=(ValueType&& /* rhs */) { >+ return *this; >+ } >+}; >+ >+TEST(optionalTest, ConstructionConstraints) { >+ EXPECT_TRUE((std::is_constructible<AnyLike, absl::optional<AnyLike>>::value)); >+ >+ EXPECT_TRUE( >+ (std::is_constructible<AnyLike, const absl::optional<AnyLike>&>::value)); >+ >+ EXPECT_TRUE((std::is_constructible<absl::optional<AnyLike>, AnyLike>::value)); >+ EXPECT_TRUE( >+ (std::is_constructible<absl::optional<AnyLike>, const AnyLike&>::value)); >+ >+ EXPECT_TRUE((std::is_convertible<absl::optional<AnyLike>, AnyLike>::value)); >+ >+ EXPECT_TRUE( >+ (std::is_convertible<const absl::optional<AnyLike>&, AnyLike>::value)); >+ >+ EXPECT_TRUE((std::is_convertible<AnyLike, absl::optional<AnyLike>>::value)); >+ EXPECT_TRUE( >+ (std::is_convertible<const AnyLike&, absl::optional<AnyLike>>::value)); >+ >+ EXPECT_TRUE(std::is_move_constructible<absl::optional<AnyLike>>::value); >+ EXPECT_TRUE(std::is_copy_constructible<absl::optional<AnyLike>>::value); >+} >+ >+TEST(optionalTest, AssignmentConstraints) { >+ EXPECT_TRUE((std::is_assignable<AnyLike&, absl::optional<AnyLike>>::value)); >+ EXPECT_TRUE( >+ (std::is_assignable<AnyLike&, const absl::optional<AnyLike>&>::value)); >+ EXPECT_TRUE((std::is_assignable<absl::optional<AnyLike>&, AnyLike>::value)); >+ EXPECT_TRUE( >+ (std::is_assignable<absl::optional<AnyLike>&, const AnyLike&>::value)); >+ EXPECT_TRUE(std::is_move_assignable<absl::optional<AnyLike>>::value); >+ EXPECT_TRUE(std::is_copy_assignable<absl::optional<AnyLike>>::value); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/span.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/span.h >new file mode 100644 >index 0000000000000000000000000000000000000000..76be819ecca2186e5dd49dba0b2fd4a6d27ff9e8 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/span.h >@@ -0,0 +1,749 @@ >+// >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// ----------------------------------------------------------------------------- >+// span.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines a `Span<T>` type for holding a view of an existing >+// array of data. The `Span` object, much like the `absl::string_view` object, >+// does not own such data itself. A span provides a lightweight way to pass >+// around view of such data. >+// >+// Additionally, this header file defines `MakeSpan()` and `MakeConstSpan()` >+// factory functions, for clearly creating spans of type `Span<T>` or read-only >+// `Span<const T>` when such types may be difficult to identify due to issues >+// with implicit conversion. >+// >+// The C++ standards committee currently has a proposal for a `std::span` type, >+// (http://wg21.link/p0122), which is not yet part of the standard (though may >+// become part of C++20). As of August 2017, the differences between >+// `absl::Span` and this proposal are: >+// * `absl::Span` uses `size_t` for `size_type` >+// * `absl::Span` has no `operator()` >+// * `absl::Span` has no constructors for `std::unique_ptr` or >+// `std::shared_ptr` >+// * `absl::Span` has the factory functions `MakeSpan()` and >+// `MakeConstSpan()` >+// * `absl::Span` has `front()` and `back()` methods >+// * bounds-checked access to `absl::Span` is accomplished with `at()` >+// * `absl::Span` has compiler-provided move and copy constructors and >+// assignment. This is due to them being specified as `constexpr`, but that >+// implies const in C++11. >+// * `absl::Span` has no `element_type` or `index_type` typedefs >+// * A read-only `absl::Span<const T>` can be implicitly constructed from an >+// initializer list. >+// * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or >+// `as_mutable_bytes()` methods >+// * `absl::Span` has no static extent template parameter, nor constructors >+// which exist only because of the static extent parameter. >+// * `absl::Span` has an explicit mutable-reference constructor >+// >+// For more information, see the class comments below. >+#ifndef ABSL_TYPES_SPAN_H_ >+#define ABSL_TYPES_SPAN_H_ >+ >+#include <algorithm> >+#include <cassert> >+#include <cstddef> >+#include <initializer_list> >+#include <iterator> >+#include <string> >+#include <type_traits> >+#include <utility> >+ >+#include "absl/algorithm/algorithm.h" >+#include "absl/base/internal/throw_delegate.h" >+#include "absl/base/macros.h" >+#include "absl/base/optimization.h" >+#include "absl/base/port.h" >+#include "absl/meta/type_traits.h" >+ >+namespace absl { >+ >+template <typename T> >+class Span; >+ >+namespace span_internal { >+// A constexpr min function >+constexpr size_t Min(size_t a, size_t b) noexcept { return a < b ? a : b; } >+ >+// Wrappers for access to container data pointers. >+template <typename C> >+constexpr auto GetDataImpl(C& c, char) noexcept // NOLINT(runtime/references) >+ -> decltype(c.data()) { >+ return c.data(); >+} >+ >+// Before C++17, std::string::data returns a const char* in all cases. >+inline char* GetDataImpl(std::string& s, // NOLINT(runtime/references) >+ int) noexcept { >+ return &s[0]; >+} >+ >+template <typename C> >+constexpr auto GetData(C& c) noexcept // NOLINT(runtime/references) >+ -> decltype(GetDataImpl(c, 0)) { >+ return GetDataImpl(c, 0); >+} >+ >+// Detection idioms for size() and data(). >+template <typename C> >+using HasSize = >+ std::is_integral<absl::decay_t<decltype(std::declval<C&>().size())>>; >+ >+// We want to enable conversion from vector<T*> to Span<const T* const> but >+// disable conversion from vector<Derived> to Span<Base>. Here we use >+// the fact that U** is convertible to Q* const* if and only if Q is the same >+// type or a more cv-qualified version of U. We also decay the result type of >+// data() to avoid problems with classes which have a member function data() >+// which returns a reference. >+template <typename T, typename C> >+using HasData = >+ std::is_convertible<absl::decay_t<decltype(GetData(std::declval<C&>()))>*, >+ T* const*>; >+ >+// Extracts value type from a Container >+template <typename C> >+struct ElementType { >+ using type = typename absl::remove_reference_t<C>::value_type; >+}; >+ >+template <typename T, size_t N> >+struct ElementType<T (&)[N]> { >+ using type = T; >+}; >+ >+template <typename C> >+using ElementT = typename ElementType<C>::type; >+ >+template <typename T> >+using EnableIfMutable = >+ typename std::enable_if<!std::is_const<T>::value, int>::type; >+ >+template <typename T> >+bool EqualImpl(Span<T> a, Span<T> b) { >+ static_assert(std::is_const<T>::value, ""); >+ return absl::equal(a.begin(), a.end(), b.begin(), b.end()); >+} >+ >+template <typename T> >+bool LessThanImpl(Span<T> a, Span<T> b) { >+ static_assert(std::is_const<T>::value, ""); >+ return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); >+} >+ >+// The `IsConvertible` classes here are needed because of the >+// `std::is_convertible` bug in libcxx when compiled with GCC. This build >+// configuration is used by Android NDK toolchain. Reference link: >+// https://bugs.llvm.org/show_bug.cgi?id=27538. >+template <typename From, typename To> >+struct IsConvertibleHelper { >+ private: >+ static std::true_type testval(To); >+ static std::false_type testval(...); >+ >+ public: >+ using type = decltype(testval(std::declval<From>())); >+}; >+ >+template <typename From, typename To> >+struct IsConvertible : IsConvertibleHelper<From, To>::type {}; >+ >+// TODO(zhangxy): replace `IsConvertible` with `std::is_convertible` once the >+// older version of libcxx is not supported. >+template <typename From, typename To> >+using EnableIfConvertibleToSpanConst = >+ typename std::enable_if<IsConvertible<From, Span<const To>>::value>::type; >+} // namespace span_internal >+ >+//------------------------------------------------------------------------------ >+// Span >+//------------------------------------------------------------------------------ >+// >+// A `Span` is an "array view" type for holding a view of a contiguous data >+// array; the `Span` object does not and cannot own such data itself. A span >+// provides an easy way to provide overloads for anything operating on >+// contiguous sequences without needing to manage pointers and array lengths >+// manually. >+ >+// A span is conceptually a pointer (ptr) and a length (size) into an already >+// existing array of contiguous memory; the array it represents references the >+// elements "ptr[0] .. ptr[size-1]". Passing a properly-constructed `Span` >+// instead of raw pointers avoids many issues related to index out of bounds >+// errors. >+// >+// Spans may also be constructed from containers holding contiguous sequences. >+// Such containers must supply `data()` and `size() const` methods (e.g >+// `std::vector<T>`, `absl::InlinedVector<T, N>`). All implicit conversions to >+// `absl::Span` from such containers will create spans of type `const T`; >+// spans which can mutate their values (of type `T`) must use explicit >+// constructors. >+// >+// A `Span<T>` is somewhat analogous to an `absl::string_view`, but for an array >+// of elements of type `T`. A user of `Span` must ensure that the data being >+// pointed to outlives the `Span` itself. >+// >+// You can construct a `Span<T>` in several ways: >+// >+// * Explicitly from a reference to a container type >+// * Explicitly from a pointer and size >+// * Implicitly from a container type (but only for spans of type `const T`) >+// * Using the `MakeSpan()` or `MakeConstSpan()` factory functions. >+// >+// Examples: >+// >+// // Construct a Span explicitly from a container: >+// std::vector<int> v = {1, 2, 3, 4, 5}; >+// auto span = absl::Span<const int>(v); >+// >+// // Construct a Span explicitly from a C-style array: >+// int a[5] = {1, 2, 3, 4, 5}; >+// auto span = absl::Span<const int>(a); >+// >+// // Construct a Span implicitly from a container >+// void MyRoutine(absl::Span<const int> a) { >+// ... >+// } >+// std::vector v = {1,2,3,4,5}; >+// MyRoutine(v) // convert to Span<const T> >+// >+// Note that `Span` objects, in addition to requiring that the memory they >+// point to remains alive, must also ensure that such memory does not get >+// reallocated. Therefore, to avoid undefined behavior, containers with >+// associated span views should not invoke operations that may reallocate memory >+// (such as resizing) or invalidate iterators into the container. >+// >+// One common use for a `Span` is when passing arguments to a routine that can >+// accept a variety of array types (e.g. a `std::vector`, `absl::InlinedVector`, >+// a C-style array, etc.). Instead of creating overloads for each case, you >+// can simply specify a `Span` as the argument to such a routine. >+// >+// Example: >+// >+// void MyRoutine(absl::Span<const int> a) { >+// ... >+// } >+// >+// std::vector v = {1,2,3,4,5}; >+// MyRoutine(v); >+// >+// absl::InlinedVector<int, 4> my_inline_vector; >+// MyRoutine(my_inline_vector); >+// >+// // Explicit constructor from pointer,size >+// int* my_array = new int[10]; >+// MyRoutine(absl::Span<const int>(my_array, 10)); >+template <typename T> >+class Span { >+ private: >+ // Used to determine whether a Span can be constructed from a container of >+ // type C. >+ template <typename C> >+ using EnableIfConvertibleFrom = >+ typename std::enable_if<span_internal::HasData<T, C>::value && >+ span_internal::HasSize<C>::value>::type; >+ >+ // Used to SFINAE-enable a function when the slice elements are const. >+ template <typename U> >+ using EnableIfConstView = >+ typename std::enable_if<std::is_const<T>::value, U>::type; >+ >+ // Used to SFINAE-enable a function when the slice elements are mutable. >+ template <typename U> >+ using EnableIfMutableView = >+ typename std::enable_if<!std::is_const<T>::value, U>::type; >+ >+ public: >+ using value_type = absl::remove_cv_t<T>; >+ using pointer = T*; >+ using const_pointer = const T*; >+ using reference = T&; >+ using const_reference = const T&; >+ using iterator = pointer; >+ using const_iterator = const_pointer; >+ using reverse_iterator = std::reverse_iterator<iterator>; >+ using const_reverse_iterator = std::reverse_iterator<const_iterator>; >+ using size_type = size_t; >+ using difference_type = ptrdiff_t; >+ >+ static const size_type npos = ~(size_type(0)); >+ >+ constexpr Span() noexcept : Span(nullptr, 0) {} >+ constexpr Span(pointer array, size_type length) noexcept >+ : ptr_(array), len_(length) {} >+ >+ // Implicit conversion constructors >+ template <size_t N> >+ constexpr Span(T (&a)[N]) noexcept // NOLINT(runtime/explicit) >+ : Span(a, N) {} >+ >+ // Explicit reference constructor for a mutable `Span<T>` type. Can be >+ // replaced with MakeSpan() to infer the type parameter. >+ template <typename V, typename = EnableIfConvertibleFrom<V>, >+ typename = EnableIfMutableView<V>> >+ explicit Span(V& v) noexcept // NOLINT(runtime/references) >+ : Span(span_internal::GetData(v), v.size()) {} >+ >+ // Implicit reference constructor for a read-only `Span<const T>` type >+ template <typename V, typename = EnableIfConvertibleFrom<V>, >+ typename = EnableIfConstView<V>> >+ constexpr Span(const V& v) noexcept // NOLINT(runtime/explicit) >+ : Span(span_internal::GetData(v), v.size()) {} >+ >+ // Implicit constructor from an initializer list, making it possible to pass a >+ // brace-enclosed initializer list to a function expecting a `Span`. Such >+ // spans constructed from an initializer list must be of type `Span<const T>`. >+ // >+ // void Process(absl::Span<const int> x); >+ // Process({1, 2, 3}); >+ // >+ // Note that as always the array referenced by the span must outlive the span. >+ // Since an initializer list constructor acts as if it is fed a temporary >+ // array (cf. C++ standard [dcl.init.list]/5), it's safe to use this >+ // constructor only when the `std::initializer_list` itself outlives the span. >+ // In order to meet this requirement it's sufficient to ensure that neither >+ // the span nor a copy of it is used outside of the expression in which it's >+ // created: >+ // >+ // // Assume that this function uses the array directly, not retaining any >+ // // copy of the span or pointer to any of its elements. >+ // void Process(absl::Span<const int> ints); >+ // >+ // // Okay: the std::initializer_list<int> will reference a temporary array >+ // // that isn't destroyed until after the call to Process returns. >+ // Process({ 17, 19 }); >+ // >+ // // Not okay: the storage used by the std::initializer_list<int> is not >+ // // allowed to be referenced after the first line. >+ // absl::Span<const int> ints = { 17, 19 }; >+ // Process(ints); >+ // >+ // // Not okay for the same reason as above: even when the elements of the >+ // // initializer list expression are not temporaries the underlying array >+ // // is, so the initializer list must still outlive the span. >+ // const int foo = 17; >+ // absl::Span<const int> ints = { foo }; >+ // Process(ints); >+ // >+ template <typename LazyT = T, >+ typename = EnableIfConstView<LazyT>> >+ Span( >+ std::initializer_list<value_type> v) noexcept // NOLINT(runtime/explicit) >+ : Span(v.begin(), v.size()) {} >+ >+ // Accessors >+ >+ // Span::data() >+ // >+ // Returns a pointer to the span's underlying array of data (which is held >+ // outside the span). >+ constexpr pointer data() const noexcept { return ptr_; } >+ >+ // Span::size() >+ // >+ // Returns the size of this span. >+ constexpr size_type size() const noexcept { return len_; } >+ >+ // Span::length() >+ // >+ // Returns the length (size) of this span. >+ constexpr size_type length() const noexcept { return size(); } >+ >+ // Span::empty() >+ // >+ // Returns a boolean indicating whether or not this span is considered empty. >+ constexpr bool empty() const noexcept { return size() == 0; } >+ >+ // Span::operator[] >+ // >+ // Returns a reference to the i'th element of this span. >+ constexpr reference operator[](size_type i) const noexcept { >+ // MSVC 2015 accepts this as constexpr, but not ptr_[i] >+ return *(data() + i); >+ } >+ >+ // Span::at() >+ // >+ // Returns a reference to the i'th element of this span. >+ constexpr reference at(size_type i) const { >+ return ABSL_PREDICT_TRUE(i < size()) >+ ? ptr_[i] >+ : (base_internal::ThrowStdOutOfRange( >+ "Span::at failed bounds check"), >+ ptr_[i]); >+ } >+ >+ // Span::front() >+ // >+ // Returns a reference to the first element of this span. >+ reference front() const noexcept { return ABSL_ASSERT(size() > 0), ptr_[0]; } >+ >+ // Span::back() >+ // >+ // Returns a reference to the last element of this span. >+ reference back() const noexcept { >+ return ABSL_ASSERT(size() > 0), ptr_[size() - 1]; >+ } >+ >+ // Span::begin() >+ // >+ // Returns an iterator to the first element of this span. >+ constexpr iterator begin() const noexcept { return ptr_; } >+ >+ // Span::cbegin() >+ // >+ // Returns a const iterator to the first element of this span. >+ constexpr const_iterator cbegin() const noexcept { return ptr_; } >+ >+ // Span::end() >+ // >+ // Returns an iterator to the last element of this span. >+ iterator end() const noexcept { return ptr_ + len_; } >+ >+ // Span::cend() >+ // >+ // Returns a const iterator to the last element of this span. >+ const_iterator cend() const noexcept { return end(); } >+ >+ // Span::rbegin() >+ // >+ // Returns a reverse iterator starting at the last element of this span. >+ reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } >+ >+ // Span::crbegin() >+ // >+ // Returns a reverse const iterator starting at the last element of this span. >+ const_reverse_iterator crbegin() const noexcept { return rbegin(); } >+ >+ // Span::rend() >+ // >+ // Returns a reverse iterator starting at the first element of this span. >+ reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } >+ >+ // Span::crend() >+ // >+ // Returns a reverse iterator starting at the first element of this span. >+ const_reverse_iterator crend() const noexcept { return rend(); } >+ >+ // Span mutations >+ >+ // Span::remove_prefix() >+ // >+ // Removes the first `n` elements from the span. >+ void remove_prefix(size_type n) noexcept { >+ assert(len_ >= n); >+ ptr_ += n; >+ len_ -= n; >+ } >+ >+ // Span::remove_suffix() >+ // >+ // Removes the last `n` elements from the span. >+ void remove_suffix(size_type n) noexcept { >+ assert(len_ >= n); >+ len_ -= n; >+ } >+ >+ // Span::subspan() >+ // >+ // Returns a `Span` starting at element `pos` and of length `len`. Both `pos` >+ // and `len` are of type `size_type` and thus non-negative. Parameter `pos` >+ // must be <= size(). Any `len` value that points past the end of the span >+ // will be trimmed to at most size() - `pos`. A default `len` value of `npos` >+ // ensures the returned subspan continues until the end of the span. >+ // >+ // Examples: >+ // >+ // std::vector<int> vec = {10, 11, 12, 13}; >+ // absl::MakeSpan(vec).subspan(1, 2); // {11, 12} >+ // absl::MakeSpan(vec).subspan(2, 8); // {12, 13} >+ // absl::MakeSpan(vec).subspan(1); // {11, 12, 13} >+ // absl::MakeSpan(vec).subspan(4); // {} >+ // absl::MakeSpan(vec).subspan(5); // throws std::out_of_range >+ constexpr Span subspan(size_type pos = 0, size_type len = npos) const { >+ return (pos <= len_) >+ ? Span(ptr_ + pos, span_internal::Min(len_ - pos, len)) >+ : (base_internal::ThrowStdOutOfRange("pos > size()"), Span()); >+ } >+ >+ private: >+ pointer ptr_; >+ size_type len_; >+}; >+ >+template <typename T> >+const typename Span<T>::size_type Span<T>::npos; >+ >+// Span relationals >+ >+// Equality is compared element-by-element, while ordering is lexicographical. >+// We provide three overloads for each operator to cover any combination on the >+// left or right hand side of mutable Span<T>, read-only Span<const T>, and >+// convertible-to-read-only Span<T>. >+// TODO(zhangxy): Due to MSVC overload resolution bug with partial ordering >+// template functions, 5 overloads per operator is needed as a workaround. We >+// should update them to 3 overloads per operator using non-deduced context like >+// string_view, i.e. >+// - (Span<T>, Span<T>) >+// - (Span<T>, non_deduced<Span<const T>>) >+// - (non_deduced<Span<const T>>, Span<T>) >+ >+// operator== >+template <typename T> >+bool operator==(Span<T> a, Span<T> b) { >+ return span_internal::EqualImpl<const T>(a, b); >+} >+template <typename T> >+bool operator==(Span<const T> a, Span<T> b) { >+ return span_internal::EqualImpl<const T>(a, b); >+} >+template <typename T> >+bool operator==(Span<T> a, Span<const T> b) { >+ return span_internal::EqualImpl<const T>(a, b); >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator==(const U& a, Span<T> b) { >+ return span_internal::EqualImpl<const T>(a, b); >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator==(Span<T> a, const U& b) { >+ return span_internal::EqualImpl<const T>(a, b); >+} >+ >+// operator!= >+template <typename T> >+bool operator!=(Span<T> a, Span<T> b) { >+ return !(a == b); >+} >+template <typename T> >+bool operator!=(Span<const T> a, Span<T> b) { >+ return !(a == b); >+} >+template <typename T> >+bool operator!=(Span<T> a, Span<const T> b) { >+ return !(a == b); >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator!=(const U& a, Span<T> b) { >+ return !(a == b); >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator!=(Span<T> a, const U& b) { >+ return !(a == b); >+} >+ >+// operator< >+template <typename T> >+bool operator<(Span<T> a, Span<T> b) { >+ return span_internal::LessThanImpl<const T>(a, b); >+} >+template <typename T> >+bool operator<(Span<const T> a, Span<T> b) { >+ return span_internal::LessThanImpl<const T>(a, b); >+} >+template <typename T> >+bool operator<(Span<T> a, Span<const T> b) { >+ return span_internal::LessThanImpl<const T>(a, b); >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator<(const U& a, Span<T> b) { >+ return span_internal::LessThanImpl<const T>(a, b); >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator<(Span<T> a, const U& b) { >+ return span_internal::LessThanImpl<const T>(a, b); >+} >+ >+// operator> >+template <typename T> >+bool operator>(Span<T> a, Span<T> b) { >+ return b < a; >+} >+template <typename T> >+bool operator>(Span<const T> a, Span<T> b) { >+ return b < a; >+} >+template <typename T> >+bool operator>(Span<T> a, Span<const T> b) { >+ return b < a; >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator>(const U& a, Span<T> b) { >+ return b < a; >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator>(Span<T> a, const U& b) { >+ return b < a; >+} >+ >+// operator<= >+template <typename T> >+bool operator<=(Span<T> a, Span<T> b) { >+ return !(b < a); >+} >+template <typename T> >+bool operator<=(Span<const T> a, Span<T> b) { >+ return !(b < a); >+} >+template <typename T> >+bool operator<=(Span<T> a, Span<const T> b) { >+ return !(b < a); >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator<=(const U& a, Span<T> b) { >+ return !(b < a); >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator<=(Span<T> a, const U& b) { >+ return !(b < a); >+} >+ >+// operator>= >+template <typename T> >+bool operator>=(Span<T> a, Span<T> b) { >+ return !(a < b); >+} >+template <typename T> >+bool operator>=(Span<const T> a, Span<T> b) { >+ return !(a < b); >+} >+template <typename T> >+bool operator>=(Span<T> a, Span<const T> b) { >+ return !(a < b); >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator>=(const U& a, Span<T> b) { >+ return !(a < b); >+} >+template <typename T, typename U, >+ typename = span_internal::EnableIfConvertibleToSpanConst<U, T>> >+bool operator>=(Span<T> a, const U& b) { >+ return !(a < b); >+} >+ >+// MakeSpan() >+// >+// Constructs a mutable `Span<T>`, deducing `T` automatically from either a >+// container or pointer+size. >+// >+// Because a read-only `Span<const T>` is implicitly constructed from container >+// types regardless of whether the container itself is a const container, >+// constructing mutable spans of type `Span<T>` from containers requires >+// explicit constructors. The container-accepting version of `MakeSpan()` >+// deduces the type of `T` by the constness of the pointer received from the >+// container's `data()` member. Similarly, the pointer-accepting version returns >+// a `Span<const T>` if `T` is `const`, and a `Span<T>` otherwise. >+// >+// Examples: >+// >+// void MyRoutine(absl::Span<MyComplicatedType> a) { >+// ... >+// }; >+// // my_vector is a container of non-const types >+// std::vector<MyComplicatedType> my_vector; >+// >+// // Constructing a Span implicitly attempts to create a Span of type >+// // `Span<const T>` >+// MyRoutine(my_vector); // error, type mismatch >+// >+// // Explicitly constructing the Span is verbose >+// MyRoutine(absl::Span<MyComplicatedType>(my_vector)); >+// >+// // Use MakeSpan() to make an absl::Span<T> >+// MyRoutine(absl::MakeSpan(my_vector)); >+// >+// // Construct a span from an array ptr+size >+// absl::Span<T> my_span() { >+// return absl::MakeSpan(&array[0], num_elements_); >+// } >+// >+template <int&... ExplicitArgumentBarrier, typename T> >+constexpr Span<T> MakeSpan(T* ptr, size_t size) noexcept { >+ return Span<T>(ptr, size); >+} >+ >+template <int&... ExplicitArgumentBarrier, typename T> >+Span<T> MakeSpan(T* begin, T* end) noexcept { >+ return ABSL_ASSERT(begin <= end), Span<T>(begin, end - begin); >+} >+ >+template <int&... ExplicitArgumentBarrier, typename C> >+constexpr auto MakeSpan(C& c) noexcept // NOLINT(runtime/references) >+ -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) { >+ return MakeSpan(span_internal::GetData(c), c.size()); >+} >+ >+template <int&... ExplicitArgumentBarrier, typename T, size_t N> >+constexpr Span<T> MakeSpan(T (&array)[N]) noexcept { >+ return Span<T>(array, N); >+} >+ >+// MakeConstSpan() >+// >+// Constructs a `Span<const T>` as with `MakeSpan`, deducing `T` automatically, >+// but always returning a `Span<const T>`. >+// >+// Examples: >+// >+// void ProcessInts(absl::Span<const int> some_ints); >+// >+// // Call with a pointer and size. >+// int array[3] = { 0, 0, 0 }; >+// ProcessInts(absl::MakeConstSpan(&array[0], 3)); >+// >+// // Call with a [begin, end) pair. >+// ProcessInts(absl::MakeConstSpan(&array[0], &array[3])); >+// >+// // Call directly with an array. >+// ProcessInts(absl::MakeConstSpan(array)); >+// >+// // Call with a contiguous container. >+// std::vector<int> some_ints = ...; >+// ProcessInts(absl::MakeConstSpan(some_ints)); >+// ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 })); >+// >+template <int&... ExplicitArgumentBarrier, typename T> >+constexpr Span<const T> MakeConstSpan(T* ptr, size_t size) noexcept { >+ return Span<const T>(ptr, size); >+} >+ >+template <int&... ExplicitArgumentBarrier, typename T> >+Span<const T> MakeConstSpan(T* begin, T* end) noexcept { >+ return ABSL_ASSERT(begin <= end), Span<const T>(begin, end - begin); >+} >+ >+template <int&... ExplicitArgumentBarrier, typename C> >+constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) { >+ return MakeSpan(c); >+} >+ >+template <int&... ExplicitArgumentBarrier, typename T, size_t N> >+constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept { >+ return Span<const T>(array, N); >+} >+} // namespace absl >+#endif // ABSL_TYPES_SPAN_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/span_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/span_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..fbce7e87479841cf89138026993238c399862168 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/span_test.cc >@@ -0,0 +1,781 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/types/span.h" >+ >+#include <array> >+#include <initializer_list> >+#include <numeric> >+#include <stdexcept> >+#include <string> >+#include <type_traits> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/attributes.h" >+#include "absl/base/config.h" >+#include "absl/base/internal/exception_testing.h" >+#include "absl/container/fixed_array.h" >+#include "absl/container/inlined_vector.h" >+#include "absl/strings/str_cat.h" >+ >+namespace { >+ >+MATCHER_P(DataIs, data, >+ absl::StrCat("data() is ", negation ? "is " : "isn't ", >+ testing::PrintToString(data))) { >+ return arg.data() == data; >+} >+ >+template <typename T> >+auto SpanIs(T data, size_t size) >+ -> decltype(testing::AllOf(DataIs(data), testing::SizeIs(size))) { >+ return testing::AllOf(DataIs(data), testing::SizeIs(size)); >+} >+ >+template <typename Container> >+auto SpanIs(const Container& c) -> decltype(SpanIs(c.data(), c.size())) { >+ return SpanIs(c.data(), c.size()); >+} >+ >+std::vector<int> MakeRamp(int len, int offset = 0) { >+ std::vector<int> v(len); >+ std::iota(v.begin(), v.end(), offset); >+ return v; >+} >+ >+TEST(IntSpan, EmptyCtors) { >+ absl::Span<int> s; >+ EXPECT_THAT(s, SpanIs(nullptr, 0)); >+} >+ >+TEST(IntSpan, PtrLenCtor) { >+ int a[] = {1, 2, 3}; >+ absl::Span<int> s(&a[0], 2); >+ EXPECT_THAT(s, SpanIs(a, 2)); >+} >+ >+TEST(IntSpan, ArrayCtor) { >+ int a[] = {1, 2, 3}; >+ absl::Span<int> s(a); >+ EXPECT_THAT(s, SpanIs(a, 3)); >+ >+ EXPECT_TRUE((std::is_constructible<absl::Span<const int>, int[3]>::value)); >+ EXPECT_TRUE( >+ (std::is_constructible<absl::Span<const int>, const int[3]>::value)); >+ EXPECT_FALSE((std::is_constructible<absl::Span<int>, const int[3]>::value)); >+ EXPECT_TRUE((std::is_convertible<int[3], absl::Span<const int>>::value)); >+ EXPECT_TRUE( >+ (std::is_convertible<const int[3], absl::Span<const int>>::value)); >+} >+ >+template <typename T> >+void TakesGenericSpan(absl::Span<T>) {} >+ >+TEST(IntSpan, ContainerCtor) { >+ std::vector<int> empty; >+ absl::Span<int> s_empty(empty); >+ EXPECT_THAT(s_empty, SpanIs(empty)); >+ >+ std::vector<int> filled{1, 2, 3}; >+ absl::Span<int> s_filled(filled); >+ EXPECT_THAT(s_filled, SpanIs(filled)); >+ >+ absl::Span<int> s_from_span(filled); >+ EXPECT_THAT(s_from_span, SpanIs(s_filled)); >+ >+ absl::Span<const int> const_filled = filled; >+ EXPECT_THAT(const_filled, SpanIs(filled)); >+ >+ absl::Span<const int> const_from_span = s_filled; >+ EXPECT_THAT(const_from_span, SpanIs(s_filled)); >+ >+ EXPECT_TRUE( >+ (std::is_convertible<std::vector<int>&, absl::Span<const int>>::value)); >+ EXPECT_TRUE( >+ (std::is_convertible<absl::Span<int>&, absl::Span<const int>>::value)); >+ >+ TakesGenericSpan(absl::Span<int>(filled)); >+} >+ >+// A struct supplying shallow data() const. >+struct ContainerWithShallowConstData { >+ std::vector<int> storage; >+ int* data() const { return const_cast<int*>(storage.data()); } >+ int size() const { return storage.size(); } >+}; >+ >+TEST(IntSpan, ShallowConstness) { >+ const ContainerWithShallowConstData c{MakeRamp(20)}; >+ absl::Span<int> s( >+ c); // We should be able to do this even though data() is const. >+ s[0] = -1; >+ EXPECT_EQ(c.storage[0], -1); >+} >+ >+TEST(CharSpan, StringCtor) { >+ std::string empty = ""; >+ absl::Span<char> s_empty(empty); >+ EXPECT_THAT(s_empty, SpanIs(empty)); >+ >+ std::string abc = "abc"; >+ absl::Span<char> s_abc(abc); >+ EXPECT_THAT(s_abc, SpanIs(abc)); >+ >+ absl::Span<const char> s_const_abc = abc; >+ EXPECT_THAT(s_const_abc, SpanIs(abc)); >+ >+ EXPECT_FALSE((std::is_constructible<absl::Span<int>, std::string>::value)); >+ EXPECT_FALSE((std::is_constructible<absl::Span<const int>, std::string>::value)); >+ EXPECT_TRUE((std::is_convertible<std::string, absl::Span<const char>>::value)); >+} >+ >+TEST(IntSpan, FromConstPointer) { >+ EXPECT_TRUE((std::is_constructible<absl::Span<const int* const>, >+ std::vector<int*>>::value)); >+ EXPECT_TRUE((std::is_constructible<absl::Span<const int* const>, >+ std::vector<const int*>>::value)); >+ EXPECT_FALSE(( >+ std::is_constructible<absl::Span<const int*>, std::vector<int*>>::value)); >+ EXPECT_FALSE(( >+ std::is_constructible<absl::Span<int*>, std::vector<const int*>>::value)); >+} >+ >+struct TypeWithMisleadingData { >+ int& data() { return i; } >+ int size() { return 1; } >+ int i; >+}; >+ >+struct TypeWithMisleadingSize { >+ int* data() { return &i; } >+ const char* size() { return "1"; } >+ int i; >+}; >+ >+TEST(IntSpan, EvilTypes) { >+ EXPECT_FALSE( >+ (std::is_constructible<absl::Span<int>, TypeWithMisleadingData&>::value)); >+ EXPECT_FALSE( >+ (std::is_constructible<absl::Span<int>, TypeWithMisleadingSize&>::value)); >+} >+ >+struct Base { >+ int* data() { return &i; } >+ int size() { return 1; } >+ int i; >+}; >+struct Derived : Base {}; >+ >+TEST(IntSpan, SpanOfDerived) { >+ EXPECT_TRUE((std::is_constructible<absl::Span<int>, Base&>::value)); >+ EXPECT_TRUE((std::is_constructible<absl::Span<int>, Derived&>::value)); >+ EXPECT_FALSE( >+ (std::is_constructible<absl::Span<Base>, std::vector<Derived>>::value)); >+} >+ >+void TestInitializerList(absl::Span<const int> s, const std::vector<int>& v) { >+ EXPECT_TRUE(absl::equal(s.begin(), s.end(), v.begin(), v.end())); >+} >+ >+TEST(ConstIntSpan, InitializerListConversion) { >+ TestInitializerList({}, {}); >+ TestInitializerList({1}, {1}); >+ TestInitializerList({1, 2, 3}, {1, 2, 3}); >+ >+ EXPECT_FALSE((std::is_constructible<absl::Span<int>, >+ std::initializer_list<int>>::value)); >+ EXPECT_FALSE(( >+ std::is_convertible<absl::Span<int>, std::initializer_list<int>>::value)); >+} >+ >+TEST(IntSpan, Data) { >+ int i; >+ absl::Span<int> s(&i, 1); >+ EXPECT_EQ(&i, s.data()); >+} >+ >+TEST(IntSpan, SizeLengthEmpty) { >+ absl::Span<int> empty; >+ EXPECT_EQ(empty.size(), 0); >+ EXPECT_TRUE(empty.empty()); >+ EXPECT_EQ(empty.size(), empty.length()); >+ >+ auto v = MakeRamp(10); >+ absl::Span<int> s(v); >+ EXPECT_EQ(s.size(), 10); >+ EXPECT_FALSE(s.empty()); >+ EXPECT_EQ(s.size(), s.length()); >+} >+ >+TEST(IntSpan, ElementAccess) { >+ auto v = MakeRamp(10); >+ absl::Span<int> s(v); >+ for (int i = 0; i < s.size(); ++i) { >+ EXPECT_EQ(s[i], s.at(i)); >+ } >+ >+ EXPECT_EQ(s.front(), s[0]); >+ EXPECT_EQ(s.back(), s[9]); >+} >+ >+TEST(IntSpan, AtThrows) { >+ auto v = MakeRamp(10); >+ absl::Span<int> s(v); >+ >+ EXPECT_EQ(s.at(9), 9); >+ ABSL_BASE_INTERNAL_EXPECT_FAIL(s.at(10), std::out_of_range, >+ "failed bounds check"); >+} >+ >+TEST(IntSpan, RemovePrefixAndSuffix) { >+ auto v = MakeRamp(20, 1); >+ absl::Span<int> s(v); >+ EXPECT_EQ(s.size(), 20); >+ >+ s.remove_suffix(0); >+ s.remove_prefix(0); >+ EXPECT_EQ(s.size(), 20); >+ >+ s.remove_prefix(1); >+ EXPECT_EQ(s.size(), 19); >+ EXPECT_EQ(s[0], 2); >+ >+ s.remove_suffix(1); >+ EXPECT_EQ(s.size(), 18); >+ EXPECT_EQ(s.back(), 19); >+ >+ s.remove_prefix(7); >+ EXPECT_EQ(s.size(), 11); >+ EXPECT_EQ(s[0], 9); >+ >+ s.remove_suffix(11); >+ EXPECT_EQ(s.size(), 0); >+ >+ EXPECT_EQ(v, MakeRamp(20, 1)); >+} >+ >+TEST(IntSpan, Subspan) { >+ std::vector<int> empty; >+ EXPECT_EQ(absl::MakeSpan(empty).subspan(), empty); >+ EXPECT_THAT(absl::MakeSpan(empty).subspan(0, 0), SpanIs(empty)); >+ EXPECT_THAT(absl::MakeSpan(empty).subspan(0, absl::Span<const int>::npos), >+ SpanIs(empty)); >+ >+ auto ramp = MakeRamp(10); >+ EXPECT_THAT(absl::MakeSpan(ramp).subspan(), SpanIs(ramp)); >+ EXPECT_THAT(absl::MakeSpan(ramp).subspan(0, 10), SpanIs(ramp)); >+ EXPECT_THAT(absl::MakeSpan(ramp).subspan(0, absl::Span<const int>::npos), >+ SpanIs(ramp)); >+ EXPECT_THAT(absl::MakeSpan(ramp).subspan(0, 3), SpanIs(ramp.data(), 3)); >+ EXPECT_THAT(absl::MakeSpan(ramp).subspan(5, absl::Span<const int>::npos), >+ SpanIs(ramp.data() + 5, 5)); >+ EXPECT_THAT(absl::MakeSpan(ramp).subspan(3, 3), SpanIs(ramp.data() + 3, 3)); >+ EXPECT_THAT(absl::MakeSpan(ramp).subspan(10, 5), SpanIs(ramp.data() + 10, 0)); >+ >+#ifdef ABSL_HAVE_EXCEPTIONS >+ EXPECT_THROW(absl::MakeSpan(ramp).subspan(11, 5), std::out_of_range); >+#else >+ EXPECT_DEATH_IF_SUPPORTED(absl::MakeSpan(ramp).subspan(11, 5), ""); >+#endif >+} >+ >+TEST(IntSpan, MakeSpanPtrLength) { >+ std::vector<int> empty; >+ auto s_empty = absl::MakeSpan(empty.data(), empty.size()); >+ EXPECT_THAT(s_empty, SpanIs(empty)); >+ >+ std::array<int, 3> a{{1, 2, 3}}; >+ auto s = absl::MakeSpan(a.data(), a.size()); >+ EXPECT_THAT(s, SpanIs(a)); >+ >+ EXPECT_THAT(absl::MakeConstSpan(empty.data(), empty.size()), SpanIs(s_empty)); >+ EXPECT_THAT(absl::MakeConstSpan(a.data(), a.size()), SpanIs(s)); >+} >+ >+TEST(IntSpan, MakeSpanTwoPtrs) { >+ std::vector<int> empty; >+ auto s_empty = absl::MakeSpan(empty.data(), empty.data()); >+ EXPECT_THAT(s_empty, SpanIs(empty)); >+ >+ std::vector<int> v{1, 2, 3}; >+ auto s = absl::MakeSpan(v.data(), v.data() + 1); >+ EXPECT_THAT(s, SpanIs(v.data(), 1)); >+ >+ EXPECT_THAT(absl::MakeConstSpan(empty.data(), empty.data()), SpanIs(s_empty)); >+ EXPECT_THAT(absl::MakeConstSpan(v.data(), v.data() + 1), SpanIs(s)); >+} >+ >+TEST(IntSpan, MakeSpanContainer) { >+ std::vector<int> empty; >+ auto s_empty = absl::MakeSpan(empty); >+ EXPECT_THAT(s_empty, SpanIs(empty)); >+ >+ std::vector<int> v{1, 2, 3}; >+ auto s = absl::MakeSpan(v); >+ EXPECT_THAT(s, SpanIs(v)); >+ >+ EXPECT_THAT(absl::MakeConstSpan(empty), SpanIs(s_empty)); >+ EXPECT_THAT(absl::MakeConstSpan(v), SpanIs(s)); >+ >+ EXPECT_THAT(absl::MakeSpan(s), SpanIs(s)); >+ EXPECT_THAT(absl::MakeConstSpan(s), SpanIs(s)); >+} >+ >+TEST(CharSpan, MakeSpanString) { >+ std::string empty = ""; >+ auto s_empty = absl::MakeSpan(empty); >+ EXPECT_THAT(s_empty, SpanIs(empty)); >+ >+ std::string str = "abc"; >+ auto s_str = absl::MakeSpan(str); >+ EXPECT_THAT(s_str, SpanIs(str)); >+ >+ EXPECT_THAT(absl::MakeConstSpan(empty), SpanIs(s_empty)); >+ EXPECT_THAT(absl::MakeConstSpan(str), SpanIs(s_str)); >+} >+ >+TEST(IntSpan, MakeSpanArray) { >+ int a[] = {1, 2, 3}; >+ auto s = absl::MakeSpan(a); >+ EXPECT_THAT(s, SpanIs(a, 3)); >+ >+ const int ca[] = {1, 2, 3}; >+ auto s_ca = absl::MakeSpan(ca); >+ EXPECT_THAT(s_ca, SpanIs(ca, 3)); >+ >+ EXPECT_THAT(absl::MakeConstSpan(a), SpanIs(s)); >+ EXPECT_THAT(absl::MakeConstSpan(ca), SpanIs(s_ca)); >+} >+ >+// Compile-asserts that the argument has the expected decayed type. >+template <typename Expected, typename T> >+void CheckType(const T& /* value */) { >+ testing::StaticAssertTypeEq<Expected, T>(); >+} >+ >+TEST(IntSpan, MakeSpanTypes) { >+ std::vector<int> vec; >+ const std::vector<int> cvec; >+ int a[1]; >+ const int ca[] = {1}; >+ int* ip = a; >+ const int* cip = ca; >+ std::string s = ""; >+ const std::string cs = ""; >+ CheckType<absl::Span<int>>(absl::MakeSpan(vec)); >+ CheckType<absl::Span<const int>>(absl::MakeSpan(cvec)); >+ CheckType<absl::Span<int>>(absl::MakeSpan(ip, ip + 1)); >+ CheckType<absl::Span<int>>(absl::MakeSpan(ip, 1)); >+ CheckType<absl::Span<const int>>(absl::MakeSpan(cip, cip + 1)); >+ CheckType<absl::Span<const int>>(absl::MakeSpan(cip, 1)); >+ CheckType<absl::Span<int>>(absl::MakeSpan(a)); >+ CheckType<absl::Span<int>>(absl::MakeSpan(a, a + 1)); >+ CheckType<absl::Span<int>>(absl::MakeSpan(a, 1)); >+ CheckType<absl::Span<const int>>(absl::MakeSpan(ca)); >+ CheckType<absl::Span<const int>>(absl::MakeSpan(ca, ca + 1)); >+ CheckType<absl::Span<const int>>(absl::MakeSpan(ca, 1)); >+ CheckType<absl::Span<char>>(absl::MakeSpan(s)); >+ CheckType<absl::Span<const char>>(absl::MakeSpan(cs)); >+} >+ >+TEST(ConstIntSpan, MakeConstSpanTypes) { >+ std::vector<int> vec; >+ const std::vector<int> cvec; >+ int array[1]; >+ const int carray[] = {0}; >+ int* ptr = array; >+ const int* cptr = carray; >+ std::string s = ""; >+ std::string cs = ""; >+ CheckType<absl::Span<const int>>(absl::MakeConstSpan(vec)); >+ CheckType<absl::Span<const int>>(absl::MakeConstSpan(cvec)); >+ CheckType<absl::Span<const int>>(absl::MakeConstSpan(ptr, ptr + 1)); >+ CheckType<absl::Span<const int>>(absl::MakeConstSpan(ptr, 1)); >+ CheckType<absl::Span<const int>>(absl::MakeConstSpan(cptr, cptr + 1)); >+ CheckType<absl::Span<const int>>(absl::MakeConstSpan(cptr, 1)); >+ CheckType<absl::Span<const int>>(absl::MakeConstSpan(array)); >+ CheckType<absl::Span<const int>>(absl::MakeConstSpan(carray)); >+ CheckType<absl::Span<const char>>(absl::MakeConstSpan(s)); >+ CheckType<absl::Span<const char>>(absl::MakeConstSpan(cs)); >+} >+ >+TEST(IntSpan, Equality) { >+ const int arr1[] = {1, 2, 3, 4, 5}; >+ int arr2[] = {1, 2, 3, 4, 5}; >+ std::vector<int> vec1(std::begin(arr1), std::end(arr1)); >+ std::vector<int> vec2 = vec1; >+ std::vector<int> other_vec = {2, 4, 6, 8, 10}; >+ // These two slices are from different vectors, but have the same size and >+ // have the same elements (right now). They should compare equal. Test both >+ // == and !=. >+ const absl::Span<const int> from1 = vec1; >+ const absl::Span<const int> from2 = vec2; >+ EXPECT_EQ(from1, from1); >+ EXPECT_FALSE(from1 != from1); >+ EXPECT_EQ(from1, from2); >+ EXPECT_FALSE(from1 != from2); >+ >+ // These two slices have different underlying vector values. They should be >+ // considered not equal. Test both == and !=. >+ const absl::Span<const int> from_other = other_vec; >+ EXPECT_NE(from1, from_other); >+ EXPECT_FALSE(from1 == from_other); >+ >+ // Comparison between a vector and its slice should be equal. And vice-versa. >+ // This ensures implicit conversion to Span works on both sides of ==. >+ EXPECT_EQ(vec1, from1); >+ EXPECT_FALSE(vec1 != from1); >+ EXPECT_EQ(from1, vec1); >+ EXPECT_FALSE(from1 != vec1); >+ >+ // This verifies that absl::Span<T> can be compared freely with >+ // absl::Span<const T>. >+ const absl::Span<int> mutable_from1(vec1); >+ const absl::Span<int> mutable_from2(vec2); >+ EXPECT_EQ(from1, mutable_from1); >+ EXPECT_EQ(mutable_from1, from1); >+ EXPECT_EQ(mutable_from1, mutable_from2); >+ EXPECT_EQ(mutable_from2, mutable_from1); >+ >+ // Comparison between a vector and its slice should be equal for mutable >+ // Spans as well. >+ EXPECT_EQ(vec1, mutable_from1); >+ EXPECT_FALSE(vec1 != mutable_from1); >+ EXPECT_EQ(mutable_from1, vec1); >+ EXPECT_FALSE(mutable_from1 != vec1); >+ >+ // Comparison between convertible-to-Span-of-const and Span-of-mutable. Arrays >+ // are used because they're the only value type which converts to a >+ // Span-of-mutable. EXPECT_TRUE is used instead of EXPECT_EQ to avoid >+ // array-to-pointer decay. >+ EXPECT_TRUE(arr1 == mutable_from1); >+ EXPECT_FALSE(arr1 != mutable_from1); >+ EXPECT_TRUE(mutable_from1 == arr1); >+ EXPECT_FALSE(mutable_from1 != arr1); >+ >+ // Comparison between convertible-to-Span-of-mutable and Span-of-const >+ EXPECT_TRUE(arr2 == from1); >+ EXPECT_FALSE(arr2 != from1); >+ EXPECT_TRUE(from1 == arr2); >+ EXPECT_FALSE(from1 != arr2); >+ >+ // With a different size, the array slices should not be equal. >+ EXPECT_NE(from1, absl::Span<const int>(from1).subspan(0, from1.size() - 1)); >+ >+ // With different contents, the array slices should not be equal. >+ ++vec2.back(); >+ EXPECT_NE(from1, from2); >+} >+ >+class IntSpanOrderComparisonTest : public testing::Test { >+ public: >+ IntSpanOrderComparisonTest() >+ : arr_before_{1, 2, 3}, >+ arr_after_{1, 2, 4}, >+ carr_after_{1, 2, 4}, >+ vec_before_(std::begin(arr_before_), std::end(arr_before_)), >+ vec_after_(std::begin(arr_after_), std::end(arr_after_)), >+ before_(vec_before_), >+ after_(vec_after_), >+ cbefore_(vec_before_), >+ cafter_(vec_after_) {} >+ >+ protected: >+ int arr_before_[3], arr_after_[3]; >+ const int carr_after_[3]; >+ std::vector<int> vec_before_, vec_after_; >+ absl::Span<int> before_, after_; >+ absl::Span<const int> cbefore_, cafter_; >+}; >+ >+TEST_F(IntSpanOrderComparisonTest, CompareSpans) { >+ EXPECT_TRUE(cbefore_ < cafter_); >+ EXPECT_TRUE(cbefore_ <= cafter_); >+ EXPECT_TRUE(cafter_ > cbefore_); >+ EXPECT_TRUE(cafter_ >= cbefore_); >+ >+ EXPECT_FALSE(cbefore_ > cafter_); >+ EXPECT_FALSE(cafter_ < cbefore_); >+ >+ EXPECT_TRUE(before_ < after_); >+ EXPECT_TRUE(before_ <= after_); >+ EXPECT_TRUE(after_ > before_); >+ EXPECT_TRUE(after_ >= before_); >+ >+ EXPECT_FALSE(before_ > after_); >+ EXPECT_FALSE(after_ < before_); >+ >+ EXPECT_TRUE(cbefore_ < after_); >+ EXPECT_TRUE(cbefore_ <= after_); >+ EXPECT_TRUE(after_ > cbefore_); >+ EXPECT_TRUE(after_ >= cbefore_); >+ >+ EXPECT_FALSE(cbefore_ > after_); >+ EXPECT_FALSE(after_ < cbefore_); >+} >+ >+TEST_F(IntSpanOrderComparisonTest, SpanOfConstAndContainer) { >+ EXPECT_TRUE(cbefore_ < vec_after_); >+ EXPECT_TRUE(cbefore_ <= vec_after_); >+ EXPECT_TRUE(vec_after_ > cbefore_); >+ EXPECT_TRUE(vec_after_ >= cbefore_); >+ >+ EXPECT_FALSE(cbefore_ > vec_after_); >+ EXPECT_FALSE(vec_after_ < cbefore_); >+ >+ EXPECT_TRUE(arr_before_ < cafter_); >+ EXPECT_TRUE(arr_before_ <= cafter_); >+ EXPECT_TRUE(cafter_ > arr_before_); >+ EXPECT_TRUE(cafter_ >= arr_before_); >+ >+ EXPECT_FALSE(arr_before_ > cafter_); >+ EXPECT_FALSE(cafter_ < arr_before_); >+} >+ >+TEST_F(IntSpanOrderComparisonTest, SpanOfMutableAndContainer) { >+ EXPECT_TRUE(vec_before_ < after_); >+ EXPECT_TRUE(vec_before_ <= after_); >+ EXPECT_TRUE(after_ > vec_before_); >+ EXPECT_TRUE(after_ >= vec_before_); >+ >+ EXPECT_FALSE(vec_before_ > after_); >+ EXPECT_FALSE(after_ < vec_before_); >+ >+ EXPECT_TRUE(before_ < carr_after_); >+ EXPECT_TRUE(before_ <= carr_after_); >+ EXPECT_TRUE(carr_after_ > before_); >+ EXPECT_TRUE(carr_after_ >= before_); >+ >+ EXPECT_FALSE(before_ > carr_after_); >+ EXPECT_FALSE(carr_after_ < before_); >+} >+ >+TEST_F(IntSpanOrderComparisonTest, EqualSpans) { >+ EXPECT_FALSE(before_ < before_); >+ EXPECT_TRUE(before_ <= before_); >+ EXPECT_FALSE(before_ > before_); >+ EXPECT_TRUE(before_ >= before_); >+} >+ >+TEST_F(IntSpanOrderComparisonTest, Subspans) { >+ auto subspan = before_.subspan(0, 1); >+ EXPECT_TRUE(subspan < before_); >+ EXPECT_TRUE(subspan <= before_); >+ EXPECT_TRUE(before_ > subspan); >+ EXPECT_TRUE(before_ >= subspan); >+ >+ EXPECT_FALSE(subspan > before_); >+ EXPECT_FALSE(before_ < subspan); >+} >+ >+TEST_F(IntSpanOrderComparisonTest, EmptySpans) { >+ absl::Span<int> empty; >+ EXPECT_FALSE(empty < empty); >+ EXPECT_TRUE(empty <= empty); >+ EXPECT_FALSE(empty > empty); >+ EXPECT_TRUE(empty >= empty); >+ >+ EXPECT_TRUE(empty < before_); >+ EXPECT_TRUE(empty <= before_); >+ EXPECT_TRUE(before_ > empty); >+ EXPECT_TRUE(before_ >= empty); >+ >+ EXPECT_FALSE(empty > before_); >+ EXPECT_FALSE(before_ < empty); >+} >+ >+TEST(IntSpan, ExposesContainerTypesAndConsts) { >+ absl::Span<int> slice; >+ CheckType<absl::Span<int>::iterator>(slice.begin()); >+ EXPECT_TRUE((std::is_convertible<decltype(slice.begin()), >+ absl::Span<int>::const_iterator>::value)); >+ CheckType<absl::Span<int>::const_iterator>(slice.cbegin()); >+ EXPECT_TRUE((std::is_convertible<decltype(slice.end()), >+ absl::Span<int>::const_iterator>::value)); >+ CheckType<absl::Span<int>::const_iterator>(slice.cend()); >+ CheckType<absl::Span<int>::reverse_iterator>(slice.rend()); >+ EXPECT_TRUE( >+ (std::is_convertible<decltype(slice.rend()), >+ absl::Span<int>::const_reverse_iterator>::value)); >+ CheckType<absl::Span<int>::const_reverse_iterator>(slice.crend()); >+ testing::StaticAssertTypeEq<int, absl::Span<int>::value_type>(); >+ testing::StaticAssertTypeEq<int, absl::Span<const int>::value_type>(); >+ testing::StaticAssertTypeEq<int*, absl::Span<int>::pointer>(); >+ testing::StaticAssertTypeEq<const int*, absl::Span<const int>::pointer>(); >+ testing::StaticAssertTypeEq<int&, absl::Span<int>::reference>(); >+ testing::StaticAssertTypeEq<const int&, absl::Span<const int>::reference>(); >+ testing::StaticAssertTypeEq<const int&, absl::Span<int>::const_reference>(); >+ testing::StaticAssertTypeEq<const int&, >+ absl::Span<const int>::const_reference>(); >+ EXPECT_EQ(static_cast<absl::Span<int>::size_type>(-1), absl::Span<int>::npos); >+} >+ >+TEST(IntSpan, IteratorsAndReferences) { >+ auto accept_pointer = [](int*) {}; >+ auto accept_reference = [](int&) {}; >+ auto accept_iterator = [](absl::Span<int>::iterator) {}; >+ auto accept_const_iterator = [](absl::Span<int>::const_iterator) {}; >+ auto accept_reverse_iterator = [](absl::Span<int>::reverse_iterator) {}; >+ auto accept_const_reverse_iterator = >+ [](absl::Span<int>::const_reverse_iterator) {}; >+ >+ int a[1]; >+ absl::Span<int> s = a; >+ >+ accept_pointer(s.data()); >+ accept_iterator(s.begin()); >+ accept_const_iterator(s.begin()); >+ accept_const_iterator(s.cbegin()); >+ accept_iterator(s.end()); >+ accept_const_iterator(s.end()); >+ accept_const_iterator(s.cend()); >+ accept_reverse_iterator(s.rbegin()); >+ accept_const_reverse_iterator(s.rbegin()); >+ accept_const_reverse_iterator(s.crbegin()); >+ accept_reverse_iterator(s.rend()); >+ accept_const_reverse_iterator(s.rend()); >+ accept_const_reverse_iterator(s.crend()); >+ >+ accept_reference(s[0]); >+ accept_reference(s.at(0)); >+ accept_reference(s.front()); >+ accept_reference(s.back()); >+} >+ >+TEST(IntSpan, IteratorsAndReferences_Const) { >+ auto accept_pointer = [](int*) {}; >+ auto accept_reference = [](int&) {}; >+ auto accept_iterator = [](absl::Span<int>::iterator) {}; >+ auto accept_const_iterator = [](absl::Span<int>::const_iterator) {}; >+ auto accept_reverse_iterator = [](absl::Span<int>::reverse_iterator) {}; >+ auto accept_const_reverse_iterator = >+ [](absl::Span<int>::const_reverse_iterator) {}; >+ >+ int a[1]; >+ const absl::Span<int> s = a; >+ >+ accept_pointer(s.data()); >+ accept_iterator(s.begin()); >+ accept_const_iterator(s.begin()); >+ accept_const_iterator(s.cbegin()); >+ accept_iterator(s.end()); >+ accept_const_iterator(s.end()); >+ accept_const_iterator(s.cend()); >+ accept_reverse_iterator(s.rbegin()); >+ accept_const_reverse_iterator(s.rbegin()); >+ accept_const_reverse_iterator(s.crbegin()); >+ accept_reverse_iterator(s.rend()); >+ accept_const_reverse_iterator(s.rend()); >+ accept_const_reverse_iterator(s.crend()); >+ >+ accept_reference(s[0]); >+ accept_reference(s.at(0)); >+ accept_reference(s.front()); >+ accept_reference(s.back()); >+} >+ >+TEST(IntSpan, NoexceptTest) { >+ int a[] = {1, 2, 3}; >+ std::vector<int> v; >+ EXPECT_TRUE(noexcept(absl::Span<const int>())); >+ EXPECT_TRUE(noexcept(absl::Span<const int>(a, 2))); >+ EXPECT_TRUE(noexcept(absl::Span<const int>(a))); >+ EXPECT_TRUE(noexcept(absl::Span<const int>(v))); >+ EXPECT_TRUE(noexcept(absl::Span<int>(v))); >+ EXPECT_TRUE(noexcept(absl::Span<const int>({1, 2, 3}))); >+ EXPECT_TRUE(noexcept(absl::MakeSpan(v))); >+ EXPECT_TRUE(noexcept(absl::MakeSpan(a))); >+ EXPECT_TRUE(noexcept(absl::MakeSpan(a, 2))); >+ EXPECT_TRUE(noexcept(absl::MakeSpan(a, a + 1))); >+ EXPECT_TRUE(noexcept(absl::MakeConstSpan(v))); >+ EXPECT_TRUE(noexcept(absl::MakeConstSpan(a))); >+ EXPECT_TRUE(noexcept(absl::MakeConstSpan(a, 2))); >+ EXPECT_TRUE(noexcept(absl::MakeConstSpan(a, a + 1))); >+ >+ absl::Span<int> s(v); >+ EXPECT_TRUE(noexcept(s.data())); >+ EXPECT_TRUE(noexcept(s.size())); >+ EXPECT_TRUE(noexcept(s.length())); >+ EXPECT_TRUE(noexcept(s.empty())); >+ EXPECT_TRUE(noexcept(s[0])); >+ EXPECT_TRUE(noexcept(s.front())); >+ EXPECT_TRUE(noexcept(s.back())); >+ EXPECT_TRUE(noexcept(s.begin())); >+ EXPECT_TRUE(noexcept(s.cbegin())); >+ EXPECT_TRUE(noexcept(s.end())); >+ EXPECT_TRUE(noexcept(s.cend())); >+ EXPECT_TRUE(noexcept(s.rbegin())); >+ EXPECT_TRUE(noexcept(s.crbegin())); >+ EXPECT_TRUE(noexcept(s.rend())); >+ EXPECT_TRUE(noexcept(s.crend())); >+ EXPECT_TRUE(noexcept(s.remove_prefix(0))); >+ EXPECT_TRUE(noexcept(s.remove_suffix(0))); >+} >+ >+// ConstexprTester exercises expressions in a constexpr context. Simply placing >+// the expression in a constexpr function is not enough, as some compilers will >+// simply compile the constexpr function as runtime code. Using template >+// parameters forces compile-time execution. >+template <int i> >+struct ConstexprTester {}; >+ >+#define ABSL_TEST_CONSTEXPR(expr) \ >+ do { \ >+ ABSL_ATTRIBUTE_UNUSED ConstexprTester<(expr, 1)> t; \ >+ } while (0) >+ >+struct ContainerWithConstexprMethods { >+ constexpr int size() const { return 1; } >+ constexpr const int* data() const { return &i; } >+ const int i; >+}; >+ >+TEST(ConstIntSpan, ConstexprTest) { >+ static constexpr int a[] = {1, 2, 3}; >+ static constexpr int sized_arr[2] = {1, 2}; >+ static constexpr ContainerWithConstexprMethods c{1}; >+ ABSL_TEST_CONSTEXPR(absl::Span<const int>()); >+ ABSL_TEST_CONSTEXPR(absl::Span<const int>(a, 2)); >+ ABSL_TEST_CONSTEXPR(absl::Span<const int>(sized_arr)); >+ ABSL_TEST_CONSTEXPR(absl::Span<const int>(c)); >+ ABSL_TEST_CONSTEXPR(absl::MakeSpan(&a[0], 1)); >+ ABSL_TEST_CONSTEXPR(absl::MakeSpan(c)); >+ ABSL_TEST_CONSTEXPR(absl::MakeSpan(a)); >+ ABSL_TEST_CONSTEXPR(absl::MakeConstSpan(&a[0], 1)); >+ ABSL_TEST_CONSTEXPR(absl::MakeConstSpan(c)); >+ ABSL_TEST_CONSTEXPR(absl::MakeConstSpan(a)); >+ >+ constexpr absl::Span<const int> span = c; >+ ABSL_TEST_CONSTEXPR(span.data()); >+ ABSL_TEST_CONSTEXPR(span.size()); >+ ABSL_TEST_CONSTEXPR(span.length()); >+ ABSL_TEST_CONSTEXPR(span.empty()); >+ ABSL_TEST_CONSTEXPR(span.begin()); >+ ABSL_TEST_CONSTEXPR(span.cbegin()); >+ ABSL_TEST_CONSTEXPR(span.subspan(0, 0)); >+ ABSL_TEST_CONSTEXPR(span[0]); >+} >+ >+struct BigStruct { >+ char bytes[10000]; >+}; >+ >+TEST(Span, SpanSize) { >+ EXPECT_LE(sizeof(absl::Span<int>), 2 * sizeof(void*)); >+ EXPECT_LE(sizeof(absl::Span<BigStruct>), 2 * sizeof(void*)); >+} >+ >+} // namespace >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant.h >new file mode 100644 >index 0000000000000000000000000000000000000000..17e0634de03746433674e99ec077b6f773e8b2d9 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant.h >@@ -0,0 +1,849 @@ >+// 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. >+// >+// ----------------------------------------------------------------------------- >+// variant.h >+// ----------------------------------------------------------------------------- >+// >+// This header file defines an `absl::variant` type for holding a type-safe >+// value of some prescribed set of types (noted as alternative types), and >+// associated functions for managing variants. >+// >+// The `absl::variant` type is a form of type-safe union. An `absl::variant` >+// should always hold a value of one of its alternative types (except in the >+// "valueless by exception state" -- see below). A default-constructed >+// `absl::variant` will hold the value of its first alternative type, provided >+// it is default-constructable. >+// >+// In exceptional cases due to error, an `absl::variant` can hold no >+// value (known as a "valueless by exception" state), though this is not the >+// norm. >+// >+// As with `absl::optional`, an `absl::variant` -- when it holds a value -- >+// allocates a value of that type directly within the `variant` itself; it >+// cannot hold a reference, array, or the type `void`; it can, however, hold a >+// pointer to externally managed memory. >+// >+// `absl::variant` is a C++11 compatible version of the C++17 `std::variant` >+// abstraction and is designed to be a drop-in replacement for code compliant >+// with C++17. >+ >+#ifndef ABSL_TYPES_VARIANT_H_ >+#define ABSL_TYPES_VARIANT_H_ >+ >+#include "absl/base/config.h" >+#include "absl/utility/utility.h" >+ >+#ifdef ABSL_HAVE_STD_VARIANT >+ >+#include <variant> >+ >+namespace absl { >+using std::bad_variant_access; >+using std::get; >+using std::get_if; >+using std::holds_alternative; >+using std::monostate; >+using std::variant; >+using std::variant_alternative; >+using std::variant_alternative_t; >+using std::variant_npos; >+using std::variant_size; >+using std::variant_size_v; >+using std::visit; >+} // namespace absl >+ >+#else // ABSL_HAVE_STD_VARIANT >+ >+#include <functional> >+#include <new> >+#include <type_traits> >+#include <utility> >+ >+#include "absl/base/macros.h" >+#include "absl/base/port.h" >+#include "absl/meta/type_traits.h" >+#include "absl/types/internal/variant.h" >+ >+namespace absl { >+ >+// ----------------------------------------------------------------------------- >+// absl::variant >+// ----------------------------------------------------------------------------- >+// >+// An 'absl::variant` type is a form of type-safe union. An `absl::variant` -- >+// except in exceptional cases -- always holds a value of one of its alternative >+// types. >+// >+// Example: >+// >+// // Construct a variant that holds either an integer or a std::string and >+// // assign it to a std::string. >+// absl::variant<int, std::string> v = std::string("abc"); >+// >+// // A default-contructed variant will hold a value-initialized value of >+// // the first alternative type. >+// auto a = absl::variant<int, std::string>(); // Holds an int of value '0'. >+// >+// // variants are assignable. >+// >+// // copy assignment >+// auto v1 = absl::variant<int, std::string>("abc"); >+// auto v2 = absl::variant<int, std::string>(10); >+// v2 = v1; // copy assign >+// >+// // move assignment >+// auto v1 = absl::variant<int, std::string>("abc"); >+// v1 = absl::variant<int, std::string>(10); >+// >+// // assignment through type conversion >+// a = 128; // variant contains int >+// a = "128"; // variant contains std::string >+// >+// An `absl::variant` holding a value of one of its alternative types `T` holds >+// an allocation of `T` directly within the variant itself. An `absl::variant` >+// is not allowed to allocate additional storage, such as dynamic memory, to >+// allocate the contained value. The contained value shall be allocated in a >+// region of the variant storage suitably aligned for all alternative types. >+template <typename... Ts> >+class variant; >+ >+// swap() >+// >+// Swaps two `absl::variant` values. This function is equivalent to `v.swap(w)` >+// where `v` and `w` are `absl::variant` types. >+// >+// Note that this function requires all alternative types to be both swappable >+// and move-constructible, because any two variants may refer to either the same >+// type (in which case, they will be swapped) or to two different types (in >+// which case the values will need to be moved). >+// >+template <typename... Ts> >+void swap(variant<Ts...>& v, variant<Ts...>& w) noexcept(noexcept(v.swap(w))) { >+ v.swap(w); >+} >+ >+// variant_size >+// >+// Returns the number of alterative types available for a given `absl::variant` >+// type as a compile-time constant expression. As this is a class template, it >+// is not generally useful for accessing the number of alternative types of >+// any given `absl::variant` instance. >+// >+// Example: >+// >+// auto a = absl::variant<int, std::string>; >+// constexpr int num_types = >+// absl::variant_size<absl::variant<int, std::string>>(); >+// >+// // You can also use the member constant `value`. >+// constexpr int num_types = >+// absl::variant_size<absl::variant<int, std::string>>::value; >+// >+// // `absl::variant_size` is more valuable for use in generic code: >+// template <typename Variant> >+// constexpr bool IsVariantMultivalue() { >+// return absl::variant_size<Variant>() > 1; >+// } >+// >+// Note that the set of cv-qualified specializations of `variant_size` are >+// provided to ensure that those specializations compile (especially when passed >+// within template logic). >+template <class T> >+struct variant_size; >+ >+template <class... Ts> >+struct variant_size<variant<Ts...>> >+ : std::integral_constant<std::size_t, sizeof...(Ts)> {}; >+ >+// Specialization of `variant_size` for const qualified variants. >+template <class T> >+struct variant_size<const T> : variant_size<T>::type {}; >+ >+// Specialization of `variant_size` for volatile qualified variants. >+template <class T> >+struct variant_size<volatile T> : variant_size<T>::type {}; >+ >+// Specialization of `variant_size` for const volatile qualified variants. >+template <class T> >+struct variant_size<const volatile T> : variant_size<T>::type {}; >+ >+// variant_alternative >+// >+// Returns the alternative type for a given `absl::variant` at the passed >+// index value as a compile-time constant expression. As this is a class >+// template resulting in a type, it is not useful for access of the run-time >+// value of any given `absl::variant` variable. >+// >+// Example: >+// >+// // The type of the 0th alternative is "int". >+// using alternative_type_0 >+// = absl::variant_alternative<0, absl::variant<int, std::string>>::type; >+// >+// static_assert(std::is_same<alternative_type_0, int>::value, ""); >+// >+// // `absl::variant_alternative` is more valuable for use in generic code: >+// template <typename Variant> >+// constexpr bool IsFirstElementTrivial() { >+// return std::is_trivial_v<variant_alternative<0, Variant>::type>; >+// } >+// >+// Note that the set of cv-qualified specializations of `variant_alternative` >+// are provided to ensure that those specializations compile (especially when >+// passed within template logic). >+template <std::size_t I, class T> >+struct variant_alternative; >+ >+template <std::size_t I, class... Types> >+struct variant_alternative<I, variant<Types...>> { >+ using type = >+ variant_internal::VariantAlternativeSfinaeT<I, variant<Types...>>; >+}; >+ >+// Specialization of `variant_alternative` for const qualified variants. >+template <std::size_t I, class T> >+struct variant_alternative<I, const T> { >+ using type = const typename variant_alternative<I, T>::type; >+}; >+ >+// Specialization of `variant_alternative` for volatile qualified variants. >+template <std::size_t I, class T> >+struct variant_alternative<I, volatile T> { >+ using type = volatile typename variant_alternative<I, T>::type; >+}; >+ >+// Specialization of `variant_alternative` for const volatile qualified >+// variants. >+template <std::size_t I, class T> >+struct variant_alternative<I, const volatile T> { >+ using type = const volatile typename variant_alternative<I, T>::type; >+}; >+ >+// Template type alias for variant_alternative<I, T>::type. >+// >+// Example: >+// >+// using alternative_type_0 >+// = absl::variant_alternative_t<0, absl::variant<int, std::string>>; >+// static_assert(std::is_same<alternative_type_0, int>::value, ""); >+template <std::size_t I, class T> >+using variant_alternative_t = typename variant_alternative<I, T>::type; >+ >+// holds_alternative() >+// >+// Checks whether the given variant currently holds a given alternative type, >+// returning `true` if so. >+// >+// Example: >+// >+// absl::variant<int, std::string> foo = 42; >+// if (absl::holds_alternative<int>(foo)) { >+// std::cout << "The variant holds an integer"; >+// } >+template <class T, class... Types> >+constexpr bool holds_alternative(const variant<Types...>& v) noexcept { >+ static_assert( >+ variant_internal::UnambiguousIndexOfImpl<variant<Types...>, T, >+ 0>::value != sizeof...(Types), >+ "The type T must occur exactly once in Types..."); >+ return v.index() == >+ variant_internal::UnambiguousIndexOf<variant<Types...>, T>::value; >+} >+ >+// get() >+// >+// Returns a reference to the value currently within a given variant, using >+// either a unique alternative type amongst the variant's set of alternative >+// types, or the variant's index value. Attempting to get a variant's value >+// using a type that is not unique within the variant's set of alternative types >+// is a compile-time error. If the index of the alternative being specified is >+// different from the index of the alternative that is currently stored, throws >+// `absl::bad_variant_access`. >+// >+// Example: >+// >+// auto a = absl::variant<int, std::string>; >+// >+// // Get the value by type (if unique). >+// int i = absl::get<int>(a); >+// >+// auto b = absl::variant<int, int>; >+// >+// // Getting the value by a type that is not unique is ill-formed. >+// int j = absl::get<int>(b); // Compile Error! >+// >+// // Getting value by index not ambiguous and allowed. >+// int k = absl::get<1>(b); >+ >+// Overload for getting a variant's lvalue by type. >+template <class T, class... Types> >+constexpr T& get(variant<Types...>& v) { // NOLINT >+ return variant_internal::VariantCoreAccess::CheckedAccess< >+ variant_internal::IndexOf<T, Types...>::value>(v); >+} >+ >+// Overload for getting a variant's rvalue by type. >+// Note: `absl::move()` is required to allow use of constexpr in C++11. >+template <class T, class... Types> >+constexpr T&& get(variant<Types...>&& v) { >+ return variant_internal::VariantCoreAccess::CheckedAccess< >+ variant_internal::IndexOf<T, Types...>::value>(absl::move(v)); >+} >+ >+// Overload for getting a variant's const lvalue by type. >+template <class T, class... Types> >+constexpr const T& get(const variant<Types...>& v) { >+ return variant_internal::VariantCoreAccess::CheckedAccess< >+ variant_internal::IndexOf<T, Types...>::value>(v); >+} >+ >+// Overload for getting a variant's const rvalue by type. >+// Note: `absl::move()` is required to allow use of constexpr in C++11. >+template <class T, class... Types> >+constexpr const T&& get(const variant<Types...>&& v) { >+ return variant_internal::VariantCoreAccess::CheckedAccess< >+ variant_internal::IndexOf<T, Types...>::value>(absl::move(v)); >+} >+ >+// Overload for getting a variant's lvalue by index. >+template <std::size_t I, class... Types> >+constexpr variant_alternative_t<I, variant<Types...>>& get( >+ variant<Types...>& v) { // NOLINT >+ return variant_internal::VariantCoreAccess::CheckedAccess<I>(v); >+} >+ >+// Overload for getting a variant's rvalue by index. >+// Note: `absl::move()` is required to allow use of constexpr in C++11. >+template <std::size_t I, class... Types> >+constexpr variant_alternative_t<I, variant<Types...>>&& get( >+ variant<Types...>&& v) { >+ return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v)); >+} >+ >+// Overload for getting a variant's const lvalue by index. >+template <std::size_t I, class... Types> >+constexpr const variant_alternative_t<I, variant<Types...>>& get( >+ const variant<Types...>& v) { >+ return variant_internal::VariantCoreAccess::CheckedAccess<I>(v); >+} >+ >+// Overload for getting a variant's const rvalue by index. >+// Note: `absl::move()` is required to allow use of constexpr in C++11. >+template <std::size_t I, class... Types> >+constexpr const variant_alternative_t<I, variant<Types...>>&& get( >+ const variant<Types...>&& v) { >+ return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v)); >+} >+ >+// get_if() >+// >+// Returns a pointer to the value currently stored within a given variant, if >+// present, using either a unique alternative type amongst the variant's set of >+// alternative types, or the variant's index value. If such a value does not >+// exist, returns `nullptr`. >+// >+// As with `get`, attempting to get a variant's value using a type that is not >+// unique within the variant's set of alternative types is a compile-time error. >+ >+// Overload for getting a pointer to the value stored in the given variant by >+// index. >+template <std::size_t I, class... Types> >+constexpr absl::add_pointer_t<variant_alternative_t<I, variant<Types...>>> >+get_if(variant<Types...>* v) noexcept { >+ return (v != nullptr && v->index() == I) >+ ? std::addressof( >+ variant_internal::VariantCoreAccess::Access<I>(*v)) >+ : nullptr; >+} >+ >+// Overload for getting a pointer to the const value stored in the given >+// variant by index. >+template <std::size_t I, class... Types> >+constexpr absl::add_pointer_t<const variant_alternative_t<I, variant<Types...>>> >+get_if(const variant<Types...>* v) noexcept { >+ return (v != nullptr && v->index() == I) >+ ? std::addressof( >+ variant_internal::VariantCoreAccess::Access<I>(*v)) >+ : nullptr; >+} >+ >+// Overload for getting a pointer to the value stored in the given variant by >+// type. >+template <class T, class... Types> >+constexpr absl::add_pointer_t<T> get_if(variant<Types...>* v) noexcept { >+ return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v); >+} >+ >+// Overload for getting a pointer to the const value stored in the given variant >+// by type. >+template <class T, class... Types> >+constexpr absl::add_pointer_t<const T> get_if( >+ const variant<Types...>* v) noexcept { >+ return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v); >+} >+ >+// visit() >+// >+// Calls a provided functor on a given set of variants. `absl::visit()` is >+// commonly used to conditionally inspect the state of a given variant (or set >+// of variants). >+// Requires: The expression in the Effects: element shall be a valid expression >+// of the same type and value category, for all combinations of alternative >+// types of all variants. Otherwise, the program is ill-formed. >+// >+// Example: >+// >+// // Define a visitor functor >+// struct GetVariant { >+// template<typename T> >+// void operator()(const T& i) const { >+// std::cout << "The variant's value is: " << i; >+// } >+// }; >+// >+// // Declare our variant, and call `absl::visit()` on it. >+// std::variant<int, std::string> foo = std::string("foo"); >+// GetVariant visitor; >+// std::visit(visitor, foo); // Prints `The variant's value is: foo' >+template <typename Visitor, typename... Variants> >+variant_internal::VisitResult<Visitor, Variants...> visit(Visitor&& vis, >+ Variants&&... vars) { >+ return variant_internal:: >+ VisitIndices<variant_size<absl::decay_t<Variants> >::value...>::Run( >+ variant_internal::PerformVisitation<Visitor, Variants...>{ >+ std::forward_as_tuple(absl::forward<Variants>(vars)...), >+ absl::forward<Visitor>(vis)}, >+ vars.index()...); >+} >+ >+// monostate >+// >+// The monostate class serves as a first alternative type for a variant for >+// which the first variant type is otherwise not default-constructible. >+struct monostate {}; >+ >+// `absl::monostate` Relational Operators >+ >+constexpr bool operator<(monostate, monostate) noexcept { return false; } >+constexpr bool operator>(monostate, monostate) noexcept { return false; } >+constexpr bool operator<=(monostate, monostate) noexcept { return true; } >+constexpr bool operator>=(monostate, monostate) noexcept { return true; } >+constexpr bool operator==(monostate, monostate) noexcept { return true; } >+constexpr bool operator!=(monostate, monostate) noexcept { return false; } >+ >+ >+//------------------------------------------------------------------------------ >+// `absl::variant` Template Definition >+//------------------------------------------------------------------------------ >+template <typename T0, typename... Tn> >+class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> { >+ static_assert(absl::conjunction<std::is_object<T0>, >+ std::is_object<Tn>...>::value, >+ "Attempted to instantiate a variant containing a non-object " >+ "type."); >+ // Intentionally not qualifing `negation` with `absl::` to work around a bug >+ // in MSVC 2015 with inline namespace and variadic template. >+ static_assert(absl::conjunction<negation<std::is_array<T0> >, >+ negation<std::is_array<Tn> >...>::value, >+ "Attempted to instantiate a variant containing an array type."); >+ static_assert(absl::conjunction<std::is_nothrow_destructible<T0>, >+ std::is_nothrow_destructible<Tn>...>::value, >+ "Attempted to instantiate a variant containing a non-nothrow " >+ "destructible type."); >+ >+ friend struct variant_internal::VariantCoreAccess; >+ >+ private: >+ using Base = variant_internal::VariantBase<T0, Tn...>; >+ >+ public: >+ // Constructors >+ >+ // Constructs a variant holding a default-initialized value of the first >+ // alternative type. >+ constexpr variant() /*noexcept(see 111above)*/ = default; >+ >+ // Copy constructor, standard semantics >+ variant(const variant& other) = default; >+ >+ // Move constructor, standard semantics >+ variant(variant&& other) /*noexcept(see above)*/ = default; >+ >+ // Constructs a variant of an alternative type specified by overload >+ // resolution of the provided forwarding arguments through >+ // direct-initialization. >+ // >+ // Note: If the selected constructor is a constexpr constructor, this >+ // constructor shall be a constexpr constructor. >+ // >+ // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html >+ // has been voted passed the design phase in the C++ standard meeting in Mar >+ // 2018. It will be implemented and integrated into `absl::variant`. >+ template < >+ class T, >+ std::size_t I = std::enable_if< >+ variant_internal::IsNeitherSelfNorInPlace<variant, >+ absl::decay_t<T>>::value, >+ variant_internal::IndexOfConstructedType<variant, T>>::type::value, >+ class Tj = absl::variant_alternative_t<I, variant>, >+ absl::enable_if_t<std::is_constructible<Tj, T>::value>* = >+ nullptr> >+ constexpr variant(T&& t) noexcept(std::is_nothrow_constructible<Tj, T>::value) >+ : Base(variant_internal::EmplaceTag<I>(), absl::forward<T>(t)) {} >+ >+ // Constructs a variant of an alternative type from the arguments through >+ // direct-initialization. >+ // >+ // Note: If the selected constructor is a constexpr constructor, this >+ // constructor shall be a constexpr constructor. >+ template <class T, class... Args, >+ typename std::enable_if<std::is_constructible< >+ variant_internal::UnambiguousTypeOfT<variant, T>, >+ Args...>::value>::type* = nullptr> >+ constexpr explicit variant(in_place_type_t<T>, Args&&... args) >+ : Base(variant_internal::EmplaceTag< >+ variant_internal::UnambiguousIndexOf<variant, T>::value>(), >+ absl::forward<Args>(args)...) {} >+ >+ // Constructs a variant of an alternative type from an initializer list >+ // and other arguments through direct-initialization. >+ // >+ // Note: If the selected constructor is a constexpr constructor, this >+ // constructor shall be a constexpr constructor. >+ template <class T, class U, class... Args, >+ typename std::enable_if<std::is_constructible< >+ variant_internal::UnambiguousTypeOfT<variant, T>, >+ std::initializer_list<U>&, Args...>::value>::type* = nullptr> >+ constexpr explicit variant(in_place_type_t<T>, std::initializer_list<U> il, >+ Args&&... args) >+ : Base(variant_internal::EmplaceTag< >+ variant_internal::UnambiguousIndexOf<variant, T>::value>(), >+ il, absl::forward<Args>(args)...) {} >+ >+ // Constructs a variant of an alternative type from a provided index, >+ // through value-initialization using the provided forwarded arguments. >+ template <std::size_t I, class... Args, >+ typename std::enable_if<std::is_constructible< >+ variant_internal::VariantAlternativeSfinaeT<I, variant>, >+ Args...>::value>::type* = nullptr> >+ constexpr explicit variant(in_place_index_t<I>, Args&&... args) >+ : Base(variant_internal::EmplaceTag<I>(), absl::forward<Args>(args)...) {} >+ >+ // Constructs a variant of an alternative type from a provided index, >+ // through value-initialization of an initializer list and the provided >+ // forwarded arguments. >+ template <std::size_t I, class U, class... Args, >+ typename std::enable_if<std::is_constructible< >+ variant_internal::VariantAlternativeSfinaeT<I, variant>, >+ std::initializer_list<U>&, Args...>::value>::type* = nullptr> >+ constexpr explicit variant(in_place_index_t<I>, std::initializer_list<U> il, >+ Args&&... args) >+ : Base(variant_internal::EmplaceTag<I>(), il, >+ absl::forward<Args>(args)...) {} >+ >+ // Destructors >+ >+ // Destroys the variant's currently contained value, provided that >+ // `absl::valueless_by_exception()` is false. >+ ~variant() = default; >+ >+ // Assignment Operators >+ >+ // Copy assignement operator >+ variant& operator=(const variant& other) = default; >+ >+ // Move assignment operator >+ variant& operator=(variant&& other) /*noexcept(see above)*/ = default; >+ >+ // Converting assignment operator >+ // >+ // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html >+ // has been voted passed the design phase in the C++ standard meeting in Mar >+ // 2018. It will be implemented and integrated into `absl::variant`. >+ template < >+ class T, >+ std::size_t I = std::enable_if< >+ !std::is_same<absl::decay_t<T>, variant>::value, >+ variant_internal::IndexOfConstructedType<variant, T>>::type::value, >+ class Tj = absl::variant_alternative_t<I, variant>, >+ typename std::enable_if<std::is_assignable<Tj&, T>::value && >+ std::is_constructible<Tj, T>::value>::type* = >+ nullptr> >+ variant& operator=(T&& t) noexcept( >+ std::is_nothrow_assignable<Tj&, T>::value&& >+ std::is_nothrow_constructible<Tj, T>::value) { >+ variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run( >+ variant_internal::VariantCoreAccess::MakeConversionAssignVisitor( >+ this, absl::forward<T>(t)), >+ index()); >+ >+ return *this; >+ } >+ >+ >+ // emplace() Functions >+ >+ // Constructs a value of the given alternative type T within the variant. >+ // >+ // Example: >+ // >+ // absl::variant<std::vector<int>, int, std::string> v; >+ // v.emplace<int>(99); >+ // v.emplace<std::string>("abc"); >+ template < >+ class T, class... Args, >+ typename std::enable_if<std::is_constructible< >+ absl::variant_alternative_t< >+ variant_internal::UnambiguousIndexOf<variant, T>::value, variant>, >+ Args...>::value>::type* = nullptr> >+ T& emplace(Args&&... args) { >+ return variant_internal::VariantCoreAccess::Replace< >+ variant_internal::UnambiguousIndexOf<variant, T>::value>( >+ this, absl::forward<Args>(args)...); >+ } >+ >+ // Constructs a value of the given alternative type T within the variant using >+ // an initializer list. >+ // >+ // Example: >+ // >+ // absl::variant<std::vector<int>, int, std::string> v; >+ // v.emplace<std::vector<int>>({0, 1, 2}); >+ template < >+ class T, class U, class... Args, >+ typename std::enable_if<std::is_constructible< >+ absl::variant_alternative_t< >+ variant_internal::UnambiguousIndexOf<variant, T>::value, variant>, >+ std::initializer_list<U>&, Args...>::value>::type* = nullptr> >+ T& emplace(std::initializer_list<U> il, Args&&... args) { >+ return variant_internal::VariantCoreAccess::Replace< >+ variant_internal::UnambiguousIndexOf<variant, T>::value>( >+ this, il, absl::forward<Args>(args)...); >+ } >+ >+ // Destroys the current value of the variant (provided that >+ // `absl::valueless_by_exception()` is false, and constructs a new value at >+ // the given index. >+ // >+ // Example: >+ // >+ // absl::variant<std::vector<int>, int, int> v; >+ // v.emplace<1>(99); >+ // v.emplace<2>(98); >+ // v.emplace<int>(99); // Won't compile. 'int' isn't a unique type. >+ template <std::size_t I, class... Args, >+ typename std::enable_if< >+ std::is_constructible<absl::variant_alternative_t<I, variant>, >+ Args...>::value>::type* = nullptr> >+ absl::variant_alternative_t<I, variant>& emplace(Args&&... args) { >+ return variant_internal::VariantCoreAccess::Replace<I>( >+ this, absl::forward<Args>(args)...); >+ } >+ >+ // Destroys the current value of the variant (provided that >+ // `absl::valueless_by_exception()` is false, and constructs a new value at >+ // the given index using an initializer list and the provided arguments. >+ // >+ // Example: >+ // >+ // absl::variant<std::vector<int>, int, int> v; >+ // v.emplace<0>({0, 1, 2}); >+ template <std::size_t I, class U, class... Args, >+ typename std::enable_if<std::is_constructible< >+ absl::variant_alternative_t<I, variant>, >+ std::initializer_list<U>&, Args...>::value>::type* = nullptr> >+ absl::variant_alternative_t<I, variant>& emplace(std::initializer_list<U> il, >+ Args&&... args) { >+ return variant_internal::VariantCoreAccess::Replace<I>( >+ this, il, absl::forward<Args>(args)...); >+ } >+ >+ // variant::valueless_by_exception() >+ // >+ // Returns false if and only if the variant currently holds a valid value. >+ constexpr bool valueless_by_exception() const noexcept { >+ return this->index_ == absl::variant_npos; >+ } >+ >+ // variant::index() >+ // >+ // Returns the index value of the variant's currently selected alternative >+ // type. >+ constexpr std::size_t index() const noexcept { return this->index_; } >+ >+ // variant::swap() >+ // >+ // Swaps the values of two variant objects. >+ // >+ // TODO(calabrese) >+ // `variant::swap()` and `swap()` rely on `std::is_(nothrow)_swappable()` >+ // which is introduced in C++17. So we assume `is_swappable()` is always >+ // true and `is_nothrow_swappable()` is same as `std::is_trivial()`. >+ void swap(variant& rhs) noexcept( >+ absl::conjunction<std::is_trivial<T0>, std::is_trivial<Tn>...>::value) { >+ return variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run( >+ variant_internal::Swap<T0, Tn...>{this, &rhs}, rhs.index()); >+ } >+}; >+ >+// We need a valid declaration of variant<> for SFINAE and overload resolution >+// to work properly above, but we don't need a full declaration since this type >+// will never be constructed. This declaration, though incomplete, suffices. >+template <> >+class variant<>; >+ >+//------------------------------------------------------------------------------ >+// Relational Operators >+//------------------------------------------------------------------------------ >+// >+// If neither operand is in the `variant::valueless_by_exception` state: >+// >+// * If the index of both variants is the same, the relational operator >+// returns the result of the corresponding relational operator for the >+// corresponding alternative type. >+// * If the index of both variants is not the same, the relational operator >+// returns the result of that operation applied to the value of the left >+// operand's index and the value of the right operand's index. >+// * If at least one operand is in the valueless_by_exception state: >+// - A variant in the valueless_by_exception state is only considered equal >+// to another variant in the valueless_by_exception state. >+// - If exactly one operand is in the valueless_by_exception state, the >+// variant in the valueless_by_exception state is less than the variant >+// that is not in the valueless_by_exception state. >+// >+// Note: The value 1 is added to each index in the relational comparisons such >+// that the index corresponding to the valueless_by_exception state wraps around >+// to 0 (the lowest value for the index type), and the remaining indices stay in >+// the same relative order. >+ >+// Equal-to operator >+template <typename... Types> >+constexpr variant_internal::RequireAllHaveEqualT<Types...> operator==( >+ const variant<Types...>& a, const variant<Types...>& b) { >+ return (a.index() == b.index()) && >+ variant_internal::VisitIndices<sizeof...(Types)>::Run( >+ variant_internal::EqualsOp<Types...>{&a, &b}, a.index()); >+} >+ >+// Not equal operator >+template <typename... Types> >+constexpr variant_internal::RequireAllHaveNotEqualT<Types...> operator!=( >+ const variant<Types...>& a, const variant<Types...>& b) { >+ return (a.index() != b.index()) || >+ variant_internal::VisitIndices<sizeof...(Types)>::Run( >+ variant_internal::NotEqualsOp<Types...>{&a, &b}, a.index()); >+} >+ >+// Less-than operator >+template <typename... Types> >+constexpr variant_internal::RequireAllHaveLessThanT<Types...> operator<( >+ const variant<Types...>& a, const variant<Types...>& b) { >+ return (a.index() != b.index()) >+ ? (a.index() + 1) < (b.index() + 1) >+ : variant_internal::VisitIndices<sizeof...(Types)>::Run( >+ variant_internal::LessThanOp<Types...>{&a, &b}, a.index()); >+} >+ >+// Greater-than operator >+template <typename... Types> >+constexpr variant_internal::RequireAllHaveGreaterThanT<Types...> operator>( >+ const variant<Types...>& a, const variant<Types...>& b) { >+ return (a.index() != b.index()) >+ ? (a.index() + 1) > (b.index() + 1) >+ : variant_internal::VisitIndices<sizeof...(Types)>::Run( >+ variant_internal::GreaterThanOp<Types...>{&a, &b}, >+ a.index()); >+} >+ >+// Less-than or equal-to operator >+template <typename... Types> >+constexpr variant_internal::RequireAllHaveLessThanOrEqualT<Types...> operator<=( >+ const variant<Types...>& a, const variant<Types...>& b) { >+ return (a.index() != b.index()) >+ ? (a.index() + 1) < (b.index() + 1) >+ : variant_internal::VisitIndices<sizeof...(Types)>::Run( >+ variant_internal::LessThanOrEqualsOp<Types...>{&a, &b}, >+ a.index()); >+} >+ >+// Greater-than or equal-to operator >+template <typename... Types> >+constexpr variant_internal::RequireAllHaveGreaterThanOrEqualT<Types...> >+operator>=(const variant<Types...>& a, const variant<Types...>& b) { >+ return (a.index() != b.index()) >+ ? (a.index() + 1) > (b.index() + 1) >+ : variant_internal::VisitIndices<sizeof...(Types)>::Run( >+ variant_internal::GreaterThanOrEqualsOp<Types...>{&a, &b}, >+ a.index()); >+} >+ >+} // namespace absl >+ >+namespace std { >+ >+// hash() >+template <> // NOLINT >+struct hash<absl::monostate> { >+ std::size_t operator()(absl::monostate) const { return 0; } >+}; >+ >+template <class... T> // NOLINT >+struct hash<absl::variant<T...>> >+ : absl::variant_internal::VariantHashBase<absl::variant<T...>, void, >+ absl::remove_const_t<T>...> {}; >+ >+} // namespace std >+ >+#endif // ABSL_HAVE_STD_VARIANT >+ >+namespace absl { >+namespace variant_internal { >+ >+// Helper visitor for converting a variant<Ts...>` into another type (mostly >+// variant) that can be constructed from any type. >+template <typename To> >+struct ConversionVisitor { >+ template <typename T> >+ To operator()(T&& v) const { >+ return To(std::forward<T>(v)); >+ } >+}; >+ >+} // namespace variant_internal >+ >+// ConvertVariantTo() >+// >+// Helper functions to convert an `absl::variant` to a variant of another set of >+// types, provided that the alternative type of the new variant type can be >+// converted from any type in the source variant. >+// >+// Example: >+// >+// absl::variant<name1, name2, float> InternalReq(const Req&); >+// >+// // name1 and name2 are convertible to name >+// absl::variant<name, float> ExternalReq(const Req& req) { >+// return absl::ConvertVariantTo<absl::variant<name, float>>( >+// InternalReq(req)); >+// } >+template <typename To, typename Variant> >+To ConvertVariantTo(Variant&& variant) { >+ return absl::visit(variant_internal::ConversionVisitor<To>{}, >+ std::forward<Variant>(variant)); >+} >+ >+} // namespace absl >+ >+#endif // ABSL_TYPES_VARIANT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant_benchmark.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant_benchmark.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..99658ac70c46438023a51ca3304812faa2707efd >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant_benchmark.cc >@@ -0,0 +1,220 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Unit tests for the variant template. The 'is' and 'IsEmpty' methods >+// of variant are not explicitly tested because they are used repeatedly >+// in building other tests. All other public variant methods should have >+// explicit tests. >+ >+#include "absl/types/variant.h" >+ >+#include <cstddef> >+#include <cstdlib> >+#include <string> >+#include <tuple> >+ >+#include "benchmark/benchmark.h" >+#include "absl/utility/utility.h" >+ >+namespace absl { >+namespace { >+ >+template <std::size_t I> >+struct VariantAlternative { >+ char member; >+}; >+ >+template <class Indices> >+struct VariantOfAlternativesImpl; >+ >+template <std::size_t... Indices> >+struct VariantOfAlternativesImpl<absl::index_sequence<Indices...>> { >+ using type = absl::variant<VariantAlternative<Indices>...>; >+}; >+ >+template <std::size_t NumAlternatives> >+using VariantOfAlternatives = typename VariantOfAlternativesImpl< >+ absl::make_index_sequence<NumAlternatives>>::type; >+ >+struct Empty {}; >+ >+template <class... T> >+void Ignore(T...) noexcept {} >+ >+template <class T> >+Empty DoNotOptimizeAndReturnEmpty(T&& arg) noexcept { >+ benchmark::DoNotOptimize(arg); >+ return {}; >+} >+ >+struct VisitorApplier { >+ struct Visitor { >+ template <class... T> >+ void operator()(T&&... args) const noexcept { >+ Ignore(DoNotOptimizeAndReturnEmpty(args)...); >+ } >+ }; >+ >+ template <class... Vars> >+ void operator()(const Vars&... vars) const noexcept { >+ absl::visit(Visitor(), vars...); >+ } >+}; >+ >+template <std::size_t NumIndices, std::size_t CurrIndex = NumIndices - 1> >+struct MakeWithIndex { >+ using Variant = VariantOfAlternatives<NumIndices>; >+ >+ static Variant Run(std::size_t index) { >+ return index == CurrIndex >+ ? Variant(absl::in_place_index_t<CurrIndex>()) >+ : MakeWithIndex<NumIndices, CurrIndex - 1>::Run(index); >+ } >+}; >+ >+template <std::size_t NumIndices> >+struct MakeWithIndex<NumIndices, 0> { >+ using Variant = VariantOfAlternatives<NumIndices>; >+ >+ static Variant Run(std::size_t /*index*/) { return Variant(); } >+}; >+ >+template <std::size_t NumIndices, class Dimensions> >+struct MakeVariantTuple; >+ >+template <class T, std::size_t /*I*/> >+using always_t = T; >+ >+template <std::size_t NumIndices> >+VariantOfAlternatives<NumIndices> MakeVariant(std::size_t dimension, >+ std::size_t index) { >+ return dimension == 0 >+ ? MakeWithIndex<NumIndices>::Run(index % NumIndices) >+ : MakeVariant<NumIndices>(dimension - 1, index / NumIndices); >+} >+ >+template <std::size_t NumIndices, std::size_t... Dimensions> >+struct MakeVariantTuple<NumIndices, absl::index_sequence<Dimensions...>> { >+ using VariantTuple = >+ std::tuple<always_t<VariantOfAlternatives<NumIndices>, Dimensions>...>; >+ >+ static VariantTuple Run(int index) { >+ return std::make_tuple(MakeVariant<NumIndices>(Dimensions, index)...); >+ } >+}; >+ >+constexpr std::size_t integral_pow(std::size_t base, std::size_t power) { >+ return power == 0 ? 1 : base * integral_pow(base, power - 1); >+} >+ >+template <std::size_t End, std::size_t I = 0> >+struct VisitTestBody { >+ template <class Vars, class State> >+ static bool Run(Vars& vars, State& state) { >+ if (state.KeepRunning()) { >+ absl::apply(VisitorApplier(), vars[I]); >+ return VisitTestBody<End, I + 1>::Run(vars, state); >+ } >+ return false; >+ } >+}; >+ >+template <std::size_t End> >+struct VisitTestBody<End, End> { >+ template <class Vars, class State> >+ static bool Run(Vars& /*vars*/, State& /*state*/) { >+ return true; >+ } >+}; >+ >+// Visit operations where branch prediction is likely to give a boost. >+template <std::size_t NumIndices, std::size_t NumDimensions = 1> >+void BM_RedundantVisit(benchmark::State& state) { >+ auto vars = >+ MakeVariantTuple<NumIndices, absl::make_index_sequence<NumDimensions>>:: >+ Run(static_cast<std::size_t>(state.range(0))); >+ >+ for (auto _ : state) { // NOLINT >+ benchmark::DoNotOptimize(vars); >+ absl::apply(VisitorApplier(), vars); >+ } >+} >+ >+// Visit operations where branch prediction is unlikely to give a boost. >+template <std::size_t NumIndices, std::size_t NumDimensions = 1> >+void BM_Visit(benchmark::State& state) { >+ constexpr std::size_t num_possibilities = >+ integral_pow(NumIndices, NumDimensions); >+ >+ using VariantTupleMaker = >+ MakeVariantTuple<NumIndices, absl::make_index_sequence<NumDimensions>>; >+ using Tuple = typename VariantTupleMaker::VariantTuple; >+ >+ Tuple vars[num_possibilities]; >+ for (std::size_t i = 0; i < num_possibilities; ++i) >+ vars[i] = VariantTupleMaker::Run(i); >+ >+ while (VisitTestBody<num_possibilities>::Run(vars, state)) { >+ } >+} >+ >+// Visitation >+// Each visit is on a different variant with a different active alternative) >+ >+// Unary visit >+BENCHMARK_TEMPLATE(BM_Visit, 1); >+BENCHMARK_TEMPLATE(BM_Visit, 2); >+BENCHMARK_TEMPLATE(BM_Visit, 3); >+BENCHMARK_TEMPLATE(BM_Visit, 4); >+BENCHMARK_TEMPLATE(BM_Visit, 5); >+BENCHMARK_TEMPLATE(BM_Visit, 6); >+BENCHMARK_TEMPLATE(BM_Visit, 7); >+BENCHMARK_TEMPLATE(BM_Visit, 8); >+BENCHMARK_TEMPLATE(BM_Visit, 16); >+BENCHMARK_TEMPLATE(BM_Visit, 32); >+BENCHMARK_TEMPLATE(BM_Visit, 64); >+ >+// Binary visit >+BENCHMARK_TEMPLATE(BM_Visit, 1, 2); >+BENCHMARK_TEMPLATE(BM_Visit, 2, 2); >+BENCHMARK_TEMPLATE(BM_Visit, 3, 2); >+BENCHMARK_TEMPLATE(BM_Visit, 4, 2); >+BENCHMARK_TEMPLATE(BM_Visit, 5, 2); >+ >+// Ternary visit >+BENCHMARK_TEMPLATE(BM_Visit, 1, 3); >+BENCHMARK_TEMPLATE(BM_Visit, 2, 3); >+BENCHMARK_TEMPLATE(BM_Visit, 3, 3); >+ >+// Quaternary visit >+BENCHMARK_TEMPLATE(BM_Visit, 1, 4); >+BENCHMARK_TEMPLATE(BM_Visit, 2, 4); >+ >+// Redundant Visitation >+// Each visit consistently has the same alternative active >+ >+// Unary visit >+BENCHMARK_TEMPLATE(BM_RedundantVisit, 1)->Arg(0); >+BENCHMARK_TEMPLATE(BM_RedundantVisit, 2)->DenseRange(0, 1); >+BENCHMARK_TEMPLATE(BM_RedundantVisit, 8)->DenseRange(0, 7); >+ >+// Binary visit >+BENCHMARK_TEMPLATE(BM_RedundantVisit, 1, 2)->Arg(0); >+BENCHMARK_TEMPLATE(BM_RedundantVisit, 2, 2) >+ ->DenseRange(0, integral_pow(2, 2) - 1); >+BENCHMARK_TEMPLATE(BM_RedundantVisit, 4, 2) >+ ->DenseRange(0, integral_pow(4, 2) - 1); >+ >+} // namespace >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant_exception_safety_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant_exception_safety_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..27c0b96ca6f340850b0251bc6e916d37cdf11645 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant_exception_safety_test.cc >@@ -0,0 +1,508 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+#include "absl/types/variant.h" >+ >+#include <iostream> >+#include <memory> >+#include <utility> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/internal/exception_safety_testing.h" >+#include "absl/memory/memory.h" >+ >+namespace absl { >+namespace { >+ >+using ::testing::MakeExceptionSafetyTester; >+using ::testing::strong_guarantee; >+using ::testing::TestNothrowOp; >+using ::testing::TestThrowingCtor; >+ >+using Thrower = testing::ThrowingValue<>; >+using CopyNothrow = testing::ThrowingValue<testing::TypeSpec::kNoThrowCopy>; >+using MoveNothrow = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>; >+using ThrowingAlloc = testing::ThrowingAllocator<Thrower>; >+using ThrowerVec = std::vector<Thrower, ThrowingAlloc>; >+using ThrowingVariant = >+ absl::variant<Thrower, CopyNothrow, MoveNothrow, ThrowerVec>; >+ >+struct ConversionException {}; >+ >+template <class T> >+struct ExceptionOnConversion { >+ operator T() const { // NOLINT >+ throw ConversionException(); >+ } >+}; >+ >+// Forces a variant into the valueless by exception state. >+void ToValuelessByException(ThrowingVariant& v) { // NOLINT >+ try { >+ v.emplace<Thrower>(); >+ v.emplace<Thrower>(ExceptionOnConversion<Thrower>()); >+ } catch (ConversionException& /*e*/) { >+ // This space intentionally left blank. >+ } >+} >+ >+// Check that variant is still in a usable state after an exception is thrown. >+testing::AssertionResult CheckInvariants(ThrowingVariant* v) { >+ using testing::AssertionFailure; >+ using testing::AssertionSuccess; >+ >+ // Try using the active alternative >+ if (absl::holds_alternative<Thrower>(*v)) { >+ auto& t = absl::get<Thrower>(*v); >+ t = Thrower{-100}; >+ if (t.Get() != -100) { >+ return AssertionFailure() << "Thrower should be assigned -100"; >+ } >+ } else if (absl::holds_alternative<ThrowerVec>(*v)) { >+ auto& tv = absl::get<ThrowerVec>(*v); >+ tv.clear(); >+ tv.emplace_back(-100); >+ if (tv.size() != 1 || tv[0].Get() != -100) { >+ return AssertionFailure() << "ThrowerVec should be {Thrower{-100}}"; >+ } >+ } else if (absl::holds_alternative<CopyNothrow>(*v)) { >+ auto& t = absl::get<CopyNothrow>(*v); >+ t = CopyNothrow{-100}; >+ if (t.Get() != -100) { >+ return AssertionFailure() << "CopyNothrow should be assigned -100"; >+ } >+ } else if (absl::holds_alternative<MoveNothrow>(*v)) { >+ auto& t = absl::get<MoveNothrow>(*v); >+ t = MoveNothrow{-100}; >+ if (t.Get() != -100) { >+ return AssertionFailure() << "MoveNothrow should be assigned -100"; >+ } >+ } >+ >+ // Try making variant valueless_by_exception >+ if (!v->valueless_by_exception()) ToValuelessByException(*v); >+ if (!v->valueless_by_exception()) { >+ return AssertionFailure() << "Variant should be valueless_by_exception"; >+ } >+ try { >+ auto unused = absl::get<Thrower>(*v); >+ static_cast<void>(unused); >+ return AssertionFailure() << "Variant should not contain Thrower"; >+ } catch (absl::bad_variant_access) { >+ } catch (...) { >+ return AssertionFailure() << "Unexpected exception throw from absl::get"; >+ } >+ >+ // Try using the variant >+ v->emplace<Thrower>(100); >+ if (!absl::holds_alternative<Thrower>(*v) || >+ absl::get<Thrower>(*v) != Thrower(100)) { >+ return AssertionFailure() << "Variant should contain Thrower(100)"; >+ } >+ v->emplace<ThrowerVec>({Thrower(100)}); >+ if (!absl::holds_alternative<ThrowerVec>(*v) || >+ absl::get<ThrowerVec>(*v)[0] != Thrower(100)) { >+ return AssertionFailure() >+ << "Variant should contain ThrowerVec{Thrower(100)}"; >+ } >+ return AssertionSuccess(); >+} >+ >+template <typename... Args> >+Thrower ExpectedThrower(Args&&... args) { >+ return Thrower(42, args...); >+} >+ >+ThrowerVec ExpectedThrowerVec() { return {Thrower(100), Thrower(200)}; } >+ThrowingVariant ValuelessByException() { >+ ThrowingVariant v; >+ ToValuelessByException(v); >+ return v; >+} >+ThrowingVariant WithThrower() { return Thrower(39); } >+ThrowingVariant WithThrowerVec() { >+ return ThrowerVec{Thrower(1), Thrower(2), Thrower(3)}; >+} >+ThrowingVariant WithCopyNoThrow() { return CopyNothrow(39); } >+ThrowingVariant WithMoveNoThrow() { return MoveNothrow(39); } >+ >+TEST(VariantExceptionSafetyTest, DefaultConstructor) { >+ TestThrowingCtor<ThrowingVariant>(); >+} >+ >+TEST(VariantExceptionSafetyTest, CopyConstructor) { >+ { >+ ThrowingVariant v(ExpectedThrower()); >+ TestThrowingCtor<ThrowingVariant>(v); >+ } >+ { >+ ThrowingVariant v(ExpectedThrowerVec()); >+ TestThrowingCtor<ThrowingVariant>(v); >+ } >+ { >+ ThrowingVariant v(ValuelessByException()); >+ TestThrowingCtor<ThrowingVariant>(v); >+ } >+} >+ >+TEST(VariantExceptionSafetyTest, MoveConstructor) { >+ { >+ ThrowingVariant v(ExpectedThrower()); >+ TestThrowingCtor<ThrowingVariant>(std::move(v)); >+ } >+ { >+ ThrowingVariant v(ExpectedThrowerVec()); >+ TestThrowingCtor<ThrowingVariant>(std::move(v)); >+ } >+ { >+ ThrowingVariant v(ValuelessByException()); >+ TestThrowingCtor<ThrowingVariant>(std::move(v)); >+ } >+} >+ >+TEST(VariantExceptionSafetyTest, ValueConstructor) { >+ TestThrowingCtor<ThrowingVariant>(ExpectedThrower()); >+ TestThrowingCtor<ThrowingVariant>(ExpectedThrowerVec()); >+} >+ >+TEST(VariantExceptionSafetyTest, InPlaceTypeConstructor) { >+ TestThrowingCtor<ThrowingVariant>(absl::in_place_type_t<Thrower>{}, >+ ExpectedThrower()); >+ TestThrowingCtor<ThrowingVariant>(absl::in_place_type_t<ThrowerVec>{}, >+ ExpectedThrowerVec()); >+} >+ >+TEST(VariantExceptionSafetyTest, InPlaceIndexConstructor) { >+ TestThrowingCtor<ThrowingVariant>(absl::in_place_index_t<0>{}, >+ ExpectedThrower()); >+ TestThrowingCtor<ThrowingVariant>(absl::in_place_index_t<3>{}, >+ ExpectedThrowerVec()); >+} >+ >+TEST(VariantExceptionSafetyTest, CopyAssign) { >+ // variant& operator=(const variant& rhs); >+ // Let j be rhs.index() >+ { >+ // - neither *this nor rhs holds a value >+ const ThrowingVariant rhs = ValuelessByException(); >+ ThrowingVariant lhs = ValuelessByException(); >+ EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; })); >+ } >+ { >+ // - *this holds a value but rhs does not >+ const ThrowingVariant rhs = ValuelessByException(); >+ ThrowingVariant lhs = WithThrower(); >+ EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; })); >+ } >+ // - index() == j >+ { >+ const ThrowingVariant rhs(ExpectedThrower()); >+ auto tester = >+ MakeExceptionSafetyTester() >+ .WithInitialValue(WithThrower()) >+ .WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }); >+ EXPECT_TRUE(tester.WithInvariants(CheckInvariants).Test()); >+ EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test()); >+ } >+ { >+ const ThrowingVariant rhs(ExpectedThrowerVec()); >+ auto tester = >+ MakeExceptionSafetyTester() >+ .WithInitialValue(WithThrowerVec()) >+ .WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }); >+ EXPECT_TRUE(tester.WithInvariants(CheckInvariants).Test()); >+ EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test()); >+ } >+ // libstdc++ std::variant has bugs on copy assignment regarding exception >+ // safety. >+#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) >+ // index() != j >+ // if is_nothrow_copy_constructible_v<Tj> or >+ // !is_nothrow_move_constructible<Tj> is true, equivalent to >+ // emplace<j>(get<j>(rhs)) >+ { >+ // is_nothrow_copy_constructible_v<Tj> == true >+ // should not throw because emplace() invokes Tj's copy ctor >+ // which should not throw. >+ const ThrowingVariant rhs(CopyNothrow{}); >+ ThrowingVariant lhs = WithThrower(); >+ EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; })); >+ } >+ { >+ // is_nothrow_copy_constructible<Tj> == false && >+ // is_nothrow_move_constructible<Tj> == false >+ // should provide basic guarantee because emplace() invokes Tj's copy ctor >+ // which may throw. >+ const ThrowingVariant rhs(ExpectedThrower()); >+ auto tester = >+ MakeExceptionSafetyTester() >+ .WithInitialValue(WithCopyNoThrow()) >+ .WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }); >+ EXPECT_TRUE(tester >+ .WithInvariants(CheckInvariants, >+ [](ThrowingVariant* lhs) { >+ return lhs->valueless_by_exception(); >+ }) >+ .Test()); >+ EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test()); >+ } >+#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) >+ { >+ // is_nothrow_copy_constructible_v<Tj> == false && >+ // is_nothrow_move_constructible_v<Tj> == true >+ // should provide strong guarantee because it is equivalent to >+ // operator=(variant(rhs)) which creates a temporary then invoke the move >+ // ctor which shouldn't throw. >+ const ThrowingVariant rhs(MoveNothrow{}); >+ EXPECT_TRUE(MakeExceptionSafetyTester() >+ .WithInitialValue(WithThrower()) >+ .WithInvariants(CheckInvariants, strong_guarantee) >+ .Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; })); >+ } >+} >+ >+TEST(VariantExceptionSafetyTest, MoveAssign) { >+ // variant& operator=(variant&& rhs); >+ // Let j be rhs.index() >+ { >+ // - neither *this nor rhs holds a value >+ ThrowingVariant rhs = ValuelessByException(); >+ ThrowingVariant lhs = ValuelessByException(); >+ EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); })); >+ } >+ { >+ // - *this holds a value but rhs does not >+ ThrowingVariant rhs = ValuelessByException(); >+ ThrowingVariant lhs = WithThrower(); >+ EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); })); >+ } >+ { >+ // - index() == j >+ // assign get<j>(std::move(rhs)) to the value contained in *this. >+ // If an exception is thrown during call to Tj's move assignment, the state >+ // of the contained value is as defined by the exception safety guarantee of >+ // Tj's move assignment; index() will be j. >+ ThrowingVariant rhs(ExpectedThrower()); >+ size_t j = rhs.index(); >+ // Since Thrower's move assignment has basic guarantee, so should variant's. >+ auto tester = MakeExceptionSafetyTester() >+ .WithInitialValue(WithThrower()) >+ .WithOperation([&](ThrowingVariant* lhs) { >+ auto copy = rhs; >+ *lhs = std::move(copy); >+ }); >+ EXPECT_TRUE(tester >+ .WithInvariants( >+ CheckInvariants, >+ [&](ThrowingVariant* lhs) { return lhs->index() == j; }) >+ .Test()); >+ EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test()); >+ } >+ { >+ // - otherwise (index() != j), equivalent to >+ // emplace<j>(get<j>(std::move(rhs))) >+ // - If an exception is thrown during the call to Tj's move construction >+ // (with j being rhs.index()), the variant will hold no value. >+ ThrowingVariant rhs(CopyNothrow{}); >+ EXPECT_TRUE(MakeExceptionSafetyTester() >+ .WithInitialValue(WithThrower()) >+ .WithInvariants(CheckInvariants, >+ [](ThrowingVariant* lhs) { >+ return lhs->valueless_by_exception(); >+ }) >+ .Test([&](ThrowingVariant* lhs) { >+ auto copy = rhs; >+ *lhs = std::move(copy); >+ })); >+ } >+} >+ >+TEST(VariantExceptionSafetyTest, ValueAssign) { >+ // template<class T> variant& operator=(T&& t); >+ // Let Tj be the type that is selected by overload resolution to be assigned. >+ { >+ // If *this holds a Tj, assigns std::forward<T>(t) to the value contained in >+ // *this. If an exception is thrown during the assignment of >+ // std::forward<T>(t) to the value contained in *this, the state of the >+ // contained value and t are as defined by the exception safety guarantee of >+ // the assignment expression; valueless_by_exception() will be false. >+ // Since Thrower's copy/move assignment has basic guarantee, so should >+ // variant's. >+ Thrower rhs = ExpectedThrower(); >+ // copy assign >+ auto copy_tester = >+ MakeExceptionSafetyTester() >+ .WithInitialValue(WithThrower()) >+ .WithOperation([rhs](ThrowingVariant* lhs) { *lhs = rhs; }); >+ EXPECT_TRUE(copy_tester >+ .WithInvariants(CheckInvariants, >+ [](ThrowingVariant* lhs) { >+ return !lhs->valueless_by_exception(); >+ }) >+ .Test()); >+ EXPECT_FALSE(copy_tester.WithInvariants(strong_guarantee).Test()); >+ // move assign >+ auto move_tester = MakeExceptionSafetyTester() >+ .WithInitialValue(WithThrower()) >+ .WithOperation([&](ThrowingVariant* lhs) { >+ auto copy = rhs; >+ *lhs = std::move(copy); >+ }); >+ EXPECT_TRUE(move_tester >+ .WithInvariants(CheckInvariants, >+ [](ThrowingVariant* lhs) { >+ return !lhs->valueless_by_exception(); >+ }) >+ .Test()); >+ >+ EXPECT_FALSE(move_tester.WithInvariants(strong_guarantee).Test()); >+ } >+ // Otherwise (*this holds something else), if is_nothrow_constructible_v<Tj, >+ // T> || !is_nothrow_move_constructible_v<Tj> is true, equivalent to >+ // emplace<j>(std::forward<T>(t)). >+ // We simplify the test by letting T = `const Tj&` or `Tj&&`, so we can reuse >+ // the CopyNothrow and MoveNothrow types. >+ >+ // if is_nothrow_constructible_v<Tj, T> >+ // (i.e. is_nothrow_copy/move_constructible_v<Tj>) is true, emplace() just >+ // invokes the copy/move constructor and it should not throw. >+ { >+ const CopyNothrow rhs; >+ ThrowingVariant lhs = WithThrower(); >+ EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; })); >+ } >+ { >+ MoveNothrow rhs; >+ ThrowingVariant lhs = WithThrower(); >+ EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); })); >+ } >+ // if is_nothrow_constructible_v<Tj, T> == false && >+ // is_nothrow_move_constructible<Tj> == false >+ // emplace() invokes the copy/move constructor which may throw so it should >+ // provide basic guarantee and variant object might not hold a value. >+ { >+ Thrower rhs = ExpectedThrower(); >+ // copy >+ auto copy_tester = >+ MakeExceptionSafetyTester() >+ .WithInitialValue(WithCopyNoThrow()) >+ .WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }); >+ EXPECT_TRUE(copy_tester >+ .WithInvariants(CheckInvariants, >+ [](ThrowingVariant* lhs) { >+ return lhs->valueless_by_exception(); >+ }) >+ .Test()); >+ EXPECT_FALSE(copy_tester.WithInvariants(strong_guarantee).Test()); >+ // move >+ auto move_tester = MakeExceptionSafetyTester() >+ .WithInitialValue(WithCopyNoThrow()) >+ .WithOperation([](ThrowingVariant* lhs) { >+ *lhs = ExpectedThrower(testing::nothrow_ctor); >+ }); >+ EXPECT_TRUE(move_tester >+ .WithInvariants(CheckInvariants, >+ [](ThrowingVariant* lhs) { >+ return lhs->valueless_by_exception(); >+ }) >+ .Test()); >+ EXPECT_FALSE(move_tester.WithInvariants(strong_guarantee).Test()); >+ } >+ // Otherwise (if is_nothrow_constructible_v<Tj, T> == false && >+ // is_nothrow_move_constructible<Tj> == true), >+ // equivalent to operator=(variant(std::forward<T>(t))) >+ // This should have strong guarantee because it creates a temporary variant >+ // and operator=(variant&&) invokes Tj's move ctor which doesn't throw. >+ // libstdc++ std::variant has bugs on conversion assignment regarding >+ // exception safety. >+#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) >+ { >+ MoveNothrow rhs; >+ EXPECT_TRUE(MakeExceptionSafetyTester() >+ .WithInitialValue(WithThrower()) >+ .WithInvariants(CheckInvariants, strong_guarantee) >+ .Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; })); >+ } >+#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) >+} >+ >+TEST(VariantExceptionSafetyTest, Emplace) { >+ // If an exception during the initialization of the contained value, the >+ // variant might not hold a value. The standard requires emplace() to provide >+ // only basic guarantee. >+ { >+ Thrower args = ExpectedThrower(); >+ auto tester = MakeExceptionSafetyTester() >+ .WithInitialValue(WithThrower()) >+ .WithOperation([&args](ThrowingVariant* v) { >+ v->emplace<Thrower>(args); >+ }); >+ EXPECT_TRUE(tester >+ .WithInvariants(CheckInvariants, >+ [](ThrowingVariant* v) { >+ return v->valueless_by_exception(); >+ }) >+ .Test()); >+ EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test()); >+ } >+} >+ >+TEST(VariantExceptionSafetyTest, Swap) { >+ // if both are valueless_by_exception(), no effect >+ { >+ ThrowingVariant rhs = ValuelessByException(); >+ ThrowingVariant lhs = ValuelessByException(); >+ EXPECT_TRUE(TestNothrowOp([&]() { lhs.swap(rhs); })); >+ } >+ // if index() == rhs.index(), calls swap(get<i>(*this), get<i>(rhs)) >+ // where i is index(). >+ { >+ ThrowingVariant rhs = ExpectedThrower(); >+ EXPECT_TRUE(MakeExceptionSafetyTester() >+ .WithInitialValue(WithThrower()) >+ .WithInvariants(CheckInvariants) >+ .Test([&](ThrowingVariant* lhs) { >+ auto copy = rhs; >+ lhs->swap(copy); >+ })); >+ } >+ // Otherwise, exchanges the value of rhs and *this. The exception safety >+ // involves variant in moved-from state which is not specified in the >+ // standard, and since swap is 3-step it's impossible for it to provide a >+ // overall strong guarantee. So, we are only checking basic guarantee here. >+ { >+ ThrowingVariant rhs = ExpectedThrower(); >+ EXPECT_TRUE(MakeExceptionSafetyTester() >+ .WithInitialValue(WithCopyNoThrow()) >+ .WithInvariants(CheckInvariants) >+ .Test([&](ThrowingVariant* lhs) { >+ auto copy = rhs; >+ lhs->swap(copy); >+ })); >+ } >+ { >+ ThrowingVariant rhs = ExpectedThrower(); >+ EXPECT_TRUE(MakeExceptionSafetyTester() >+ .WithInitialValue(WithCopyNoThrow()) >+ .WithInvariants(CheckInvariants) >+ .Test([&](ThrowingVariant* lhs) { >+ auto copy = rhs; >+ copy.swap(*lhs); >+ })); >+ } >+} >+ >+} // namespace >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..262bd9446c1841a570715745c3434ee1b8e19f95 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/types/variant_test.cc >@@ -0,0 +1,2612 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+// Unit tests for the variant template. The 'is' and 'IsEmpty' methods >+// of variant are not explicitly tested because they are used repeatedly >+// in building other tests. All other public variant methods should have >+// explicit tests. >+ >+#include "absl/types/variant.h" >+ >+#include <algorithm> >+#include <cstddef> >+#include <functional> >+#include <initializer_list> >+#include <memory> >+#include <ostream> >+#include <queue> >+#include <type_traits> >+#include <unordered_set> >+#include <utility> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/config.h" >+#include "absl/base/port.h" >+#include "absl/memory/memory.h" >+#include "absl/meta/type_traits.h" >+#include "absl/strings/string_view.h" >+ >+#ifdef ABSL_HAVE_EXCEPTIONS >+ >+#define ABSL_VARIANT_TEST_EXPECT_FAIL(expr, exception_t, text) \ >+ EXPECT_THROW(expr, exception_t) >+ >+#else >+ >+#define ABSL_VARIANT_TEST_EXPECT_FAIL(expr, exception_t, text) \ >+ EXPECT_DEATH(expr, text) >+ >+#endif // ABSL_HAVE_EXCEPTIONS >+ >+#define ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(...) \ >+ ABSL_VARIANT_TEST_EXPECT_FAIL((__VA_ARGS__), absl::bad_variant_access, \ >+ "Bad variant access") >+ >+struct Hashable {}; >+ >+namespace std { >+template <> >+struct hash<Hashable> { >+ size_t operator()(const Hashable&); >+}; >+} // namespace std >+ >+struct NonHashable {}; >+ >+namespace absl { >+namespace { >+ >+using ::testing::DoubleEq; >+using ::testing::Pointee; >+using ::testing::VariantWith; >+ >+struct MoveCanThrow { >+ MoveCanThrow() : v(0) {} >+ MoveCanThrow(int v) : v(v) {} // NOLINT(runtime/explicit) >+ MoveCanThrow(const MoveCanThrow& other) : v(other.v) {} >+ MoveCanThrow& operator=(const MoveCanThrow& /*other*/) { return *this; } >+ int v; >+}; >+ >+bool operator==(MoveCanThrow lhs, MoveCanThrow rhs) { return lhs.v == rhs.v; } >+bool operator!=(MoveCanThrow lhs, MoveCanThrow rhs) { return lhs.v != rhs.v; } >+bool operator<(MoveCanThrow lhs, MoveCanThrow rhs) { return lhs.v < rhs.v; } >+bool operator<=(MoveCanThrow lhs, MoveCanThrow rhs) { return lhs.v <= rhs.v; } >+bool operator>=(MoveCanThrow lhs, MoveCanThrow rhs) { return lhs.v >= rhs.v; } >+bool operator>(MoveCanThrow lhs, MoveCanThrow rhs) { return lhs.v > rhs.v; } >+ >+// This helper class allows us to determine if it was swapped with std::swap() >+// or with its friend swap() function. >+struct SpecialSwap { >+ explicit SpecialSwap(int i) : i(i) {} >+ friend void swap(SpecialSwap& a, SpecialSwap& b) { >+ a.special_swap = b.special_swap = true; >+ std::swap(a.i, b.i); >+ } >+ bool operator==(SpecialSwap other) const { return i == other.i; } >+ int i; >+ bool special_swap = false; >+}; >+ >+struct MoveOnlyWithListConstructor { >+ MoveOnlyWithListConstructor() = default; >+ explicit MoveOnlyWithListConstructor(std::initializer_list<int> /*ilist*/, >+ int value) >+ : value(value) {} >+ MoveOnlyWithListConstructor(MoveOnlyWithListConstructor&&) = default; >+ MoveOnlyWithListConstructor& operator=(MoveOnlyWithListConstructor&&) = >+ default; >+ >+ int value = 0; >+}; >+ >+#ifdef ABSL_HAVE_EXCEPTIONS >+ >+struct ConversionException {}; >+ >+template <class T> >+struct ExceptionOnConversion { >+ operator T() const { // NOLINT(runtime/explicit) >+ throw ConversionException(); >+ } >+}; >+ >+// Forces a variant into the valueless by exception state. >+template <class H, class... T> >+void ToValuelessByException(absl::variant<H, T...>& v) { // NOLINT >+ try { >+ v.template emplace<0>(ExceptionOnConversion<H>()); >+ } catch (ConversionException& /*e*/) { >+ // This space intentionally left blank. >+ } >+} >+ >+#endif // ABSL_HAVE_EXCEPTIONS >+ >+// An indexed sequence of distinct structures holding a single >+// value of type T >+template<typename T, size_t N> >+struct ValueHolder { >+ explicit ValueHolder(const T& x) : value(x) {} >+ typedef T value_type; >+ value_type value; >+ static const size_t kIndex = N; >+}; >+template<typename T, size_t N> >+const size_t ValueHolder<T, N>::kIndex; >+ >+// The following three functions make ValueHolder compatible with >+// EXPECT_EQ and EXPECT_NE >+template<typename T, size_t N> >+inline bool operator==(const ValueHolder<T, N>& left, >+ const ValueHolder<T, N>& right) { >+ return left.value == right.value; >+} >+ >+template<typename T, size_t N> >+inline bool operator!=(const ValueHolder<T, N>& left, >+ const ValueHolder<T, N>& right) { >+ return left.value != right.value; >+} >+ >+template<typename T, size_t N> >+inline std::ostream& operator<<( >+ std::ostream& stream, const ValueHolder<T, N>& object) { >+ return stream << object.value; >+} >+ >+// Makes a variant holding twelve uniquely typed T wrappers. >+template<typename T> >+struct VariantFactory { >+ typedef variant<ValueHolder<T, 1>, ValueHolder<T, 2>, ValueHolder<T, 3>, >+ ValueHolder<T, 4>> >+ Type; >+}; >+ >+// A typelist in 1:1 with VariantFactory, to use type driven unit tests. >+typedef ::testing::Types<ValueHolder<size_t, 1>, ValueHolder<size_t, 2>, >+ ValueHolder<size_t, 3>, >+ ValueHolder<size_t, 4>> VariantTypes; >+ >+// Increments the provided counter pointer in the destructor >+struct IncrementInDtor { >+ explicit IncrementInDtor(int* counter) : counter(counter) {} >+ ~IncrementInDtor() { *counter += 1; } >+ int* counter; >+}; >+ >+struct IncrementInDtorCopyCanThrow { >+ explicit IncrementInDtorCopyCanThrow(int* counter) : counter(counter) {} >+ IncrementInDtorCopyCanThrow(IncrementInDtorCopyCanThrow&& other) noexcept = >+ default; >+ IncrementInDtorCopyCanThrow(const IncrementInDtorCopyCanThrow& other) >+ : counter(other.counter) {} >+ IncrementInDtorCopyCanThrow& operator=( >+ IncrementInDtorCopyCanThrow&&) noexcept = default; >+ IncrementInDtorCopyCanThrow& operator=( >+ IncrementInDtorCopyCanThrow const& other) { >+ counter = other.counter; >+ return *this; >+ } >+ ~IncrementInDtorCopyCanThrow() { *counter += 1; } >+ int* counter; >+}; >+ >+// This is defined so operator== for ValueHolder<IncrementInDtor> will >+// return true if two IncrementInDtor objects increment the same >+// counter >+inline bool operator==(const IncrementInDtor& left, >+ const IncrementInDtor& right) { >+ return left.counter == right.counter; >+} >+ >+// This is defined so EXPECT_EQ can work with IncrementInDtor >+inline std::ostream& operator<<( >+ std::ostream& stream, const IncrementInDtor& object) { >+ return stream << object.counter; >+} >+ >+// A class that can be copied, but not assigned. >+class CopyNoAssign { >+ public: >+ explicit CopyNoAssign(int value) : foo(value) {} >+ CopyNoAssign(const CopyNoAssign& other) : foo(other.foo) {} >+ int foo; >+ private: >+ const CopyNoAssign& operator=(const CopyNoAssign&); >+}; >+ >+// A class that can neither be copied nor assigned. We provide >+// overloads for the constructor with up to four parameters so we can >+// test the overloads of variant::emplace. >+class NonCopyable { >+ public: >+ NonCopyable() >+ : value(0) {} >+ explicit NonCopyable(int value1) >+ : value(value1) {} >+ >+ NonCopyable(int value1, int value2) >+ : value(value1 + value2) {} >+ >+ NonCopyable(int value1, int value2, int value3) >+ : value(value1 + value2 + value3) {} >+ >+ NonCopyable(int value1, int value2, int value3, int value4) >+ : value(value1 + value2 + value3 + value4) {} >+ NonCopyable(const NonCopyable&) = delete; >+ NonCopyable& operator=(const NonCopyable&) = delete; >+ int value; >+}; >+ >+// A typed test and typed test case over the VariantTypes typelist, >+// from which we derive a number of tests that will execute for one of >+// each type. >+template <typename T> >+class VariantTypesTest : public ::testing::Test {}; >+TYPED_TEST_CASE(VariantTypesTest, VariantTypes); >+ >+//////////////////// >+// [variant.ctor] // >+//////////////////// >+ >+struct NonNoexceptDefaultConstructible { >+ NonNoexceptDefaultConstructible() {} >+ int value = 5; >+}; >+ >+struct NonDefaultConstructible { >+ NonDefaultConstructible() = delete; >+}; >+ >+TEST(VariantTest, TestDefaultConstructor) { >+ { >+ using X = variant<int>; >+ constexpr variant<int> x{}; >+ ASSERT_FALSE(x.valueless_by_exception()); >+ ASSERT_EQ(0, x.index()); >+ EXPECT_EQ(0, absl::get<0>(x)); >+ EXPECT_TRUE(std::is_nothrow_default_constructible<X>::value); >+ } >+ >+ { >+ using X = variant<NonNoexceptDefaultConstructible>; >+ X x{}; >+ ASSERT_FALSE(x.valueless_by_exception()); >+ ASSERT_EQ(0, x.index()); >+ EXPECT_EQ(5, absl::get<0>(x).value); >+ EXPECT_FALSE(std::is_nothrow_default_constructible<X>::value); >+ } >+ >+ { >+ using X = variant<int, NonNoexceptDefaultConstructible>; >+ X x{}; >+ ASSERT_FALSE(x.valueless_by_exception()); >+ ASSERT_EQ(0, x.index()); >+ EXPECT_EQ(0, absl::get<0>(x)); >+ EXPECT_TRUE(std::is_nothrow_default_constructible<X>::value); >+ } >+ >+ { >+ using X = variant<NonNoexceptDefaultConstructible, int>; >+ X x{}; >+ ASSERT_FALSE(x.valueless_by_exception()); >+ ASSERT_EQ(0, x.index()); >+ EXPECT_EQ(5, absl::get<0>(x).value); >+ EXPECT_FALSE(std::is_nothrow_default_constructible<X>::value); >+ } >+ EXPECT_FALSE( >+ std::is_default_constructible<variant<NonDefaultConstructible>>::value); >+ EXPECT_FALSE((std::is_default_constructible< >+ variant<NonDefaultConstructible, int>>::value)); >+ EXPECT_TRUE((std::is_default_constructible< >+ variant<int, NonDefaultConstructible>>::value)); >+} >+ >+// Test that for each slot, copy constructing a variant with that type >+// produces a sensible object that correctly reports its type, and >+// that copies the provided value. >+TYPED_TEST(VariantTypesTest, TestCopyCtor) { >+ typedef typename VariantFactory<typename TypeParam::value_type>::Type Variant; >+ using value_type1 = absl::variant_alternative_t<0, Variant>; >+ using value_type2 = absl::variant_alternative_t<1, Variant>; >+ using value_type3 = absl::variant_alternative_t<2, Variant>; >+ using value_type4 = absl::variant_alternative_t<3, Variant>; >+ const TypeParam value(TypeParam::kIndex); >+ Variant original(value); >+ Variant copied(original); >+ EXPECT_TRUE(absl::holds_alternative<value_type1>(copied) || >+ TypeParam::kIndex != 1); >+ EXPECT_TRUE(absl::holds_alternative<value_type2>(copied) || >+ TypeParam::kIndex != 2); >+ EXPECT_TRUE(absl::holds_alternative<value_type3>(copied) || >+ TypeParam::kIndex != 3); >+ EXPECT_TRUE(absl::holds_alternative<value_type4>(copied) || >+ TypeParam::kIndex != 4); >+ EXPECT_TRUE((absl::get_if<value_type1>(&original) == >+ absl::get_if<value_type1>(&copied)) || >+ TypeParam::kIndex == 1); >+ EXPECT_TRUE((absl::get_if<value_type2>(&original) == >+ absl::get_if<value_type2>(&copied)) || >+ TypeParam::kIndex == 2); >+ EXPECT_TRUE((absl::get_if<value_type3>(&original) == >+ absl::get_if<value_type3>(&copied)) || >+ TypeParam::kIndex == 3); >+ EXPECT_TRUE((absl::get_if<value_type4>(&original) == >+ absl::get_if<value_type4>(&copied)) || >+ TypeParam::kIndex == 4); >+ EXPECT_TRUE((absl::get_if<value_type1>(&original) == >+ absl::get_if<value_type1>(&copied)) || >+ TypeParam::kIndex == 1); >+ EXPECT_TRUE((absl::get_if<value_type2>(&original) == >+ absl::get_if<value_type2>(&copied)) || >+ TypeParam::kIndex == 2); >+ EXPECT_TRUE((absl::get_if<value_type3>(&original) == >+ absl::get_if<value_type3>(&copied)) || >+ TypeParam::kIndex == 3); >+ EXPECT_TRUE((absl::get_if<value_type4>(&original) == >+ absl::get_if<value_type4>(&copied)) || >+ TypeParam::kIndex == 4); >+ const TypeParam* ovalptr = absl::get_if<TypeParam>(&original); >+ const TypeParam* cvalptr = absl::get_if<TypeParam>(&copied); >+ ASSERT_TRUE(ovalptr != nullptr); >+ ASSERT_TRUE(cvalptr != nullptr); >+ EXPECT_EQ(*ovalptr, *cvalptr); >+ TypeParam* mutable_ovalptr = absl::get_if<TypeParam>(&original); >+ TypeParam* mutable_cvalptr = absl::get_if<TypeParam>(&copied); >+ ASSERT_TRUE(mutable_ovalptr != nullptr); >+ ASSERT_TRUE(mutable_cvalptr != nullptr); >+ EXPECT_EQ(*mutable_ovalptr, *mutable_cvalptr); >+} >+ >+template <class> >+struct MoveOnly { >+ MoveOnly() = default; >+ explicit MoveOnly(int value) : value(value) {} >+ MoveOnly(MoveOnly&&) = default; >+ MoveOnly& operator=(MoveOnly&&) = default; >+ int value = 5; >+}; >+ >+TEST(VariantTest, TestMoveConstruct) { >+ using V = variant<MoveOnly<class A>, MoveOnly<class B>, MoveOnly<class C>>; >+ >+ V v(in_place_index_t<1>{}, 10); >+ V v2 = absl::move(v); >+ EXPECT_EQ(10, absl::get<1>(v2).value); >+} >+ >+// Used internally to emulate missing triviality traits for tests. >+template <class T> >+union SingleUnion { >+ T member; >+}; >+ >+// NOTE: These don't work with types that can't be union members. >+// They are just for testing. >+template <class T> >+struct is_trivially_move_constructible >+ : std::is_move_constructible<SingleUnion<T>>::type {}; >+ >+template <class T> >+struct is_trivially_move_assignable >+ : std::is_move_assignable<SingleUnion<T>>::type {}; >+ >+TEST(VariantTest, NothrowMoveConstructible) { >+ // Verify that variant is nothrow move constructible iff its template >+ // arguments are. >+ using U = std::unique_ptr<int>; >+ struct E { >+ E(E&&) {} >+ }; >+ static_assert(std::is_nothrow_move_constructible<variant<U>>::value, ""); >+ static_assert(std::is_nothrow_move_constructible<variant<U, int>>::value, ""); >+ static_assert(!std::is_nothrow_move_constructible<variant<U, E>>::value, ""); >+} >+ >+// Test that for each slot, constructing a variant with that type >+// produces a sensible object that correctly reports its type, and >+// that copies the provided value. >+TYPED_TEST(VariantTypesTest, TestValueCtor) { >+ typedef typename VariantFactory<typename TypeParam::value_type>::Type Variant; >+ using value_type1 = absl::variant_alternative_t<0, Variant>; >+ using value_type2 = absl::variant_alternative_t<1, Variant>; >+ using value_type3 = absl::variant_alternative_t<2, Variant>; >+ using value_type4 = absl::variant_alternative_t<3, Variant>; >+ const TypeParam value(TypeParam::kIndex); >+ Variant v(value); >+ EXPECT_TRUE(absl::holds_alternative<value_type1>(v) || >+ TypeParam::kIndex != 1); >+ EXPECT_TRUE(absl::holds_alternative<value_type2>(v) || >+ TypeParam::kIndex != 2); >+ EXPECT_TRUE(absl::holds_alternative<value_type3>(v) || >+ TypeParam::kIndex != 3); >+ EXPECT_TRUE(absl::holds_alternative<value_type4>(v) || >+ TypeParam::kIndex != 4); >+ EXPECT_TRUE(nullptr != absl::get_if<value_type1>(&v) || >+ TypeParam::kIndex != 1); >+ EXPECT_TRUE(nullptr != absl::get_if<value_type2>(&v) || >+ TypeParam::kIndex != 2); >+ EXPECT_TRUE(nullptr != absl::get_if<value_type3>(&v) || >+ TypeParam::kIndex != 3); >+ EXPECT_TRUE(nullptr != absl::get_if<value_type4>(&v) || >+ TypeParam::kIndex != 4); >+ EXPECT_TRUE(nullptr != absl::get_if<value_type1>(&v) || >+ TypeParam::kIndex != 1); >+ EXPECT_TRUE(nullptr != absl::get_if<value_type2>(&v) || >+ TypeParam::kIndex != 2); >+ EXPECT_TRUE(nullptr != absl::get_if<value_type3>(&v) || >+ TypeParam::kIndex != 3); >+ EXPECT_TRUE(nullptr != absl::get_if<value_type4>(&v) || >+ TypeParam::kIndex != 4); >+ const TypeParam* valptr = absl::get_if<TypeParam>(&v); >+ ASSERT_TRUE(nullptr != valptr); >+ EXPECT_EQ(value.value, valptr->value); >+ const TypeParam* mutable_valptr = absl::get_if<TypeParam>(&v); >+ ASSERT_TRUE(nullptr != mutable_valptr); >+ EXPECT_EQ(value.value, mutable_valptr->value); >+} >+ >+TEST(VariantTest, InPlaceType) { >+ using Var = variant<int, std::string, NonCopyable, std::vector<int>>; >+ >+ Var v1(in_place_type_t<int>(), 7); >+ ASSERT_TRUE(absl::holds_alternative<int>(v1)); >+ EXPECT_EQ(7, absl::get<int>(v1)); >+ >+ Var v2(in_place_type_t<std::string>(), "ABC"); >+ ASSERT_TRUE(absl::holds_alternative<std::string>(v2)); >+ EXPECT_EQ("ABC", absl::get<std::string>(v2)); >+ >+ Var v3(in_place_type_t<std::string>(), "ABC", 2); >+ ASSERT_TRUE(absl::holds_alternative<std::string>(v3)); >+ EXPECT_EQ("AB", absl::get<std::string>(v3)); >+ >+ Var v4(in_place_type_t<NonCopyable>{}); >+ ASSERT_TRUE(absl::holds_alternative<NonCopyable>(v4)); >+ >+ Var v5(in_place_type_t<std::vector<int>>(), {1, 2, 3}); >+ ASSERT_TRUE(absl::holds_alternative<std::vector<int>>(v5)); >+ EXPECT_THAT(absl::get<std::vector<int>>(v5), ::testing::ElementsAre(1, 2, 3)); >+} >+ >+TEST(VariantTest, InPlaceTypeInitializerList) { >+ using Var = variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>; >+ >+ Var v1(in_place_type_t<MoveOnlyWithListConstructor>(), {1, 2, 3, 4, 5}, 6); >+ ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1)); >+ EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value); >+} >+ >+TEST(VariantTest, InPlaceIndex) { >+ using Var = variant<int, std::string, NonCopyable, std::vector<int>>; >+ >+ Var v1(in_place_index_t<0>(), 7); >+ ASSERT_TRUE(absl::holds_alternative<int>(v1)); >+ EXPECT_EQ(7, absl::get<int>(v1)); >+ >+ Var v2(in_place_index_t<1>(), "ABC"); >+ ASSERT_TRUE(absl::holds_alternative<std::string>(v2)); >+ EXPECT_EQ("ABC", absl::get<std::string>(v2)); >+ >+ Var v3(in_place_index_t<1>(), "ABC", 2); >+ ASSERT_TRUE(absl::holds_alternative<std::string>(v3)); >+ EXPECT_EQ("AB", absl::get<std::string>(v3)); >+ >+ Var v4(in_place_index_t<2>{}); >+ EXPECT_TRUE(absl::holds_alternative<NonCopyable>(v4)); >+ >+ // Verify that a variant with only non-copyables can still be constructed. >+ EXPECT_TRUE(absl::holds_alternative<NonCopyable>( >+ variant<NonCopyable>(in_place_index_t<0>{}))); >+ >+ Var v5(in_place_index_t<3>(), {1, 2, 3}); >+ ASSERT_TRUE(absl::holds_alternative<std::vector<int>>(v5)); >+ EXPECT_THAT(absl::get<std::vector<int>>(v5), ::testing::ElementsAre(1, 2, 3)); >+} >+ >+TEST(VariantTest, InPlaceIndexInitializerList) { >+ using Var = variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>; >+ >+ Var v1(in_place_index_t<3>(), {1, 2, 3, 4, 5}, 6); >+ ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1)); >+ EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value); >+} >+ >+//////////////////// >+// [variant.dtor] // >+//////////////////// >+ >+// Make sure that the destructor destroys the contained value >+TEST(VariantTest, TestDtor) { >+ typedef VariantFactory<IncrementInDtor>::Type Variant; >+ using value_type1 = absl::variant_alternative_t<0, Variant>; >+ using value_type2 = absl::variant_alternative_t<1, Variant>; >+ using value_type3 = absl::variant_alternative_t<2, Variant>; >+ using value_type4 = absl::variant_alternative_t<3, Variant>; >+ int counter = 0; >+ IncrementInDtor counter_adjuster(&counter); >+ EXPECT_EQ(0, counter); >+ >+ value_type1 value1(counter_adjuster); >+ { Variant object(value1); } >+ EXPECT_EQ(1, counter); >+ >+ value_type2 value2(counter_adjuster); >+ { Variant object(value2); } >+ EXPECT_EQ(2, counter); >+ >+ value_type3 value3(counter_adjuster); >+ { Variant object(value3); } >+ EXPECT_EQ(3, counter); >+ >+ value_type4 value4(counter_adjuster); >+ { Variant object(value4); } >+ EXPECT_EQ(4, counter); >+} >+ >+#ifdef ABSL_HAVE_EXCEPTIONS >+ >+// Test destruction when in the valueless_by_exception state. >+TEST(VariantTest, TestDtorValuelessByException) { >+ int counter = 0; >+ IncrementInDtor counter_adjuster(&counter); >+ >+ { >+ using Variant = VariantFactory<IncrementInDtor>::Type; >+ >+ Variant v(in_place_index_t<0>(), counter_adjuster); >+ EXPECT_EQ(0, counter); >+ >+ ToValuelessByException(v); >+ ASSERT_TRUE(v.valueless_by_exception()); >+ EXPECT_EQ(1, counter); >+ } >+ EXPECT_EQ(1, counter); >+} >+ >+#endif // ABSL_HAVE_EXCEPTIONS >+ >+////////////////////// >+// [variant.assign] // >+////////////////////// >+ >+// Test that self-assignment doesn't destroy the current value >+TEST(VariantTest, TestSelfAssignment) { >+ typedef VariantFactory<IncrementInDtor>::Type Variant; >+ int counter = 0; >+ IncrementInDtor counter_adjuster(&counter); >+ absl::variant_alternative_t<0, Variant> value(counter_adjuster); >+ Variant object(value); >+ object.operator=(object); >+ EXPECT_EQ(0, counter); >+ >+ // A std::string long enough that it's likely to defeat any inline representation >+ // optimization. >+ const std::string long_str(128, 'a'); >+ >+ std::string foo = long_str; >+ foo = *&foo; >+ EXPECT_EQ(long_str, foo); >+ >+ variant<int, std::string> so = long_str; >+ ASSERT_EQ(1, so.index()); >+ EXPECT_EQ(long_str, absl::get<1>(so)); >+ so = *&so; >+ >+ ASSERT_EQ(1, so.index()); >+ EXPECT_EQ(long_str, absl::get<1>(so)); >+} >+ >+// Test that assigning a variant<..., T, ...> to a variant<..., T, ...> produces >+// a variant<..., T, ...> with the correct value. >+TYPED_TEST(VariantTypesTest, TestAssignmentCopiesValueSameTypes) { >+ typedef typename VariantFactory<typename TypeParam::value_type>::Type Variant; >+ const TypeParam value(TypeParam::kIndex); >+ const Variant source(value); >+ Variant target(TypeParam(value.value + 1)); >+ ASSERT_TRUE(absl::holds_alternative<TypeParam>(source)); >+ ASSERT_TRUE(absl::holds_alternative<TypeParam>(target)); >+ ASSERT_NE(absl::get<TypeParam>(source), absl::get<TypeParam>(target)); >+ target = source; >+ ASSERT_TRUE(absl::holds_alternative<TypeParam>(source)); >+ ASSERT_TRUE(absl::holds_alternative<TypeParam>(target)); >+ EXPECT_EQ(absl::get<TypeParam>(source), absl::get<TypeParam>(target)); >+} >+ >+// Test that assisnging a variant<..., T, ...> to a variant<1, ...> >+// produces a variant<..., T, ...> with the correct value. >+TYPED_TEST(VariantTypesTest, TestAssignmentCopiesValuesVaryingSourceType) { >+ typedef typename VariantFactory<typename TypeParam::value_type>::Type Variant; >+ using value_type1 = absl::variant_alternative_t<0, Variant>; >+ const TypeParam value(TypeParam::kIndex); >+ const Variant source(value); >+ ASSERT_TRUE(absl::holds_alternative<TypeParam>(source)); >+ Variant target(value_type1(1)); >+ ASSERT_TRUE(absl::holds_alternative<value_type1>(target)); >+ target = source; >+ EXPECT_TRUE(absl::holds_alternative<TypeParam>(source)); >+ EXPECT_TRUE(absl::holds_alternative<TypeParam>(target)); >+ EXPECT_EQ(absl::get<TypeParam>(source), absl::get<TypeParam>(target)); >+} >+ >+// Test that assigning a variant<1, ...> to a variant<..., T, ...> >+// produces a variant<1, ...> with the correct value. >+TYPED_TEST(VariantTypesTest, TestAssignmentCopiesValuesVaryingTargetType) { >+ typedef typename VariantFactory<typename TypeParam::value_type>::Type Variant; >+ using value_type1 = absl::variant_alternative_t<0, Variant>; >+ const Variant source(value_type1(1)); >+ ASSERT_TRUE(absl::holds_alternative<value_type1>(source)); >+ const TypeParam value(TypeParam::kIndex); >+ Variant target(value); >+ ASSERT_TRUE(absl::holds_alternative<TypeParam>(target)); >+ target = source; >+ EXPECT_TRUE(absl::holds_alternative<value_type1>(target)); >+ EXPECT_TRUE(absl::holds_alternative<value_type1>(source)); >+ EXPECT_EQ(absl::get<value_type1>(source), absl::get<value_type1>(target)); >+} >+ >+// Test that operator=<T> works, that assigning a new value destroys >+// the old and that assigning the new value again does not redestroy >+// the old >+TEST(VariantTest, TestAssign) { >+ typedef VariantFactory<IncrementInDtor>::Type Variant; >+ using value_type1 = absl::variant_alternative_t<0, Variant>; >+ using value_type2 = absl::variant_alternative_t<1, Variant>; >+ using value_type3 = absl::variant_alternative_t<2, Variant>; >+ using value_type4 = absl::variant_alternative_t<3, Variant>; >+ >+ const int kSize = 4; >+ int counter[kSize]; >+ std::unique_ptr<IncrementInDtor> counter_adjustor[kSize]; >+ for (int i = 0; i != kSize; i++) { >+ counter[i] = 0; >+ counter_adjustor[i] = absl::make_unique<IncrementInDtor>(&counter[i]); >+ } >+ >+ value_type1 v1(*counter_adjustor[0]); >+ value_type2 v2(*counter_adjustor[1]); >+ value_type3 v3(*counter_adjustor[2]); >+ value_type4 v4(*counter_adjustor[3]); >+ >+ // Test that reassignment causes destruction of old value >+ { >+ Variant object(v1); >+ object = v2; >+ object = v3; >+ object = v4; >+ object = v1; >+ } >+ >+ EXPECT_EQ(2, counter[0]); >+ EXPECT_EQ(1, counter[1]); >+ EXPECT_EQ(1, counter[2]); >+ EXPECT_EQ(1, counter[3]); >+ >+ std::fill(std::begin(counter), std::end(counter), 0); >+ >+ // Test that self-assignment does not cause destruction of old value >+ { >+ Variant object(v1); >+ object.operator=(object); >+ EXPECT_EQ(0, counter[0]); >+ } >+ { >+ Variant object(v2); >+ object.operator=(object); >+ EXPECT_EQ(0, counter[1]); >+ } >+ { >+ Variant object(v3); >+ object.operator=(object); >+ EXPECT_EQ(0, counter[2]); >+ } >+ { >+ Variant object(v4); >+ object.operator=(object); >+ EXPECT_EQ(0, counter[3]); >+ } >+ >+ EXPECT_EQ(1, counter[0]); >+ EXPECT_EQ(1, counter[1]); >+ EXPECT_EQ(1, counter[2]); >+ EXPECT_EQ(1, counter[3]); >+} >+ >+// This tests that we perform a backup if the copy-assign can throw but the move >+// cannot throw. >+TEST(VariantTest, TestBackupAssign) { >+ typedef VariantFactory<IncrementInDtorCopyCanThrow>::Type Variant; >+ using value_type1 = absl::variant_alternative_t<0, Variant>; >+ using value_type2 = absl::variant_alternative_t<1, Variant>; >+ using value_type3 = absl::variant_alternative_t<2, Variant>; >+ using value_type4 = absl::variant_alternative_t<3, Variant>; >+ >+ const int kSize = 4; >+ int counter[kSize]; >+ std::unique_ptr<IncrementInDtorCopyCanThrow> counter_adjustor[kSize]; >+ for (int i = 0; i != kSize; i++) { >+ counter[i] = 0; >+ counter_adjustor[i].reset(new IncrementInDtorCopyCanThrow(&counter[i])); >+ } >+ >+ value_type1 v1(*counter_adjustor[0]); >+ value_type2 v2(*counter_adjustor[1]); >+ value_type3 v3(*counter_adjustor[2]); >+ value_type4 v4(*counter_adjustor[3]); >+ >+ // Test that reassignment causes destruction of old value >+ { >+ Variant object(v1); >+ object = v2; >+ object = v3; >+ object = v4; >+ object = v1; >+ } >+ >+ // libstdc++ doesn't pass this test >+#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) >+ EXPECT_EQ(3, counter[0]); >+ EXPECT_EQ(2, counter[1]); >+ EXPECT_EQ(2, counter[2]); >+ EXPECT_EQ(2, counter[3]); >+#endif >+ >+ std::fill(std::begin(counter), std::end(counter), 0); >+ >+ // Test that self-assignment does not cause destruction of old value >+ { >+ Variant object(v1); >+ object.operator=(object); >+ EXPECT_EQ(0, counter[0]); >+ } >+ { >+ Variant object(v2); >+ object.operator=(object); >+ EXPECT_EQ(0, counter[1]); >+ } >+ { >+ Variant object(v3); >+ object.operator=(object); >+ EXPECT_EQ(0, counter[2]); >+ } >+ { >+ Variant object(v4); >+ object.operator=(object); >+ EXPECT_EQ(0, counter[3]); >+ } >+ >+ EXPECT_EQ(1, counter[0]); >+ EXPECT_EQ(1, counter[1]); >+ EXPECT_EQ(1, counter[2]); >+ EXPECT_EQ(1, counter[3]); >+} >+ >+/////////////////// >+// [variant.mod] // >+/////////////////// >+ >+TEST(VariantTest, TestEmplaceBasic) { >+ using Variant = variant<int, char>; >+ >+ Variant v(absl::in_place_index_t<0>{}, 0); >+ >+ { >+ char& emplace_result = v.emplace<char>(); >+ ASSERT_TRUE(absl::holds_alternative<char>(v)); >+ EXPECT_EQ(absl::get<char>(v), 0); >+ EXPECT_EQ(&emplace_result, &absl::get<char>(v)); >+ } >+ >+ // Make sure that another emplace does zero-initialization >+ absl::get<char>(v) = 'a'; >+ v.emplace<char>('b'); >+ ASSERT_TRUE(absl::holds_alternative<char>(v)); >+ EXPECT_EQ(absl::get<char>(v), 'b'); >+ >+ { >+ int& emplace_result = v.emplace<int>(); >+ EXPECT_TRUE(absl::holds_alternative<int>(v)); >+ EXPECT_EQ(absl::get<int>(v), 0); >+ EXPECT_EQ(&emplace_result, &absl::get<int>(v)); >+ } >+} >+ >+TEST(VariantTest, TestEmplaceInitializerList) { >+ using Var = variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>; >+ >+ Var v1(absl::in_place_index_t<0>{}, 555); >+ MoveOnlyWithListConstructor& emplace_result = >+ v1.emplace<MoveOnlyWithListConstructor>({1, 2, 3, 4, 5}, 6); >+ ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1)); >+ EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value); >+ EXPECT_EQ(&emplace_result, &absl::get<MoveOnlyWithListConstructor>(v1)); >+} >+ >+TEST(VariantTest, TestEmplaceIndex) { >+ using Variant = variant<int, char>; >+ >+ Variant v(absl::in_place_index_t<0>{}, 555); >+ >+ { >+ char& emplace_result = v.emplace<1>(); >+ ASSERT_TRUE(absl::holds_alternative<char>(v)); >+ EXPECT_EQ(absl::get<char>(v), 0); >+ EXPECT_EQ(&emplace_result, &absl::get<char>(v)); >+ } >+ >+ // Make sure that another emplace does zero-initialization >+ absl::get<char>(v) = 'a'; >+ v.emplace<1>('b'); >+ ASSERT_TRUE(absl::holds_alternative<char>(v)); >+ EXPECT_EQ(absl::get<char>(v), 'b'); >+ >+ { >+ int& emplace_result = v.emplace<0>(); >+ EXPECT_TRUE(absl::holds_alternative<int>(v)); >+ EXPECT_EQ(absl::get<int>(v), 0); >+ EXPECT_EQ(&emplace_result, &absl::get<int>(v)); >+ } >+} >+ >+TEST(VariantTest, TestEmplaceIndexInitializerList) { >+ using Var = variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>; >+ >+ Var v1(absl::in_place_index_t<0>{}, 555); >+ MoveOnlyWithListConstructor& emplace_result = >+ v1.emplace<3>({1, 2, 3, 4, 5}, 6); >+ ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1)); >+ EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value); >+ EXPECT_EQ(&emplace_result, &absl::get<MoveOnlyWithListConstructor>(v1)); >+} >+ >+////////////////////// >+// [variant.status] // >+////////////////////// >+ >+TEST(VariantTest, Index) { >+ using Var = variant<int, std::string, double>; >+ >+ Var v = 1; >+ EXPECT_EQ(0, v.index()); >+ v = "str"; >+ EXPECT_EQ(1, v.index()); >+ v = 0.; >+ EXPECT_EQ(2, v.index()); >+ >+ Var v2 = v; >+ EXPECT_EQ(2, v2.index()); >+ v2.emplace<int>(3); >+ EXPECT_EQ(0, v2.index()); >+} >+ >+TEST(VariantTest, NotValuelessByException) { >+ using Var = variant<int, std::string, double>; >+ >+ Var v = 1; >+ EXPECT_FALSE(v.valueless_by_exception()); >+ v = "str"; >+ EXPECT_FALSE(v.valueless_by_exception()); >+ v = 0.; >+ EXPECT_FALSE(v.valueless_by_exception()); >+ >+ Var v2 = v; >+ EXPECT_FALSE(v.valueless_by_exception()); >+ v2.emplace<int>(3); >+ EXPECT_FALSE(v.valueless_by_exception()); >+} >+ >+#ifdef ABSL_HAVE_EXCEPTIONS >+ >+TEST(VariantTest, IndexValuelessByException) { >+ using Var = variant<MoveCanThrow, std::string, double>; >+ >+ Var v(absl::in_place_index_t<0>{}); >+ EXPECT_EQ(0, v.index()); >+ ToValuelessByException(v); >+ EXPECT_EQ(absl::variant_npos, v.index()); >+ v = "str"; >+ EXPECT_EQ(1, v.index()); >+} >+ >+TEST(VariantTest, ValuelessByException) { >+ using Var = variant<MoveCanThrow, std::string, double>; >+ >+ Var v(absl::in_place_index_t<0>{}); >+ EXPECT_FALSE(v.valueless_by_exception()); >+ ToValuelessByException(v); >+ EXPECT_TRUE(v.valueless_by_exception()); >+ v = "str"; >+ EXPECT_FALSE(v.valueless_by_exception()); >+} >+ >+#endif // ABSL_HAVE_EXCEPTIONS >+ >+//////////////////// >+// [variant.swap] // >+//////////////////// >+ >+TEST(VariantTest, MemberSwap) { >+ SpecialSwap v1(3); >+ SpecialSwap v2(7); >+ >+ variant<SpecialSwap> a = v1, b = v2; >+ >+ EXPECT_THAT(a, VariantWith<SpecialSwap>(v1)); >+ EXPECT_THAT(b, VariantWith<SpecialSwap>(v2)); >+ >+ a.swap(b); >+ EXPECT_THAT(a, VariantWith<SpecialSwap>(v2)); >+ EXPECT_THAT(b, VariantWith<SpecialSwap>(v1)); >+ EXPECT_TRUE(absl::get<SpecialSwap>(a).special_swap); >+ >+ using V = variant<MoveCanThrow, std::string, int>; >+ int i = 33; >+ std::string s = "abc"; >+ V valueless(in_place_index_t<0>{}); >+ ToValuelessByException(valueless); >+ { >+ // lhs and rhs holds different alternative >+ V lhs(i), rhs(s); >+ lhs.swap(rhs); >+ EXPECT_THAT(lhs, VariantWith<std::string>(s)); >+ EXPECT_THAT(rhs, VariantWith<int>(i)); >+ } >+ { >+ // lhs is valueless >+ V lhs(valueless), rhs(i); >+ lhs.swap(rhs); >+ EXPECT_THAT(lhs, VariantWith<int>(i)); >+ EXPECT_TRUE(rhs.valueless_by_exception()); >+ } >+ { >+ // rhs is valueless >+ V lhs(s), rhs(valueless); >+ lhs.swap(rhs); >+ EXPECT_THAT(rhs, VariantWith<std::string>(s)); >+ EXPECT_TRUE(lhs.valueless_by_exception()); >+ } >+ { >+ // both are valueless >+ V lhs(valueless), rhs(valueless); >+ lhs.swap(rhs); >+ EXPECT_TRUE(lhs.valueless_by_exception()); >+ EXPECT_TRUE(rhs.valueless_by_exception()); >+ } >+} >+ >+////////////////////// >+// [variant.helper] // >+////////////////////// >+ >+TEST(VariantTest, VariantSize) { >+ { >+ using Size1Variant = absl::variant<int>; >+ EXPECT_EQ(1, absl::variant_size<Size1Variant>::value); >+ EXPECT_EQ(1, absl::variant_size<const Size1Variant>::value); >+ EXPECT_EQ(1, absl::variant_size<volatile Size1Variant>::value); >+ EXPECT_EQ(1, absl::variant_size<const volatile Size1Variant>::value); >+ } >+ >+ { >+ using Size3Variant = absl::variant<int, float, int>; >+ EXPECT_EQ(3, absl::variant_size<Size3Variant>::value); >+ EXPECT_EQ(3, absl::variant_size<const Size3Variant>::value); >+ EXPECT_EQ(3, absl::variant_size<volatile Size3Variant>::value); >+ EXPECT_EQ(3, absl::variant_size<const volatile Size3Variant>::value); >+ } >+} >+ >+TEST(VariantTest, VariantAlternative) { >+ { >+ using V = absl::variant<float, int, const char*>; >+ EXPECT_TRUE( >+ (std::is_same<float, absl::variant_alternative_t<0, V>>::value)); >+ EXPECT_TRUE((std::is_same<const float, >+ absl::variant_alternative_t<0, const V>>::value)); >+ EXPECT_TRUE( >+ (std::is_same<volatile float, >+ absl::variant_alternative_t<0, volatile V>>::value)); >+ EXPECT_TRUE(( >+ std::is_same<const volatile float, >+ absl::variant_alternative_t<0, const volatile V>>::value)); >+ >+ EXPECT_TRUE((std::is_same<int, absl::variant_alternative_t<1, V>>::value)); >+ EXPECT_TRUE((std::is_same<const int, >+ absl::variant_alternative_t<1, const V>>::value)); >+ EXPECT_TRUE( >+ (std::is_same<volatile int, >+ absl::variant_alternative_t<1, volatile V>>::value)); >+ EXPECT_TRUE(( >+ std::is_same<const volatile int, >+ absl::variant_alternative_t<1, const volatile V>>::value)); >+ >+ EXPECT_TRUE( >+ (std::is_same<const char*, absl::variant_alternative_t<2, V>>::value)); >+ EXPECT_TRUE((std::is_same<const char* const, >+ absl::variant_alternative_t<2, const V>>::value)); >+ EXPECT_TRUE( >+ (std::is_same<const char* volatile, >+ absl::variant_alternative_t<2, volatile V>>::value)); >+ EXPECT_TRUE(( >+ std::is_same<const char* const volatile, >+ absl::variant_alternative_t<2, const volatile V>>::value)); >+ } >+ >+ { >+ using V = absl::variant<float, volatile int, const char*>; >+ EXPECT_TRUE( >+ (std::is_same<float, absl::variant_alternative_t<0, V>>::value)); >+ EXPECT_TRUE((std::is_same<const float, >+ absl::variant_alternative_t<0, const V>>::value)); >+ EXPECT_TRUE( >+ (std::is_same<volatile float, >+ absl::variant_alternative_t<0, volatile V>>::value)); >+ EXPECT_TRUE(( >+ std::is_same<const volatile float, >+ absl::variant_alternative_t<0, const volatile V>>::value)); >+ >+ EXPECT_TRUE( >+ (std::is_same<volatile int, absl::variant_alternative_t<1, V>>::value)); >+ EXPECT_TRUE((std::is_same<const volatile int, >+ absl::variant_alternative_t<1, const V>>::value)); >+ EXPECT_TRUE( >+ (std::is_same<volatile int, >+ absl::variant_alternative_t<1, volatile V>>::value)); >+ EXPECT_TRUE(( >+ std::is_same<const volatile int, >+ absl::variant_alternative_t<1, const volatile V>>::value)); >+ >+ EXPECT_TRUE( >+ (std::is_same<const char*, absl::variant_alternative_t<2, V>>::value)); >+ EXPECT_TRUE((std::is_same<const char* const, >+ absl::variant_alternative_t<2, const V>>::value)); >+ EXPECT_TRUE( >+ (std::is_same<const char* volatile, >+ absl::variant_alternative_t<2, volatile V>>::value)); >+ EXPECT_TRUE(( >+ std::is_same<const char* const volatile, >+ absl::variant_alternative_t<2, const volatile V>>::value)); >+ } >+} >+ >+/////////////////// >+// [variant.get] // >+/////////////////// >+ >+TEST(VariantTest, HoldsAlternative) { >+ using Var = variant<int, std::string, double>; >+ >+ Var v = 1; >+ EXPECT_TRUE(absl::holds_alternative<int>(v)); >+ EXPECT_FALSE(absl::holds_alternative<std::string>(v)); >+ EXPECT_FALSE(absl::holds_alternative<double>(v)); >+ v = "str"; >+ EXPECT_FALSE(absl::holds_alternative<int>(v)); >+ EXPECT_TRUE(absl::holds_alternative<std::string>(v)); >+ EXPECT_FALSE(absl::holds_alternative<double>(v)); >+ v = 0.; >+ EXPECT_FALSE(absl::holds_alternative<int>(v)); >+ EXPECT_FALSE(absl::holds_alternative<std::string>(v)); >+ EXPECT_TRUE(absl::holds_alternative<double>(v)); >+ >+ Var v2 = v; >+ EXPECT_FALSE(absl::holds_alternative<int>(v2)); >+ EXPECT_FALSE(absl::holds_alternative<std::string>(v2)); >+ EXPECT_TRUE(absl::holds_alternative<double>(v2)); >+ v2.emplace<int>(3); >+ EXPECT_TRUE(absl::holds_alternative<int>(v2)); >+ EXPECT_FALSE(absl::holds_alternative<std::string>(v2)); >+ EXPECT_FALSE(absl::holds_alternative<double>(v2)); >+} >+ >+TEST(VariantTest, GetIndex) { >+ using Var = variant<int, std::string, double, int>; >+ >+ { >+ Var v(absl::in_place_index_t<0>{}, 0); >+ >+ using LValueGetType = decltype(absl::get<0>(v)); >+ using RValueGetType = decltype(absl::get<0>(absl::move(v))); >+ >+ EXPECT_TRUE((std::is_same<LValueGetType, int&>::value)); >+ EXPECT_TRUE((std::is_same<RValueGetType, int&&>::value)); >+ EXPECT_EQ(absl::get<0>(v), 0); >+ EXPECT_EQ(absl::get<0>(absl::move(v)), 0); >+ >+ const Var& const_v = v; >+ using ConstLValueGetType = decltype(absl::get<0>(const_v)); >+ using ConstRValueGetType = decltype(absl::get<0>(absl::move(const_v))); >+ EXPECT_TRUE((std::is_same<ConstLValueGetType, const int&>::value)); >+ EXPECT_TRUE((std::is_same<ConstRValueGetType, const int&&>::value)); >+ EXPECT_EQ(absl::get<0>(const_v), 0); >+ EXPECT_EQ(absl::get<0>(absl::move(const_v)), 0); >+ } >+ >+ { >+ Var v = std::string("Hello"); >+ >+ using LValueGetType = decltype(absl::get<1>(v)); >+ using RValueGetType = decltype(absl::get<1>(absl::move(v))); >+ >+ EXPECT_TRUE((std::is_same<LValueGetType, std::string&>::value)); >+ EXPECT_TRUE((std::is_same<RValueGetType, std::string&&>::value)); >+ EXPECT_EQ(absl::get<1>(v), "Hello"); >+ EXPECT_EQ(absl::get<1>(absl::move(v)), "Hello"); >+ >+ const Var& const_v = v; >+ using ConstLValueGetType = decltype(absl::get<1>(const_v)); >+ using ConstRValueGetType = decltype(absl::get<1>(absl::move(const_v))); >+ EXPECT_TRUE((std::is_same<ConstLValueGetType, const std::string&>::value)); >+ EXPECT_TRUE((std::is_same<ConstRValueGetType, const std::string&&>::value)); >+ EXPECT_EQ(absl::get<1>(const_v), "Hello"); >+ EXPECT_EQ(absl::get<1>(absl::move(const_v)), "Hello"); >+ } >+ >+ { >+ Var v = 2.0; >+ >+ using LValueGetType = decltype(absl::get<2>(v)); >+ using RValueGetType = decltype(absl::get<2>(absl::move(v))); >+ >+ EXPECT_TRUE((std::is_same<LValueGetType, double&>::value)); >+ EXPECT_TRUE((std::is_same<RValueGetType, double&&>::value)); >+ EXPECT_EQ(absl::get<2>(v), 2.); >+ EXPECT_EQ(absl::get<2>(absl::move(v)), 2.); >+ >+ const Var& const_v = v; >+ using ConstLValueGetType = decltype(absl::get<2>(const_v)); >+ using ConstRValueGetType = decltype(absl::get<2>(absl::move(const_v))); >+ EXPECT_TRUE((std::is_same<ConstLValueGetType, const double&>::value)); >+ EXPECT_TRUE((std::is_same<ConstRValueGetType, const double&&>::value)); >+ EXPECT_EQ(absl::get<2>(const_v), 2.); >+ EXPECT_EQ(absl::get<2>(absl::move(const_v)), 2.); >+ } >+ >+ { >+ Var v(absl::in_place_index_t<0>{}, 0); >+ v.emplace<3>(1); >+ >+ using LValueGetType = decltype(absl::get<3>(v)); >+ using RValueGetType = decltype(absl::get<3>(absl::move(v))); >+ >+ EXPECT_TRUE((std::is_same<LValueGetType, int&>::value)); >+ EXPECT_TRUE((std::is_same<RValueGetType, int&&>::value)); >+ EXPECT_EQ(absl::get<3>(v), 1); >+ EXPECT_EQ(absl::get<3>(absl::move(v)), 1); >+ >+ const Var& const_v = v; >+ using ConstLValueGetType = decltype(absl::get<3>(const_v)); >+ using ConstRValueGetType = decltype(absl::get<3>(absl::move(const_v))); >+ EXPECT_TRUE((std::is_same<ConstLValueGetType, const int&>::value)); >+ EXPECT_TRUE((std::is_same<ConstRValueGetType, const int&&>::value)); >+ EXPECT_EQ(absl::get<3>(const_v), 1); >+ EXPECT_EQ(absl::get<3>(absl::move(const_v)), 1); // NOLINT >+ } >+} >+ >+TEST(VariantTest, BadGetIndex) { >+ using Var = variant<int, std::string, double>; >+ >+ { >+ Var v = 1; >+ >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<1>(v)); >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<1>(std::move(v))); >+ >+ const Var& const_v = v; >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<1>(const_v)); >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS( >+ absl::get<1>(std::move(const_v))); // NOLINT >+ } >+ >+ { >+ Var v = std::string("Hello"); >+ >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<0>(v)); >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<0>(std::move(v))); >+ >+ const Var& const_v = v; >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<0>(const_v)); >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS( >+ absl::get<0>(std::move(const_v))); // NOLINT >+ } >+} >+ >+TEST(VariantTest, GetType) { >+ using Var = variant<int, std::string, double>; >+ >+ { >+ Var v = 1; >+ >+ using LValueGetType = decltype(absl::get<int>(v)); >+ using RValueGetType = decltype(absl::get<int>(absl::move(v))); >+ >+ EXPECT_TRUE((std::is_same<LValueGetType, int&>::value)); >+ EXPECT_TRUE((std::is_same<RValueGetType, int&&>::value)); >+ EXPECT_EQ(absl::get<int>(v), 1); >+ EXPECT_EQ(absl::get<int>(absl::move(v)), 1); >+ >+ const Var& const_v = v; >+ using ConstLValueGetType = decltype(absl::get<int>(const_v)); >+ using ConstRValueGetType = decltype(absl::get<int>(absl::move(const_v))); >+ EXPECT_TRUE((std::is_same<ConstLValueGetType, const int&>::value)); >+ EXPECT_TRUE((std::is_same<ConstRValueGetType, const int&&>::value)); >+ EXPECT_EQ(absl::get<int>(const_v), 1); >+ EXPECT_EQ(absl::get<int>(absl::move(const_v)), 1); >+ } >+ >+ { >+ Var v = std::string("Hello"); >+ >+ using LValueGetType = decltype(absl::get<1>(v)); >+ using RValueGetType = decltype(absl::get<1>(absl::move(v))); >+ >+ EXPECT_TRUE((std::is_same<LValueGetType, std::string&>::value)); >+ EXPECT_TRUE((std::is_same<RValueGetType, std::string&&>::value)); >+ EXPECT_EQ(absl::get<std::string>(v), "Hello"); >+ EXPECT_EQ(absl::get<std::string>(absl::move(v)), "Hello"); >+ >+ const Var& const_v = v; >+ using ConstLValueGetType = decltype(absl::get<1>(const_v)); >+ using ConstRValueGetType = decltype(absl::get<1>(absl::move(const_v))); >+ EXPECT_TRUE((std::is_same<ConstLValueGetType, const std::string&>::value)); >+ EXPECT_TRUE((std::is_same<ConstRValueGetType, const std::string&&>::value)); >+ EXPECT_EQ(absl::get<std::string>(const_v), "Hello"); >+ EXPECT_EQ(absl::get<std::string>(absl::move(const_v)), "Hello"); >+ } >+ >+ { >+ Var v = 2.0; >+ >+ using LValueGetType = decltype(absl::get<2>(v)); >+ using RValueGetType = decltype(absl::get<2>(absl::move(v))); >+ >+ EXPECT_TRUE((std::is_same<LValueGetType, double&>::value)); >+ EXPECT_TRUE((std::is_same<RValueGetType, double&&>::value)); >+ EXPECT_EQ(absl::get<double>(v), 2.); >+ EXPECT_EQ(absl::get<double>(absl::move(v)), 2.); >+ >+ const Var& const_v = v; >+ using ConstLValueGetType = decltype(absl::get<2>(const_v)); >+ using ConstRValueGetType = decltype(absl::get<2>(absl::move(const_v))); >+ EXPECT_TRUE((std::is_same<ConstLValueGetType, const double&>::value)); >+ EXPECT_TRUE((std::is_same<ConstRValueGetType, const double&&>::value)); >+ EXPECT_EQ(absl::get<double>(const_v), 2.); >+ EXPECT_EQ(absl::get<double>(absl::move(const_v)), 2.); >+ } >+} >+ >+TEST(VariantTest, BadGetType) { >+ using Var = variant<int, std::string, double>; >+ >+ { >+ Var v = 1; >+ >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<std::string>(v)); >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS( >+ absl::get<std::string>(std::move(v))); >+ >+ const Var& const_v = v; >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<std::string>(const_v)); >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS( >+ absl::get<std::string>(std::move(const_v))); // NOLINT >+ } >+ >+ { >+ Var v = std::string("Hello"); >+ >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<int>(v)); >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<int>(std::move(v))); >+ >+ const Var& const_v = v; >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<int>(const_v)); >+ ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS( >+ absl::get<int>(std::move(const_v))); // NOLINT >+ } >+} >+ >+TEST(VariantTest, GetIfIndex) { >+ using Var = variant<int, std::string, double, int>; >+ >+ { >+ Var v(absl::in_place_index_t<0>{}, 0); >+ EXPECT_TRUE(noexcept(absl::get_if<0>(&v))); >+ >+ { >+ auto* elem = absl::get_if<0>(&v); >+ EXPECT_TRUE((std::is_same<decltype(elem), int*>::value)); >+ ASSERT_NE(elem, nullptr); >+ EXPECT_EQ(*elem, 0); >+ { >+ auto* bad_elem = absl::get_if<1>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), std::string*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<2>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), double*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<3>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), int*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ } >+ >+ const Var& const_v = v; >+ EXPECT_TRUE(noexcept(absl::get_if<0>(&const_v))); >+ >+ { >+ auto* elem = absl::get_if<0>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(elem), const int*>::value)); >+ ASSERT_NE(elem, nullptr); >+ EXPECT_EQ(*elem, 0); >+ { >+ auto* bad_elem = absl::get_if<1>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const std::string*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<2>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const double*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<3>(&const_v); >+ EXPECT_EQ(bad_elem, nullptr); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const int*>::value)); >+ } >+ } >+ } >+ >+ { >+ Var v = std::string("Hello"); >+ EXPECT_TRUE(noexcept(absl::get_if<1>(&v))); >+ >+ { >+ auto* elem = absl::get_if<1>(&v); >+ EXPECT_TRUE((std::is_same<decltype(elem), std::string*>::value)); >+ ASSERT_NE(elem, nullptr); >+ EXPECT_EQ(*elem, "Hello"); >+ { >+ auto* bad_elem = absl::get_if<0>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), int*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<2>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), double*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<3>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), int*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ } >+ >+ const Var& const_v = v; >+ EXPECT_TRUE(noexcept(absl::get_if<1>(&const_v))); >+ >+ { >+ auto* elem = absl::get_if<1>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(elem), const std::string*>::value)); >+ ASSERT_NE(elem, nullptr); >+ EXPECT_EQ(*elem, "Hello"); >+ { >+ auto* bad_elem = absl::get_if<0>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const int*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<2>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const double*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<3>(&const_v); >+ EXPECT_EQ(bad_elem, nullptr); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const int*>::value)); >+ } >+ } >+ } >+ >+ { >+ Var v = 2.0; >+ EXPECT_TRUE(noexcept(absl::get_if<2>(&v))); >+ >+ { >+ auto* elem = absl::get_if<2>(&v); >+ EXPECT_TRUE((std::is_same<decltype(elem), double*>::value)); >+ ASSERT_NE(elem, nullptr); >+ EXPECT_EQ(*elem, 2.0); >+ { >+ auto* bad_elem = absl::get_if<0>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), int*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<1>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), std::string*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<3>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), int*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ } >+ >+ const Var& const_v = v; >+ EXPECT_TRUE(noexcept(absl::get_if<2>(&const_v))); >+ >+ { >+ auto* elem = absl::get_if<2>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(elem), const double*>::value)); >+ ASSERT_NE(elem, nullptr); >+ EXPECT_EQ(*elem, 2.0); >+ { >+ auto* bad_elem = absl::get_if<0>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const int*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<1>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const std::string*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<3>(&const_v); >+ EXPECT_EQ(bad_elem, nullptr); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const int*>::value)); >+ } >+ } >+ } >+ >+ { >+ Var v(absl::in_place_index_t<0>{}, 0); >+ v.emplace<3>(1); >+ EXPECT_TRUE(noexcept(absl::get_if<3>(&v))); >+ >+ { >+ auto* elem = absl::get_if<3>(&v); >+ EXPECT_TRUE((std::is_same<decltype(elem), int*>::value)); >+ ASSERT_NE(elem, nullptr); >+ EXPECT_EQ(*elem, 1); >+ { >+ auto* bad_elem = absl::get_if<0>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), int*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<1>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), std::string*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<2>(&v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), double*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ } >+ >+ const Var& const_v = v; >+ EXPECT_TRUE(noexcept(absl::get_if<3>(&const_v))); >+ >+ { >+ auto* elem = absl::get_if<3>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(elem), const int*>::value)); >+ ASSERT_NE(elem, nullptr); >+ EXPECT_EQ(*elem, 1); >+ { >+ auto* bad_elem = absl::get_if<0>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const int*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<1>(&const_v); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const std::string*>::value)); >+ EXPECT_EQ(bad_elem, nullptr); >+ } >+ { >+ auto* bad_elem = absl::get_if<2>(&const_v); >+ EXPECT_EQ(bad_elem, nullptr); >+ EXPECT_TRUE((std::is_same<decltype(bad_elem), const double*>::value)); >+ } >+ } >+ } >+} >+ >+////////////////////// >+// [variant.relops] // >+////////////////////// >+ >+TEST(VariantTest, OperatorEquals) { >+ variant<int, std::string> a(1), b(1); >+ EXPECT_TRUE(a == b); >+ EXPECT_TRUE(b == a); >+ EXPECT_FALSE(a != b); >+ EXPECT_FALSE(b != a); >+ >+ b = "str"; >+ EXPECT_FALSE(a == b); >+ EXPECT_FALSE(b == a); >+ EXPECT_TRUE(a != b); >+ EXPECT_TRUE(b != a); >+ >+ b = 0; >+ EXPECT_FALSE(a == b); >+ EXPECT_FALSE(b == a); >+ EXPECT_TRUE(a != b); >+ EXPECT_TRUE(b != a); >+ >+ a = b = "foo"; >+ EXPECT_TRUE(a == b); >+ EXPECT_TRUE(b == a); >+ EXPECT_FALSE(a != b); >+ EXPECT_FALSE(b != a); >+ >+ a = "bar"; >+ EXPECT_FALSE(a == b); >+ EXPECT_FALSE(b == a); >+ EXPECT_TRUE(a != b); >+ EXPECT_TRUE(b != a); >+} >+ >+TEST(VariantTest, OperatorRelational) { >+ variant<int, std::string> a(1), b(1); >+ EXPECT_FALSE(a < b); >+ EXPECT_FALSE(b < a); >+ EXPECT_FALSE(a > b); >+ EXPECT_FALSE(b > a); >+ EXPECT_TRUE(a <= b); >+ EXPECT_TRUE(b <= a); >+ EXPECT_TRUE(a >= b); >+ EXPECT_TRUE(b >= a); >+ >+ b = "str"; >+ EXPECT_TRUE(a < b); >+ EXPECT_FALSE(b < a); >+ EXPECT_FALSE(a > b); >+ EXPECT_TRUE(b > a); >+ EXPECT_TRUE(a <= b); >+ EXPECT_FALSE(b <= a); >+ EXPECT_FALSE(a >= b); >+ EXPECT_TRUE(b >= a); >+ >+ b = 0; >+ EXPECT_FALSE(a < b); >+ EXPECT_TRUE(b < a); >+ EXPECT_TRUE(a > b); >+ EXPECT_FALSE(b > a); >+ EXPECT_FALSE(a <= b); >+ EXPECT_TRUE(b <= a); >+ EXPECT_TRUE(a >= b); >+ EXPECT_FALSE(b >= a); >+ >+ a = b = "foo"; >+ EXPECT_FALSE(a < b); >+ EXPECT_FALSE(b < a); >+ EXPECT_FALSE(a > b); >+ EXPECT_FALSE(b > a); >+ EXPECT_TRUE(a <= b); >+ EXPECT_TRUE(b <= a); >+ EXPECT_TRUE(a >= b); >+ EXPECT_TRUE(b >= a); >+ >+ a = "bar"; >+ EXPECT_TRUE(a < b); >+ EXPECT_FALSE(b < a); >+ EXPECT_FALSE(a > b); >+ EXPECT_TRUE(b > a); >+ EXPECT_TRUE(a <= b); >+ EXPECT_FALSE(b <= a); >+ EXPECT_FALSE(a >= b); >+ EXPECT_TRUE(b >= a); >+} >+ >+#ifdef ABSL_HAVE_EXCEPTIONS >+ >+TEST(VariantTest, ValuelessOperatorEquals) { >+ variant<MoveCanThrow, std::string> int_v(1), string_v("Hello"), >+ valueless(absl::in_place_index_t<0>{}), >+ other_valueless(absl::in_place_index_t<0>{}); >+ ToValuelessByException(valueless); >+ ToValuelessByException(other_valueless); >+ >+ EXPECT_TRUE(valueless == other_valueless); >+ EXPECT_TRUE(other_valueless == valueless); >+ EXPECT_FALSE(valueless == int_v); >+ EXPECT_FALSE(valueless == string_v); >+ EXPECT_FALSE(int_v == valueless); >+ EXPECT_FALSE(string_v == valueless); >+ >+ EXPECT_FALSE(valueless != other_valueless); >+ EXPECT_FALSE(other_valueless != valueless); >+ EXPECT_TRUE(valueless != int_v); >+ EXPECT_TRUE(valueless != string_v); >+ EXPECT_TRUE(int_v != valueless); >+ EXPECT_TRUE(string_v != valueless); >+} >+ >+TEST(VariantTest, ValuelessOperatorRelational) { >+ variant<MoveCanThrow, std::string> int_v(1), string_v("Hello"), >+ valueless(absl::in_place_index_t<0>{}), >+ other_valueless(absl::in_place_index_t<0>{}); >+ ToValuelessByException(valueless); >+ ToValuelessByException(other_valueless); >+ >+ EXPECT_FALSE(valueless < other_valueless); >+ EXPECT_FALSE(other_valueless < valueless); >+ EXPECT_TRUE(valueless < int_v); >+ EXPECT_TRUE(valueless < string_v); >+ EXPECT_FALSE(int_v < valueless); >+ EXPECT_FALSE(string_v < valueless); >+ >+ EXPECT_TRUE(valueless <= other_valueless); >+ EXPECT_TRUE(other_valueless <= valueless); >+ EXPECT_TRUE(valueless <= int_v); >+ EXPECT_TRUE(valueless <= string_v); >+ EXPECT_FALSE(int_v <= valueless); >+ EXPECT_FALSE(string_v <= valueless); >+ >+ EXPECT_TRUE(valueless >= other_valueless); >+ EXPECT_TRUE(other_valueless >= valueless); >+ EXPECT_FALSE(valueless >= int_v); >+ EXPECT_FALSE(valueless >= string_v); >+ EXPECT_TRUE(int_v >= valueless); >+ EXPECT_TRUE(string_v >= valueless); >+ >+ EXPECT_FALSE(valueless > other_valueless); >+ EXPECT_FALSE(other_valueless > valueless); >+ EXPECT_FALSE(valueless > int_v); >+ EXPECT_FALSE(valueless > string_v); >+ EXPECT_TRUE(int_v > valueless); >+ EXPECT_TRUE(string_v > valueless); >+} >+ >+#endif >+ >+///////////////////// >+// [variant.visit] // >+///////////////////// >+ >+template <typename T> >+struct ConvertTo { >+ template <typename U> >+ T operator()(const U& u) const { >+ return u; >+ } >+}; >+ >+TEST(VariantTest, VisitSimple) { >+ variant<std::string, const char*> v = "A"; >+ >+ std::string str = absl::visit(ConvertTo<std::string>{}, v); >+ EXPECT_EQ("A", str); >+ >+ v = std::string("B"); >+ >+ absl::string_view piece = absl::visit(ConvertTo<absl::string_view>{}, v); >+ EXPECT_EQ("B", piece); >+ >+ struct StrLen { >+ int operator()(const std::string& s) const { return s.size(); } >+ int operator()(const char* s) const { return strlen(s); } >+ }; >+ >+ v = "SomeStr"; >+ EXPECT_EQ(7, absl::visit(StrLen{}, v)); >+ v = std::string("VeryLargeThisTime"); >+ EXPECT_EQ(17, absl::visit(StrLen{}, v)); >+} >+ >+TEST(VariantTest, VisitRValue) { >+ variant<std::string> v = std::string("X"); >+ struct Visitor { >+ bool operator()(const std::string&) const { return false; } >+ bool operator()(std::string&&) const { return true; } // NOLINT >+ >+ int operator()(const std::string&, const std::string&) const { return 0; } >+ int operator()(const std::string&, std::string&&) const { return 1; } // NOLINT >+ int operator()(std::string&&, const std::string&) const { return 2; } // NOLINT >+ int operator()(std::string&&, std::string&&) const { return 3; } // NOLINT >+ }; >+ EXPECT_FALSE(absl::visit(Visitor{}, v)); >+ EXPECT_TRUE(absl::visit(Visitor{}, absl::move(v))); >+ >+ // Also test the variadic overload. >+ EXPECT_EQ(0, absl::visit(Visitor{}, v, v)); >+ EXPECT_EQ(1, absl::visit(Visitor{}, v, absl::move(v))); >+ EXPECT_EQ(2, absl::visit(Visitor{}, absl::move(v), v)); >+ EXPECT_EQ(3, absl::visit(Visitor{}, absl::move(v), absl::move(v))); >+} >+ >+TEST(VariantTest, VisitRValueVisitor) { >+ variant<std::string> v = std::string("X"); >+ struct Visitor { >+ bool operator()(const std::string&) const& { return false; } >+ bool operator()(const std::string&) && { return true; } >+ }; >+ Visitor visitor; >+ EXPECT_FALSE(absl::visit(visitor, v)); >+ EXPECT_TRUE(absl::visit(Visitor{}, v)); >+} >+ >+TEST(VariantTest, VisitResultTypeDifferent) { >+ variant<std::string> v = std::string("X"); >+ struct LValue_LValue {}; >+ struct RValue_LValue {}; >+ struct LValue_RValue {}; >+ struct RValue_RValue {}; >+ struct Visitor { >+ LValue_LValue operator()(const std::string&) const& { return {}; } >+ RValue_LValue operator()(std::string&&) const& { return {}; } // NOLINT >+ LValue_RValue operator()(const std::string&) && { return {}; } >+ RValue_RValue operator()(std::string&&) && { return {}; } // NOLINT >+ } visitor; >+ >+ EXPECT_TRUE( >+ (std::is_same<LValue_LValue, decltype(absl::visit(visitor, v))>::value)); >+ EXPECT_TRUE( >+ (std::is_same<RValue_LValue, >+ decltype(absl::visit(visitor, absl::move(v)))>::value)); >+ EXPECT_TRUE(( >+ std::is_same<LValue_RValue, decltype(absl::visit(Visitor{}, v))>::value)); >+ EXPECT_TRUE( >+ (std::is_same<RValue_RValue, >+ decltype(absl::visit(Visitor{}, absl::move(v)))>::value)); >+} >+ >+TEST(VariantTest, VisitVariadic) { >+ using A = variant<int, std::string>; >+ using B = variant<std::unique_ptr<int>, absl::string_view>; >+ >+ struct Visitor { >+ std::pair<int, int> operator()(int a, std::unique_ptr<int> b) const { >+ return {a, *b}; >+ } >+ std::pair<int, int> operator()(absl::string_view a, >+ std::unique_ptr<int> b) const { >+ return {static_cast<int>(a.size()), static_cast<int>(*b)}; >+ } >+ std::pair<int, int> operator()(int a, absl::string_view b) const { >+ return {a, static_cast<int>(b.size())}; >+ } >+ std::pair<int, int> operator()(absl::string_view a, >+ absl::string_view b) const { >+ return {static_cast<int>(a.size()), static_cast<int>(b.size())}; >+ } >+ }; >+ >+ EXPECT_THAT(absl::visit(Visitor(), A(1), B(std::unique_ptr<int>(new int(7)))), >+ ::testing::Pair(1, 7)); >+ EXPECT_THAT(absl::visit(Visitor(), A(1), B(absl::string_view("ABC"))), >+ ::testing::Pair(1, 3)); >+ EXPECT_THAT(absl::visit(Visitor(), A(std::string("BBBBB")), >+ B(std::unique_ptr<int>(new int(7)))), >+ ::testing::Pair(5, 7)); >+ EXPECT_THAT( >+ absl::visit(Visitor(), A(std::string("BBBBB")), B(absl::string_view("ABC"))), >+ ::testing::Pair(5, 3)); >+} >+ >+TEST(VariantTest, VisitNoArgs) { >+ EXPECT_EQ(5, absl::visit([] { return 5; })); >+} >+ >+struct ConstFunctor { >+ int operator()(int a, int b) const { return a - b; } >+}; >+ >+struct MutableFunctor { >+ int operator()(int a, int b) { return a - b; } >+}; >+ >+struct Class { >+ int Method(int a, int b) { return a - b; } >+ int ConstMethod(int a, int b) const { return a - b; } >+ >+ int member; >+}; >+ >+TEST(VariantTest, VisitReferenceWrapper) { >+ ConstFunctor cf; >+ MutableFunctor mf; >+ absl::variant<int> three = 3; >+ absl::variant<int> two = 2; >+ >+ EXPECT_EQ(1, absl::visit(std::cref(cf), three, two)); >+ EXPECT_EQ(1, absl::visit(std::ref(cf), three, two)); >+ EXPECT_EQ(1, absl::visit(std::ref(mf), three, two)); >+} >+ >+// libstdc++ std::variant doesn't support the INVOKE semantics. >+#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) >+TEST(VariantTest, VisitMemberFunction) { >+ absl::variant<std::unique_ptr<Class>> p(absl::make_unique<Class>()); >+ absl::variant<std::unique_ptr<const Class>> cp( >+ absl::make_unique<const Class>()); >+ absl::variant<int> three = 3; >+ absl::variant<int> two = 2; >+ >+ EXPECT_EQ(1, absl::visit(&Class::Method, p, three, two)); >+ EXPECT_EQ(1, absl::visit(&Class::ConstMethod, p, three, two)); >+ EXPECT_EQ(1, absl::visit(&Class::ConstMethod, cp, three, two)); >+} >+ >+TEST(VariantTest, VisitDataMember) { >+ absl::variant<std::unique_ptr<Class>> p(absl::make_unique<Class>(Class{42})); >+ absl::variant<std::unique_ptr<const Class>> cp( >+ absl::make_unique<const Class>(Class{42})); >+ EXPECT_EQ(42, absl::visit(&Class::member, p)); >+ >+ absl::visit(&Class::member, p) = 5; >+ EXPECT_EQ(5, absl::visit(&Class::member, p)); >+ >+ EXPECT_EQ(42, absl::visit(&Class::member, cp)); >+} >+#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) >+ >+///////////////////////// >+// [variant.monostate] // >+///////////////////////// >+ >+TEST(VariantTest, MonostateBasic) { >+ absl::monostate mono; >+ (void)mono; >+ >+ // TODO(mattcalabrese) Expose move triviality metafunctions in absl. >+ EXPECT_TRUE(absl::is_trivially_default_constructible<absl::monostate>::value); >+ EXPECT_TRUE(is_trivially_move_constructible<absl::monostate>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<absl::monostate>::value); >+ EXPECT_TRUE(is_trivially_move_assignable<absl::monostate>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<absl::monostate>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<absl::monostate>::value); >+} >+ >+TEST(VariantTest, VariantMonostateDefaultConstruction) { >+ absl::variant<absl::monostate, NonDefaultConstructible> var; >+ EXPECT_EQ(var.index(), 0); >+} >+ >+//////////////////////////////// >+// [variant.monostate.relops] // >+//////////////////////////////// >+ >+TEST(VariantTest, MonostateComparisons) { >+ absl::monostate lhs, rhs; >+ >+ EXPECT_EQ(lhs, lhs); >+ EXPECT_EQ(lhs, rhs); >+ >+ EXPECT_FALSE(lhs != lhs); >+ EXPECT_FALSE(lhs != rhs); >+ EXPECT_FALSE(lhs < lhs); >+ EXPECT_FALSE(lhs < rhs); >+ EXPECT_FALSE(lhs > lhs); >+ EXPECT_FALSE(lhs > rhs); >+ >+ EXPECT_LE(lhs, lhs); >+ EXPECT_LE(lhs, rhs); >+ EXPECT_GE(lhs, lhs); >+ EXPECT_GE(lhs, rhs); >+ >+ EXPECT_TRUE(noexcept(std::declval<absl::monostate>() == >+ std::declval<absl::monostate>())); >+ EXPECT_TRUE(noexcept(std::declval<absl::monostate>() != >+ std::declval<absl::monostate>())); >+ EXPECT_TRUE(noexcept(std::declval<absl::monostate>() < >+ std::declval<absl::monostate>())); >+ EXPECT_TRUE(noexcept(std::declval<absl::monostate>() > >+ std::declval<absl::monostate>())); >+ EXPECT_TRUE(noexcept(std::declval<absl::monostate>() <= >+ std::declval<absl::monostate>())); >+ EXPECT_TRUE(noexcept(std::declval<absl::monostate>() >= >+ std::declval<absl::monostate>())); >+} >+ >+/////////////////////// >+// [variant.specalg] // >+/////////////////////// >+ >+TEST(VariantTest, NonmemberSwap) { >+ using std::swap; >+ >+ SpecialSwap v1(3); >+ SpecialSwap v2(7); >+ >+ variant<SpecialSwap> a = v1, b = v2; >+ >+ EXPECT_THAT(a, VariantWith<SpecialSwap>(v1)); >+ EXPECT_THAT(b, VariantWith<SpecialSwap>(v2)); >+ >+ std::swap(a, b); >+ EXPECT_THAT(a, VariantWith<SpecialSwap>(v2)); >+ EXPECT_THAT(b, VariantWith<SpecialSwap>(v1)); >+#ifndef ABSL_HAVE_STD_VARIANT >+ EXPECT_FALSE(absl::get<SpecialSwap>(a).special_swap); >+#endif >+ >+ swap(a, b); >+ EXPECT_THAT(a, VariantWith<SpecialSwap>(v1)); >+ EXPECT_THAT(b, VariantWith<SpecialSwap>(v2)); >+ EXPECT_TRUE(absl::get<SpecialSwap>(b).special_swap); >+} >+ >+////////////////////////// >+// [variant.bad.access] // >+////////////////////////// >+ >+TEST(VariantTest, BadAccess) { >+ EXPECT_TRUE(noexcept(absl::bad_variant_access())); >+ absl::bad_variant_access exception_obj; >+ std::exception* base = &exception_obj; >+ (void)base; >+} >+ >+//////////////////// >+// [variant.hash] // >+//////////////////// >+ >+TEST(VariantTest, MonostateHash) { >+ absl::monostate mono, other_mono; >+ std::hash<absl::monostate> const hasher{}; >+ static_assert(std::is_same<decltype(hasher(mono)), std::size_t>::value, ""); >+ EXPECT_EQ(hasher(mono), hasher(other_mono)); >+} >+ >+TEST(VariantTest, Hash) { >+ static_assert(type_traits_internal::IsHashEnabled<variant<int>>::value, ""); >+ static_assert(type_traits_internal::IsHashEnabled<variant<Hashable>>::value, >+ ""); >+ static_assert( >+ type_traits_internal::IsHashEnabled<variant<int, Hashable>>::value, ""); >+ >+#if defined(_MSC_VER) || \ >+ (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 4000 && \ >+ _LIBCPP_STD_VER > 11) || \ >+ defined(__APPLE__) >+ // For MSVC and libc++ (< 4.0 and c++14), std::hash primary template has a >+ // static_assert to catch any user-defined type T that doesn't provide a hash >+ // specialization. So instantiating std::hash<variant<T>> will result >+ // in a hard error which is not SFINAE friendly. >+#define ABSL_STD_HASH_NOT_SFINAE_FRIENDLY 1 >+#endif >+ >+#ifndef ABSL_STD_HASH_NOT_SFINAE_FRIENDLY >+ static_assert( >+ !type_traits_internal::IsHashEnabled<variant<NonHashable>>::value, ""); >+ static_assert(!type_traits_internal::IsHashEnabled< >+ variant<Hashable, NonHashable>>::value, >+ ""); >+#endif >+ >+// MSVC std::hash<std::variant> does not use the index, thus produce the same >+// result on the same value as different alternative. >+#if !(defined(_MSC_VER) && defined(ABSL_HAVE_STD_VARIANT)) >+ { >+ // same value as different alternative >+ variant<int, int> v0(in_place_index_t<0>{}, 42); >+ variant<int, int> v1(in_place_index_t<1>{}, 42); >+ std::hash<variant<int, int>> hash; >+ EXPECT_NE(hash(v0), hash(v1)); >+ } >+#endif // !(defined(_MSC_VER) && defined(ABSL_HAVE_STD_VARIANT)) >+ >+ { >+ std::hash<variant<int>> hash; >+ std::set<size_t> hashcodes; >+ for (int i = 0; i < 100; ++i) { >+ hashcodes.insert(hash(i)); >+ } >+ EXPECT_GT(hashcodes.size(), 90); >+ >+ // test const-qualified >+ static_assert( >+ type_traits_internal::IsHashEnabled<variant<const int>>::value, ""); >+ static_assert( >+ type_traits_internal::IsHashEnabled<variant<const Hashable>>::value, >+ ""); >+ std::hash<absl::variant<const int>> c_hash; >+ for (int i = 0; i < 100; ++i) { >+ EXPECT_EQ(hash(i), c_hash(i)); >+ } >+ } >+} >+ >+//////////////////////////////////////// >+// Miscellaneous and deprecated tests // >+//////////////////////////////////////// >+ >+// Test that a set requiring a basic type conversion works correctly. >+TEST(VariantTest, TestConvertingSet) { >+ typedef variant<double> Variant; >+ Variant v(1.0); >+ const int two = 2; >+ v = two; >+ EXPECT_TRUE(absl::holds_alternative<double>(v)); >+ ASSERT_TRUE(nullptr != absl::get_if<double>(&v)); >+ EXPECT_DOUBLE_EQ(2, absl::get<double>(v)); >+} >+ >+// Test that a vector of variants behaves reasonably. >+TEST(VariantTest, Container) { >+ typedef variant<int, float> Variant; >+ >+ // Creation of vector should work >+ std::vector<Variant> vec; >+ vec.push_back(Variant(10)); >+ vec.push_back(Variant(20.0f)); >+ >+ // Vector resizing should work if we supply a value for new slots >+ vec.resize(10, Variant(0)); >+} >+ >+// Test that a variant with a non-copyable type can be constructed and >+// manipulated to some degree. >+TEST(VariantTest, TestVariantWithNonCopyableType) { >+ typedef variant<int, NonCopyable> Variant; >+ const int kValue = 1; >+ Variant v(kValue); >+ ASSERT_TRUE(absl::holds_alternative<int>(v)); >+ EXPECT_EQ(kValue, absl::get<int>(v)); >+} >+ >+// Test that a variant with a non-copyable type can be transformed to >+// the non-copyable type with a call to `emplace` for different numbers >+// of arguments. We do not need to test this for each of T1 ... T8 >+// because `emplace` does not overload on T1 ... to T8, so if this >+// works for any one of T1 ... T8, then it works for all of them. We >+// do need to test that it works with varying numbers of parameters >+// though. >+TEST(VariantTest, TestEmplace) { >+ typedef variant<int, NonCopyable> Variant; >+ const int kValue = 1; >+ Variant v(kValue); >+ ASSERT_TRUE(absl::holds_alternative<int>(v)); >+ EXPECT_EQ(kValue, absl::get<int>(v)); >+ >+ // emplace with zero arguments, then back to 'int' >+ v.emplace<NonCopyable>(); >+ ASSERT_TRUE(absl::holds_alternative<NonCopyable>(v)); >+ EXPECT_EQ(0, absl::get<NonCopyable>(v).value); >+ v = kValue; >+ ASSERT_TRUE(absl::holds_alternative<int>(v)); >+ >+ // emplace with one argument: >+ v.emplace<NonCopyable>(1); >+ ASSERT_TRUE(absl::holds_alternative<NonCopyable>(v)); >+ EXPECT_EQ(1, absl::get<NonCopyable>(v).value); >+ v = kValue; >+ ASSERT_TRUE(absl::holds_alternative<int>(v)); >+ >+ // emplace with two arguments: >+ v.emplace<NonCopyable>(1, 2); >+ ASSERT_TRUE(absl::holds_alternative<NonCopyable>(v)); >+ EXPECT_EQ(3, absl::get<NonCopyable>(v).value); >+ v = kValue; >+ ASSERT_TRUE(absl::holds_alternative<int>(v)); >+ >+ // emplace with three arguments >+ v.emplace<NonCopyable>(1, 2, 3); >+ ASSERT_TRUE(absl::holds_alternative<NonCopyable>(v)); >+ EXPECT_EQ(6, absl::get<NonCopyable>(v).value); >+ v = kValue; >+ ASSERT_TRUE(absl::holds_alternative<int>(v)); >+ >+ // emplace with four arguments >+ v.emplace<NonCopyable>(1, 2, 3, 4); >+ ASSERT_TRUE(absl::holds_alternative<NonCopyable>(v)); >+ EXPECT_EQ(10, absl::get<NonCopyable>(v).value); >+ v = kValue; >+ ASSERT_TRUE(absl::holds_alternative<int>(v)); >+} >+ >+TEST(VariantTest, TestEmplaceDestroysCurrentValue) { >+ typedef variant<int, IncrementInDtor, NonCopyable> Variant; >+ int counter = 0; >+ Variant v(0); >+ ASSERT_TRUE(absl::holds_alternative<int>(v)); >+ v.emplace<IncrementInDtor>(&counter); >+ ASSERT_TRUE(absl::holds_alternative<IncrementInDtor>(v)); >+ ASSERT_EQ(0, counter); >+ v.emplace<NonCopyable>(); >+ ASSERT_TRUE(absl::holds_alternative<NonCopyable>(v)); >+ EXPECT_EQ(1, counter); >+} >+ >+TEST(VariantTest, TestMoveSemantics) { >+ typedef variant<std::unique_ptr<int>, std::unique_ptr<std::string>> Variant; >+ >+ // Construct a variant by moving from an element value. >+ Variant v(absl::WrapUnique(new int(10))); >+ EXPECT_TRUE(absl::holds_alternative<std::unique_ptr<int>>(v)); >+ >+ // Construct a variant by moving from another variant. >+ Variant v2(absl::move(v)); >+ ASSERT_TRUE(absl::holds_alternative<std::unique_ptr<int>>(v2)); >+ ASSERT_NE(nullptr, absl::get<std::unique_ptr<int>>(v2)); >+ EXPECT_EQ(10, *absl::get<std::unique_ptr<int>>(v2)); >+ >+ // Moving from a variant object leaves it holding moved-from value of the >+ // same element type. >+ EXPECT_TRUE(absl::holds_alternative<std::unique_ptr<int>>(v)); >+ ASSERT_NE(nullptr, absl::get_if<std::unique_ptr<int>>(&v)); >+ EXPECT_EQ(nullptr, absl::get<std::unique_ptr<int>>(v)); >+ >+ // Assign a variant from an element value by move. >+ v = absl::make_unique<std::string>("foo"); >+ ASSERT_TRUE(absl::holds_alternative<std::unique_ptr<std::string>>(v)); >+ EXPECT_EQ("foo", *absl::get<std::unique_ptr<std::string>>(v)); >+ >+ // Move-assign a variant. >+ v2 = absl::move(v); >+ ASSERT_TRUE(absl::holds_alternative<std::unique_ptr<std::string>>(v2)); >+ EXPECT_EQ("foo", *absl::get<std::unique_ptr<std::string>>(v2)); >+ EXPECT_TRUE(absl::holds_alternative<std::unique_ptr<std::string>>(v)); >+} >+ >+variant<int, std::string> PassThrough(const variant<int, std::string>& arg) { >+ return arg; >+} >+ >+TEST(VariantTest, TestImplicitConversion) { >+ EXPECT_TRUE(absl::holds_alternative<int>(PassThrough(0))); >+ >+ // We still need the explicit cast for std::string, because C++ won't apply >+ // two user-defined implicit conversions in a row. >+ EXPECT_TRUE(absl::holds_alternative<std::string>(PassThrough(std::string("foo")))); >+} >+ >+struct Convertible2; >+struct Convertible1 { >+ Convertible1() {} >+ Convertible1(const Convertible1&) {} >+ Convertible1& operator=(const Convertible1&) { return *this; } >+ >+ // implicit conversion from Convertible2 >+ Convertible1(const Convertible2&) {} // NOLINT(runtime/explicit) >+}; >+ >+struct Convertible2 { >+ Convertible2() {} >+ Convertible2(const Convertible2&) {} >+ Convertible2& operator=(const Convertible2&) { return *this; } >+ >+ // implicit conversion from Convertible1 >+ Convertible2(const Convertible1&) {} // NOLINT(runtime/explicit) >+}; >+ >+TEST(VariantTest, TestRvalueConversion) { >+ variant<double, std::string> var( >+ ConvertVariantTo<variant<double, std::string>>(variant<std::string, int>(0))); >+ ASSERT_TRUE(absl::holds_alternative<double>(var)); >+ EXPECT_EQ(0.0, absl::get<double>(var)); >+ >+ var = ConvertVariantTo<variant<double, std::string>>( >+ variant<const char*, float>("foo")); >+ ASSERT_TRUE(absl::holds_alternative<std::string>(var)); >+ EXPECT_EQ("foo", absl::get<std::string>(var)); >+ >+ variant<double> singleton( >+ ConvertVariantTo<variant<double>>(variant<int, float>(42))); >+ ASSERT_TRUE(absl::holds_alternative<double>(singleton)); >+ EXPECT_EQ(42.0, absl::get<double>(singleton)); >+ >+ singleton = ConvertVariantTo<variant<double>>(variant<int, float>(3.14f)); >+ ASSERT_TRUE(absl::holds_alternative<double>(singleton)); >+ EXPECT_FLOAT_EQ(3.14f, static_cast<float>(absl::get<double>(singleton))); >+ >+ singleton = ConvertVariantTo<variant<double>>(variant<int>(0)); >+ ASSERT_TRUE(absl::holds_alternative<double>(singleton)); >+ EXPECT_EQ(0.0, absl::get<double>(singleton)); >+ >+ variant<int32_t, uint32_t> variant2( >+ ConvertVariantTo<variant<int32_t, uint32_t>>(variant<int32_t>(42))); >+ ASSERT_TRUE(absl::holds_alternative<int32_t>(variant2)); >+ EXPECT_EQ(42, absl::get<int32_t>(variant2)); >+ >+ variant2 = ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42)); >+ ASSERT_TRUE(absl::holds_alternative<uint32_t>(variant2)); >+ EXPECT_EQ(42, absl::get<uint32_t>(variant2)); >+ >+ variant<Convertible1, Convertible2> variant3( >+ ConvertVariantTo<variant<Convertible1, Convertible2>>( >+ (variant<Convertible2, Convertible1>(Convertible1())))); >+ ASSERT_TRUE(absl::holds_alternative<Convertible1>(variant3)); >+ >+ variant3 = ConvertVariantTo<variant<Convertible1, Convertible2>>( >+ variant<Convertible2, Convertible1>(Convertible2())); >+ ASSERT_TRUE(absl::holds_alternative<Convertible2>(variant3)); >+} >+ >+TEST(VariantTest, TestLvalueConversion) { >+ variant<std::string, int> source1 = 0; >+ variant<double, std::string> destination( >+ ConvertVariantTo<variant<double, std::string>>(source1)); >+ ASSERT_TRUE(absl::holds_alternative<double>(destination)); >+ EXPECT_EQ(0.0, absl::get<double>(destination)); >+ >+ variant<const char*, float> source2 = "foo"; >+ destination = ConvertVariantTo<variant<double, std::string>>(source2); >+ ASSERT_TRUE(absl::holds_alternative<std::string>(destination)); >+ EXPECT_EQ("foo", absl::get<std::string>(destination)); >+ >+ variant<int, float> source3(42); >+ variant<double> singleton(ConvertVariantTo<variant<double>>(source3)); >+ ASSERT_TRUE(absl::holds_alternative<double>(singleton)); >+ EXPECT_EQ(42.0, absl::get<double>(singleton)); >+ >+ source3 = 3.14f; >+ singleton = ConvertVariantTo<variant<double>>(source3); >+ ASSERT_TRUE(absl::holds_alternative<double>(singleton)); >+ EXPECT_FLOAT_EQ(3.14f, static_cast<float>(absl::get<double>(singleton))); >+ >+ variant<int> source4(0); >+ singleton = ConvertVariantTo<variant<double>>(source4); >+ ASSERT_TRUE(absl::holds_alternative<double>(singleton)); >+ EXPECT_EQ(0.0, absl::get<double>(singleton)); >+ >+ variant<int32_t> source5(42); >+ variant<int32_t, uint32_t> variant2( >+ ConvertVariantTo<variant<int32_t, uint32_t>>(source5)); >+ ASSERT_TRUE(absl::holds_alternative<int32_t>(variant2)); >+ EXPECT_EQ(42, absl::get<int32_t>(variant2)); >+ >+ variant<uint32_t> source6(42); >+ variant2 = ConvertVariantTo<variant<int32_t, uint32_t>>(source6); >+ ASSERT_TRUE(absl::holds_alternative<uint32_t>(variant2)); >+ EXPECT_EQ(42, absl::get<uint32_t>(variant2)); >+ >+ variant<Convertible2, Convertible1> source7((Convertible1())); >+ variant<Convertible1, Convertible2> variant3( >+ ConvertVariantTo<variant<Convertible1, Convertible2>>(source7)); >+ ASSERT_TRUE(absl::holds_alternative<Convertible1>(variant3)); >+ >+ source7 = Convertible2(); >+ variant3 = ConvertVariantTo<variant<Convertible1, Convertible2>>(source7); >+ ASSERT_TRUE(absl::holds_alternative<Convertible2>(variant3)); >+} >+ >+TEST(VariantTest, TestMoveConversion) { >+ using Variant = >+ variant<std::unique_ptr<const int>, std::unique_ptr<const std::string>>; >+ using OtherVariant = variant<std::unique_ptr<int>, std::unique_ptr<std::string>>; >+ >+ Variant var( >+ ConvertVariantTo<Variant>(OtherVariant{absl::make_unique<int>(0)})); >+ ASSERT_TRUE(absl::holds_alternative<std::unique_ptr<const int>>(var)); >+ ASSERT_NE(absl::get<std::unique_ptr<const int>>(var), nullptr); >+ EXPECT_EQ(0, *absl::get<std::unique_ptr<const int>>(var)); >+ >+ var = >+ ConvertVariantTo<Variant>(OtherVariant(absl::make_unique<std::string>("foo"))); >+ ASSERT_TRUE(absl::holds_alternative<std::unique_ptr<const std::string>>(var)); >+ EXPECT_EQ("foo", *absl::get<std::unique_ptr<const std::string>>(var)); >+} >+ >+TEST(VariantTest, DoesNotMoveFromLvalues) { >+ // We use shared_ptr here because it's both copyable and movable, and >+ // a moved-from shared_ptr is guaranteed to be null, so we can detect >+ // whether moving or copying has occurred. >+ using Variant = >+ variant<std::shared_ptr<const int>, std::shared_ptr<const std::string>>; >+ using OtherVariant = variant<std::shared_ptr<int>, std::shared_ptr<std::string>>; >+ >+ Variant v1(std::make_shared<const int>(0)); >+ >+ // Test copy constructor >+ Variant v2(v1); >+ EXPECT_EQ(absl::get<std::shared_ptr<const int>>(v1), >+ absl::get<std::shared_ptr<const int>>(v2)); >+ >+ // Test copy-assignment operator >+ v1 = std::make_shared<const std::string>("foo"); >+ v2 = v1; >+ EXPECT_EQ(absl::get<std::shared_ptr<const std::string>>(v1), >+ absl::get<std::shared_ptr<const std::string>>(v2)); >+ >+ // Test converting copy constructor >+ OtherVariant other(std::make_shared<int>(0)); >+ Variant v3(ConvertVariantTo<Variant>(other)); >+ EXPECT_EQ(absl::get<std::shared_ptr<int>>(other), >+ absl::get<std::shared_ptr<const int>>(v3)); >+ >+ other = std::make_shared<std::string>("foo"); >+ v3 = ConvertVariantTo<Variant>(other); >+ EXPECT_EQ(absl::get<std::shared_ptr<std::string>>(other), >+ absl::get<std::shared_ptr<const std::string>>(v3)); >+} >+ >+TEST(VariantTest, TestRvalueConversionViaConvertVariantTo) { >+ variant<double, std::string> var( >+ ConvertVariantTo<variant<double, std::string>>(variant<std::string, int>(3))); >+ EXPECT_THAT(absl::get_if<double>(&var), Pointee(3.0)); >+ >+ var = ConvertVariantTo<variant<double, std::string>>( >+ variant<const char*, float>("foo")); >+ EXPECT_THAT(absl::get_if<std::string>(&var), Pointee(std::string("foo"))); >+ >+ variant<double> singleton( >+ ConvertVariantTo<variant<double>>(variant<int, float>(42))); >+ EXPECT_THAT(absl::get_if<double>(&singleton), Pointee(42.0)); >+ >+ singleton = ConvertVariantTo<variant<double>>(variant<int, float>(3.14f)); >+ EXPECT_THAT(absl::get_if<double>(&singleton), Pointee(DoubleEq(3.14f))); >+ >+ singleton = ConvertVariantTo<variant<double>>(variant<int>(3)); >+ EXPECT_THAT(absl::get_if<double>(&singleton), Pointee(3.0)); >+ >+ variant<int32_t, uint32_t> variant2( >+ ConvertVariantTo<variant<int32_t, uint32_t>>(variant<int32_t>(42))); >+ EXPECT_THAT(absl::get_if<int32_t>(&variant2), Pointee(42)); >+ >+ variant2 = ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42)); >+ EXPECT_THAT(absl::get_if<uint32_t>(&variant2), Pointee(42)); >+ >+ variant<Convertible1, Convertible2> variant3( >+ ConvertVariantTo<variant<Convertible1, Convertible2>>( >+ (variant<Convertible2, Convertible1>(Convertible1())))); >+ ASSERT_TRUE(absl::holds_alternative<Convertible1>(variant3)); >+ >+ variant3 = ConvertVariantTo<variant<Convertible1, Convertible2>>( >+ variant<Convertible2, Convertible1>(Convertible2())); >+ ASSERT_TRUE(absl::holds_alternative<Convertible2>(variant3)); >+} >+ >+TEST(VariantTest, TestLvalueConversionViaConvertVariantTo) { >+ variant<std::string, int> source1 = 3; >+ variant<double, std::string> destination( >+ ConvertVariantTo<variant<double, std::string>>(source1)); >+ EXPECT_THAT(absl::get_if<double>(&destination), Pointee(3.0)); >+ >+ variant<const char*, float> source2 = "foo"; >+ destination = ConvertVariantTo<variant<double, std::string>>(source2); >+ EXPECT_THAT(absl::get_if<std::string>(&destination), Pointee(std::string("foo"))); >+ >+ variant<int, float> source3(42); >+ variant<double> singleton(ConvertVariantTo<variant<double>>(source3)); >+ EXPECT_THAT(absl::get_if<double>(&singleton), Pointee(42.0)); >+ >+ source3 = 3.14f; >+ singleton = ConvertVariantTo<variant<double>>(source3); >+ EXPECT_FLOAT_EQ(3.14f, static_cast<float>(absl::get<double>(singleton))); >+ EXPECT_THAT(absl::get_if<double>(&singleton), Pointee(DoubleEq(3.14f))); >+ >+ variant<int> source4(3); >+ singleton = ConvertVariantTo<variant<double>>(source4); >+ EXPECT_THAT(absl::get_if<double>(&singleton), Pointee(3.0)); >+ >+ variant<int32_t> source5(42); >+ variant<int32_t, uint32_t> variant2( >+ ConvertVariantTo<variant<int32_t, uint32_t>>(source5)); >+ EXPECT_THAT(absl::get_if<int32_t>(&variant2), Pointee(42)); >+ >+ variant<uint32_t> source6(42); >+ variant2 = ConvertVariantTo<variant<int32_t, uint32_t>>(source6); >+ EXPECT_THAT(absl::get_if<uint32_t>(&variant2), Pointee(42)); >+ >+ variant<Convertible2, Convertible1> source7((Convertible1())); >+ variant<Convertible1, Convertible2> variant3( >+ ConvertVariantTo<variant<Convertible1, Convertible2>>(source7)); >+ ASSERT_TRUE(absl::holds_alternative<Convertible1>(variant3)); >+ >+ source7 = Convertible2(); >+ variant3 = ConvertVariantTo<variant<Convertible1, Convertible2>>(source7); >+ ASSERT_TRUE(absl::holds_alternative<Convertible2>(variant3)); >+} >+ >+TEST(VariantTest, TestMoveConversionViaConvertVariantTo) { >+ using Variant = >+ variant<std::unique_ptr<const int>, std::unique_ptr<const std::string>>; >+ using OtherVariant = variant<std::unique_ptr<int>, std::unique_ptr<std::string>>; >+ >+ Variant var( >+ ConvertVariantTo<Variant>(OtherVariant{absl::make_unique<int>(3)})); >+ EXPECT_THAT(absl::get_if<std::unique_ptr<const int>>(&var), >+ Pointee(Pointee(3))); >+ >+ var = >+ ConvertVariantTo<Variant>(OtherVariant(absl::make_unique<std::string>("foo"))); >+ EXPECT_THAT(absl::get_if<std::unique_ptr<const std::string>>(&var), >+ Pointee(Pointee(std::string("foo")))); >+} >+ >+// If all alternatives are trivially copy/move constructible, variant should >+// also be trivially copy/move constructible. This is not required by the >+// standard and we know that libstdc++ variant doesn't have this feature. >+// For more details see the paper: >+// http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0602r0.html >+#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) >+#define ABSL_VARIANT_PROPAGATE_COPY_MOVE_TRIVIALITY 1 >+#endif >+ >+TEST(VariantTest, TestCopyAndMoveTypeTraits) { >+ EXPECT_TRUE(std::is_copy_constructible<variant<std::string>>::value); >+ EXPECT_TRUE(std::is_copy_assignable<variant<std::string>>::value); >+ EXPECT_TRUE(std::is_move_constructible<variant<std::string>>::value); >+ EXPECT_TRUE(std::is_move_assignable<variant<std::string>>::value); >+ EXPECT_TRUE(std::is_move_constructible<variant<std::unique_ptr<int>>>::value); >+ EXPECT_TRUE(std::is_move_assignable<variant<std::unique_ptr<int>>>::value); >+ EXPECT_FALSE( >+ std::is_copy_constructible<variant<std::unique_ptr<int>>>::value); >+ EXPECT_FALSE(std::is_copy_assignable<variant<std::unique_ptr<int>>>::value); >+ >+ EXPECT_FALSE( >+ absl::is_trivially_copy_constructible<variant<std::string>>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<variant<std::string>>::value); >+#if ABSL_VARIANT_PROPAGATE_COPY_MOVE_TRIVIALITY >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<variant<int>>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<variant<int>>::value); >+ EXPECT_TRUE(is_trivially_move_constructible<variant<int>>::value); >+ EXPECT_TRUE(is_trivially_move_assignable<variant<int>>::value); >+#endif // ABSL_VARIANT_PROPAGATE_COPY_MOVE_TRIVIALITY >+} >+ >+TEST(VariantTest, TestVectorOfMoveonlyVariant) { >+ // Verify that variant<MoveonlyType> works correctly as a std::vector element. >+ std::vector<variant<std::unique_ptr<int>, std::string>> vec; >+ vec.push_back(absl::make_unique<int>(42)); >+ vec.emplace_back("Hello"); >+ vec.reserve(3); >+ auto another_vec = absl::move(vec); >+ // As a sanity check, verify vector contents. >+ ASSERT_EQ(2, another_vec.size()); >+ EXPECT_EQ(42, *absl::get<std::unique_ptr<int>>(another_vec[0])); >+ EXPECT_EQ("Hello", absl::get<std::string>(another_vec[1])); >+} >+ >+TEST(VariantTest, NestedVariant) { >+#if ABSL_VARIANT_PROPAGATE_COPY_MOVE_TRIVIALITY >+ static_assert(absl::is_trivially_copy_constructible<variant<int>>(), ""); >+ static_assert(absl::is_trivially_copy_assignable<variant<int>>(), ""); >+ static_assert(is_trivially_move_constructible<variant<int>>(), ""); >+ static_assert(is_trivially_move_assignable<variant<int>>(), ""); >+ >+ static_assert(absl::is_trivially_copy_constructible<variant<variant<int>>>(), >+ ""); >+ static_assert(absl::is_trivially_copy_assignable<variant<variant<int>>>(), >+ ""); >+ static_assert(is_trivially_move_constructible<variant<variant<int>>>(), ""); >+ static_assert(is_trivially_move_assignable<variant<variant<int>>>(), ""); >+#endif // ABSL_VARIANT_PROPAGATE_COPY_MOVE_TRIVIALITY >+ >+ variant<int> x(42); >+ variant<variant<int>> y(x); >+ variant<variant<int>> z(y); >+ EXPECT_TRUE(absl::holds_alternative<variant<int>>(z)); >+ EXPECT_EQ(x, absl::get<variant<int>>(z)); >+} >+ >+struct TriviallyDestructible { >+ TriviallyDestructible(TriviallyDestructible&&) {} >+ TriviallyDestructible(const TriviallyDestructible&) {} >+ TriviallyDestructible& operator=(TriviallyDestructible&&) { return *this; } >+ TriviallyDestructible& operator=(const TriviallyDestructible&) { >+ return *this; >+ } >+}; >+ >+struct TriviallyMovable { >+ TriviallyMovable(TriviallyMovable&&) = default; >+ TriviallyMovable(TriviallyMovable const&) {} >+ TriviallyMovable& operator=(const TriviallyMovable&) { return *this; } >+}; >+ >+struct TriviallyCopyable { >+ TriviallyCopyable(const TriviallyCopyable&) = default; >+ TriviallyCopyable& operator=(const TriviallyCopyable&) { return *this; } >+}; >+ >+struct TriviallyMoveAssignable { >+ TriviallyMoveAssignable(TriviallyMoveAssignable&&) = default; >+ TriviallyMoveAssignable(const TriviallyMoveAssignable&) {} >+ TriviallyMoveAssignable& operator=(TriviallyMoveAssignable&&) = default; >+ TriviallyMoveAssignable& operator=(const TriviallyMoveAssignable&) { >+ return *this; >+ } >+}; >+ >+struct TriviallyCopyAssignable {}; >+ >+#if ABSL_VARIANT_PROPAGATE_COPY_MOVE_TRIVIALITY >+TEST(VariantTest, TestTriviality) { >+ { >+ using TrivDestVar = absl::variant<TriviallyDestructible>; >+ >+ EXPECT_FALSE(is_trivially_move_constructible<TrivDestVar>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_constructible<TrivDestVar>::value); >+ EXPECT_FALSE(is_trivially_move_assignable<TrivDestVar>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<TrivDestVar>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<TrivDestVar>::value); >+ } >+ >+ { >+ using TrivMoveVar = absl::variant<TriviallyMovable>; >+ >+ EXPECT_TRUE(is_trivially_move_constructible<TrivMoveVar>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_constructible<TrivMoveVar>::value); >+ EXPECT_FALSE(is_trivially_move_assignable<TrivMoveVar>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<TrivMoveVar>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<TrivMoveVar>::value); >+ } >+ >+ { >+ using TrivCopyVar = absl::variant<TriviallyCopyable>; >+ >+ EXPECT_TRUE(is_trivially_move_constructible<TrivCopyVar>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_constructible<TrivCopyVar>::value); >+ EXPECT_FALSE(is_trivially_move_assignable<TrivCopyVar>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<TrivCopyVar>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<TrivCopyVar>::value); >+ } >+ >+ { >+ using TrivMoveAssignVar = absl::variant<TriviallyMoveAssignable>; >+ >+ EXPECT_TRUE(is_trivially_move_constructible<TrivMoveAssignVar>::value); >+ EXPECT_FALSE( >+ absl::is_trivially_copy_constructible<TrivMoveAssignVar>::value); >+ EXPECT_TRUE(is_trivially_move_assignable<TrivMoveAssignVar>::value); >+ EXPECT_FALSE(absl::is_trivially_copy_assignable<TrivMoveAssignVar>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<TrivMoveAssignVar>::value); >+ } >+ >+ { >+ using TrivCopyAssignVar = absl::variant<TriviallyCopyAssignable>; >+ >+ EXPECT_TRUE(is_trivially_move_constructible<TrivCopyAssignVar>::value); >+ EXPECT_TRUE( >+ absl::is_trivially_copy_constructible<TrivCopyAssignVar>::value); >+ EXPECT_TRUE(is_trivially_move_assignable<TrivCopyAssignVar>::value); >+ EXPECT_TRUE(absl::is_trivially_copy_assignable<TrivCopyAssignVar>::value); >+ EXPECT_TRUE(absl::is_trivially_destructible<TrivCopyAssignVar>::value); >+ } >+} >+#endif // ABSL_VARIANT_PROPAGATE_COPY_MOVE_TRIVIALITY >+ >+// To verify that absl::variant correctly use the nontrivial move ctor of its >+// member rather than use the trivial copy constructor. >+TEST(VariantTest, MoveCtorBug) { >+ // To simulate std::tuple in libstdc++. >+ struct TrivialCopyNontrivialMove { >+ TrivialCopyNontrivialMove() = default; >+ TrivialCopyNontrivialMove(const TrivialCopyNontrivialMove&) = default; >+ TrivialCopyNontrivialMove(TrivialCopyNontrivialMove&&) { called = true; } >+ bool called = false; >+ }; >+ { >+ using V = absl::variant<TrivialCopyNontrivialMove, int>; >+ V v1(absl::in_place_index_t<0>{}); >+ // this should invoke the move ctor, rather than the trivial copy ctor. >+ V v2(std::move(v1)); >+ EXPECT_TRUE(absl::get<0>(v2).called); >+ } >+ { >+ // this case failed to compile before our fix due to a GCC bug. >+ using V = absl::variant<int, TrivialCopyNontrivialMove>; >+ V v1(absl::in_place_index_t<1>{}); >+ // this should invoke the move ctor, rather than the trivial copy ctor. >+ V v2(std::move(v1)); >+ EXPECT_TRUE(absl::get<1>(v2).called); >+ } >+} >+ >+} // namespace >+} // namespace absl >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/BUILD.bazel b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/BUILD.bazel >new file mode 100644 >index 0000000000000000000000000000000000000000..c01b49bc97dd1d2ceeb4780cbe93d14ffe654a69 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/BUILD.bazel >@@ -0,0 +1,33 @@ >+load( >+ "//absl:copts.bzl", >+ "ABSL_DEFAULT_COPTS", >+ "ABSL_TEST_COPTS", >+) >+ >+package(default_visibility = ["//visibility:public"]) >+ >+licenses(["notice"]) # Apache 2.0 >+ >+cc_library( >+ name = "utility", >+ hdrs = ["utility.h"], >+ copts = ABSL_DEFAULT_COPTS, >+ deps = [ >+ "//absl/base:base_internal", >+ "//absl/base:config", >+ "//absl/meta:type_traits", >+ ], >+) >+ >+cc_test( >+ name = "utility_test", >+ srcs = ["utility_test.cc"], >+ copts = ABSL_TEST_COPTS, >+ deps = [ >+ ":utility", >+ "//absl/base:core_headers", >+ "//absl/memory", >+ "//absl/strings", >+ "@com_google_googletest//:gtest_main", >+ ], >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..4cf3c810e6577838ac92b602f5d49d6dee1d14fa >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/BUILD.gn >@@ -0,0 +1,32 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//build_overrides/build.gni") >+ >+if (build_with_chromium) { >+ visibility = [ >+ "//third_party/webrtc/*", >+ "//third_party/abseil-cpp/*", >+ "//third_party/googletest:gtest", >+ ] >+} else { >+ visibility = [ "*" ] >+} >+ >+source_set("utility") { >+ configs -= [ "//build/config/compiler:chromium_code" ] >+ configs += [ >+ "//build/config/compiler:no_chromium_code", >+ "//third_party/abseil-cpp:absl_default_cflags_cc", >+ ] >+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] >+ public = [ >+ "utility.h", >+ ] >+ deps = [ >+ "../base:base_internal", >+ "../base:config", >+ "../meta:type_traits", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/CMakeLists.txt b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/CMakeLists.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..dc3a63190546884629107478582b2b89a8efcd96 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/CMakeLists.txt >@@ -0,0 +1,52 @@ >+# >+# Copyright 2017 The Abseil Authors. >+# >+# Licensed under the Apache License, Version 2.0 (the "License"); >+# you may not use this file except in compliance with the License. >+# You may obtain a copy of the License at >+# >+# http://www.apache.org/licenses/LICENSE-2.0 >+# >+# Unless required by applicable law or agreed to in writing, software >+# distributed under the License is distributed on an "AS IS" BASIS, >+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+# See the License for the specific language governing permissions and >+# limitations under the License. >+# >+ >+ >+list(APPEND UTILITY_PUBLIC_HEADERS >+ "utility.h" >+) >+ >+absl_header_library( >+ TARGET >+ absl_utility >+ PUBLIC_LIBRARIES >+ absl::base >+ EXPORT_NAME >+ utility >+) >+ >+ >+# >+## TESTS >+# >+ >+# test utility_test >+set(UTILITY_TEST_SRC "utility_test.cc") >+set(UTILITY_TEST_PUBLIC_LIBRARIES >+ absl::base >+ absl::memory >+ absl::strings >+ absl::utility >+) >+ >+absl_test( >+ TARGET >+ utility_test >+ SOURCES >+ ${UTILITY_TEST_SRC} >+ PUBLIC_LIBRARIES >+ ${UTILITY_TEST_PUBLIC_LIBRARIES} >+) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/utility.h b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/utility.h >new file mode 100644 >index 0000000000000000000000000000000000000000..d73602c47d3b6da166357fbcdc5d41519d623561 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/utility.h >@@ -0,0 +1,291 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+// >+// This header file contains C++11 versions of standard <utility> header >+// abstractions available within C++14 and C++17, and are designed to be drop-in >+// replacement for code compliant with C++14 and C++17. >+// >+// The following abstractions are defined: >+// >+// * integer_sequence<T, Ints...> == std::integer_sequence<T, Ints...> >+// * index_sequence<Ints...> == std::index_sequence<Ints...> >+// * make_integer_sequence<T, N> == std::make_integer_sequence<T, N> >+// * make_index_sequence<N> == std::make_index_sequence<N> >+// * index_sequence_for<Ts...> == std::index_sequence_for<Ts...> >+// * apply<Functor, Tuple> == std::apply<Functor, Tuple> >+// * exchange<T> == std::exchange<T> >+// >+// This header file also provides the tag types `in_place_t`, `in_place_type_t`, >+// and `in_place_index_t`, as well as the constant `in_place`, and >+// `constexpr` `std::move()` and `std::forward()` implementations in C++11. >+// >+// References: >+// >+// http://en.cppreference.com/w/cpp/utility/integer_sequence >+// http://en.cppreference.com/w/cpp/utility/apply >+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html >+// >+ >+#ifndef ABSL_UTILITY_UTILITY_H_ >+#define ABSL_UTILITY_UTILITY_H_ >+ >+#include <cstddef> >+#include <cstdlib> >+#include <tuple> >+#include <utility> >+ >+#include "absl/base/config.h" >+#include "absl/base/internal/inline_variable.h" >+#include "absl/base/internal/invoke.h" >+#include "absl/meta/type_traits.h" >+ >+namespace absl { >+ >+// integer_sequence >+// >+// Class template representing a compile-time integer sequence. An instantiation >+// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its >+// type through its template arguments (which is a common need when >+// working with C++11 variadic templates). `absl::integer_sequence` is designed >+// to be a drop-in replacement for C++14's `std::integer_sequence`. >+// >+// Example: >+// >+// template< class T, T... Ints > >+// void user_function(integer_sequence<T, Ints...>); >+// >+// int main() >+// { >+// // user_function's `T` will be deduced to `int` and `Ints...` >+// // will be deduced to `0, 1, 2, 3, 4`. >+// user_function(make_integer_sequence<int, 5>()); >+// } >+template <typename T, T... Ints> >+struct integer_sequence { >+ using value_type = T; >+ static constexpr size_t size() noexcept { return sizeof...(Ints); } >+}; >+ >+// index_sequence >+// >+// A helper template for an `integer_sequence` of `size_t`, >+// `absl::index_sequence` is designed to be a drop-in replacement for C++14's >+// `std::index_sequence`. >+template <size_t... Ints> >+using index_sequence = integer_sequence<size_t, Ints...>; >+ >+namespace utility_internal { >+ >+template <typename Seq, size_t SeqSize, size_t Rem> >+struct Extend; >+ >+// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. >+template <typename T, T... Ints, size_t SeqSize> >+struct Extend<integer_sequence<T, Ints...>, SeqSize, 0> { >+ using type = integer_sequence<T, Ints..., (Ints + SeqSize)...>; >+}; >+ >+template <typename T, T... Ints, size_t SeqSize> >+struct Extend<integer_sequence<T, Ints...>, SeqSize, 1> { >+ using type = integer_sequence<T, Ints..., (Ints + SeqSize)..., 2 * SeqSize>; >+}; >+ >+// Recursion helper for 'make_integer_sequence<T, N>'. >+// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'. >+template <typename T, size_t N> >+struct Gen { >+ using type = >+ typename Extend<typename Gen<T, N / 2>::type, N / 2, N % 2>::type; >+}; >+ >+template <typename T> >+struct Gen<T, 0> { >+ using type = integer_sequence<T>; >+}; >+ >+} // namespace utility_internal >+ >+// Compile-time sequences of integers >+ >+// make_integer_sequence >+// >+// This template alias is equivalent to >+// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in >+// replacement for C++14's `std::make_integer_sequence`. >+template <typename T, T N> >+using make_integer_sequence = typename utility_internal::Gen<T, N>::type; >+ >+// make_index_sequence >+// >+// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, >+// and is designed to be a drop-in replacement for C++14's >+// `std::make_index_sequence`. >+template <size_t N> >+using make_index_sequence = make_integer_sequence<size_t, N>; >+ >+// index_sequence_for >+// >+// Converts a typename pack into an index sequence of the same length, and >+// is designed to be a drop-in replacement for C++14's >+// `std::index_sequence_for()` >+template <typename... Ts> >+using index_sequence_for = make_index_sequence<sizeof...(Ts)>; >+ >+// Tag types >+ >+#ifdef ABSL_HAVE_STD_OPTIONAL >+ >+using std::in_place_t; >+using std::in_place; >+ >+#else // ABSL_HAVE_STD_OPTIONAL >+ >+// in_place_t >+// >+// Tag type used to specify in-place construction, such as with >+// `absl::optional`, designed to be a drop-in replacement for C++17's >+// `std::in_place_t`. >+struct in_place_t {}; >+ >+ABSL_INTERNAL_INLINE_CONSTEXPR(in_place_t, in_place, {}); >+ >+#endif // ABSL_HAVE_STD_OPTIONAL >+ >+#if defined(ABSL_HAVE_STD_ANY) || defined(ABSL_HAVE_STD_VARIANT) >+using std::in_place_type_t; >+#else >+ >+// in_place_type_t >+// >+// Tag type used for in-place construction when the type to construct needs to >+// be specified, such as with `absl::any`, designed to be a drop-in replacement >+// for C++17's `std::in_place_type_t`. >+template <typename T> >+struct in_place_type_t {}; >+#endif // ABSL_HAVE_STD_ANY || ABSL_HAVE_STD_VARIANT >+ >+#ifdef ABSL_HAVE_STD_VARIANT >+using std::in_place_index_t; >+#else >+ >+// in_place_index_t >+// >+// Tag type used for in-place construction when the type to construct needs to >+// be specified, such as with `absl::any`, designed to be a drop-in replacement >+// for C++17's `std::in_place_index_t`. >+template <size_t I> >+struct in_place_index_t {}; >+#endif // ABSL_HAVE_STD_VARIANT >+ >+// Constexpr move and forward >+ >+// move() >+// >+// A constexpr version of `std::move()`, designed to be a drop-in replacement >+// for C++14's `std::move()`. >+template <typename T> >+constexpr absl::remove_reference_t<T>&& move(T&& t) noexcept { >+ return static_cast<absl::remove_reference_t<T>&&>(t); >+} >+ >+// forward() >+// >+// A constexpr version of `std::forward()`, designed to be a drop-in replacement >+// for C++14's `std::forward()`. >+template <typename T> >+constexpr T&& forward( >+ absl::remove_reference_t<T>& t) noexcept { // NOLINT(runtime/references) >+ return static_cast<T&&>(t); >+} >+ >+namespace utility_internal { >+// Helper method for expanding tuple into a called method. >+template <typename Functor, typename Tuple, std::size_t... Indexes> >+auto apply_helper(Functor&& functor, Tuple&& t, index_sequence<Indexes...>) >+ -> decltype(absl::base_internal::Invoke( >+ absl::forward<Functor>(functor), >+ std::get<Indexes>(absl::forward<Tuple>(t))...)) { >+ return absl::base_internal::Invoke( >+ absl::forward<Functor>(functor), >+ std::get<Indexes>(absl::forward<Tuple>(t))...); >+} >+ >+} // namespace utility_internal >+ >+// apply >+// >+// Invokes a Callable using elements of a tuple as its arguments. >+// Each element of the tuple corresponds to an argument of the call (in order). >+// Both the Callable argument and the tuple argument are perfect-forwarded. >+// For member-function Callables, the first tuple element acts as the `this` >+// pointer. `absl::apply` is designed to be a drop-in replacement for C++17's >+// `std::apply`. Unlike C++17's `std::apply`, this is not currently `constexpr`. >+// >+// Example: >+// >+// class Foo{void Bar(int);}; >+// void user_function(int, std::string); >+// void user_function(std::unique_ptr<Foo>); >+// >+// int main() >+// { >+// std::tuple<int, std::string> tuple1(42, "bar"); >+// // Invokes the user function overload on int, std::string. >+// absl::apply(&user_function, tuple1); >+// >+// auto foo = absl::make_unique<Foo>(); >+// std::tuple<Foo*, int> tuple2(foo.get(), 42); >+// // Invokes the method Bar on foo with one argument 42. >+// absl::apply(&Foo::Bar, foo.get(), 42); >+// >+// std::tuple<std::unique_ptr<Foo>> tuple3(absl::make_unique<Foo>()); >+// // Invokes the user function that takes ownership of the unique >+// // pointer. >+// absl::apply(&user_function, std::move(tuple)); >+// } >+template <typename Functor, typename Tuple> >+auto apply(Functor&& functor, Tuple&& t) >+ -> decltype(utility_internal::apply_helper( >+ absl::forward<Functor>(functor), absl::forward<Tuple>(t), >+ absl::make_index_sequence<std::tuple_size< >+ typename std::remove_reference<Tuple>::type>::value>{})) { >+ return utility_internal::apply_helper( >+ absl::forward<Functor>(functor), absl::forward<Tuple>(t), >+ absl::make_index_sequence<std::tuple_size< >+ typename std::remove_reference<Tuple>::type>::value>{}); >+} >+ >+// exchange >+// >+// Replaces the value of `obj` with `new_value` and returns the old value of >+// `obj`. `absl::exchange` is designed to be a drop-in replacement for C++14's >+// `std::exchange`. >+// >+// Example: >+// >+// Foo& operator=(Foo&& other) { >+// ptr1_ = absl::exchange(other.ptr1_, nullptr); >+// int1_ = absl::exchange(other.int1_, -1); >+// return *this; >+// } >+template <typename T, typename U = T> >+T exchange(T& obj, U&& new_value) { >+ T old_value = absl::move(obj); >+ obj = absl::forward<U>(new_value); >+ return old_value; >+} >+ >+} // namespace absl >+ >+#endif // ABSL_UTILITY_UTILITY_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/utility_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/utility_test.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..3c447b20bb04a95555135612edff520ac0597a61 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/absl/utility/utility_test.cc >@@ -0,0 +1,345 @@ >+// Copyright 2017 The Abseil Authors. >+// >+// Licensed under the Apache License, Version 2.0 (the "License"); >+// you may not use this file except in compliance with the License. >+// You may obtain a copy of the License at >+// >+// http://www.apache.org/licenses/LICENSE-2.0 >+// >+// Unless required by applicable law or agreed to in writing, software >+// distributed under the License is distributed on an "AS IS" BASIS, >+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+// See the License for the specific language governing permissions and >+// limitations under the License. >+ >+#include "absl/utility/utility.h" >+ >+#include <sstream> >+#include <string> >+#include <tuple> >+#include <type_traits> >+#include <vector> >+ >+#include "gmock/gmock.h" >+#include "gtest/gtest.h" >+#include "absl/base/attributes.h" >+#include "absl/memory/memory.h" >+#include "absl/strings/str_cat.h" >+ >+namespace { >+ >+#ifdef _MSC_VER >+// Warnings for unused variables in this test are false positives. On other >+// platforms, they are suppressed by ABSL_ATTRIBUTE_UNUSED, but that doesn't >+// work on MSVC. >+// Both the unused variables and the name length warnings are due to calls >+// to absl::make_index_sequence with very large values, creating very long type >+// names. The resulting warnings are so long they make build output unreadable. >+#pragma warning( push ) >+#pragma warning( disable : 4503 ) // decorated name length exceeded >+#pragma warning( disable : 4101 ) // unreferenced local variable >+#endif // _MSC_VER >+ >+using ::testing::ElementsAre; >+using ::testing::Pointee; >+using ::testing::StaticAssertTypeEq; >+ >+TEST(IntegerSequenceTest, ValueType) { >+ StaticAssertTypeEq<int, absl::integer_sequence<int>::value_type>(); >+ StaticAssertTypeEq<char, absl::integer_sequence<char>::value_type>(); >+} >+ >+TEST(IntegerSequenceTest, Size) { >+ EXPECT_EQ(0, (absl::integer_sequence<int>::size())); >+ EXPECT_EQ(1, (absl::integer_sequence<int, 0>::size())); >+ EXPECT_EQ(1, (absl::integer_sequence<int, 1>::size())); >+ EXPECT_EQ(2, (absl::integer_sequence<int, 1, 2>::size())); >+ EXPECT_EQ(3, (absl::integer_sequence<int, 0, 1, 2>::size())); >+ EXPECT_EQ(3, (absl::integer_sequence<int, -123, 123, 456>::size())); >+ constexpr size_t sz = absl::integer_sequence<int, 0, 1>::size(); >+ EXPECT_EQ(2, sz); >+} >+ >+TEST(IntegerSequenceTest, MakeIndexSequence) { >+ StaticAssertTypeEq<absl::index_sequence<>, absl::make_index_sequence<0>>(); >+ StaticAssertTypeEq<absl::index_sequence<0>, absl::make_index_sequence<1>>(); >+ StaticAssertTypeEq<absl::index_sequence<0, 1>, >+ absl::make_index_sequence<2>>(); >+ StaticAssertTypeEq<absl::index_sequence<0, 1, 2>, >+ absl::make_index_sequence<3>>(); >+} >+ >+TEST(IntegerSequenceTest, MakeIntegerSequence) { >+ StaticAssertTypeEq<absl::integer_sequence<int>, >+ absl::make_integer_sequence<int, 0>>(); >+ StaticAssertTypeEq<absl::integer_sequence<int, 0>, >+ absl::make_integer_sequence<int, 1>>(); >+ StaticAssertTypeEq<absl::integer_sequence<int, 0, 1>, >+ absl::make_integer_sequence<int, 2>>(); >+ StaticAssertTypeEq<absl::integer_sequence<int, 0, 1, 2>, >+ absl::make_integer_sequence<int, 3>>(); >+} >+ >+template <typename... Ts> >+class Counter {}; >+ >+template <size_t... Is> >+void CountAll(absl::index_sequence<Is...>) { >+ // We only need an alias here, but instantiate a variable to silence warnings >+ // for unused typedefs in some compilers. >+ ABSL_ATTRIBUTE_UNUSED Counter<absl::make_index_sequence<Is>...> seq; >+} >+ >+// This test verifies that absl::make_index_sequence can handle large arguments >+// without blowing up template instantiation stack, going OOM or taking forever >+// to compile (there is hard 15 minutes limit imposed by forge). >+TEST(IntegerSequenceTest, MakeIndexSequencePerformance) { >+ // O(log N) template instantiations. >+ // We only need an alias here, but instantiate a variable to silence warnings >+ // for unused typedefs in some compilers. >+ ABSL_ATTRIBUTE_UNUSED absl::make_index_sequence<(1 << 16) - 1> seq; >+ // O(N) template instantiations. >+ CountAll(absl::make_index_sequence<(1 << 8) - 1>()); >+} >+ >+template <typename F, typename Tup, size_t... Is> >+auto ApplyFromTupleImpl(F f, const Tup& tup, absl::index_sequence<Is...>) >+ -> decltype(f(std::get<Is>(tup)...)) { >+ return f(std::get<Is>(tup)...); >+} >+ >+template <typename Tup> >+using TupIdxSeq = absl::make_index_sequence<std::tuple_size<Tup>::value>; >+ >+template <typename F, typename Tup> >+auto ApplyFromTuple(F f, const Tup& tup) >+ -> decltype(ApplyFromTupleImpl(f, tup, TupIdxSeq<Tup>{})) { >+ return ApplyFromTupleImpl(f, tup, TupIdxSeq<Tup>{}); >+} >+ >+template <typename T> >+std::string Fmt(const T& x) { >+ std::ostringstream os; >+ os << x; >+ return os.str(); >+} >+ >+struct PoorStrCat { >+ template <typename... Args> >+ std::string operator()(const Args&... args) const { >+ std::string r; >+ for (const auto& e : {Fmt(args)...}) r += e; >+ return r; >+ } >+}; >+ >+template <typename Tup, size_t... Is> >+std::vector<std::string> TupStringVecImpl(const Tup& tup, >+ absl::index_sequence<Is...>) { >+ return {Fmt(std::get<Is>(tup))...}; >+} >+ >+template <typename... Ts> >+std::vector<std::string> TupStringVec(const std::tuple<Ts...>& tup) { >+ return TupStringVecImpl(tup, absl::index_sequence_for<Ts...>()); >+} >+ >+TEST(MakeIndexSequenceTest, ApplyFromTupleExample) { >+ PoorStrCat f{}; >+ EXPECT_EQ("12abc3.14", f(12, "abc", 3.14)); >+ EXPECT_EQ("12abc3.14", ApplyFromTuple(f, std::make_tuple(12, "abc", 3.14))); >+} >+ >+TEST(IndexSequenceForTest, Basic) { >+ StaticAssertTypeEq<absl::index_sequence<>, absl::index_sequence_for<>>(); >+ StaticAssertTypeEq<absl::index_sequence<0>, absl::index_sequence_for<int>>(); >+ StaticAssertTypeEq<absl::index_sequence<0, 1, 2, 3>, >+ absl::index_sequence_for<int, void, char, int>>(); >+} >+ >+TEST(IndexSequenceForTest, Example) { >+ EXPECT_THAT(TupStringVec(std::make_tuple(12, "abc", 3.14)), >+ ElementsAre("12", "abc", "3.14")); >+} >+ >+int Function(int a, int b) { return a - b; } >+ >+int Sink(std::unique_ptr<int> p) { return *p; } >+ >+std::unique_ptr<int> Factory(int n) { return absl::make_unique<int>(n); } >+ >+void NoOp() {} >+ >+struct ConstFunctor { >+ int operator()(int a, int b) const { return a - b; } >+}; >+ >+struct MutableFunctor { >+ int operator()(int a, int b) { return a - b; } >+}; >+ >+struct EphemeralFunctor { >+ EphemeralFunctor() {} >+ EphemeralFunctor(const EphemeralFunctor&) {} >+ EphemeralFunctor(EphemeralFunctor&&) {} >+ int operator()(int a, int b) && { return a - b; } >+}; >+ >+struct OverloadedFunctor { >+ OverloadedFunctor() {} >+ OverloadedFunctor(const OverloadedFunctor&) {} >+ OverloadedFunctor(OverloadedFunctor&&) {} >+ template <typename... Args> >+ std::string operator()(const Args&... args) & { >+ return absl::StrCat("&", args...); >+ } >+ template <typename... Args> >+ std::string operator()(const Args&... args) const& { >+ return absl::StrCat("const&", args...); >+ } >+ template <typename... Args> >+ std::string operator()(const Args&... args) && { >+ return absl::StrCat("&&", args...); >+ } >+}; >+ >+struct Class { >+ int Method(int a, int b) { return a - b; } >+ int ConstMethod(int a, int b) const { return a - b; } >+ >+ int member; >+}; >+ >+struct FlipFlop { >+ int ConstMethod() const { return member; } >+ FlipFlop operator*() const { return {-member}; } >+ >+ int member; >+}; >+ >+TEST(ApplyTest, Function) { >+ EXPECT_EQ(1, absl::apply(Function, std::make_tuple(3, 2))); >+ EXPECT_EQ(1, absl::apply(&Function, std::make_tuple(3, 2))); >+} >+ >+TEST(ApplyTest, NonCopyableArgument) { >+ EXPECT_EQ(42, absl::apply(Sink, std::make_tuple(absl::make_unique<int>(42)))); >+} >+ >+TEST(ApplyTest, NonCopyableResult) { >+ EXPECT_THAT(absl::apply(Factory, std::make_tuple(42)), >+ ::testing::Pointee(42)); >+} >+ >+TEST(ApplyTest, VoidResult) { absl::apply(NoOp, std::tuple<>()); } >+ >+TEST(ApplyTest, ConstFunctor) { >+ EXPECT_EQ(1, absl::apply(ConstFunctor(), std::make_tuple(3, 2))); >+} >+ >+TEST(ApplyTest, MutableFunctor) { >+ MutableFunctor f; >+ EXPECT_EQ(1, absl::apply(f, std::make_tuple(3, 2))); >+ EXPECT_EQ(1, absl::apply(MutableFunctor(), std::make_tuple(3, 2))); >+} >+TEST(ApplyTest, EphemeralFunctor) { >+ EphemeralFunctor f; >+ EXPECT_EQ(1, absl::apply(std::move(f), std::make_tuple(3, 2))); >+ EXPECT_EQ(1, absl::apply(EphemeralFunctor(), std::make_tuple(3, 2))); >+} >+TEST(ApplyTest, OverloadedFunctor) { >+ OverloadedFunctor f; >+ const OverloadedFunctor& cf = f; >+ >+ EXPECT_EQ("&", absl::apply(f, std::tuple<>{})); >+ EXPECT_EQ("& 42", absl::apply(f, std::make_tuple(" 42"))); >+ >+ EXPECT_EQ("const&", absl::apply(cf, std::tuple<>{})); >+ EXPECT_EQ("const& 42", absl::apply(cf, std::make_tuple(" 42"))); >+ >+ EXPECT_EQ("&&", absl::apply(std::move(f), std::tuple<>{})); >+ OverloadedFunctor f2; >+ EXPECT_EQ("&& 42", absl::apply(std::move(f2), std::make_tuple(" 42"))); >+} >+ >+TEST(ApplyTest, ReferenceWrapper) { >+ ConstFunctor cf; >+ MutableFunctor mf; >+ EXPECT_EQ(1, absl::apply(std::cref(cf), std::make_tuple(3, 2))); >+ EXPECT_EQ(1, absl::apply(std::ref(cf), std::make_tuple(3, 2))); >+ EXPECT_EQ(1, absl::apply(std::ref(mf), std::make_tuple(3, 2))); >+} >+ >+TEST(ApplyTest, MemberFunction) { >+ std::unique_ptr<Class> p(new Class); >+ std::unique_ptr<const Class> cp(new Class); >+ EXPECT_EQ( >+ 1, absl::apply(&Class::Method, >+ std::tuple<std::unique_ptr<Class>&, int, int>(p, 3, 2))); >+ EXPECT_EQ(1, absl::apply(&Class::Method, >+ std::tuple<Class*, int, int>(p.get(), 3, 2))); >+ EXPECT_EQ( >+ 1, absl::apply(&Class::Method, std::tuple<Class&, int, int>(*p, 3, 2))); >+ >+ EXPECT_EQ( >+ 1, absl::apply(&Class::ConstMethod, >+ std::tuple<std::unique_ptr<Class>&, int, int>(p, 3, 2))); >+ EXPECT_EQ(1, absl::apply(&Class::ConstMethod, >+ std::tuple<Class*, int, int>(p.get(), 3, 2))); >+ EXPECT_EQ(1, absl::apply(&Class::ConstMethod, >+ std::tuple<Class&, int, int>(*p, 3, 2))); >+ >+ EXPECT_EQ(1, absl::apply(&Class::ConstMethod, >+ std::tuple<std::unique_ptr<const Class>&, int, int>( >+ cp, 3, 2))); >+ EXPECT_EQ(1, absl::apply(&Class::ConstMethod, >+ std::tuple<const Class*, int, int>(cp.get(), 3, 2))); >+ EXPECT_EQ(1, absl::apply(&Class::ConstMethod, >+ std::tuple<const Class&, int, int>(*cp, 3, 2))); >+ >+ EXPECT_EQ(1, absl::apply(&Class::Method, >+ std::make_tuple(absl::make_unique<Class>(), 3, 2))); >+ EXPECT_EQ(1, absl::apply(&Class::ConstMethod, >+ std::make_tuple(absl::make_unique<Class>(), 3, 2))); >+ EXPECT_EQ( >+ 1, absl::apply(&Class::ConstMethod, >+ std::make_tuple(absl::make_unique<const Class>(), 3, 2))); >+} >+ >+TEST(ApplyTest, DataMember) { >+ std::unique_ptr<Class> p(new Class{42}); >+ std::unique_ptr<const Class> cp(new Class{42}); >+ EXPECT_EQ( >+ 42, absl::apply(&Class::member, std::tuple<std::unique_ptr<Class>&>(p))); >+ EXPECT_EQ(42, absl::apply(&Class::member, std::tuple<Class&>(*p))); >+ EXPECT_EQ(42, absl::apply(&Class::member, std::tuple<Class*>(p.get()))); >+ >+ absl::apply(&Class::member, std::tuple<std::unique_ptr<Class>&>(p)) = 42; >+ absl::apply(&Class::member, std::tuple<Class*>(p.get())) = 42; >+ absl::apply(&Class::member, std::tuple<Class&>(*p)) = 42; >+ >+ EXPECT_EQ(42, absl::apply(&Class::member, >+ std::tuple<std::unique_ptr<const Class>&>(cp))); >+ EXPECT_EQ(42, absl::apply(&Class::member, std::tuple<const Class&>(*cp))); >+ EXPECT_EQ(42, >+ absl::apply(&Class::member, std::tuple<const Class*>(cp.get()))); >+} >+ >+TEST(ApplyTest, FlipFlop) { >+ FlipFlop obj = {42}; >+ // This call could resolve to (obj.*&FlipFlop::ConstMethod)() or >+ // ((*obj).*&FlipFlop::ConstMethod)(). We verify that it's the former. >+ EXPECT_EQ(42, absl::apply(&FlipFlop::ConstMethod, std::make_tuple(obj))); >+ EXPECT_EQ(42, absl::apply(&FlipFlop::member, std::make_tuple(obj))); >+} >+ >+TEST(ExchangeTest, MoveOnly) { >+ auto a = Factory(1); >+ EXPECT_EQ(1, *a); >+ auto b = absl::exchange(a, Factory(2)); >+ EXPECT_EQ(2, *a); >+ EXPECT_EQ(1, *b); >+} >+ >+} // namespace >+ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/rename_dynamic_annotations.sh b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/rename_dynamic_annotations.sh >new file mode 100755 >index 0000000000000000000000000000000000000000..b39017f958571723bbc770066c78bcd4caa20f87 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/abseil-cpp/rename_dynamic_annotations.sh >@@ -0,0 +1,127 @@ >+#!/bin/bash >+ >+# This script renames all the functions and the macros defined in >+# absl/base/dynamic_annotations.{h,cc}. >+# >+# Chromium's dynamic_annotations live in //base/third_party/dynamic_annotations >+# and the are in conflict with Abseil's dynamic_annotations (ODR violations and >+# macro clashing). >+# In order to avoid problems in Chromium, this copy of Abseil has its own >+# dynamic_annotations renamed. >+ >+for w in \ >+ AnnotateBarrierDestroy \ >+ AnnotateBarrierInit \ >+ AnnotateBarrierWaitAfter \ >+ AnnotateBarrierWaitBefore \ >+ AnnotateBenignRace \ >+ AnnotateBenignRaceSized \ >+ AnnotateCondVarSignal \ >+ AnnotateCondVarSignalAll \ >+ AnnotateCondVarWait \ >+ AnnotateEnableRaceDetection \ >+ AnnotateExpectRace \ >+ AnnotateFlushExpectedRaces \ >+ AnnotateFlushState \ >+ AnnotateHappensAfter \ >+ AnnotateHappensBefore \ >+ AnnotateIgnoreReadsBegin \ >+ AnnotateIgnoreReadsEnd \ >+ AnnotateIgnoreSyncBegin \ >+ AnnotateIgnoreSyncEnd \ >+ AnnotateIgnoreWritesBegin \ >+ AnnotateIgnoreWritesEnd \ >+ AnnotateMemoryIsInitialized \ >+ AnnotateMemoryIsUninitialized \ >+ AnnotateMutexIsNotPHB \ >+ AnnotateMutexIsUsedAsCondVar \ >+ AnnotateNewMemory \ >+ AnnotateNoOp \ >+ AnnotatePCQCreate \ >+ AnnotatePCQDestroy \ >+ AnnotatePCQGet \ >+ AnnotatePCQPut \ >+ AnnotatePublishMemoryRange \ >+ AnnotateRWLockAcquired \ >+ AnnotateRWLockCreate \ >+ AnnotateRWLockCreateStatic \ >+ AnnotateRWLockDestroy \ >+ AnnotateRWLockReleased \ >+ AnnotateThreadName \ >+ AnnotateTraceMemory \ >+ AnnotateUnpublishMemoryRange \ >+ GetRunningOnValgrind \ >+ RunningOnValgrind \ >+ StaticAnnotateIgnoreReadsBegin \ >+ StaticAnnotateIgnoreReadsEnd \ >+ StaticAnnotateIgnoreWritesBegin \ >+ StaticAnnotateIgnoreWritesEnd \ >+ ValgrindSlowdown \ >+; do >+ find absl/ -type f -exec sed -i "s/\b$w\b/Absl$w/g" {} \; >+done >+ >+for w in \ >+ ADDRESS_SANITIZER_REDZONE \ >+ ANNOTALYSIS_ENABLED \ >+ ANNOTATE_BARRIER_DESTROY \ >+ ANNOTATE_BARRIER_INIT \ >+ ANNOTATE_BARRIER_WAIT_AFTER \ >+ ANNOTATE_BARRIER_WAIT_BEFORE \ >+ ANNOTATE_BENIGN_RACE \ >+ ANNOTATE_BENIGN_RACE_SIZED \ >+ ANNOTATE_BENIGN_RACE_STATIC \ >+ ANNOTATE_CONDVAR_LOCK_WAIT \ >+ ANNOTATE_CONDVAR_SIGNAL \ >+ ANNOTATE_CONDVAR_SIGNAL_ALL \ >+ ANNOTATE_CONDVAR_WAIT \ >+ ANNOTATE_CONTIGUOUS_CONTAINER \ >+ ANNOTATE_ENABLE_RACE_DETECTION \ >+ ANNOTATE_EXPECT_RACE \ >+ ANNOTATE_FLUSH_EXPECTED_RACES \ >+ ANNOTATE_FLUSH_STATE \ >+ ANNOTATE_HAPPENS_AFTER \ >+ ANNOTATE_HAPPENS_BEFORE \ >+ ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN ANNOTATE_IGNORE_READS_AND_WRITES_END \ >+ ANNOTATE_IGNORE_READS_BEGIN \ >+ ANNOTATE_IGNORE_READS_END \ >+ ANNOTATE_IGNORE_SYNC_BEGIN \ >+ ANNOTATE_IGNORE_SYNC_END \ >+ ANNOTATE_IGNORE_WRITES_BEGIN \ >+ ANNOTATE_IGNORE_WRITES_END \ >+ ANNOTATE_MEMORY_IS_INITIALIZED \ >+ ANNOTATE_MEMORY_IS_UNINITIALIZED \ >+ ANNOTATE_MUTEX_IS_USED_AS_CONDVAR \ >+ ANNOTATE_NEW_MEMORY \ >+ ANNOTATE_NOT_HAPPENS_BEFORE_MUTEX \ >+ ANNOTATE_NO_OP \ >+ ANNOTATE_PCQ_CREATE ANNOTATE_PCQ_DESTROY \ >+ ANNOTATE_PCQ_GET ANNOTATE_PCQ_PUT \ >+ ANNOTATE_PUBLISH_MEMORY_RANGE \ >+ ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX \ >+ ANNOTATE_RWLOCK_ACQUIRED \ >+ ANNOTATE_RWLOCK_CREATE \ >+ ANNOTATE_RWLOCK_CREATE_STATIC \ >+ ANNOTATE_RWLOCK_DESTROY \ >+ ANNOTATE_RWLOCK_RELEASED \ >+ ANNOTATE_SWAP_MEMORY_RANGE \ >+ ANNOTATE_THREAD_NAME \ >+ ANNOTATE_TRACE_MEMORY \ >+ ANNOTATE_UNPROTECTED_READ \ >+ ANNOTATE_UNPUBLISH_MEMORY_RANGE \ >+ ANNOTATIONS_ENABLED \ >+ ATTRIBUTE_IGNORE_READS_BEGIN \ >+ ATTRIBUTE_IGNORE_READS_END \ >+ DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK \ >+ DYNAMIC_ANNOTATIONS_ENABLED \ >+ DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL \ >+ DYNAMIC_ANNOTATIONS_GLUE \ >+ DYNAMIC_ANNOTATIONS_GLUE0 \ >+ DYNAMIC_ANNOTATIONS_IMPL \ >+ DYNAMIC_ANNOTATIONS_NAME \ >+ DYNAMIC_ANNOTATIONS_PREFIX \ >+ DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND \ >+ DYNAMIC_ANNOTATIONS_WANT_ATTRIBUTE_WEAK \ >+; do >+ find absl/ -type f -exec sed -i "s/\b$w\b/ABSL_$w/g" {} \; >+done >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/.gn b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/.gn >index 015d0f0e5e862f120b63376cc8bfc96f8217858b..26a4a62d1994e5abd6f534a9b6b20b71bacb07e9 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/.gn >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/.gn >@@ -6,6 +6,8 @@ > # in the file PATENTS. All contributing project authors may > # be found in the AUTHORS file in the root of the source tree. > >+import("//build/dotfile_settings.gni") >+ > # The location of the build configuration file. > buildconfig = "//build/config/BUILDCONFIG.gn" > >@@ -23,29 +25,8 @@ check_targets = [ "//libyuv/*" ] > # These are the list of GN files that run exec_script. This whitelist exists > # to force additional review for new uses of exec_script, which is strongly > # discouraged except for gypi_to_gn calls. >-exec_script_whitelist = [ >- "//build/config/android/BUILD.gn", >- "//build/config/android/config.gni", >- "//build/config/android/internal_rules.gni", >- "//build/config/android/rules.gni", >- "//build/config/BUILD.gn", >- "//build/config/compiler/BUILD.gn", >- "//build/config/gcc/gcc_version.gni", >- "//build/config/ios/ios_sdk.gni", >- "//build/config/linux/BUILD.gn", >- "//build/config/linux/pkg_config.gni", >- "//build/config/mac/mac_sdk.gni", >- "//build/config/posix/BUILD.gn", >- "//build/config/sysroot.gni", >- "//build/config/win/BUILD.gn", >- "//build/config/win/visual_studio_version.gni", >- "//build/gn_helpers.py", >- "//build/gypi_to_gn.py", >- "//build/toolchain/concurrent_links.gni", >- "//build/toolchain/gcc_toolchain.gni", >- "//build/toolchain/mac/BUILD.gn", >- "//build/toolchain/win/BUILD.gn", >-] >+exec_script_whitelist = build_dotfile_settings.exec_script_whitelist + >+ [ "//build_overrides/build.gni" ] > > default_args = { > mac_sdk_min = "10.11" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/Android.bp b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/Android.bp >index a3d8d834ac771791f9f9363f9f03ba2accefd069..7d95a7865abe182356dcb849efaa52c019988f6f 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/Android.bp >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/Android.bp >@@ -24,14 +24,12 @@ cc_library { > "source/rotate_any.cc", > "source/rotate_argb.cc", > "source/rotate_common.cc", >- "source/rotate_dspr2.cc", > "source/rotate_gcc.cc", > "source/rotate_msa.cc", > "source/rotate_neon.cc", > "source/rotate_neon64.cc", > "source/row_any.cc", > "source/row_common.cc", >- "source/row_dspr2.cc", > "source/row_gcc.cc", > "source/row_msa.cc", > "source/row_neon.cc", >@@ -40,7 +38,6 @@ cc_library { > "source/scale_any.cc", > "source/scale_argb.cc", > "source/scale_common.cc", >- "source/scale_dspr2.cc", > "source/scale_gcc.cc", > "source/scale_msa.cc", > "source/scale_neon.cc", >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/Android.mk b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/Android.mk >index 854020610eab2c5ff71cc6205a73cc9a9ae5d4d4..dbc6cad37ab3ca5b09ea342639935ef48f1dae50 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/Android.mk >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/Android.mk >@@ -24,14 +24,12 @@ LOCAL_SRC_FILES := \ > source/rotate_any.cc \ > source/rotate_argb.cc \ > source/rotate_common.cc \ >- source/rotate_dspr2.cc \ > source/rotate_gcc.cc \ > source/rotate_msa.cc \ > source/rotate_neon.cc \ > source/rotate_neon64.cc \ > source/row_any.cc \ > source/row_common.cc \ >- source/row_dspr2.cc \ > source/row_gcc.cc \ > source/row_msa.cc \ > source/row_neon.cc \ >@@ -40,7 +38,6 @@ LOCAL_SRC_FILES := \ > source/scale_any.cc \ > source/scale_argb.cc \ > source/scale_common.cc \ >- source/scale_dspr2.cc \ > source/scale_gcc.cc \ > source/scale_msa.cc \ > source/scale_neon.cc \ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/BUILD.gn >index 9badf08c8466e2957d54c10b53c870761c988f72..03ce499e6d9db8d2decdbadd94f877b403a24d6d 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/BUILD.gn >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/BUILD.gn >@@ -12,6 +12,11 @@ import("//testing/test.gni") > declare_args() { > # Set to false to disable building with gflags. > libyuv_use_gflags = true >+ >+ # When building a shared library using a target in WebRTC or >+ # Chromium projects that depends on libyuv, setting this flag >+ # to true makes libyuv symbols visible inside that library. >+ libyuv_symbols_visible = false > } > > config("libyuv_config") { >@@ -42,7 +47,8 @@ group("default") { > } > > group("libyuv") { >- public_configs = [ ":libyuv_config" ] >+ all_dependent_configs = [ ":libyuv_config" ] >+ deps = [] > > if (is_win && target_cpu == "x64") { > # Compile with clang in order to get inline assembly >@@ -55,13 +61,19 @@ group("libyuv") { > ] > } > >+ if (libyuv_use_neon) { >+ deps += [ ":libyuv_neon" ] >+ } >+ >+ if (libyuv_use_msa) { >+ deps += [ ":libyuv_msa" ] >+ } >+ > if (!is_ios) { > # Make sure that clients of libyuv link with libjpeg. This can't go in > # libyuv_internal because in Windows x64 builds that will generate a clang > # build of libjpeg, and we don't want two copies. >- deps = [ >- "//third_party:jpeg", >- ] >+ deps += [ "//third_party:jpeg" ] > } > } > >@@ -110,19 +122,16 @@ static_library("libyuv_internal") { > "source/rotate_any.cc", > "source/rotate_argb.cc", > "source/rotate_common.cc", >- "source/rotate_dspr2.cc", > "source/rotate_gcc.cc", > "source/rotate_win.cc", > "source/row_any.cc", > "source/row_common.cc", >- "source/row_dspr2.cc", > "source/row_gcc.cc", > "source/row_win.cc", > "source/scale.cc", > "source/scale_any.cc", > "source/scale_argb.cc", > "source/scale_common.cc", >- "source/scale_dspr2.cc", > "source/scale_gcc.cc", > "source/scale_win.cc", > "source/video_common.cc", >@@ -132,6 +141,11 @@ static_library("libyuv_internal") { > defines = [] > deps = [] > >+ if (libyuv_symbols_visible) { >+ configs -= [ "//build/config/gcc:symbol_visibility_hidden" ] >+ configs += [ "//build/config/gcc:symbol_visibility_default" ] >+ } >+ > if (!is_ios) { > defines += [ "HAVE_JPEG" ] > >@@ -140,14 +154,6 @@ static_library("libyuv_internal") { > deps += [ "//third_party:jpeg_includes" ] > } > >- if (libyuv_use_neon) { >- deps += [ ":libyuv_neon" ] >- } >- >- if (libyuv_use_msa) { >- deps += [ ":libyuv_msa" ] >- } >- > # Always enable optimization for Release and NaCl builds (to workaround > # crbug.com/538243). > if (!is_debug || is_nacl) { >@@ -167,6 +173,7 @@ static_library("libyuv_internal") { > ] > } > } >+ > if (libyuv_use_neon) { > static_library("libyuv_neon") { > sources = [ >@@ -181,6 +188,10 @@ if (libyuv_use_neon) { > "source/scale_neon64.cc", > ] > >+ deps = [ >+ ":libyuv_internal", >+ ] >+ > public_configs = [ ":libyuv_config" ] > > # Always enable optimization for Release and NaCl builds (to workaround >@@ -210,6 +221,10 @@ if (libyuv_use_msa) { > "source/scale_msa.cc", > ] > >+ deps = [ >+ ":libyuv_internal", >+ ] >+ > public_configs = [ ":libyuv_config" ] > } > } >@@ -302,7 +317,6 @@ if (libyuv_include_tests) { > # Enable the following 3 macros to turn off assembly for specified CPU. > # "LIBYUV_DISABLE_X86", > # "LIBYUV_DISABLE_NEON", >- # "LIBYUV_DISABLE_DSPR2", > # Enable the following macro to build libyuv as a shared library (dll). > # "LIBYUV_USING_SHARED_LIBRARY" > ] >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/DEPS b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/DEPS >index fdb133c7ac1b8a7291c2c07621cfaed91a2bfe17..266327470b7c0fa2c3631a3d0b28439e18c7d253 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/DEPS >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/DEPS >@@ -1,38 +1,38 @@ > vars = { > 'chromium_git': 'https://chromium.googlesource.com', >- 'chromium_revision': 'ff3b31782d552b03104a6d831c7530605b52b13f', >- 'swarming_revision': '5e8001d9a710121ce7a68efd0804430a34b4f9e4', >+ 'chromium_revision': '80f0c5570649c35a869429b2ab8c381a0a7246cb', >+ 'swarming_revision': '88229872dd17e71658fe96763feaa77915d8cbd6', > # Three lines of non-changing comments so that > # the commit queue can handle CLs rolling lss > # and whatever else without interference from each other. >- 'lss_revision': '63f24c8221a229f677d26ebe8f3d1528a9d787ac', >+ 'lss_revision': 'e6527b0cd469e3ff5764785dadcb39bf7d787154', > # Three lines of non-changing comments so that > # the commit queue can handle CLs rolling catapult > # and whatever else without interference from each other. >- 'catapult_revision': 'aa736cc76ee5e35215abcfb83a8c354f12d0c684', >+ 'catapult_revision': 'e7298f36f7912f2caa122086cfbe71734d04b73f', > } > > deps = { > 'src/build': >- Var('chromium_git') + '/chromium/src/build' + '@' + '156ba982d749902e3403c242e23ded87fd316494', >+ Var('chromium_git') + '/chromium/src/build' + '@' + '39738e75b27f39d4c0030a0b11d5d2ddd34715f7', > 'src/buildtools': >- Var('chromium_git') + '/chromium/buildtools.git' + '@' + 'f6d165d9d842ddd29056c127a5f3a3c5d8e0d2e3', >+ Var('chromium_git') + '/chromium/buildtools.git' + '@' + 'a09e064635a49f08e585e3b173d5fbc3dd3f485e', > 'src/testing': >- Var('chromium_git') + '/chromium/src/testing' + '@' + 'cc96d3d66b5b9613fd0fe055509cfec5eb54b19c', >+ Var('chromium_git') + '/chromium/src/testing' + '@' + '5f7e36cad6434fd3d65674af96653a23ecc9f694', > 'src/third_party': >- Var('chromium_git') + '/chromium/src/third_party' + '@' + '72c52c224cdd3c377f7caff8ffed0f5749e79549', >+ Var('chromium_git') + '/chromium/src/third_party' + '@' + '2c0ced3ddbf84ce1c0759b277d9538da42f23650', > 'src/third_party/catapult': >- Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' + Var('catapult_revision'), >+ Var('chromium_git') + '/catapult.git' + '@' + Var('catapult_revision'), > 'src/third_party/colorama/src': > Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8', > 'src/third_party/googletest/src': >- Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '7f8fefabedf2965980585be8c2bff97458f28e0b', >+ Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '0062e4869f07a3ef235703ddf63af604b712446c', > 'src/third_party/libjpeg_turbo': > Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + 'a1750dbc79a8792dde3d3f7d7d8ac28ba01ac9dd', > 'src/third_party/yasm/source/patched-yasm': > Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + 'b98114e18d8b9b84586b10d24353ab8616d4c5fc', > 'src/tools': >- Var('chromium_git') + '/chromium/src/tools' + '@' + 'eceb2c420b20350a2d2ba261953109280968647a', >+ Var('chromium_git') + '/chromium/src/tools' + '@' + '6202b67fc46a9984097caf237e12e3b8f7a9f7da', > 'src/tools/gyp': > Var('chromium_git') + '/external/gyp.git' + '@' + 'd61a9397e668fa9843c4aa7da9e79460fe590bfb', > 'src/tools/swarming_client': >@@ -45,45 +45,84 @@ deps = { > Var('chromium_git') + '/external/github.com/gflags/gflags' + '@' + '03bebcb065c83beff83d50ae025a55a4bf94dfca', > 'src/third_party/gtest-parallel': > Var('chromium_git') + '/external/webrtc/deps/third_party/gtest-parallel' + '@' + '1dad0e9f6d82ff994130b529d7d814b40eb32b0e', >-} > >-deps_os = { >- 'android': { >- 'src/base': >- Var('chromium_git') + '/chromium/src/base' + '@' + '9b543d487c7c38be191c6180001ff9ce186ae326', >- 'src/third_party/android_tools': >- Var('chromium_git') + '/android_tools.git' + '@' + 'aadb2fed04af8606545b0afe4e3060bc1a15fad7', >- 'src/third_party/ced/src': >- Var('chromium_git') + '/external/github.com/google/compact_enc_det.git' + '@' + '94c367a1fe3a13207f4b22604fcfd1d9f9ddf6d9', >- 'src/third_party/icu': >- Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '08cb956852a5ccdba7f9c941728bb833529ba3c6', >- 'src/third_party/jsr-305/src': >- Var('chromium_git') + '/external/jsr-305.git' + '@' + '642c508235471f7220af6d5df2d3210e3bfc0919', >- 'src/third_party/junit/src': >- Var('chromium_git') + '/external/junit.git' + '@' + '64155f8a9babcfcf4263cf4d08253a1556e75481', >- 'src/third_party/lss': >- Var('chromium_git') + '/linux-syscall-support.git' + '@' + Var('lss_revision'), >- 'src/third_party/mockito/src': >- Var('chromium_git') + '/external/mockito/mockito.git' + '@' + 'de83ad4598ad4cf5ea53c69a8a8053780b04b850', >- 'src/third_party/requests/src': >- Var('chromium_git') + '/external/github.com/kennethreitz/requests.git' + '@' + 'f172b30356d821d180fa4ecfa3e71c7274a32de4', >- 'src/third_party/robolectric/robolectric': >- Var('chromium_git') + '/external/robolectric.git' + '@' + 'b02c65cc6d7465f58f0de48a39914aa905692afa', >- 'src/third_party/ub-uiautomator/lib': >- Var('chromium_git') + '/chromium/third_party/ub-uiautomator.git' + '@' + '00270549ce3161ae72ceb24712618ea28b4f9434', >- }, >- 'ios': { >- 'src/ios': >- Var('chromium_git') + '/chromium/src/ios' + '@' + '39c4b2fcf73f5b1e82af3b9c57267c17217d6a30', >- }, >- 'unix': { >- 'src/third_party/lss': >- Var('chromium_git') + '/linux-syscall-support.git' + '@' + Var('lss_revision'), >- }, >- 'win': { >- # Dependencies used by libjpeg-turbo >- 'src/third_party/yasm/binaries': >- Var('chromium_git') + '/chromium/deps/yasm/binaries.git' + '@' + '52f9b3f4b0aa06da24ef8b123058bb61ee468881', >+ 'src/third_party/lss': { >+ 'url': Var('chromium_git') + '/linux-syscall-support.git' + '@' + Var('lss_revision'), >+ 'condition': 'checkout_android or checkout_linux', >+ }, >+ >+ # Android deps: >+ 'src/third_party/auto/src': { >+ 'url': Var('chromium_git') + '/external/github.com/google/auto.git' + '@' + '8a81a858ae7b78a1aef71ac3905fade0bbd64e82', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/auto/src': { >+ 'url': Var('chromium_git') + '/external/github.com/google/auto.git' + '@' + '8a81a858ae7b78a1aef71ac3905fade0bbd64e82', >+ 'condition': 'checkout_android', >+ }, >+ 'src/base': { >+ 'url': Var('chromium_git') + '/chromium/src/base' + '@' + 'ac3d2b81181b085a9952cb83dba748420eefe691', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/android_ndk': { >+ 'url': Var('chromium_git') + '/android_ndk.git' + '@' + 'e951c37287c7d8cd915bf8d4149fd4a06d808b55', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/android_tools': { >+ 'url': Var('chromium_git') + '/android_tools.git' + '@' + '9a70d48fcdd68cd0e7e968f342bd767ee6323bd1', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/ced/src': { >+ 'url': Var('chromium_git') + '/external/github.com/google/compact_enc_det.git' + '@' + '94c367a1fe3a13207f4b22604fcfd1d9f9ddf6d9', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/errorprone/lib': { >+ 'url': Var('chromium_git') + '/chromium/third_party/errorprone.git' + '@' + 'ecc57c2b00627667874744b9ad8efe10734d97a8', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/findbugs': { >+ 'url': Var('chromium_git') + '/chromium/deps/findbugs.git' + '@' + '4275d9ac8610db6b1bc9a5e887f97e41b33fac67', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/icu': { >+ 'url': Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'd888fd2a1be890f4d35e43f68d6d79f42519a357', >+ }, >+ 'src/third_party/jsr-305/src': { >+ 'url': Var('chromium_git') + '/external/jsr-305.git' + '@' + '642c508235471f7220af6d5df2d3210e3bfc0919', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/junit/src': { >+ 'url': Var('chromium_git') + '/external/junit.git' + '@' + '64155f8a9babcfcf4263cf4d08253a1556e75481', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/mockito/src': { >+ 'url': Var('chromium_git') + '/external/mockito/mockito.git' + '@' + 'de83ad4598ad4cf5ea53c69a8a8053780b04b850', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/requests/src': { >+ 'url': Var('chromium_git') + '/external/github.com/kennethreitz/requests.git' + '@' + 'f172b30356d821d180fa4ecfa3e71c7274a32de4', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/robolectric/robolectric': { >+ 'url': Var('chromium_git') + '/external/robolectric.git' + '@' + '7e067f1112e1502caa742f7be72d37b5678d3403', >+ 'condition': 'checkout_android', >+ }, >+ 'src/third_party/ub-uiautomator/lib': { >+ 'url': Var('chromium_git') + '/chromium/third_party/ub-uiautomator.git' + '@' + '00270549ce3161ae72ceb24712618ea28b4f9434', >+ 'condition': 'checkout_android', >+ }, >+ >+ # iOS deps: >+ 'src/ios': { >+ 'url': Var('chromium_git') + '/chromium/src/ios' + '@' + '299ef76e844a74a1f2f4ce7f06d101861fb49aba', >+ 'condition': 'checkout_ios' >+ }, >+ >+ # Win deps: >+ # Dependencies used by libjpeg-turbo >+ 'src/third_party/yasm/binaries': { >+ 'url': Var('chromium_git') + '/chromium/deps/yasm/binaries.git' + '@' + '52f9b3f4b0aa06da24ef8b123058bb61ee468881', >+ 'condition': 'checkout_win', > }, > } > >@@ -116,200 +155,41 @@ hooks = [ > 'src', > ], > }, >- # Android dependencies. Many are downloaded using Google Storage these days. >- # They're copied from https://cs.chromium.org/chromium/src/DEPS for all >- # such dependencies we share with Chromium. >- { >- # This downloads SDK extras and puts them in the >- # third_party/android_tools/sdk/extras directory. >- 'name': 'sdkextras', >- 'pattern': '.', >- # When adding a new sdk extras package to download, add the package >- # directory and zip file to .gitignore in third_party/android_tools. >- 'action': ['python', >- 'src/build/android/play_services/update.py', >- 'download' >- ], >- }, >- { >- 'name': 'intellij', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-intellij', >- '-l', 'third_party/intellij' >- ], >- }, >- { >- 'name': 'javax_inject', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-javax-inject', >- '-l', 'third_party/javax_inject' >- ], >- }, >- { >- 'name': 'hamcrest', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-hamcrest', >- '-l', 'third_party/hamcrest' >- ], >- }, >- { >- 'name': 'guava', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-guava', >- '-l', 'third_party/guava' >- ], >- }, >- { >- 'name': 'android_support_test_runner', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-android-support-test-runner', >- '-l', 'third_party/android_support_test_runner' >- ], >- }, >- { >- 'name': 'byte_buddy', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-byte-buddy', >- '-l', 'third_party/byte_buddy' >- ], >- }, >+ # Downloads the current stable linux sysroot to build/linux/ if needed. > { >- 'name': 'espresso', >+ 'name': 'sysroot_arm', > 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-espresso', >- '-l', 'third_party/espresso' >- ], >- }, >- { >- 'name': 'robolectric_libs', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-robolectric', >- '-l', 'third_party/robolectric' >- ], >- }, >- { >- 'name': 'apache_velocity', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-apache-velocity', >- '-l', 'third_party/apache_velocity' >- ], >- }, >- { >- 'name': 'ow2_asm', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-ow2-asm', >- '-l', 'third_party/ow2_asm' >- ], >- }, >- { >- 'name': 'desugar', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-android-tools/bazel/desugar', >- '-l', 'third_party/bazel/desugar' >- ], >- }, >- { >- 'name': 'icu4j', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-icu4j', >- '-l', 'third_party/icu4j' >- ], >- }, >- { >- 'name': 'accessibility_test_framework', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-accessibility-test-framework', >- '-l', 'third_party/accessibility_test_framework' >- ], >- }, >- { >- 'name': 'bouncycastle', >- 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-bouncycastle', >- '-l', 'third_party/bouncycastle' >- ], >+ 'condition': 'checkout_linux and checkout_arm', >+ 'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py', >+ '--arch=arm'], > }, > { >- 'name': 'sqlite4java', >+ 'name': 'sysroot_arm64', > 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-sqlite4java', >- '-l', 'third_party/sqlite4java' >- ], >+ 'condition': 'checkout_linux and checkout_arm64', >+ 'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py', >+ '--arch=arm64'], > }, > { >- 'name': 'xstream', >+ 'name': 'sysroot_x86', > 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-robolectric', >- '-l', 'third_party/xstream' >- ], >+ 'condition': 'checkout_linux and (checkout_x86 or checkout_x64)', >+ 'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py', >+ '--arch=x86'], > }, > { >- 'name': 'objenesis', >+ 'name': 'sysroot_mips', > 'pattern': '.', >- 'action': ['python', >- 'src/build/android/update_deps/update_third_party_deps.py', >- 'download', >- '-b', 'chromium-objenesis', >- '-l', 'third_party/objenesis' >- ], >+ 'condition': 'checkout_linux and checkout_mips', >+ 'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py', >+ '--arch=mips'], > }, > { >- # Downloads the current stable linux sysroot to build/linux/ if needed. >- # This sysroot updates at about the same rate that the chrome build deps >- # change. This script is a no-op except for linux users who are doing >- # official chrome builds or cross compiling. >- 'name': 'sysroot', >+ 'name': 'sysroot_x64', > 'pattern': '.', >+ 'condition': 'checkout_linux and checkout_x64', > 'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py', >- '--running-as-hook'], >+ '--arch=x64'], > }, > { > # Update the Windows toolchain if necessary. >@@ -444,6 +324,30 @@ hooks = [ > '-d', 'src/tools/luci-go/linux64', > ], > }, >+ { >+ 'name': 'Android CIPD Ensure', >+ 'pattern': '.', >+ 'condition': 'checkout_android', >+ 'action': ['src/build/cipd/cipd_wrapper.py', >+ '--chromium-root', 'src', >+ '--ensure-file', 'src/build/cipd/android/android.ensure', >+ ], >+ }, >+ # Android dependencies. Many are downloaded using Google Storage these days. >+ # They're copied from https://cs.chromium.org/chromium/src/DEPS for all >+ # such dependencies we share with Chromium. >+ { >+ # This downloads SDK extras and puts them in the >+ # third_party/android_tools/sdk/extras directory. >+ 'name': 'sdkextras', >+ 'pattern': '.', >+ # When adding a new sdk extras package to download, add the package >+ # directory and zip file to .gitignore in third_party/android_tools. >+ 'action': ['python', >+ 'src/build/android/play_services/update.py', >+ 'download' >+ ], >+ }, > ] > > recursedeps = [ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/README.chromium b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/README.chromium >index 88c069734ac2342aad55414a2753243c273db883..c25373e23ce4214f22882c6d9904bea39681820c 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/README.chromium >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/README.chromium >@@ -1,6 +1,6 @@ > Name: libyuv > URL: http://code.google.com/p/libyuv/ >-Version: 1678 >+Version: 1703 > License: BSD > License File: LICENSE > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/README.md b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/README.md >index b59b71c5d2b4faab505641d9dd9173cba9178b4f..7b6619220b8dcd183948083221de49df6fb4b2a7 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/README.md >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/README.md >@@ -1,12 +1,12 @@ > **libyuv** is an open source project that includes YUV scaling and conversion functionality. > > * Scale YUV to prepare content for compression, with point, bilinear or box filter. >-* Convert to YUV from webcam formats. >-* Convert from YUV to formats for rendering/effects. >+* Convert to YUV from webcam formats for compression. >+* Convert to RGB formats for rendering/effects. > * Rotate by 90/180/270 degrees to adjust for mobile devices in portrait mode. >-* Optimized for SSE2/SSSE3/AVX2 on x86/x64. >+* Optimized for SSSE3/AVX2 on x86/x64. > * Optimized for Neon on Arm. >-* Optimized for DSP R2 on Mips. >+* Optimized for MSA on Mips. > > ### Development > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/deprecated_builds.md b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/deprecated_builds.md >index d54a0282c155acfe3d3ebd3efb6699dd72cc5b56..29e0bf9bc30bcbb49e8b05c6e205906cf7baa6a4 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/deprecated_builds.md >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/deprecated_builds.md >@@ -165,11 +165,11 @@ mipsel > > arm32 disassembly: > >- third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-objdump -d out/Release/obj/source/libyuv.row_neon.o >+ third_party/android_ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-objdump -d out/Release/obj/source/libyuv.row_neon.o > > arm64 disassembly: > >- third_party/android_tools/ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -d out/Release/obj/source/libyuv.row_neon64.o >+ third_party/android_ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -d out/Release/obj/source/libyuv.row_neon64.o > > Running tests: > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/environment_variables.md b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/environment_variables.md >index 9071c54de2349dc3e0d50fecdd6fba6281e2fb3e..c28d83e7dc14905e9506e4f7eee8ac35957ffb16 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/environment_variables.md >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/environment_variables.md >@@ -17,7 +17,7 @@ By default the cpu is detected and the most advanced form of SIMD is used. But > LIBYUV_DISABLE_AVX512BW > LIBYUV_DISABLE_ERMS > LIBYUV_DISABLE_FMA3 >- LIBYUV_DISABLE_DSPR2 >+ LIBYUV_DISABLE_MSA > LIBYUV_DISABLE_NEON > > # Test Width/Height/Repeat >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/formats.md b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/formats.md >index 2b75d31ac7507a5379fcba46e9ae278d415a7c8a..f78f57bb4c41a3e150842a0c4fb5c043e33656f0 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/formats.md >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/formats.md >@@ -35,9 +35,8 @@ This is how OSX formats map to libyuv > # FOURCC (Four Charactacter Code) List > > The following is extracted from video_common.h as a complete list of formats supported by libyuv. >- > enum FourCC { >- // 8 Primary YUV formats: 5 planar, 2 biplanar, 2 packed. >+ // 9 Primary YUV formats: 5 planar, 2 biplanar, 2 packed. > FOURCC_I420 = FOURCC('I', '4', '2', '0'), > FOURCC_I422 = FOURCC('I', '4', '2', '2'), > FOURCC_I444 = FOURCC('I', '4', '4', '4'), >@@ -46,37 +45,35 @@ The following is extracted from video_common.h as a complete list of formats sup > FOURCC_NV12 = FOURCC('N', 'V', '1', '2'), > FOURCC_YUY2 = FOURCC('Y', 'U', 'Y', '2'), > FOURCC_UYVY = FOURCC('U', 'Y', 'V', 'Y'), >+ FOURCC_H010 = FOURCC('H', '0', '1', '0'), // unofficial fourcc. 10 bit lsb > >- // 1 Secondary YUV formats: row biplanar. >+ // 1 Secondary YUV format: row biplanar. > FOURCC_M420 = FOURCC('M', '4', '2', '0'), > >- // 9 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp. >+ // 11 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp, 1 10 bpc > FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'), > FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'), > FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'), >+ FOURCC_AR30 = FOURCC('A', 'R', '3', '0'), // 10 bit per channel. 2101010. >+ FOURCC_AB30 = FOURCC('A', 'B', '3', '0'), // ABGR version of 10 bit > FOURCC_24BG = FOURCC('2', '4', 'B', 'G'), >- FOURCC_RAW = FOURCC('r', 'a', 'w', ' '), >+ FOURCC_RAW = FOURCC('r', 'a', 'w', ' '), > FOURCC_RGBA = FOURCC('R', 'G', 'B', 'A'), > FOURCC_RGBP = FOURCC('R', 'G', 'B', 'P'), // rgb565 LE. > FOURCC_RGBO = FOURCC('R', 'G', 'B', 'O'), // argb1555 LE. > FOURCC_R444 = FOURCC('R', '4', '4', '4'), // argb4444 LE. > >- // 4 Secondary RGB formats: 4 Bayer Patterns. >- FOURCC_RGGB = FOURCC('R', 'G', 'G', 'B'), >- FOURCC_BGGR = FOURCC('B', 'G', 'G', 'R'), >- FOURCC_GRBG = FOURCC('G', 'R', 'B', 'G'), >- FOURCC_GBRG = FOURCC('G', 'B', 'R', 'G'), >- > // 1 Primary Compressed YUV format. > FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'), > >- // 5 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias. >+ // 7 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias. > FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'), > FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'), > FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'), > FOURCC_YU12 = FOURCC('Y', 'U', '1', '2'), // Linux version of I420. > FOURCC_J420 = FOURCC('J', '4', '2', '0'), >- FOURCC_J400 = FOURCC('J', '4', '0', '0'), >+ FOURCC_J400 = FOURCC('J', '4', '0', '0'), // unofficial fourcc >+ FOURCC_H420 = FOURCC('H', '4', '2', '0'), // unofficial fourcc > > // 14 Auxiliary aliases. CanonicalFourCC() maps these to canonical fourcc. > FOURCC_IYUV = FOURCC('I', 'Y', 'U', 'V'), // Alias for I420. >@@ -97,9 +94,6 @@ The following is extracted from video_common.h as a complete list of formats sup > FOURCC_L565 = FOURCC('L', '5', '6', '5'), // Alias for RGBP. > FOURCC_5551 = FOURCC('5', '5', '5', '1'), // Alias for RGBO. > >- // 1 Auxiliary compressed YUV format set aside for capturer. >- FOURCC_H264 = FOURCC('H', '2', '6', '4'), >- > # Planar YUV > The following formats contains a full size Y plane followed by 1 or 2 > planes for UV: I420, I422, I444, I400, NV21, NV12, I400 >@@ -145,3 +139,24 @@ There are 2 RGB layouts - RGB24 (aka 24BG) and RAW > > RGB24 is B,G,R in memory > RAW is R,G,B in memory >+ >+# AR30 and XR30 >+ >+AR30 is 2 10 10 10 ARGB stored in little endian order. >+The 2 bit alpha has 4 values. Here are the comparable 8 bit alpha values. >+0 - 0. 00000000b = 0x00 = 0 >+1 - 33%. 01010101b = 0x55 = 85 >+2 - 66%. 10101010b = 0xaa = 170 >+3 - 100%. 11111111b = 0xff = 255 >+The 10 bit RGB values range from 0 to 1023. >+XR30 is the same as AR30 but with no alpha channel. >+ >+# NV12 and NV21 >+ >+NV12 is a biplanar format with a full sized Y plane followed by a single >+chroma plane with weaved U and V values. >+NV21 is the same but with weaved V and U values. >+The 12 in NV12 refers to 12 bits per pixel. NV12 has a half width and half >+height chroma channel, and therefore is a 420 subsampling. >+NV16 is 16 bits per pixel, with half width and full height. aka 422. >+NV24 is 24 bits per pixel with full sized chroma channel. aka 444. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/getting_started.md b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/getting_started.md >index 58e05f3cbcba7141aa4c6d367023c5bd509b1836..09297b66a5cc784de596690fb4bfe36ad4232b87 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/getting_started.md >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/docs/getting_started.md >@@ -129,25 +129,20 @@ ia32 > ninja -v -C out/Debug libyuv_unittest > ninja -v -C out/Release libyuv_unittest > >-mipsel >+mips > >- gn gen out/Release "--args=is_debug=false target_os=\"android\" target_cpu=\"mipsel\" mips_arch_variant=\"r6\" mips_use_msa=true is_component_build=true is_clang=false" >- gn gen out/Debug "--args=is_debug=true target_os=\"android\" target_cpu=\"mipsel\" mips_arch_variant=\"r6\" mips_use_msa=true is_component_build=true is_clang=false" >- ninja -v -C out/Debug libyuv_unittest >- ninja -v -C out/Release libyuv_unittest >- >- gn gen out/Release "--args=is_debug=false target_os=\"android\" target_cpu=\"mips64el\" mips_arch_variant=\"r6\" mips_use_msa=true is_component_build=true is_clang=false" >- gn gen out/Debug "--args=is_debug=true target_os=\"android\" target_cpu=\"mips64el\" mips_arch_variant=\"r6\" mips_use_msa=true is_component_build=true is_clang=false" >+ gn gen out/Release "--args=is_debug=false target_os=\"android\" target_cpu=\"mips64el\" mips_arch_variant=\"r6\" mips_use_msa=true is_component_build=true is_clang=true" >+ gn gen out/Debug "--args=is_debug=true target_os=\"android\" target_cpu=\"mips64el\" mips_arch_variant=\"r6\" mips_use_msa=true is_component_build=true is_clang=true" > ninja -v -C out/Debug libyuv_unittest > ninja -v -C out/Release libyuv_unittest > > arm disassembly: > >- third_party/android_tools/ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -d ./out/Release/obj/libyuv/row_common.o >row_common.txt >+ third_party/android_ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -d ./out/Release/obj/libyuv/row_common.o >row_common.txt > >- third_party/android_tools/ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -d ./out/Release/obj/libyuv_neon/row_neon.o >row_neon.txt >+ third_party/android_ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -d ./out/Release/obj/libyuv_neon/row_neon.o >row_neon.txt > >- third_party/android_tools/ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -d ./out/Release/obj/libyuv_neon/row_neon64.o >row_neon64.txt >+ third_party/android_ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -d ./out/Release/obj/libyuv_neon/row_neon64.o >row_neon64.txt > > Running tests: > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/basic_types.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/basic_types.h >index 7d98bb93f0eed1629124f3b374cc8df6b6241b79..01d9dfc773628adf90c4c223dd0926b7ce7ff2f0 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/basic_types.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/basic_types.h >@@ -11,79 +11,33 @@ > #ifndef INCLUDE_LIBYUV_BASIC_TYPES_H_ > #define INCLUDE_LIBYUV_BASIC_TYPES_H_ > >-#include <stddef.h> // for NULL, size_t >+#include <stddef.h> // For size_t and NULL >+ >+#if !defined(INT_TYPES_DEFINED) && !defined(GG_LONGLONG) >+#define INT_TYPES_DEFINED > > #if defined(_MSC_VER) && (_MSC_VER < 1600) > #include <sys/types.h> // for uintptr_t on x86 >+typedef unsigned __int64 uint64_t; >+typedef __int64 int64_t; >+typedef unsigned int uint32_t; >+typedef int int32_t; >+typedef unsigned short uint16_t; >+typedef short int16_t; >+typedef unsigned char uint8_t; >+typedef signed char int8_t; > #else >-#include <stdint.h> // for uintptr_t >-#endif >- >-#ifndef GG_LONGLONG >-#ifndef INT_TYPES_DEFINED >-#define INT_TYPES_DEFINED >-#ifdef COMPILER_MSVC >-typedef unsigned __int64 uint64; >-typedef __int64 int64; >-#ifndef INT64_C >-#define INT64_C(x) x##I64 >-#endif >-#ifndef UINT64_C >-#define UINT64_C(x) x##UI64 >-#endif >-#define INT64_F "I64" >-#else // COMPILER_MSVC >-#if defined(__LP64__) && !defined(__OpenBSD__) && !defined(__APPLE__) >-typedef unsigned long uint64; // NOLINT >-typedef long int64; // NOLINT >-#ifndef INT64_C >-#define INT64_C(x) x##L >-#endif >-#ifndef UINT64_C >-#define UINT64_C(x) x##UL >-#endif >-#define INT64_F "l" >-#else // defined(__LP64__) && !defined(__OpenBSD__) && !defined(__APPLE__) >-typedef unsigned long long uint64; // NOLINT >-typedef long long int64; // NOLINT >-#ifndef INT64_C >-#define INT64_C(x) x##LL >-#endif >-#ifndef UINT64_C >-#define UINT64_C(x) x##ULL >-#endif >-#define INT64_F "ll" >-#endif // __LP64__ >-#endif // COMPILER_MSVC >-typedef unsigned int uint32; >-typedef int int32; >-typedef unsigned short uint16; // NOLINT >-typedef short int16; // NOLINT >-typedef unsigned char uint8; >-typedef signed char int8; >+#include <stdint.h> // for uintptr_t and C99 types >+#endif // defined(_MSC_VER) && (_MSC_VER < 1600) >+typedef uint64_t uint64; >+typedef int64_t int64; >+typedef uint32_t uint32; >+typedef int32_t int32; >+typedef uint16_t uint16; >+typedef int16_t int16; >+typedef uint8_t uint8; >+typedef int8_t int8; > #endif // INT_TYPES_DEFINED >-#endif // GG_LONGLONG >- >-// Detect compiler is for x86 or x64. >-#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ >- defined(_M_IX86) >-#define CPU_X86 1 >-#endif >-// Detect compiler is for ARM. >-#if defined(__arm__) || defined(_M_ARM) >-#define CPU_ARM 1 >-#endif >- >-#ifndef ALIGNP >-#ifdef __cplusplus >-#define ALIGNP(p, t) \ >- reinterpret_cast<uint8*>( \ >- ((reinterpret_cast<uintptr_t>(p) + ((t)-1)) & ~((t)-1))) >-#else >-#define ALIGNP(p, t) \ >- (uint8*)((((uintptr_t)(p) + ((t)-1)) & ~((t)-1))) /* NOLINT */ >-#endif >-#endif > > #if !defined(LIBYUV_API) > #if defined(_WIN32) || defined(__CYGWIN__) >@@ -103,15 +57,9 @@ typedef signed char int8; > #endif // __GNUC__ > #endif // LIBYUV_API > >+// TODO(fbarchard): Remove bool macros. > #define LIBYUV_BOOL int > #define LIBYUV_FALSE 0 > #define LIBYUV_TRUE 1 > >-// Visual C x86 or GCC little endian. >-#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ >- defined(_M_IX86) || defined(__arm__) || defined(_M_ARM) || \ >- (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) >-#define LIBYUV_LITTLE_ENDIAN >-#endif >- > #endif // INCLUDE_LIBYUV_BASIC_TYPES_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/compare.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/compare.h >index a06eff2066f1e9b59303ed5623565117ae71687f..3353ad71c68a805146cf4ca6edfe39ed2636271d 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/compare.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/compare.h >@@ -20,80 +20,85 @@ extern "C" { > > // Compute a hash for specified memory. Seed of 5381 recommended. > LIBYUV_API >-uint32 HashDjb2(const uint8* src, uint64 count, uint32 seed); >+uint32_t HashDjb2(const uint8_t* src, uint64_t count, uint32_t seed); > > // Hamming Distance > LIBYUV_API >-uint64 ComputeHammingDistance(const uint8* src_a, >- const uint8* src_b, >- int count); >+uint64_t ComputeHammingDistance(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); > > // Scan an opaque argb image and return fourcc based on alpha offset. > // Returns FOURCC_ARGB, FOURCC_BGRA, or 0 if unknown. > LIBYUV_API >-uint32 ARGBDetect(const uint8* argb, int stride_argb, int width, int height); >+uint32_t ARGBDetect(const uint8_t* argb, >+ int stride_argb, >+ int width, >+ int height); > > // Sum Square Error - used to compute Mean Square Error or PSNR. > LIBYUV_API >-uint64 ComputeSumSquareError(const uint8* src_a, const uint8* src_b, int count); >+uint64_t ComputeSumSquareError(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); > > LIBYUV_API >-uint64 ComputeSumSquareErrorPlane(const uint8* src_a, >- int stride_a, >- const uint8* src_b, >- int stride_b, >- int width, >- int height); >+uint64_t ComputeSumSquareErrorPlane(const uint8_t* src_a, >+ int stride_a, >+ const uint8_t* src_b, >+ int stride_b, >+ int width, >+ int height); > > static const int kMaxPsnr = 128; > > LIBYUV_API >-double SumSquareErrorToPsnr(uint64 sse, uint64 count); >+double SumSquareErrorToPsnr(uint64_t sse, uint64_t count); > > LIBYUV_API >-double CalcFramePsnr(const uint8* src_a, >+double CalcFramePsnr(const uint8_t* src_a, > int stride_a, >- const uint8* src_b, >+ const uint8_t* src_b, > int stride_b, > int width, > int height); > > LIBYUV_API >-double I420Psnr(const uint8* src_y_a, >+double I420Psnr(const uint8_t* src_y_a, > int stride_y_a, >- const uint8* src_u_a, >+ const uint8_t* src_u_a, > int stride_u_a, >- const uint8* src_v_a, >+ const uint8_t* src_v_a, > int stride_v_a, >- const uint8* src_y_b, >+ const uint8_t* src_y_b, > int stride_y_b, >- const uint8* src_u_b, >+ const uint8_t* src_u_b, > int stride_u_b, >- const uint8* src_v_b, >+ const uint8_t* src_v_b, > int stride_v_b, > int width, > int height); > > LIBYUV_API >-double CalcFrameSsim(const uint8* src_a, >+double CalcFrameSsim(const uint8_t* src_a, > int stride_a, >- const uint8* src_b, >+ const uint8_t* src_b, > int stride_b, > int width, > int height); > > LIBYUV_API >-double I420Ssim(const uint8* src_y_a, >+double I420Ssim(const uint8_t* src_y_a, > int stride_y_a, >- const uint8* src_u_a, >+ const uint8_t* src_u_a, > int stride_u_a, >- const uint8* src_v_a, >+ const uint8_t* src_v_a, > int stride_v_a, >- const uint8* src_y_b, >+ const uint8_t* src_y_b, > int stride_y_b, >- const uint8* src_u_b, >+ const uint8_t* src_u_b, > int stride_u_b, >- const uint8* src_v_b, >+ const uint8_t* src_v_b, > int stride_v_b, > int width, > int height); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/compare_row.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/compare_row.h >index 2e5ebe508d1c91056641aababfbbee6269157b5e..72ee740600af1c643a2bf1473f735ce829a144f3 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/compare_row.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/compare_row.h >@@ -18,17 +18,20 @@ namespace libyuv { > extern "C" { > #endif > >-#if defined(__pnacl__) || defined(__CLR_VER) || \ >+#if defined(__pnacl__) || defined(__CLR_VER) || \ >+ (defined(__native_client__) && defined(__x86_64__)) || \ > (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) > #define LIBYUV_DISABLE_X86 > #endif >+#if defined(__native_client__) >+#define LIBYUV_DISABLE_NEON >+#endif > // MemorySanitizer does not support assembly code yet. http://crbug.com/344505 > #if defined(__has_feature) > #if __has_feature(memory_sanitizer) > #define LIBYUV_DISABLE_X86 > #endif > #endif >- > // Visual C 2012 required for AVX2. > #if defined(_M_IX86) && !defined(__clang__) && defined(_MSC_VER) && \ > _MSC_VER >= 1700 >@@ -87,22 +90,44 @@ extern "C" { > #define HAS_SUMSQUAREERROR_MSA > #endif > >-uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count); >-uint32 HammingDistance_SSE42(const uint8* src_a, const uint8* src_b, int count); >-uint32 HammingDistance_SSSE3(const uint8* src_a, const uint8* src_b, int count); >-uint32 HammingDistance_AVX2(const uint8* src_a, const uint8* src_b, int count); >-uint32 HammingDistance_NEON(const uint8* src_a, const uint8* src_b, int count); >-uint32 HammingDistance_MSA(const uint8* src_a, const uint8* src_b, int count); >- >-uint32 SumSquareError_C(const uint8* src_a, const uint8* src_b, int count); >-uint32 SumSquareError_SSE2(const uint8* src_a, const uint8* src_b, int count); >-uint32 SumSquareError_AVX2(const uint8* src_a, const uint8* src_b, int count); >-uint32 SumSquareError_NEON(const uint8* src_a, const uint8* src_b, int count); >-uint32 SumSquareError_MSA(const uint8* src_a, const uint8* src_b, int count); >- >-uint32 HashDjb2_C(const uint8* src, int count, uint32 seed); >-uint32 HashDjb2_SSE41(const uint8* src, int count, uint32 seed); >-uint32 HashDjb2_AVX2(const uint8* src, int count, uint32 seed); >+uint32_t HammingDistance_C(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+uint32_t HammingDistance_SSE42(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+uint32_t HammingDistance_SSSE3(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+uint32_t HammingDistance_AVX2(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+uint32_t HammingDistance_NEON(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+uint32_t HammingDistance_MSA(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+ >+uint32_t SumSquareError_C(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+uint32_t SumSquareError_SSE2(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+uint32_t SumSquareError_AVX2(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+uint32_t SumSquareError_NEON(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+uint32_t SumSquareError_MSA(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); >+ >+uint32_t HashDjb2_C(const uint8_t* src, int count, uint32_t seed); >+uint32_t HashDjb2_SSE41(const uint8_t* src, int count, uint32_t seed); >+uint32_t HashDjb2_AVX2(const uint8_t* src, int count, uint32_t seed); > > #ifdef __cplusplus > } // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert.h >index f096d193a74ee808f9995c8ed34700bbf757a662..d12ef24f799792a5695bf51e67e1e972892b0125 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert.h >@@ -27,34 +27,34 @@ extern "C" { > > // Convert I444 to I420. > LIBYUV_API >-int I444ToI420(const uint8* src_y, >+int I444ToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert I422 to I420. > LIBYUV_API >-int I422ToI420(const uint8* src_y, >+int I422ToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); >@@ -62,30 +62,67 @@ int I422ToI420(const uint8* src_y, > // Copy I420 to I420. > #define I420ToI420 I420Copy > LIBYUV_API >-int I420Copy(const uint8* src_y, >+int I420Copy(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > >+// Copy I010 to I010 >+#define I010ToI010 I010Copy >+#define H010ToH010 I010Copy >+LIBYUV_API >+int I010Copy(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint16_t* dst_y, >+ int dst_stride_y, >+ uint16_t* dst_u, >+ int dst_stride_u, >+ uint16_t* dst_v, >+ int dst_stride_v, >+ int width, >+ int height); >+ >+// Convert 10 bit YUV to 8 bit >+#define H010ToH420 I010ToI420 >+LIBYUV_API >+int I010ToI420(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_y, >+ int dst_stride_y, >+ uint8_t* dst_u, >+ int dst_stride_u, >+ uint8_t* dst_v, >+ int dst_stride_v, >+ int width, >+ int height); >+ > // Convert I400 (grey) to I420. > LIBYUV_API >-int I400ToI420(const uint8* src_y, >+int I400ToI420(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); >@@ -94,204 +131,204 @@ int I400ToI420(const uint8* src_y, > > // Convert NV12 to I420. > LIBYUV_API >-int NV12ToI420(const uint8* src_y, >+int NV12ToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_uv, >+ const uint8_t* src_uv, > int src_stride_uv, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert NV21 to I420. > LIBYUV_API >-int NV21ToI420(const uint8* src_y, >+int NV21ToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_vu, >+ const uint8_t* src_vu, > int src_stride_vu, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert YUY2 to I420. > LIBYUV_API >-int YUY2ToI420(const uint8* src_yuy2, >+int YUY2ToI420(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert UYVY to I420. > LIBYUV_API >-int UYVYToI420(const uint8* src_uyvy, >+int UYVYToI420(const uint8_t* src_uyvy, > int src_stride_uyvy, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert M420 to I420. > LIBYUV_API >-int M420ToI420(const uint8* src_m420, >+int M420ToI420(const uint8_t* src_m420, > int src_stride_m420, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert Android420 to I420. > LIBYUV_API >-int Android420ToI420(const uint8* src_y, >+int Android420ToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- int pixel_stride_uv, >- uint8* dst_y, >+ int src_pixel_stride_uv, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // ARGB little endian (bgra in memory) to I420. > LIBYUV_API >-int ARGBToI420(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_y, >+int ARGBToI420(const uint8_t* src_argb, >+ int src_stride_argb, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // BGRA little endian (argb in memory) to I420. > LIBYUV_API >-int BGRAToI420(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_y, >+int BGRAToI420(const uint8_t* src_bgra, >+ int src_stride_bgra, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // ABGR little endian (rgba in memory) to I420. > LIBYUV_API >-int ABGRToI420(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_y, >+int ABGRToI420(const uint8_t* src_abgr, >+ int src_stride_abgr, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // RGBA little endian (abgr in memory) to I420. > LIBYUV_API >-int RGBAToI420(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_y, >+int RGBAToI420(const uint8_t* src_rgba, >+ int src_stride_rgba, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // RGB little endian (bgr in memory) to I420. > LIBYUV_API >-int RGB24ToI420(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_y, >+int RGB24ToI420(const uint8_t* src_rgb24, >+ int src_stride_rgb24, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // RGB big endian (rgb in memory) to I420. > LIBYUV_API >-int RAWToI420(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_y, >+int RAWToI420(const uint8_t* src_raw, >+ int src_stride_raw, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // RGB16 (RGBP fourcc) little endian to I420. > LIBYUV_API >-int RGB565ToI420(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_y, >+int RGB565ToI420(const uint8_t* src_rgb565, >+ int src_stride_rgb565, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // RGB15 (RGBO fourcc) little endian to I420. > LIBYUV_API >-int ARGB1555ToI420(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_y, >+int ARGB1555ToI420(const uint8_t* src_argb1555, >+ int src_stride_argb1555, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // RGB12 (R444 fourcc) little endian to I420. > LIBYUV_API >-int ARGB4444ToI420(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_y, >+int ARGB4444ToI420(const uint8_t* src_argb4444, >+ int src_stride_argb4444, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); >@@ -300,13 +337,13 @@ int ARGB4444ToI420(const uint8* src_frame, > // src_width/height provided by capture. > // dst_width/height for clipping determine final size. > LIBYUV_API >-int MJPGToI420(const uint8* sample, >+int MJPGToI420(const uint8_t* sample, > size_t sample_size, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int src_width, > int src_height, >@@ -315,7 +352,10 @@ int MJPGToI420(const uint8* sample, > > // Query size of MJPG in pixels. > LIBYUV_API >-int MJPGSize(const uint8* sample, size_t sample_size, int* width, int* height); >+int MJPGSize(const uint8_t* sample, >+ size_t sample_size, >+ int* width, >+ int* height); > #endif > > // Convert camera sample to I420 with cropping, rotation and vertical flip. >@@ -338,16 +378,16 @@ int MJPGSize(const uint8* sample, size_t sample_size, int* width, int* height); > // Must be less than or equal to src_width/src_height > // Cropping parameters are pre-rotation. > // "rotation" can be 0, 90, 180 or 270. >-// "format" is a fourcc. ie 'I420', 'YUY2' >+// "fourcc" is a fourcc. ie 'I420', 'YUY2' > // Returns 0 for successful; -1 for invalid parameter. Non-zero for failure. > LIBYUV_API >-int ConvertToI420(const uint8* src_frame, >- size_t src_size, >- uint8* dst_y, >+int ConvertToI420(const uint8_t* sample, >+ size_t sample_size, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int crop_x, > int crop_y, >@@ -356,7 +396,7 @@ int ConvertToI420(const uint8* src_frame, > int crop_width, > int crop_height, > enum RotationMode rotation, >- uint32 format); >+ uint32_t fourcc); > > #ifdef __cplusplus > } // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_argb.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_argb.h >index f43a5060bdbf7cd033d155d2af2ba85cbbdeb13d..ab772b6c32334c8eac8600c281c9aa3f082a75b9 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_argb.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_argb.h >@@ -30,102 +30,167 @@ extern "C" { > > // Copy ARGB to ARGB. > LIBYUV_API >-int ARGBCopy(const uint8* src_argb, >+int ARGBCopy(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert I420 to ARGB. > LIBYUV_API >-int I420ToARGB(const uint8* src_y, >+int I420ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Duplicate prototype for function in convert_from.h for remoting. > LIBYUV_API >-int I420ToABGR(const uint8* src_y, >+int I420ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height); >+ >+// Convert I010 to ARGB. >+LIBYUV_API >+int I010ToARGB(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > >+// Convert I010 to ARGB. >+LIBYUV_API >+int I010ToARGB(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int width, >+ int height); >+ >+// Convert I010 to ABGR. >+LIBYUV_API >+int I010ToABGR(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height); >+ >+// Convert H010 to ARGB. >+LIBYUV_API >+int H010ToARGB(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int width, >+ int height); >+ >+// Convert H010 to ABGR. >+LIBYUV_API >+int H010ToABGR(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height); >+ > // Convert I422 to ARGB. > LIBYUV_API >-int I422ToARGB(const uint8* src_y, >+int I422ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert I444 to ARGB. > LIBYUV_API >-int I444ToARGB(const uint8* src_y, >+int I444ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert J444 to ARGB. > LIBYUV_API >-int J444ToARGB(const uint8* src_y, >+int J444ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert I444 to ABGR. > LIBYUV_API >-int I444ToABGR(const uint8* src_y, >+int I444ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height); > > // Convert I420 with Alpha to preattenuated ARGB. > LIBYUV_API >-int I420AlphaToARGB(const uint8* src_y, >+int I420AlphaToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- const uint8* src_a, >+ const uint8_t* src_a, > int src_stride_a, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height, >@@ -133,15 +198,15 @@ int I420AlphaToARGB(const uint8* src_y, > > // Convert I420 with Alpha to preattenuated ABGR. > LIBYUV_API >-int I420AlphaToABGR(const uint8* src_y, >+int I420AlphaToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- const uint8* src_a, >+ const uint8_t* src_a, > int src_stride_a, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height, >@@ -149,18 +214,18 @@ int I420AlphaToABGR(const uint8* src_y, > > // Convert I400 (grey) to ARGB. Reverse of ARGBToI400. > LIBYUV_API >-int I400ToARGB(const uint8* src_y, >+int I400ToARGB(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert J400 (jpeg grey) to ARGB. > LIBYUV_API >-int J400ToARGB(const uint8* src_y, >+int J400ToARGB(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); >@@ -170,180 +235,288 @@ int J400ToARGB(const uint8* src_y, > > // Convert NV12 to ARGB. > LIBYUV_API >-int NV12ToARGB(const uint8* src_y, >+int NV12ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_uv, >+ const uint8_t* src_uv, > int src_stride_uv, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert NV21 to ARGB. > LIBYUV_API >-int NV21ToARGB(const uint8* src_y, >+int NV21ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_vu, >+ const uint8_t* src_vu, > int src_stride_vu, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > >+// Convert NV12 to ABGR. >+int NV12ToABGR(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_uv, >+ int src_stride_uv, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height); >+ >+// Convert NV21 to ABGR. >+LIBYUV_API >+int NV21ToABGR(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_vu, >+ int src_stride_vu, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height); >+ >+// Convert NV12 to RGB24. >+LIBYUV_API >+int NV12ToRGB24(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_uv, >+ int src_stride_uv, >+ uint8_t* dst_rgb24, >+ int dst_stride_rgb24, >+ int width, >+ int height); >+ >+// Convert NV21 to RGB24. >+LIBYUV_API >+int NV21ToRGB24(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_vu, >+ int src_stride_vu, >+ uint8_t* dst_rgb24, >+ int dst_stride_rgb24, >+ int width, >+ int height); >+ > // Convert M420 to ARGB. > LIBYUV_API >-int M420ToARGB(const uint8* src_m420, >+int M420ToARGB(const uint8_t* src_m420, > int src_stride_m420, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert YUY2 to ARGB. > LIBYUV_API >-int YUY2ToARGB(const uint8* src_yuy2, >+int YUY2ToARGB(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert UYVY to ARGB. > LIBYUV_API >-int UYVYToARGB(const uint8* src_uyvy, >+int UYVYToARGB(const uint8_t* src_uyvy, > int src_stride_uyvy, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert J420 to ARGB. > LIBYUV_API >-int J420ToARGB(const uint8* src_y, >+int J420ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert J422 to ARGB. > LIBYUV_API >-int J422ToARGB(const uint8* src_y, >+int J422ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert J420 to ABGR. > LIBYUV_API >-int J420ToABGR(const uint8* src_y, >+int J420ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height); > > // Convert J422 to ABGR. > LIBYUV_API >-int J422ToABGR(const uint8* src_y, >+int J422ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height); > > // Convert H420 to ARGB. > LIBYUV_API >-int H420ToARGB(const uint8* src_y, >+int H420ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert H422 to ARGB. > LIBYUV_API >-int H422ToARGB(const uint8* src_y, >+int H422ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert H420 to ABGR. > LIBYUV_API >-int H420ToABGR(const uint8* src_y, >+int H420ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height); > > // Convert H422 to ABGR. > LIBYUV_API >-int H422ToABGR(const uint8* src_y, >+int H422ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height); > >+// Convert H010 to ARGB. >+LIBYUV_API >+int H010ToARGB(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int width, >+ int height); >+ >+// Convert I010 to AR30. >+LIBYUV_API >+int I010ToAR30(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height); >+ >+// Convert H010 to AR30. >+LIBYUV_API >+int H010ToAR30(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height); >+ >+// Convert I010 to AB30. >+LIBYUV_API >+int I010ToAB30(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ab30, >+ int dst_stride_ab30, >+ int width, >+ int height); >+ >+// Convert H010 to AB30. >+LIBYUV_API >+int H010ToAB30(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ab30, >+ int dst_stride_ab30, >+ int width, >+ int height); >+ > // BGRA little endian (argb in memory) to ARGB. > LIBYUV_API >-int BGRAToARGB(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_argb, >+int BGRAToARGB(const uint8_t* src_bgra, >+ int src_stride_bgra, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // ABGR little endian (rgba in memory) to ARGB. > LIBYUV_API >-int ABGRToARGB(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_argb, >+int ABGRToARGB(const uint8_t* src_abgr, >+ int src_stride_abgr, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // RGBA little endian (abgr in memory) to ARGB. > LIBYUV_API >-int RGBAToARGB(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_argb, >+int RGBAToARGB(const uint8_t* src_rgba, >+ int src_stride_rgba, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); >@@ -353,56 +526,88 @@ int RGBAToARGB(const uint8* src_frame, > > // RGB little endian (bgr in memory) to ARGB. > LIBYUV_API >-int RGB24ToARGB(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_argb, >+int RGB24ToARGB(const uint8_t* src_rgb24, >+ int src_stride_rgb24, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // RGB big endian (rgb in memory) to ARGB. > LIBYUV_API >-int RAWToARGB(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_argb, >+int RAWToARGB(const uint8_t* src_raw, >+ int src_stride_raw, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // RGB16 (RGBP fourcc) little endian to ARGB. > LIBYUV_API >-int RGB565ToARGB(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_argb, >+int RGB565ToARGB(const uint8_t* src_rgb565, >+ int src_stride_rgb565, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // RGB15 (RGBO fourcc) little endian to ARGB. > LIBYUV_API >-int ARGB1555ToARGB(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_argb, >+int ARGB1555ToARGB(const uint8_t* src_argb1555, >+ int src_stride_argb1555, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // RGB12 (R444 fourcc) little endian to ARGB. > LIBYUV_API >-int ARGB4444ToARGB(const uint8* src_frame, >- int src_stride_frame, >- uint8* dst_argb, >+int ARGB4444ToARGB(const uint8_t* src_argb4444, >+ int src_stride_argb4444, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > >+// Aliases >+#define AB30ToARGB AR30ToABGR >+#define AB30ToABGR AR30ToARGB >+#define AB30ToAR30 AR30ToAB30 >+ >+// Convert AR30 To ARGB. >+LIBYUV_API >+int AR30ToARGB(const uint8_t* src_ar30, >+ int src_stride_ar30, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int width, >+ int height); >+ >+// Convert AR30 To ABGR. >+LIBYUV_API >+int AR30ToABGR(const uint8_t* src_ar30, >+ int src_stride_ar30, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height); >+ >+// Convert AR30 To AB30. >+LIBYUV_API >+int AR30ToAB30(const uint8_t* src_ar30, >+ int src_stride_ar30, >+ uint8_t* dst_ab30, >+ int dst_stride_ab30, >+ int width, >+ int height); >+ > #ifdef HAVE_JPEG > // src_width/height provided by capture > // dst_width/height for clipping determine final size. > LIBYUV_API >-int MJPGToARGB(const uint8* sample, >+int MJPGToARGB(const uint8_t* sample, > size_t sample_size, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int src_width, > int src_height, >@@ -410,8 +615,36 @@ int MJPGToARGB(const uint8* sample, > int dst_height); > #endif > >+// Convert Android420 to ARGB. >+LIBYUV_API >+int Android420ToARGB(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ int src_pixel_stride_uv, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int width, >+ int height); >+ >+// Convert Android420 to ABGR. >+LIBYUV_API >+int Android420ToABGR(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ int src_pixel_stride_uv, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height); >+ > // Convert camera sample to ARGB with cropping, rotation and vertical flip. >-// "src_size" is needed to parse MJPG. >+// "sample_size" is needed to parse MJPG. > // "dst_stride_argb" number of bytes in a row of the dst_argb plane. > // Normally this would be the same as dst_width, with recommended alignment > // to 16 bytes for better efficiency. >@@ -430,12 +663,12 @@ int MJPGToARGB(const uint8* sample, > // Must be less than or equal to src_width/src_height > // Cropping parameters are pre-rotation. > // "rotation" can be 0, 90, 180 or 270. >-// "format" is a fourcc. ie 'I420', 'YUY2' >+// "fourcc" is a fourcc. ie 'I420', 'YUY2' > // Returns 0 for successful; -1 for invalid parameter. Non-zero for failure. > LIBYUV_API >-int ConvertToARGB(const uint8* src_frame, >- size_t src_size, >- uint8* dst_argb, >+int ConvertToARGB(const uint8_t* sample, >+ size_t sample_size, >+ uint8_t* dst_argb, > int dst_stride_argb, > int crop_x, > int crop_y, >@@ -444,7 +677,7 @@ int ConvertToARGB(const uint8* src_frame, > int crop_width, > int crop_height, > enum RotationMode rotation, >- uint32 format); >+ uint32_t fourcc); > > #ifdef __cplusplus > } // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_from.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_from.h >index 237f68f57aa192f3c33ae7c828b7fb65ea9f6dc8..5cd8a4bfc04cc24603e70edf87bb5b3aa2dee556 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_from.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_from.h >@@ -21,218 +21,233 @@ extern "C" { > > // See Also convert.h for conversions from formats to I420. > >-// I420Copy in convert to I420ToI420. >+// Convert 8 bit YUV to 10 bit. >+#define H420ToH010 I420ToI010 >+int I420ToI010(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ uint16_t* dst_y, >+ int dst_stride_y, >+ uint16_t* dst_u, >+ int dst_stride_u, >+ uint16_t* dst_v, >+ int dst_stride_v, >+ int width, >+ int height); > > LIBYUV_API >-int I420ToI422(const uint8* src_y, >+int I420ToI422(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > LIBYUV_API >-int I420ToI444(const uint8* src_y, >+int I420ToI444(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Copy to I400. Source can be I420, I422, I444, I400, NV12 or NV21. > LIBYUV_API >-int I400Copy(const uint8* src_y, >+int I400Copy(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height); > > LIBYUV_API >-int I420ToNV12(const uint8* src_y, >+int I420ToNV12(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int dst_stride_uv, > int width, > int height); > > LIBYUV_API >-int I420ToNV21(const uint8* src_y, >+int I420ToNV21(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_vu, >+ uint8_t* dst_vu, > int dst_stride_vu, > int width, > int height); > > LIBYUV_API >-int I420ToYUY2(const uint8* src_y, >+int I420ToYUY2(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_yuy2, >+ int dst_stride_yuy2, > int width, > int height); > > LIBYUV_API >-int I420ToUYVY(const uint8* src_y, >+int I420ToUYVY(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_uyvy, >+ int dst_stride_uyvy, > int width, > int height); > > LIBYUV_API >-int I420ToARGB(const uint8* src_y, >+int I420ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > LIBYUV_API >-int I420ToBGRA(const uint8* src_y, >+int I420ToBGRA(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >- int dst_stride_argb, >+ uint8_t* dst_bgra, >+ int dst_stride_bgra, > int width, > int height); > > LIBYUV_API >-int I420ToABGR(const uint8* src_y, >+int I420ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >- int dst_stride_argb, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, > int width, > int height); > > LIBYUV_API >-int I420ToRGBA(const uint8* src_y, >+int I420ToRGBA(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgba, >+ uint8_t* dst_rgba, > int dst_stride_rgba, > int width, > int height); > > LIBYUV_API >-int I420ToRGB24(const uint8* src_y, >+int I420ToRGB24(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_rgb24, >+ int dst_stride_rgb24, > int width, > int height); > > LIBYUV_API >-int I420ToRAW(const uint8* src_y, >+int I420ToRAW(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_raw, >+ int dst_stride_raw, > int width, > int height); > > LIBYUV_API >-int H420ToRGB24(const uint8* src_y, >+int H420ToRGB24(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_rgb24, >+ int dst_stride_rgb24, > int width, > int height); > > LIBYUV_API >-int H420ToRAW(const uint8* src_y, >+int H420ToRAW(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_raw, >+ int dst_stride_raw, > int width, > int height); > > LIBYUV_API >-int I420ToRGB565(const uint8* src_y, >+int I420ToRGB565(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_rgb565, >+ int dst_stride_rgb565, > int width, > int height); > > LIBYUV_API >-int I422ToRGB565(const uint8* src_y, >+int I422ToRGB565(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_rgb565, >+ int dst_stride_rgb565, > int width, > int height); > >@@ -241,57 +256,83 @@ int I422ToRGB565(const uint8* src_y, > // The order of the dither matrix is first byte is upper left. > > LIBYUV_API >-int I420ToRGB565Dither(const uint8* src_y, >+int I420ToRGB565Dither(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >- const uint8* dither4x4, >+ uint8_t* dst_rgb565, >+ int dst_stride_rgb565, >+ const uint8_t* dither4x4, > int width, > int height); > > LIBYUV_API >-int I420ToARGB1555(const uint8* src_y, >+int I420ToARGB1555(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_argb1555, >+ int dst_stride_argb1555, > int width, > int height); > > LIBYUV_API >-int I420ToARGB4444(const uint8* src_y, >+int I420ToARGB4444(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_argb4444, >+ int dst_stride_argb4444, > int width, > int height); > >+// Convert I420 to AR30. >+LIBYUV_API >+int I420ToAR30(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height); >+ >+// Convert H420 to AR30. >+LIBYUV_API >+int H420ToAR30(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height); >+ > // Convert I420 to specified format. > // "dst_sample_stride" is bytes in a row for the destination. Pass 0 if the > // buffer has contiguous rows. Can be negative. A multiple of 16 is optimal. > LIBYUV_API >-int ConvertFromI420(const uint8* y, >+int ConvertFromI420(const uint8_t* y, > int y_stride, >- const uint8* u, >+ const uint8_t* u, > int u_stride, >- const uint8* v, >+ const uint8_t* v, > int v_stride, >- uint8* dst_sample, >+ uint8_t* dst_sample, > int dst_sample_stride, > int width, > int height, >- uint32 format); >+ uint32_t fourcc); > > #ifdef __cplusplus > } // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_from_argb.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_from_argb.h >index 50722d761021e31aeb7fc7d38bb4f4d66a85bfda..05c815a093e8d989a369f83a888dd1aaec6768f0 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_from_argb.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/convert_from_argb.h >@@ -21,63 +21,85 @@ extern "C" { > // Copy ARGB to ARGB. > #define ARGBToARGB ARGBCopy > LIBYUV_API >-int ARGBCopy(const uint8* src_argb, >+int ARGBCopy(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert ARGB To BGRA. > LIBYUV_API >-int ARGBToBGRA(const uint8* src_argb, >+int ARGBToBGRA(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_bgra, >+ uint8_t* dst_bgra, > int dst_stride_bgra, > int width, > int height); > > // Convert ARGB To ABGR. > LIBYUV_API >-int ARGBToABGR(const uint8* src_argb, >+int ARGBToABGR(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height); > > // Convert ARGB To RGBA. > LIBYUV_API >-int ARGBToRGBA(const uint8* src_argb, >+int ARGBToRGBA(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_rgba, >+ uint8_t* dst_rgba, > int dst_stride_rgba, > int width, > int height); > >+// Aliases >+#define ARGBToAB30 ABGRToAR30 >+#define ABGRToAB30 ARGBToAR30 >+ >+// Convert ABGR To AR30. >+LIBYUV_API >+int ABGRToAR30(const uint8_t* src_abgr, >+ int src_stride_abgr, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height); >+ >+// Convert ARGB To AR30. >+LIBYUV_API >+int ARGBToAR30(const uint8_t* src_argb, >+ int src_stride_argb, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height); >+ > // Convert ARGB To RGB24. > LIBYUV_API >-int ARGBToRGB24(const uint8* src_argb, >+int ARGBToRGB24(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_rgb24, >+ uint8_t* dst_rgb24, > int dst_stride_rgb24, > int width, > int height); > > // Convert ARGB To RAW. > LIBYUV_API >-int ARGBToRAW(const uint8* src_argb, >+int ARGBToRAW(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_rgb, >- int dst_stride_rgb, >+ uint8_t* dst_raw, >+ int dst_stride_raw, > int width, > int height); > > // Convert ARGB To RGB565. > LIBYUV_API >-int ARGBToRGB565(const uint8* src_argb, >+int ARGBToRGB565(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_rgb565, >+ uint8_t* dst_rgb565, > int dst_stride_rgb565, > int width, > int height); >@@ -86,173 +108,173 @@ int ARGBToRGB565(const uint8* src_argb, > // Values in dither matrix from 0 to 7 recommended. > // The order of the dither matrix is first byte is upper left. > // TODO(fbarchard): Consider pointer to 2d array for dither4x4. >-// const uint8(*dither)[4][4]; >+// const uint8_t(*dither)[4][4]; > LIBYUV_API >-int ARGBToRGB565Dither(const uint8* src_argb, >+int ARGBToRGB565Dither(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_rgb565, >+ uint8_t* dst_rgb565, > int dst_stride_rgb565, >- const uint8* dither4x4, >+ const uint8_t* dither4x4, > int width, > int height); > > // Convert ARGB To ARGB1555. > LIBYUV_API >-int ARGBToARGB1555(const uint8* src_argb, >+int ARGBToARGB1555(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb1555, >+ uint8_t* dst_argb1555, > int dst_stride_argb1555, > int width, > int height); > > // Convert ARGB To ARGB4444. > LIBYUV_API >-int ARGBToARGB4444(const uint8* src_argb, >+int ARGBToARGB4444(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb4444, >+ uint8_t* dst_argb4444, > int dst_stride_argb4444, > int width, > int height); > > // Convert ARGB To I444. > LIBYUV_API >-int ARGBToI444(const uint8* src_argb, >+int ARGBToI444(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert ARGB To I422. > LIBYUV_API >-int ARGBToI422(const uint8* src_argb, >+int ARGBToI422(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert ARGB To I420. (also in convert.h) > LIBYUV_API >-int ARGBToI420(const uint8* src_argb, >+int ARGBToI420(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert ARGB to J420. (JPeg full range I420). > LIBYUV_API >-int ARGBToJ420(const uint8* src_argb, >+int ARGBToJ420(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_yj, >+ uint8_t* dst_yj, > int dst_stride_yj, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert ARGB to J422. > LIBYUV_API >-int ARGBToJ422(const uint8* src_argb, >+int ARGBToJ422(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_yj, >+ uint8_t* dst_yj, > int dst_stride_yj, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert ARGB to J400. (JPeg full range). > LIBYUV_API >-int ARGBToJ400(const uint8* src_argb, >+int ARGBToJ400(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_yj, >+ uint8_t* dst_yj, > int dst_stride_yj, > int width, > int height); > > // Convert ARGB to I400. > LIBYUV_API >-int ARGBToI400(const uint8* src_argb, >+int ARGBToI400(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height); > > // Convert ARGB to G. (Reverse of J400toARGB, which replicates G back to ARGB) > LIBYUV_API >-int ARGBToG(const uint8* src_argb, >+int ARGBToG(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_g, >+ uint8_t* dst_g, > int dst_stride_g, > int width, > int height); > > // Convert ARGB To NV12. > LIBYUV_API >-int ARGBToNV12(const uint8* src_argb, >+int ARGBToNV12(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int dst_stride_uv, > int width, > int height); > > // Convert ARGB To NV21. > LIBYUV_API >-int ARGBToNV21(const uint8* src_argb, >+int ARGBToNV21(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_vu, >+ uint8_t* dst_vu, > int dst_stride_vu, > int width, > int height); > > // Convert ARGB To NV21. > LIBYUV_API >-int ARGBToNV21(const uint8* src_argb, >+int ARGBToNV21(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_vu, >+ uint8_t* dst_vu, > int dst_stride_vu, > int width, > int height); > > // Convert ARGB To YUY2. > LIBYUV_API >-int ARGBToYUY2(const uint8* src_argb, >+int ARGBToYUY2(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_yuy2, >+ uint8_t* dst_yuy2, > int dst_stride_yuy2, > int width, > int height); > > // Convert ARGB To UYVY. > LIBYUV_API >-int ARGBToUYVY(const uint8* src_argb, >+int ARGBToUYVY(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_uyvy, >+ uint8_t* dst_uyvy, > int dst_stride_uyvy, > int width, > int height); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/cpu_id.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/cpu_id.h >index c2e9bbbd954603030ddd22de1c7b76afc112abdb..91480c68b0133c90a0389b3d527566b595d386a8 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/cpu_id.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/cpu_id.h >@@ -47,8 +47,7 @@ static const int kCpuHasAVX512VPOPCNTDQ = 0x100000; > > // These flags are only valid on MIPS processors. > static const int kCpuHasMIPS = 0x200000; >-static const int kCpuHasDSPR2 = 0x400000; >-static const int kCpuHasMSA = 0x800000; >+static const int kCpuHasMSA = 0x400000; > > // Optional init function. TestCpuFlag does an auto-init. > // Returns cpu_info flags. >@@ -85,7 +84,7 @@ int MaskCpuFlags(int enable_flags); > // eax is the info type that you want. > // ecx is typically the cpu number, and should normally be zero. > LIBYUV_API >-void CpuId(int eax, int ecx, int* cpu_info); >+void CpuId(int info_eax, int info_ecx, int* cpu_info); > > #ifdef __cplusplus > } // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/macros_msa.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/macros_msa.h >index 61be352e3af74b7e5b0020800f572635c1fee65a..921eb0714d66faf26cbcda7ec88762fff410d52f 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/macros_msa.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/macros_msa.h >@@ -16,38 +16,38 @@ > #include <stdint.h> > > #if (__mips_isa_rev >= 6) >-#define LW(psrc) \ >- ({ \ >- uint8* psrc_lw_m = (uint8*)(psrc); /* NOLINT */ \ >- uint32 val_m; \ >- asm volatile("lw %[val_m], %[psrc_lw_m] \n" \ >- : [val_m] "=r"(val_m) \ >- : [psrc_lw_m] "m"(*psrc_lw_m)); \ >- val_m; \ >+#define LW(psrc) \ >+ ({ \ >+ uint8_t* psrc_lw_m = (uint8_t*)(psrc); /* NOLINT */ \ >+ uint32_t val_m; \ >+ asm volatile("lw %[val_m], %[psrc_lw_m] \n" \ >+ : [val_m] "=r"(val_m) \ >+ : [psrc_lw_m] "m"(*psrc_lw_m)); \ >+ val_m; \ > }) > > #if (__mips == 64) >-#define LD(psrc) \ >- ({ \ >- uint8* psrc_ld_m = (uint8*)(psrc); /* NOLINT */ \ >- uint64 val_m = 0; \ >- asm volatile("ld %[val_m], %[psrc_ld_m] \n" \ >- : [val_m] "=r"(val_m) \ >- : [psrc_ld_m] "m"(*psrc_ld_m)); \ >- val_m; \ >+#define LD(psrc) \ >+ ({ \ >+ uint8_t* psrc_ld_m = (uint8_t*)(psrc); /* NOLINT */ \ >+ uint64_t val_m = 0; \ >+ asm volatile("ld %[val_m], %[psrc_ld_m] \n" \ >+ : [val_m] "=r"(val_m) \ >+ : [psrc_ld_m] "m"(*psrc_ld_m)); \ >+ val_m; \ > }) > #else // !(__mips == 64) >-#define LD(psrc) \ >- ({ \ >- uint8* psrc_ld_m = (uint8*)(psrc); /* NOLINT */ \ >- uint32 val0_m, val1_m; \ >- uint64 val_m = 0; \ >- val0_m = LW(psrc_ld_m); \ >- val1_m = LW(psrc_ld_m + 4); \ >- val_m = (uint64)(val1_m); /* NOLINT */ \ >- val_m = (uint64)((val_m << 32) & 0xFFFFFFFF00000000); /* NOLINT */ \ >- val_m = (uint64)(val_m | (uint64)val0_m); /* NOLINT */ \ >- val_m; \ >+#define LD(psrc) \ >+ ({ \ >+ uint8_t* psrc_ld_m = (uint8_t*)(psrc); /* NOLINT */ \ >+ uint32_t val0_m, val1_m; \ >+ uint64_t val_m = 0; \ >+ val0_m = LW(psrc_ld_m); \ >+ val1_m = LW(psrc_ld_m + 4); \ >+ val_m = (uint64_t)(val1_m); /* NOLINT */ \ >+ val_m = (uint64_t)((val_m << 32) & 0xFFFFFFFF00000000); /* NOLINT */ \ >+ val_m = (uint64_t)(val_m | (uint64_t)val0_m); /* NOLINT */ \ >+ val_m; \ > }) > #endif // (__mips == 64) > >@@ -81,38 +81,38 @@ > }) > #endif // !(__mips == 64) > #else // !(__mips_isa_rev >= 6) >-#define LW(psrc) \ >- ({ \ >- uint8* psrc_lw_m = (uint8*)(psrc); /* NOLINT */ \ >- uint32 val_m; \ >- asm volatile("ulw %[val_m], %[psrc_lw_m] \n" \ >- : [val_m] "=r"(val_m) \ >- : [psrc_lw_m] "m"(*psrc_lw_m)); \ >- val_m; \ >+#define LW(psrc) \ >+ ({ \ >+ uint8_t* psrc_lw_m = (uint8_t*)(psrc); /* NOLINT */ \ >+ uint32_t val_m; \ >+ asm volatile("ulw %[val_m], %[psrc_lw_m] \n" \ >+ : [val_m] "=r"(val_m) \ >+ : [psrc_lw_m] "m"(*psrc_lw_m)); \ >+ val_m; \ > }) > > #if (__mips == 64) >-#define LD(psrc) \ >- ({ \ >- uint8* psrc_ld_m = (uint8*)(psrc); /* NOLINT */ \ >- uint64 val_m = 0; \ >- asm volatile("uld %[val_m], %[psrc_ld_m] \n" \ >- : [val_m] "=r"(val_m) \ >- : [psrc_ld_m] "m"(*psrc_ld_m)); \ >- val_m; \ >+#define LD(psrc) \ >+ ({ \ >+ uint8_t* psrc_ld_m = (uint8_t*)(psrc); /* NOLINT */ \ >+ uint64_t val_m = 0; \ >+ asm volatile("uld %[val_m], %[psrc_ld_m] \n" \ >+ : [val_m] "=r"(val_m) \ >+ : [psrc_ld_m] "m"(*psrc_ld_m)); \ >+ val_m; \ > }) > #else // !(__mips == 64) >-#define LD(psrc) \ >- ({ \ >- uint8* psrc_ld_m = (uint8*)(psrc); /* NOLINT */ \ >- uint32 val0_m, val1_m; \ >- uint64 val_m = 0; \ >- val0_m = LW(psrc_ld_m); \ >- val1_m = LW(psrc_ld_m + 4); \ >- val_m = (uint64)(val1_m); /* NOLINT */ \ >- val_m = (uint64)((val_m << 32) & 0xFFFFFFFF00000000); /* NOLINT */ \ >- val_m = (uint64)(val_m | (uint64)val0_m); /* NOLINT */ \ >- val_m; \ >+#define LD(psrc) \ >+ ({ \ >+ uint8_t* psrc_ld_m = (uint8_t*)(psrc); /* NOLINT */ \ >+ uint32_t val0_m, val1_m; \ >+ uint64_t val_m = 0; \ >+ val0_m = LW(psrc_ld_m); \ >+ val1_m = LW(psrc_ld_m + 4); \ >+ val_m = (uint64_t)(val1_m); /* NOLINT */ \ >+ val_m = (uint64_t)((val_m << 32) & 0xFFFFFFFF00000000); /* NOLINT */ \ >+ val_m = (uint64_t)(val_m | (uint64_t)val0_m); /* NOLINT */ \ >+ val_m; \ > }) > #endif // (__mips == 64) > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/mjpeg_decoder.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/mjpeg_decoder.h >index 8a4f282205b9618d54eb66746a420ec61bc463a1..6c12633387fad8234ddb8f0691564aaed029d7ee 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/mjpeg_decoder.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/mjpeg_decoder.h >@@ -26,13 +26,13 @@ namespace libyuv { > extern "C" { > #endif > >-LIBYUV_BOOL ValidateJpeg(const uint8* sample, size_t sample_size); >+LIBYUV_BOOL ValidateJpeg(const uint8_t* sample, size_t sample_size); > > #ifdef __cplusplus > } // extern "C" > #endif > >-static const uint32 kUnknownDataSize = 0xFFFFFFFF; >+static const uint32_t kUnknownDataSize = 0xFFFFFFFF; > > enum JpegSubsamplingType { > kJpegYuv420, >@@ -43,7 +43,7 @@ enum JpegSubsamplingType { > }; > > struct Buffer { >- const uint8* data; >+ const uint8_t* data; > int len; > }; > >@@ -65,7 +65,7 @@ struct SetJmpErrorMgr; > class LIBYUV_API MJpegDecoder { > public: > typedef void (*CallbackFunction)(void* opaque, >- const uint8* const* data, >+ const uint8_t* const* data, > const int* strides, > int rows); > >@@ -85,7 +85,7 @@ class LIBYUV_API MJpegDecoder { > // If return value is LIBYUV_TRUE, then the values for all the following > // getters are populated. > // src_len is the size of the compressed mjpeg frame in bytes. >- LIBYUV_BOOL LoadFrame(const uint8* src, size_t src_len); >+ LIBYUV_BOOL LoadFrame(const uint8_t* src, size_t src_len); > > // Returns width of the last loaded frame in pixels. > int GetWidth(); >@@ -138,7 +138,7 @@ class LIBYUV_API MJpegDecoder { > // at least GetComponentSize(i). The pointers in planes are incremented > // to point to after the end of the written data. > // TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded. >- LIBYUV_BOOL DecodeToBuffers(uint8** planes, int dst_width, int dst_height); >+ LIBYUV_BOOL DecodeToBuffers(uint8_t** planes, int dst_width, int dst_height); > > // Decodes the entire image and passes the data via repeated calls to a > // callback function. Each call will get the data for a whole number of >@@ -162,14 +162,14 @@ class LIBYUV_API MJpegDecoder { > LIBYUV_BOOL StartDecode(); > LIBYUV_BOOL FinishDecode(); > >- void SetScanlinePointers(uint8** data); >+ void SetScanlinePointers(uint8_t** data); > LIBYUV_BOOL DecodeImcuRow(); > > int GetComponentScanlinePadding(int component); > > // A buffer holding the input data for a frame. >- Buffer buf_; >- BufferVector buf_vec_; >+ Buffer buf_{}; >+ BufferVector buf_vec_{}; > > jpeg_decompress_struct* decompress_struct_; > jpeg_source_mgr* source_mgr_; >@@ -181,12 +181,12 @@ class LIBYUV_API MJpegDecoder { > > // Temporaries used to point to scanline outputs. > int num_outbufs_; // Outermost size of all arrays below. >- uint8*** scanlines_; >- int* scanlines_sizes_; >+ uint8_t*** scanlines_{}; >+ int* scanlines_sizes_{}; > // Temporary buffer used for decoding when we can't decode directly to the > // output buffers. Large enough for just one iMCU row. >- uint8** databuf_; >- int* databuf_strides_; >+ uint8_t** databuf_{}; >+ int* databuf_strides_{}; > }; > > } // namespace libyuv >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/planar_functions.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/planar_functions.h >index c91501a9c2c3079e9a11974fc18d451159f00ce0..91137baba254eac8b7e261b53d4a4c7a6ac15085 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/planar_functions.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/planar_functions.h >@@ -22,84 +22,120 @@ namespace libyuv { > extern "C" { > #endif > >+// TODO(fbarchard): Move cpu macros to row.h >+#if defined(__pnacl__) || defined(__CLR_VER) || \ >+ (defined(__native_client__) && defined(__x86_64__)) || \ >+ (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) >+#define LIBYUV_DISABLE_X86 >+#endif >+// MemorySanitizer does not support assembly code yet. http://crbug.com/344505 >+#if defined(__has_feature) >+#if __has_feature(memory_sanitizer) >+#define LIBYUV_DISABLE_X86 >+#endif >+#endif >+// The following are available on all x86 platforms: >+#if !defined(LIBYUV_DISABLE_X86) && \ >+ (defined(_M_IX86) || defined(__x86_64__) || defined(__i386__)) >+#define HAS_ARGBAFFINEROW_SSE2 >+#endif >+ > // Copy a plane of data. > LIBYUV_API >-void CopyPlane(const uint8* src_y, >+void CopyPlane(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height); > > LIBYUV_API >-void CopyPlane_16(const uint16* src_y, >+void CopyPlane_16(const uint16_t* src_y, > int src_stride_y, >- uint16* dst_y, >+ uint16_t* dst_y, > int dst_stride_y, > int width, > int height); > >+LIBYUV_API >+void Convert16To8Plane(const uint16_t* src_y, >+ int src_stride_y, >+ uint8_t* dst_y, >+ int dst_stride_y, >+ int scale, // 16384 for 10 bits >+ int width, >+ int height); >+ >+LIBYUV_API >+void Convert8To16Plane(const uint8_t* src_y, >+ int src_stride_y, >+ uint16_t* dst_y, >+ int dst_stride_y, >+ int scale, // 1024 for 10 bits >+ int width, >+ int height); >+ > // Set a plane of data to a 32 bit value. > LIBYUV_API >-void SetPlane(uint8* dst_y, >+void SetPlane(uint8_t* dst_y, > int dst_stride_y, > int width, > int height, >- uint32 value); >+ uint32_t value); > > // Split interleaved UV plane into separate U and V planes. > LIBYUV_API >-void SplitUVPlane(const uint8* src_uv, >+void SplitUVPlane(const uint8_t* src_uv, > int src_stride_uv, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Merge separate U and V planes into one interleaved UV plane. > LIBYUV_API >-void MergeUVPlane(const uint8* src_u, >+void MergeUVPlane(const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int dst_stride_uv, > int width, > int height); > > // Split interleaved RGB plane into separate R, G and B planes. > LIBYUV_API >-void SplitRGBPlane(const uint8* src_rgb, >+void SplitRGBPlane(const uint8_t* src_rgb, > int src_stride_rgb, >- uint8* dst_r, >+ uint8_t* dst_r, > int dst_stride_r, >- uint8* dst_g, >+ uint8_t* dst_g, > int dst_stride_g, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height); > > // Merge separate R, G and B planes into one interleaved RGB plane. > LIBYUV_API >-void MergeRGBPlane(const uint8* src_r, >+void MergeRGBPlane(const uint8_t* src_r, > int src_stride_r, >- const uint8* src_g, >+ const uint8_t* src_g, > int src_stride_g, >- const uint8* src_b, >+ const uint8_t* src_b, > int src_stride_b, >- uint8* dst_rgb, >+ uint8_t* dst_rgb, > int dst_stride_rgb, > int width, > int height); > > // Copy I400. Supports inverting. > LIBYUV_API >-int I400ToI400(const uint8* src_y, >+int I400ToI400(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height); >@@ -109,17 +145,17 @@ int I400ToI400(const uint8* src_y, > // Copy I422 to I422. > #define I422ToI422 I422Copy > LIBYUV_API >-int I422Copy(const uint8* src_y, >+int I422Copy(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); >@@ -127,84 +163,84 @@ int I422Copy(const uint8* src_y, > // Copy I444 to I444. > #define I444ToI444 I444Copy > LIBYUV_API >-int I444Copy(const uint8* src_y, >+int I444Copy(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert YUY2 to I422. > LIBYUV_API >-int YUY2ToI422(const uint8* src_yuy2, >+int YUY2ToI422(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Convert UYVY to I422. > LIBYUV_API >-int UYVYToI422(const uint8* src_uyvy, >+int UYVYToI422(const uint8_t* src_uyvy, > int src_stride_uyvy, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > LIBYUV_API >-int YUY2ToNV12(const uint8* src_yuy2, >+int YUY2ToNV12(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int dst_stride_uv, > int width, > int height); > > LIBYUV_API >-int UYVYToNV12(const uint8* src_uyvy, >+int UYVYToNV12(const uint8_t* src_uyvy, > int src_stride_uyvy, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int dst_stride_uv, > int width, > int height); > > LIBYUV_API >-int YUY2ToY(const uint8* src_yuy2, >+int YUY2ToY(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height); > > // Convert I420 to I400. (calls CopyPlane ignoring u/v). > LIBYUV_API >-int I420ToI400(const uint8* src_y, >+int I420ToI400(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height); >@@ -215,17 +251,17 @@ int I420ToI400(const uint8* src_y, > > // I420 mirror. > LIBYUV_API >-int I420Mirror(const uint8* src_y, >+int I420Mirror(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); >@@ -236,9 +272,9 @@ int I420Mirror(const uint8* src_y, > // I400 mirror. A single plane is mirrored horizontally. > // Pass negative height to achieve 180 degree rotation. > LIBYUV_API >-int I400Mirror(const uint8* src_y, >+int I400Mirror(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height); >@@ -248,20 +284,20 @@ int I400Mirror(const uint8* src_y, > > // ARGB mirror. > LIBYUV_API >-int ARGBMirror(const uint8* src_argb, >+int ARGBMirror(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert NV12 to RGB565. > LIBYUV_API >-int NV12ToRGB565(const uint8* src_y, >+int NV12ToRGB565(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_uv, >+ const uint8_t* src_uv, > int src_stride_uv, >- uint8* dst_rgb565, >+ uint8_t* dst_rgb565, > int dst_stride_rgb565, > int width, > int height); >@@ -269,39 +305,39 @@ int NV12ToRGB565(const uint8* src_y, > // I422ToARGB is in convert_argb.h > // Convert I422 to BGRA. > LIBYUV_API >-int I422ToBGRA(const uint8* src_y, >+int I422ToBGRA(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_bgra, >+ uint8_t* dst_bgra, > int dst_stride_bgra, > int width, > int height); > > // Convert I422 to ABGR. > LIBYUV_API >-int I422ToABGR(const uint8* src_y, >+int I422ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height); > > // Convert I422 to RGBA. > LIBYUV_API >-int I422ToRGBA(const uint8* src_y, >+int I422ToRGBA(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgba, >+ uint8_t* dst_rgba, > int dst_stride_rgba, > int width, > int height); >@@ -310,20 +346,20 @@ int I422ToRGBA(const uint8* src_y, > #define RGB24ToRAW RAWToRGB24 > > LIBYUV_API >-int RAWToRGB24(const uint8* src_raw, >+int RAWToRGB24(const uint8_t* src_raw, > int src_stride_raw, >- uint8* dst_rgb24, >+ uint8_t* dst_rgb24, > int dst_stride_rgb24, > int width, > int height); > > // Draw a rectangle into I420. > LIBYUV_API >-int I420Rect(uint8* dst_y, >+int I420Rect(uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int x, > int y, >@@ -335,38 +371,38 @@ int I420Rect(uint8* dst_y, > > // Draw a rectangle into ARGB. > LIBYUV_API >-int ARGBRect(uint8* dst_argb, >+int ARGBRect(uint8_t* dst_argb, > int dst_stride_argb, >- int x, >- int y, >+ int dst_x, >+ int dst_y, > int width, > int height, >- uint32 value); >+ uint32_t value); > > // Convert ARGB to gray scale ARGB. > LIBYUV_API >-int ARGBGrayTo(const uint8* src_argb, >+int ARGBGrayTo(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Make a rectangle of ARGB gray scale. > LIBYUV_API >-int ARGBGray(uint8* dst_argb, >+int ARGBGray(uint8_t* dst_argb, > int dst_stride_argb, >- int x, >- int y, >+ int dst_x, >+ int dst_y, > int width, > int height); > > // Make a rectangle of ARGB Sepia tone. > LIBYUV_API >-int ARGBSepia(uint8* dst_argb, >+int ARGBSepia(uint8_t* dst_argb, > int dst_stride_argb, >- int x, >- int y, >+ int dst_x, >+ int dst_y, > int width, > int height); > >@@ -377,11 +413,11 @@ int ARGBSepia(uint8* dst_argb, > // The next 4 coefficients apply to B, G, R, A and produce R of the output. > // The last 4 coefficients apply to B, G, R, A and produce A of the output. > LIBYUV_API >-int ARGBColorMatrix(const uint8* src_argb, >+int ARGBColorMatrix(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- const int8* matrix_argb, >+ const int8_t* matrix_argb, > int width, > int height); > >@@ -392,33 +428,33 @@ int ARGBColorMatrix(const uint8* src_argb, > // The next 4 coefficients apply to B, G, R, A and produce G of the output. > // The last 4 coefficients apply to B, G, R, A and produce R of the output. > LIBYUV_API >-int RGBColorMatrix(uint8* dst_argb, >+int RGBColorMatrix(uint8_t* dst_argb, > int dst_stride_argb, >- const int8* matrix_rgb, >- int x, >- int y, >+ const int8_t* matrix_rgb, >+ int dst_x, >+ int dst_y, > int width, > int height); > > // Apply a color table each ARGB pixel. > // Table contains 256 ARGB values. > LIBYUV_API >-int ARGBColorTable(uint8* dst_argb, >+int ARGBColorTable(uint8_t* dst_argb, > int dst_stride_argb, >- const uint8* table_argb, >- int x, >- int y, >+ const uint8_t* table_argb, >+ int dst_x, >+ int dst_y, > int width, > int height); > > // Apply a color table each ARGB pixel but preserve destination alpha. > // Table contains 256 ARGB values. > LIBYUV_API >-int RGBColorTable(uint8* dst_argb, >+int RGBColorTable(uint8_t* dst_argb, > int dst_stride_argb, >- const uint8* table_argb, >- int x, >- int y, >+ const uint8_t* table_argb, >+ int dst_x, >+ int dst_y, > int width, > int height); > >@@ -426,11 +462,11 @@ int RGBColorTable(uint8* dst_argb, > // Table contains 32768 values indexed by [Y][C] where 7 it 7 bit luma from > // RGB (YJ style) and C is an 8 bit color component (R, G or B). > LIBYUV_API >-int ARGBLumaColorTable(const uint8* src_argb, >+int ARGBLumaColorTable(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- const uint8* luma_rgb_table, >+ const uint8_t* luma, > int width, > int height); > >@@ -443,9 +479,9 @@ int ARGBLumaColorTable(const uint8* src_argb, > // A polynomial approximation can be dirived using software such as 'R'. > > LIBYUV_API >-int ARGBPolynomial(const uint8* src_argb, >+int ARGBPolynomial(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > const float* poly, > int width, >@@ -454,68 +490,72 @@ int ARGBPolynomial(const uint8* src_argb, > // Convert plane of 16 bit shorts to half floats. > // Source values are multiplied by scale before storing as half float. > LIBYUV_API >-int HalfFloatPlane(const uint16* src_y, >+int HalfFloatPlane(const uint16_t* src_y, > int src_stride_y, >- uint16* dst_y, >+ uint16_t* dst_y, > int dst_stride_y, > float scale, > int width, > int height); > >+// Convert a buffer of bytes to floats, scale the values and store as floats. >+LIBYUV_API >+int ByteToFloat(const uint8_t* src_y, float* dst_y, float scale, int width); >+ > // Quantize a rectangle of ARGB. Alpha unaffected. > // scale is a 16 bit fractional fixed point scaler between 0 and 65535. > // interval_size should be a value between 1 and 255. > // interval_offset should be a value between 0 and 255. > LIBYUV_API >-int ARGBQuantize(uint8* dst_argb, >+int ARGBQuantize(uint8_t* dst_argb, > int dst_stride_argb, > int scale, > int interval_size, > int interval_offset, >- int x, >- int y, >+ int dst_x, >+ int dst_y, > int width, > int height); > > // Copy ARGB to ARGB. > LIBYUV_API >-int ARGBCopy(const uint8* src_argb, >+int ARGBCopy(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Copy Alpha channel of ARGB to alpha of ARGB. > LIBYUV_API >-int ARGBCopyAlpha(const uint8* src_argb, >+int ARGBCopyAlpha(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Extract the alpha channel from ARGB. > LIBYUV_API >-int ARGBExtractAlpha(const uint8* src_argb, >+int ARGBExtractAlpha(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, > int width, > int height); > > // Copy Y channel to Alpha of ARGB. > LIBYUV_API >-int ARGBCopyYToAlpha(const uint8* src_y, >+int ARGBCopyYToAlpha(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > >-typedef void (*ARGBBlendRow)(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+typedef void (*ARGBBlendRow)(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); > > // Get function to Alpha Blend ARGB pixels and store to destination. >@@ -526,11 +566,11 @@ ARGBBlendRow GetARGBBlend(); > // Source is pre-multiplied by alpha using ARGBAttenuate. > // Alpha of destination is set to 255. > LIBYUV_API >-int ARGBBlend(const uint8* src_argb0, >+int ARGBBlend(const uint8_t* src_argb0, > int src_stride_argb0, >- const uint8* src_argb1, >+ const uint8_t* src_argb1, > int src_stride_argb1, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); >@@ -538,13 +578,13 @@ int ARGBBlend(const uint8* src_argb0, > // Alpha Blend plane and store to destination. > // Source is not pre-multiplied by alpha. > LIBYUV_API >-int BlendPlane(const uint8* src_y0, >+int BlendPlane(const uint8_t* src_y0, > int src_stride_y0, >- const uint8* src_y1, >+ const uint8_t* src_y1, > int src_stride_y1, >- const uint8* alpha, >+ const uint8_t* alpha, > int alpha_stride, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height); >@@ -553,102 +593,102 @@ int BlendPlane(const uint8* src_y0, > // Source is not pre-multiplied by alpha. > // Alpha is full width x height and subsampled to half size to apply to UV. > LIBYUV_API >-int I420Blend(const uint8* src_y0, >+int I420Blend(const uint8_t* src_y0, > int src_stride_y0, >- const uint8* src_u0, >+ const uint8_t* src_u0, > int src_stride_u0, >- const uint8* src_v0, >+ const uint8_t* src_v0, > int src_stride_v0, >- const uint8* src_y1, >+ const uint8_t* src_y1, > int src_stride_y1, >- const uint8* src_u1, >+ const uint8_t* src_u1, > int src_stride_u1, >- const uint8* src_v1, >+ const uint8_t* src_v1, > int src_stride_v1, >- const uint8* alpha, >+ const uint8_t* alpha, > int alpha_stride, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height); > > // Multiply ARGB image by ARGB image. Shifted down by 8. Saturates to 255. > LIBYUV_API >-int ARGBMultiply(const uint8* src_argb0, >+int ARGBMultiply(const uint8_t* src_argb0, > int src_stride_argb0, >- const uint8* src_argb1, >+ const uint8_t* src_argb1, > int src_stride_argb1, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Add ARGB image with ARGB image. Saturates to 255. > LIBYUV_API >-int ARGBAdd(const uint8* src_argb0, >+int ARGBAdd(const uint8_t* src_argb0, > int src_stride_argb0, >- const uint8* src_argb1, >+ const uint8_t* src_argb1, > int src_stride_argb1, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Subtract ARGB image (argb1) from ARGB image (argb0). Saturates to 0. > LIBYUV_API >-int ARGBSubtract(const uint8* src_argb0, >+int ARGBSubtract(const uint8_t* src_argb0, > int src_stride_argb0, >- const uint8* src_argb1, >+ const uint8_t* src_argb1, > int src_stride_argb1, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert I422 to YUY2. > LIBYUV_API >-int I422ToYUY2(const uint8* src_y, >+int I422ToYUY2(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_yuy2, >+ int dst_stride_yuy2, > int width, > int height); > > // Convert I422 to UYVY. > LIBYUV_API >-int I422ToUYVY(const uint8* src_y, >+int I422ToUYVY(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_frame, >- int dst_stride_frame, >+ uint8_t* dst_uyvy, >+ int dst_stride_uyvy, > int width, > int height); > > // Convert unattentuated ARGB to preattenuated ARGB. > LIBYUV_API >-int ARGBAttenuate(const uint8* src_argb, >+int ARGBAttenuate(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Convert preattentuated ARGB to unattenuated ARGB. > LIBYUV_API >-int ARGBUnattenuate(const uint8* src_argb, >+int ARGBUnattenuate(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); >@@ -657,9 +697,9 @@ int ARGBUnattenuate(const uint8* src_argb, > // Computes table of cumulative sum for image where the value is the sum > // of all values above and to the left of the entry. Used by ARGBBlur. > LIBYUV_API >-int ARGBComputeCumulativeSum(const uint8* src_argb, >+int ARGBComputeCumulativeSum(const uint8_t* src_argb, > int src_stride_argb, >- int32* dst_cumsum, >+ int32_t* dst_cumsum, > int dst_stride32_cumsum, > int width, > int height); >@@ -671,11 +711,11 @@ int ARGBComputeCumulativeSum(const uint8* src_argb, > // radius is number of pixels around the center. e.g. 1 = 3x3. 2=5x5. > // Blur is optimized for radius of 5 (11x11) or less. > LIBYUV_API >-int ARGBBlur(const uint8* src_argb, >+int ARGBBlur(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- int32* dst_cumsum, >+ int32_t* dst_cumsum, > int dst_stride32_cumsum, > int width, > int height, >@@ -683,24 +723,24 @@ int ARGBBlur(const uint8* src_argb, > > // Multiply ARGB image by ARGB value. > LIBYUV_API >-int ARGBShade(const uint8* src_argb, >+int ARGBShade(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height, >- uint32 value); >+ uint32_t value); > > // Interpolate between two images using specified amount of interpolation > // (0 to 255) and store to destination. > // 'interpolation' is specified as 8 bit fraction where 0 means 100% src0 > // and 255 means 1% src0 and 99% src1. > LIBYUV_API >-int InterpolatePlane(const uint8* src0, >+int InterpolatePlane(const uint8_t* src0, > int src_stride0, >- const uint8* src1, >+ const uint8_t* src1, > int src_stride1, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height, >@@ -709,11 +749,11 @@ int InterpolatePlane(const uint8* src0, > // Interpolate between two ARGB images using specified amount of interpolation > // Internally calls InterpolatePlane with width * 4 (bpp). > LIBYUV_API >-int ARGBInterpolate(const uint8* src_argb0, >+int ARGBInterpolate(const uint8_t* src_argb0, > int src_stride_argb0, >- const uint8* src_argb1, >+ const uint8_t* src_argb1, > int src_stride_argb1, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height, >@@ -723,93 +763,78 @@ int ARGBInterpolate(const uint8* src_argb0, > // Internally calls InterpolatePlane on each plane where the U and V planes > // are half width and half height. > LIBYUV_API >-int I420Interpolate(const uint8* src0_y, >+int I420Interpolate(const uint8_t* src0_y, > int src0_stride_y, >- const uint8* src0_u, >+ const uint8_t* src0_u, > int src0_stride_u, >- const uint8* src0_v, >+ const uint8_t* src0_v, > int src0_stride_v, >- const uint8* src1_y, >+ const uint8_t* src1_y, > int src1_stride_y, >- const uint8* src1_u, >+ const uint8_t* src1_u, > int src1_stride_u, >- const uint8* src1_v, >+ const uint8_t* src1_v, > int src1_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height, > int interpolation); > >-#if defined(__pnacl__) || defined(__CLR_VER) || \ >- (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) >-#define LIBYUV_DISABLE_X86 >-#endif >-// MemorySanitizer does not support assembly code yet. http://crbug.com/344505 >-#if defined(__has_feature) >-#if __has_feature(memory_sanitizer) >-#define LIBYUV_DISABLE_X86 >-#endif >-#endif >-// The following are available on all x86 platforms: >-#if !defined(LIBYUV_DISABLE_X86) && \ >- (defined(_M_IX86) || defined(__x86_64__) || defined(__i386__)) >-#define HAS_ARGBAFFINEROW_SSE2 >-#endif >- > // Row function for copying pixels from a source with a slope to a row > // of destination. Useful for scaling, rotation, mirror, texture mapping. > LIBYUV_API >-void ARGBAffineRow_C(const uint8* src_argb, >+void ARGBAffineRow_C(const uint8_t* src_argb, > int src_argb_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > const float* uv_dudv, > int width); >+// TODO(fbarchard): Move ARGBAffineRow_SSE2 to row.h > LIBYUV_API >-void ARGBAffineRow_SSE2(const uint8* src_argb, >+void ARGBAffineRow_SSE2(const uint8_t* src_argb, > int src_argb_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > const float* uv_dudv, > int width); > > // Shuffle ARGB channel order. e.g. BGRA to ARGB. > // shuffler is 16 bytes and must be aligned. > LIBYUV_API >-int ARGBShuffle(const uint8* src_bgra, >+int ARGBShuffle(const uint8_t* src_bgra, > int src_stride_bgra, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- const uint8* shuffler, >+ const uint8_t* shuffler, > int width, > int height); > > // Sobel ARGB effect with planar output. > LIBYUV_API >-int ARGBSobelToPlane(const uint8* src_argb, >+int ARGBSobelToPlane(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height); > > // Sobel ARGB effect. > LIBYUV_API >-int ARGBSobel(const uint8* src_argb, >+int ARGBSobel(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); > > // Sobel ARGB effect w/ Sobel X, Sobel, Sobel Y in ARGB. > LIBYUV_API >-int ARGBSobelXY(const uint8* src_argb, >+int ARGBSobelXY(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate.h >index b9f7154a51d776ea67351e0dcbb613548c27091e..76b692be8b0b5feaf65801fce04cd49349f41b98 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate.h >@@ -33,79 +33,79 @@ typedef enum RotationMode { > > // Rotate I420 frame. > LIBYUV_API >-int I420Rotate(const uint8* src_y, >+int I420Rotate(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, >- int src_width, >- int src_height, >+ int width, >+ int height, > enum RotationMode mode); > > // Rotate NV12 input and store in I420. > LIBYUV_API >-int NV12ToI420Rotate(const uint8* src_y, >+int NV12ToI420Rotate(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_uv, >+ const uint8_t* src_uv, > int src_stride_uv, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, >- int src_width, >- int src_height, >+ int width, >+ int height, > enum RotationMode mode); > > // Rotate a plane by 0, 90, 180, or 270. > LIBYUV_API >-int RotatePlane(const uint8* src, >+int RotatePlane(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, >- int src_width, >- int src_height, >+ int width, >+ int height, > enum RotationMode mode); > > // Rotate planes by 90, 180, 270. Deprecated. > LIBYUV_API >-void RotatePlane90(const uint8* src, >+void RotatePlane90(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height); > > LIBYUV_API >-void RotatePlane180(const uint8* src, >+void RotatePlane180(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height); > > LIBYUV_API >-void RotatePlane270(const uint8* src, >+void RotatePlane270(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height); > > LIBYUV_API >-void RotateUV90(const uint8* src, >+void RotateUV90(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height); >@@ -115,21 +115,21 @@ void RotateUV90(const uint8* src, > // split the data into two buffers while > // rotating them. Deprecated. > LIBYUV_API >-void RotateUV180(const uint8* src, >+void RotateUV180(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height); > > LIBYUV_API >-void RotateUV270(const uint8* src, >+void RotateUV270(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height); >@@ -139,19 +139,19 @@ void RotateUV270(const uint8* src, > // order will result in a rotation by +- 90 degrees. > // Deprecated. > LIBYUV_API >-void TransposePlane(const uint8* src, >+void TransposePlane(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height); > > LIBYUV_API >-void TransposeUV(const uint8* src, >+void TransposeUV(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate_argb.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate_argb.h >index be0190c178784c365474347401acd875caa7b652..20432949ab42af56b803cb7ef6ee1c5914cb7434 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate_argb.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate_argb.h >@@ -21,9 +21,9 @@ extern "C" { > > // Rotate ARGB frame > LIBYUV_API >-int ARGBRotate(const uint8* src_argb, >+int ARGBRotate(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int src_width, > int src_height, >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate_row.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate_row.h >index 973fc15284ff32033cdf00270ab0fa6cc92a3b80..5edc0fcf13a1b632fb4a2ca127567e5de031cacb 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate_row.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/rotate_row.h >@@ -18,10 +18,14 @@ namespace libyuv { > extern "C" { > #endif > >-#if defined(__pnacl__) || defined(__CLR_VER) || \ >+#if defined(__pnacl__) || defined(__CLR_VER) || \ >+ (defined(__native_client__) && defined(__x86_64__)) || \ > (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) > #define LIBYUV_DISABLE_X86 > #endif >+#if defined(__native_client__) >+#define LIBYUV_DISABLE_NEON >+#endif > // MemorySanitizer does not support assembly code yet. http://crbug.com/344505 > #if defined(__has_feature) > #if __has_feature(memory_sanitizer) >@@ -34,189 +38,151 @@ extern "C" { > #define HAS_TRANSPOSEUVWX8_SSE2 > #endif > >-// The following are available for GCC 32 or 64 bit but not NaCL for 64 bit: >-#if !defined(LIBYUV_DISABLE_X86) && \ >- (defined(__i386__) || \ >- (defined(__x86_64__) && !defined(__native_client__))) >+// The following are available for GCC 32 or 64 bit: >+#if !defined(LIBYUV_DISABLE_X86) && (defined(__i386__) || defined(__x86_64__)) > #define HAS_TRANSPOSEWX8_SSSE3 > #endif > >-// The following are available for 64 bit GCC but not NaCL: >-#if !defined(LIBYUV_DISABLE_X86) && !defined(__native_client__) && \ >- defined(__x86_64__) >+// The following are available for 64 bit GCC: >+#if !defined(LIBYUV_DISABLE_X86) && defined(__x86_64__) > #define HAS_TRANSPOSEWX8_FAST_SSSE3 > #define HAS_TRANSPOSEUVWX8_SSE2 > #endif > >-#if !defined(LIBYUV_DISABLE_NEON) && !defined(__native_client__) && \ >+#if !defined(LIBYUV_DISABLE_NEON) && \ > (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__)) > #define HAS_TRANSPOSEWX8_NEON > #define HAS_TRANSPOSEUVWX8_NEON > #endif > >-#if !defined(LIBYUV_DISABLE_DSPR2) && !defined(__native_client__) && \ >- defined(__mips__) && defined(__mips_dsp) && (__mips_dsp_rev >= 2) >-#define HAS_TRANSPOSEWX8_DSPR2 >-#define HAS_TRANSPOSEUVWX8_DSPR2 >-#endif // defined(__mips__) >- > #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) > #define HAS_TRANSPOSEWX16_MSA > #define HAS_TRANSPOSEUVWX16_MSA > #endif > >-void TransposeWxH_C(const uint8* src, >+void TransposeWxH_C(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height); > >-void TransposeWx8_C(const uint8* src, >+void TransposeWx8_C(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width); >-void TransposeWx16_C(const uint8* src, >+void TransposeWx16_C(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width); >-void TransposeWx8_NEON(const uint8* src, >+void TransposeWx8_NEON(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width); >-void TransposeWx8_SSSE3(const uint8* src, >+void TransposeWx8_SSSE3(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width); >-void TransposeWx8_Fast_SSSE3(const uint8* src, >+void TransposeWx8_Fast_SSSE3(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width); >-void TransposeWx8_DSPR2(const uint8* src, >- int src_stride, >- uint8* dst, >- int dst_stride, >- int width); >-void TransposeWx8_Fast_DSPR2(const uint8* src, >- int src_stride, >- uint8* dst, >- int dst_stride, >- int width); >-void TransposeWx16_MSA(const uint8* src, >+void TransposeWx16_MSA(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width); > >-void TransposeWx8_Any_NEON(const uint8* src, >+void TransposeWx8_Any_NEON(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width); >-void TransposeWx8_Any_SSSE3(const uint8* src, >+void TransposeWx8_Any_SSSE3(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width); >-void TransposeWx8_Fast_Any_SSSE3(const uint8* src, >+void TransposeWx8_Fast_Any_SSSE3(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width); >-void TransposeWx8_Any_DSPR2(const uint8* src, >- int src_stride, >- uint8* dst, >- int dst_stride, >- int width); >-void TransposeWx16_Any_MSA(const uint8* src, >+void TransposeWx16_Any_MSA(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width); > >-void TransposeUVWxH_C(const uint8* src, >+void TransposeUVWxH_C(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height); > >-void TransposeUVWx8_C(const uint8* src, >+void TransposeUVWx8_C(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width); >-void TransposeUVWx16_C(const uint8* src, >+void TransposeUVWx16_C(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width); >-void TransposeUVWx8_SSE2(const uint8* src, >+void TransposeUVWx8_SSE2(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width); >-void TransposeUVWx8_NEON(const uint8* src, >+void TransposeUVWx8_NEON(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width); >-void TransposeUVWx8_DSPR2(const uint8* src, >- int src_stride, >- uint8* dst_a, >- int dst_stride_a, >- uint8* dst_b, >- int dst_stride_b, >- int width); >-void TransposeUVWx16_MSA(const uint8* src, >+void TransposeUVWx16_MSA(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width); > >-void TransposeUVWx8_Any_SSE2(const uint8* src, >+void TransposeUVWx8_Any_SSE2(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width); >-void TransposeUVWx8_Any_NEON(const uint8* src, >+void TransposeUVWx8_Any_NEON(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width); >-void TransposeUVWx8_Any_DSPR2(const uint8* src, >- int src_stride, >- uint8* dst_a, >- int dst_stride_a, >- uint8* dst_b, >- int dst_stride_b, >- int width); >-void TransposeUVWx16_Any_MSA(const uint8* src, >+void TransposeUVWx16_Any_MSA(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width); > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/row.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/row.h >index 34d727641a84178011d5bbc3640898ab290e3349..b5a42d0e62cfcf5c43fe753e78c92e669442cec0 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/row.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/row.h >@@ -20,34 +20,20 @@ namespace libyuv { > extern "C" { > #endif > >-#define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a)-1))) >- >-#define align_buffer_64(var, size) \ >- uint8* var##_mem = (uint8*)(malloc((size) + 63)); /* NOLINT */ \ >- uint8* var = (uint8*)(((intptr_t)(var##_mem) + 63) & ~63) /* NOLINT */ >- >-#define free_aligned_buffer_64(var) \ >- free(var##_mem); \ >- var = 0 >- >-#if defined(__pnacl__) || defined(__CLR_VER) || \ >+#if defined(__pnacl__) || defined(__CLR_VER) || \ >+ (defined(__native_client__) && defined(__x86_64__)) || \ > (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) > #define LIBYUV_DISABLE_X86 > #endif >+#if defined(__native_client__) >+#define LIBYUV_DISABLE_NEON >+#endif > // MemorySanitizer does not support assembly code yet. http://crbug.com/344505 > #if defined(__has_feature) > #if __has_feature(memory_sanitizer) > #define LIBYUV_DISABLE_X86 > #endif > #endif >-// True if compiling for SSSE3 as a requirement. >-#if defined(__SSSE3__) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 3)) >-#define LIBYUV_SSSE3_ONLY >-#endif >- >-#if defined(__native_client__) >-#define LIBYUV_DISABLE_NEON >-#endif > // clang >= 3.5.0 required for Arm64. > #if defined(__clang__) && defined(__aarch64__) && !defined(LIBYUV_DISABLE_NEON) > #if (__clang_major__ < 3) || (__clang_major__ == 3 && (__clang_minor__ < 5)) >@@ -85,7 +71,6 @@ extern "C" { > #define HAS_ARGB4444TOARGBROW_SSE2 > #define HAS_ARGBEXTRACTALPHAROW_SSE2 > #define HAS_ARGBSETROW_X86 >-#define HAS_ARGBSHUFFLEROW_SSE2 > #define HAS_ARGBSHUFFLEROW_SSSE3 > #define HAS_ARGBTOARGB1555ROW_SSE2 > #define HAS_ARGBTOARGB4444ROW_SSE2 >@@ -184,7 +169,6 @@ extern "C" { > > // The following are available on all x86 platforms, but > // require VS2012, clang 3.4 or gcc 4.7. >-// The code supports NaCL but requires a new compiler and validator. > #if !defined(LIBYUV_DISABLE_X86) && \ > (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2) || \ > defined(GCC_HAS_AVX2)) >@@ -268,6 +252,14 @@ extern "C" { > // TODO(fbarchard): Port to Visual C > #if !defined(LIBYUV_DISABLE_X86) && \ > (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) >+#define HAS_ABGRTOAR30ROW_SSSE3 >+#define HAS_ARGBTOAR30ROW_SSSE3 >+#define HAS_CONVERT16TO8ROW_SSSE3 >+#define HAS_CONVERT8TO16ROW_SSE2 >+// I210 is for H010. 2 = 422. I for 601 vs H for 709. >+#define HAS_I210TOAR30ROW_SSSE3 >+#define HAS_I210TOARGBROW_SSSE3 >+#define HAS_I422TOAR30ROW_SSSE3 > #define HAS_MERGERGBROW_SSSE3 > #define HAS_SPLITRGBROW_SSSE3 > #endif >@@ -277,6 +269,15 @@ extern "C" { > #if !defined(LIBYUV_DISABLE_X86) && \ > (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) && \ > (defined(CLANG_HAS_AVX2) || defined(GCC_HAS_AVX2)) >+#define HAS_ABGRTOAR30ROW_AVX2 >+#define HAS_ARGBTOAR30ROW_AVX2 >+#define HAS_CONVERT16TO8ROW_AVX2 >+#define HAS_CONVERT8TO16ROW_AVX2 >+#define HAS_I210TOARGBROW_AVX2 >+#define HAS_I210TOAR30ROW_AVX2 >+#define HAS_I422TOAR30ROW_AVX2 >+#define HAS_I422TOUYVYROW_AVX2 >+#define HAS_I422TOYUY2ROW_AVX2 > #define HAS_MERGEUVROW_16_AVX2 > #define HAS_MULTIPLYROW_16_AVX2 > #endif >@@ -307,6 +308,7 @@ extern "C" { > #define HAS_ARGBTOYROW_NEON > #define HAS_BGRATOUVROW_NEON > #define HAS_BGRATOYROW_NEON >+#define HAS_BYTETOFLOATROW_NEON > #define HAS_COPYROW_NEON > #define HAS_HALFFLOATROW_NEON > #define HAS_I400TOARGBROW_NEON >@@ -325,8 +327,10 @@ extern "C" { > #define HAS_MIRRORROW_NEON > #define HAS_MIRRORUVROW_NEON > #define HAS_NV12TOARGBROW_NEON >+#define HAS_NV12TORGB24ROW_NEON > #define HAS_NV12TORGB565ROW_NEON > #define HAS_NV21TOARGBROW_NEON >+#define HAS_NV21TORGB24ROW_NEON > #define HAS_RAWTOARGBROW_NEON > #define HAS_RAWTORGB24ROW_NEON > #define HAS_RAWTOUVROW_NEON >@@ -376,37 +380,6 @@ extern "C" { > #if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) > #define HAS_SCALESUMSAMPLES_NEON > #endif >- >-// The following are available on Mips platforms: >-#if !defined(LIBYUV_DISABLE_DSPR2) && defined(__mips__) && \ >- (_MIPS_SIM == _MIPS_SIM_ABI32) && (__mips_isa_rev < 6) >-#define HAS_COPYROW_MIPS >-#if defined(__mips_dsp) && (__mips_dsp_rev >= 2) >-#define HAS_I422TOARGBROW_DSPR2 >-#define HAS_INTERPOLATEROW_DSPR2 >-#define HAS_MIRRORROW_DSPR2 >-#define HAS_MIRRORUVROW_DSPR2 >-#define HAS_SPLITUVROW_DSPR2 >-#define HAS_RGB24TOARGBROW_DSPR2 >-#define HAS_RAWTOARGBROW_DSPR2 >-#define HAS_RGB565TOARGBROW_DSPR2 >-#define HAS_ARGB1555TOARGBROW_DSPR2 >-#define HAS_ARGB4444TOARGBROW_DSPR2 >-#define HAS_I444TOARGBROW_DSPR2 >-#define HAS_I422TOARGB4444ROW_DSPR2 >-#define HAS_I422TOARGB1555ROW_DSPR2 >-#define HAS_NV12TOARGBROW_DSPR2 >-#define HAS_BGRATOUVROW_DSPR2 >-#define HAS_BGRATOYROW_DSPR2 >-#define HAS_ABGRTOUVROW_DSPR2 >-#define HAS_ARGBTOYROW_DSPR2 >-#define HAS_ABGRTOYROW_DSPR2 >-#define HAS_RGBATOUVROW_DSPR2 >-#define HAS_RGBATOYROW_DSPR2 >-#define HAS_ARGBTOUVROW_DSPR2 >-#endif >-#endif >- > #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) > #define HAS_ABGRTOUVROW_MSA > #define HAS_ABGRTOYROW_MSA >@@ -492,18 +465,18 @@ extern "C" { > #else > #define SIMD_ALIGNED(var) __declspec(align(16)) var > #endif >-typedef __declspec(align(16)) int16 vec16[8]; >-typedef __declspec(align(16)) int32 vec32[4]; >-typedef __declspec(align(16)) int8 vec8[16]; >-typedef __declspec(align(16)) uint16 uvec16[8]; >-typedef __declspec(align(16)) uint32 uvec32[4]; >-typedef __declspec(align(16)) uint8 uvec8[16]; >-typedef __declspec(align(32)) int16 lvec16[16]; >-typedef __declspec(align(32)) int32 lvec32[8]; >-typedef __declspec(align(32)) int8 lvec8[32]; >-typedef __declspec(align(32)) uint16 ulvec16[16]; >-typedef __declspec(align(32)) uint32 ulvec32[8]; >-typedef __declspec(align(32)) uint8 ulvec8[32]; >+typedef __declspec(align(16)) int16_t vec16[8]; >+typedef __declspec(align(16)) int32_t vec32[4]; >+typedef __declspec(align(16)) int8_t vec8[16]; >+typedef __declspec(align(16)) uint16_t uvec16[8]; >+typedef __declspec(align(16)) uint32_t uvec32[4]; >+typedef __declspec(align(16)) uint8_t uvec8[16]; >+typedef __declspec(align(32)) int16_t lvec16[16]; >+typedef __declspec(align(32)) int32_t lvec32[8]; >+typedef __declspec(align(32)) int8_t lvec8[32]; >+typedef __declspec(align(32)) uint16_t ulvec16[16]; >+typedef __declspec(align(32)) uint32_t ulvec32[8]; >+typedef __declspec(align(32)) uint8_t ulvec8[32]; > #elif !defined(__pnacl__) && (defined(__GNUC__) || defined(__clang__)) > // Caveat GCC 4.2 to 4.7 have a known issue using vectors with const. > #if defined(CLANG_HAS_AVX2) || defined(GCC_HAS_AVX2) >@@ -511,32 +484,32 @@ typedef __declspec(align(32)) uint8 ulvec8[32]; > #else > #define SIMD_ALIGNED(var) var __attribute__((aligned(16))) > #endif >-typedef int16 __attribute__((vector_size(16))) vec16; >-typedef int32 __attribute__((vector_size(16))) vec32; >-typedef int8 __attribute__((vector_size(16))) vec8; >-typedef uint16 __attribute__((vector_size(16))) uvec16; >-typedef uint32 __attribute__((vector_size(16))) uvec32; >-typedef uint8 __attribute__((vector_size(16))) uvec8; >-typedef int16 __attribute__((vector_size(32))) lvec16; >-typedef int32 __attribute__((vector_size(32))) lvec32; >-typedef int8 __attribute__((vector_size(32))) lvec8; >-typedef uint16 __attribute__((vector_size(32))) ulvec16; >-typedef uint32 __attribute__((vector_size(32))) ulvec32; >-typedef uint8 __attribute__((vector_size(32))) ulvec8; >+typedef int16_t __attribute__((vector_size(16))) vec16; >+typedef int32_t __attribute__((vector_size(16))) vec32; >+typedef int8_t __attribute__((vector_size(16))) vec8; >+typedef uint16_t __attribute__((vector_size(16))) uvec16; >+typedef uint32_t __attribute__((vector_size(16))) uvec32; >+typedef uint8_t __attribute__((vector_size(16))) uvec8; >+typedef int16_t __attribute__((vector_size(32))) lvec16; >+typedef int32_t __attribute__((vector_size(32))) lvec32; >+typedef int8_t __attribute__((vector_size(32))) lvec8; >+typedef uint16_t __attribute__((vector_size(32))) ulvec16; >+typedef uint32_t __attribute__((vector_size(32))) ulvec32; >+typedef uint8_t __attribute__((vector_size(32))) ulvec8; > #else > #define SIMD_ALIGNED(var) var >-typedef int16 vec16[8]; >-typedef int32 vec32[4]; >-typedef int8 vec8[16]; >-typedef uint16 uvec16[8]; >-typedef uint32 uvec32[4]; >-typedef uint8 uvec8[16]; >-typedef int16 lvec16[16]; >-typedef int32 lvec32[8]; >-typedef int8 lvec8[32]; >-typedef uint16 ulvec16[16]; >-typedef uint32 ulvec32[8]; >-typedef uint8 ulvec8[32]; >+typedef int16_t vec16[8]; >+typedef int32_t vec32[4]; >+typedef int8_t vec8[16]; >+typedef uint16_t uvec16[8]; >+typedef uint32_t uvec32[4]; >+typedef uint8_t uvec8[16]; >+typedef int16_t lvec16[16]; >+typedef int32_t lvec32[8]; >+typedef int8_t lvec8[32]; >+typedef uint16_t ulvec16[16]; >+typedef uint32_t ulvec32[8]; >+typedef uint8_t ulvec8[32]; > #endif > > #if defined(__aarch64__) >@@ -560,13 +533,13 @@ struct YuvConstants { > #else > // This struct is for Intel color conversion. > struct YuvConstants { >- int8 kUVToB[32]; >- int8 kUVToG[32]; >- int8 kUVToR[32]; >- int16 kUVBiasB[16]; >- int16 kUVBiasG[16]; >- int16 kUVBiasR[16]; >- int16 kYToRgb[16]; >+ int8_t kUVToB[32]; >+ int8_t kUVToG[32]; >+ int8_t kUVToR[32]; >+ int16_t kUVBiasB[16]; >+ int16_t kUVBiasG[16]; >+ int16_t kUVBiasR[16]; >+ int16_t kYToRgb[16]; > }; > > // Offsets into YuvConstants structure >@@ -589,6 +562,16 @@ extern const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants); // BT.601 > extern const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants); // JPeg > extern const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants); // BT.709 > >+#define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a)-1))) >+ >+#define align_buffer_64(var, size) \ >+ uint8_t* var##_mem = (uint8_t*)(malloc((size) + 63)); /* NOLINT */ \ >+ uint8_t* var = (uint8_t*)(((intptr_t)(var##_mem) + 63) & ~63) /* NOLINT */ >+ >+#define free_aligned_buffer_64(var) \ >+ free(var##_mem); \ >+ var = 0 >+ > #if defined(__APPLE__) || defined(__x86_64__) || defined(__llvm__) > #define OMITFP > #else >@@ -601,62 +584,6 @@ extern const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants); // BT.709 > #else > #define LABELALIGN > #endif >-#if defined(__native_client__) && defined(__x86_64__) >-// r14 is used for MEMOP macros. >-#define NACL_R14 "r14", >-#define BUNDLELOCK ".bundle_lock\n" >-#define BUNDLEUNLOCK ".bundle_unlock\n" >-#define MEMACCESS(base) "%%nacl:(%%r15,%q" #base ")" >-#define MEMACCESS2(offset, base) "%%nacl:" #offset "(%%r15,%q" #base ")" >-#define MEMLEA(offset, base) #offset "(%q" #base ")" >-#define MEMLEA3(offset, index, scale) #offset "(,%q" #index "," #scale ")" >-#define MEMLEA4(offset, base, index, scale) \ >- #offset "(%q" #base ",%q" #index "," #scale ")" >-#define MEMMOVESTRING(s, d) "%%nacl:(%q" #s "),%%nacl:(%q" #d "), %%r15" >-#define MEMSTORESTRING(reg, d) "%%" #reg ",%%nacl:(%q" #d "), %%r15" >-#define MEMOPREG(opcode, offset, base, index, scale, reg) \ >- BUNDLELOCK \ >- "lea " #offset "(%q" #base ",%q" #index "," #scale "),%%r14d\n" #opcode \ >- " (%%r15,%%r14),%%" #reg "\n" BUNDLEUNLOCK >-#define MEMOPMEM(opcode, reg, offset, base, index, scale) \ >- BUNDLELOCK \ >- "lea " #offset "(%q" #base ",%q" #index "," #scale "),%%r14d\n" #opcode \ >- " %%" #reg ",(%%r15,%%r14)\n" BUNDLEUNLOCK >-#define MEMOPARG(opcode, offset, base, index, scale, arg) \ >- BUNDLELOCK \ >- "lea " #offset "(%q" #base ",%q" #index "," #scale "),%%r14d\n" #opcode \ >- " (%%r15,%%r14),%" #arg "\n" BUNDLEUNLOCK >-#define VMEMOPREG(opcode, offset, base, index, scale, reg1, reg2) \ >- BUNDLELOCK \ >- "lea " #offset "(%q" #base ",%q" #index "," #scale "),%%r14d\n" #opcode \ >- " (%%r15,%%r14),%%" #reg1 ",%%" #reg2 "\n" BUNDLEUNLOCK >-#define VEXTOPMEM(op, sel, reg, offset, base, index, scale) \ >- BUNDLELOCK \ >- "lea " #offset "(%q" #base ",%q" #index "," #scale "),%%r14d\n" #op \ >- " $" #sel ",%%" #reg ",(%%r15,%%r14)\n" BUNDLEUNLOCK >-#else // defined(__native_client__) && defined(__x86_64__) >-#define NACL_R14 >-#define BUNDLEALIGN >-#define MEMACCESS(base) "(%" #base ")" >-#define MEMACCESS2(offset, base) #offset "(%" #base ")" >-#define MEMLEA(offset, base) #offset "(%" #base ")" >-#define MEMLEA3(offset, index, scale) #offset "(,%" #index "," #scale ")" >-#define MEMLEA4(offset, base, index, scale) \ >- #offset "(%" #base ",%" #index "," #scale ")" >-#define MEMMOVESTRING(s, d) >-#define MEMSTORESTRING(reg, d) >-#define MEMOPREG(opcode, offset, base, index, scale, reg) \ >- #opcode " " #offset "(%" #base ",%" #index "," #scale "),%%" #reg "\n" >-#define MEMOPMEM(opcode, reg, offset, base, index, scale) \ >- #opcode " %%" #reg "," #offset "(%" #base ",%" #index "," #scale ")\n" >-#define MEMOPARG(opcode, offset, base, index, scale, arg) \ >- #opcode " " #offset "(%" #base ",%" #index "," #scale "),%" #arg "\n" >-#define VMEMOPREG(opcode, offset, base, index, scale, reg1, reg2) \ >- #opcode " " #offset "(%" #base ",%" #index "," #scale "),%%" #reg1 \ >- ",%%" #reg2 "\n" >-#define VEXTOPMEM(op, sel, reg, offset, base, index, scale) \ >- #op " $" #sel ",%%" #reg "," #offset "(%" #base ",%" #index "," #scale ")\n" >-#endif // defined(__native_client__) && defined(__x86_64__) > > // Intel Code Analizer markers. Insert IACA_START IACA_END around code to be > // measured and then run with iaca -64 libyuv_unittest. >@@ -709,2583 +636,2743 @@ extern const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants); // BT.709 > IACA_UD_BYTES \ > } > >-void I444ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422AlphaToARGBRow_NEON(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+void I422AlphaToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ const uint8_t* src_a, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGBARow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToRGBARow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgba, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB24Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb24, >+void I422ToRGB24Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb24, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB565Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb565, >+void I422ToRGB565Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB1555Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb1555, >+void I422ToARGB1555Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB4444Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB4444Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToRGB565Row_NEON(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_rgb565, >+void NV12ToRGB565Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width); >-void NV21ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_vu, >- uint8* dst_argb, >+void NV21ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void YUY2ToARGBRow_NEON(const uint8* src_yuy2, >- uint8* dst_argb, >+void NV12ToRGB24Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb24, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void NV21ToRGB24Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* dst_rgb24, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void YUY2ToARGBRow_NEON(const uint8_t* src_yuy2, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void UYVYToARGBRow_NEON(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_NEON(const uint8_t* src_uyvy, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I444ToARGBRow_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I444ToARGBRow_DSPR2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void I422ToARGB4444Row_DSPR2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >- const struct YuvConstants* yuvconstants, >- int width); >-void I422ToARGB1555Row_DSPR2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb1555, >- const struct YuvConstants* yuvconstants, >- int width); >-void NV12ToARGBRow_DSPR2(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); > >-void I422ToARGBRow_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGBARow_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToRGBARow_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422AlphaToARGBRow_MSA(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+void I422AlphaToARGBRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ const uint8_t* src_a, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB24Row_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb24, >+void I422ToRGB24Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB565Row_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb565, >+void I422ToRGB565Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB4444Row_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB4444Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB1555Row_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb1555, >+void I422ToARGB1555Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToARGBRow_MSA(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToRGB565Row_MSA(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_rgb565, >+void NV12ToRGB565Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width); >-void NV21ToARGBRow_MSA(const uint8* src_y, >- const uint8* src_vu, >- uint8* dst_argb, >+void NV21ToARGBRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void YUY2ToARGBRow_MSA(const uint8* src_yuy2, >- uint8* dst_argb, >+void YUY2ToARGBRow_MSA(const uint8_t* src_yuy2, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void UYVYToARGBRow_MSA(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_MSA(const uint8_t* src_uyvy, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); > >-void ARGBToYRow_AVX2(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYRow_Any_AVX2(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYJRow_AVX2(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYJRow_Any_AVX2(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYJRow_SSSE3(const uint8* src_argb, uint8* dst_y, int width); >-void BGRAToYRow_SSSE3(const uint8* src_bgra, uint8* dst_y, int width); >-void ABGRToYRow_SSSE3(const uint8* src_abgr, uint8* dst_y, int width); >-void RGBAToYRow_SSSE3(const uint8* src_rgba, uint8* dst_y, int width); >-void RGB24ToYRow_SSSE3(const uint8* src_rgb24, uint8* dst_y, int width); >-void RAWToYRow_SSSE3(const uint8* src_raw, uint8* dst_y, int width); >-void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYRow_MSA(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYJRow_MSA(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToUV444Row_NEON(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void ARGBToUVRow_NEON(const uint8* src_argb, >+void ARGBToYRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width); >+void ARGBToYRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ARGBToYRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width); >+void ARGBToYJRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width); >+void ARGBToYJRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ARGBToYJRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width); >+void BGRAToYRow_SSSE3(const uint8_t* src_bgra, uint8_t* dst_y, int width); >+void ABGRToYRow_SSSE3(const uint8_t* src_abgr, uint8_t* dst_y, int width); >+void RGBAToYRow_SSSE3(const uint8_t* src_rgba, uint8_t* dst_y, int width); >+void RGB24ToYRow_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width); >+void RAWToYRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width); >+void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width); >+void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width); >+void ARGBToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void ARGBToYJRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void ARGBToUV444Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void ARGBToUVRow_NEON(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUV444Row_MSA(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUV444Row_MSA(const uint8_t* src_argb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVRow_MSA(const uint8* src_argb, >+void ARGBToUVRow_MSA(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVJRow_NEON(const uint8* src_argb, >+void ARGBToUVJRow_NEON(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void BGRAToUVRow_NEON(const uint8* src_bgra, >+void BGRAToUVRow_NEON(const uint8_t* src_bgra, > int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ABGRToUVRow_NEON(const uint8* src_abgr, >+void ABGRToUVRow_NEON(const uint8_t* src_abgr, > int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGBAToUVRow_NEON(const uint8* src_rgba, >+void RGBAToUVRow_NEON(const uint8_t* src_rgba, > int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGB24ToUVRow_NEON(const uint8* src_rgb24, >+void RGB24ToUVRow_NEON(const uint8_t* src_rgb24, > int src_stride_rgb24, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RAWToUVRow_NEON(const uint8* src_raw, >+void RAWToUVRow_NEON(const uint8_t* src_raw, > int src_stride_raw, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGB565ToUVRow_NEON(const uint8* src_rgb565, >+void RGB565ToUVRow_NEON(const uint8_t* src_rgb565, > int src_stride_rgb565, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGB1555ToUVRow_NEON(const uint8* src_argb1555, >+void ARGB1555ToUVRow_NEON(const uint8_t* src_argb1555, > int src_stride_argb1555, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGB4444ToUVRow_NEON(const uint8* src_argb4444, >+void ARGB4444ToUVRow_NEON(const uint8_t* src_argb4444, > int src_stride_argb4444, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVJRow_MSA(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVJRow_MSA(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void BGRAToUVRow_MSA(const uint8* src_bgra, >- int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >+void BGRAToUVRow_MSA(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ABGRToUVRow_MSA(const uint8* src_abgr, >- int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >+void ABGRToUVRow_MSA(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGBAToUVRow_MSA(const uint8* src_rgba, >- int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >+void RGBAToUVRow_MSA(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGB24ToUVRow_MSA(const uint8* src_rgb24, >- int src_stride_rgb24, >- uint8* dst_u, >- uint8* dst_v, >+void RGB24ToUVRow_MSA(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RAWToUVRow_MSA(const uint8* src_raw, >- int src_stride_raw, >- uint8* dst_u, >- uint8* dst_v, >+void RAWToUVRow_MSA(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGB565ToUVRow_MSA(const uint8* src_rgb565, >+void RGB565ToUVRow_MSA(const uint8_t* src_rgb565, > int src_stride_rgb565, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGB1555ToUVRow_MSA(const uint8* src_argb1555, >+void ARGB1555ToUVRow_MSA(const uint8_t* src_argb1555, > int src_stride_argb1555, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void BGRAToYRow_NEON(const uint8* src_bgra, uint8* dst_y, int width); >-void ABGRToYRow_NEON(const uint8* src_abgr, uint8* dst_y, int width); >-void RGBAToYRow_NEON(const uint8* src_rgba, uint8* dst_y, int width); >-void RGB24ToYRow_NEON(const uint8* src_rgb24, uint8* dst_y, int width); >-void RAWToYRow_NEON(const uint8* src_raw, uint8* dst_y, int width); >-void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int width); >-void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int width); >-void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int width); >-void BGRAToYRow_MSA(const uint8* src_bgra, uint8* dst_y, int width); >-void ABGRToYRow_MSA(const uint8* src_abgr, uint8* dst_y, int width); >-void RGBAToYRow_MSA(const uint8* src_rgba, uint8* dst_y, int width); >-void RGB24ToYRow_MSA(const uint8* src_rgb24, uint8* dst_y, int width); >-void RAWToYRow_MSA(const uint8* src_raw, uint8* dst_y, int width); >-void RGB565ToYRow_MSA(const uint8* src_rgb565, uint8* dst_y, int width); >-void ARGB1555ToYRow_MSA(const uint8* src_argb1555, uint8* dst_y, int width); >-void BGRAToUVRow_DSPR2(const uint8* src_bgra, >- int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void BGRAToYRow_DSPR2(const uint8* src_bgra, uint8* dst_y, int width); >-void ABGRToUVRow_DSPR2(const uint8* src_abgr, >- int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void ARGBToYRow_DSPR2(const uint8* src_argb, uint8* dst_y, int width); >-void ABGRToYRow_DSPR2(const uint8* src_abgr, uint8* dst_y, int width); >-void RGBAToUVRow_DSPR2(const uint8* src_rgba, >- int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void RGBAToYRow_DSPR2(const uint8* src_rgba, uint8* dst_y, int width); >-void ARGBToUVRow_DSPR2(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void ARGBToYRow_C(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYJRow_C(const uint8* src_argb, uint8* dst_y, int width); >-void BGRAToYRow_C(const uint8* src_bgra, uint8* dst_y, int width); >-void ABGRToYRow_C(const uint8* src_abgr, uint8* dst_y, int width); >-void RGBAToYRow_C(const uint8* src_rgba, uint8* dst_y, int width); >-void RGB24ToYRow_C(const uint8* src_rgb24, uint8* dst_y, int width); >-void RAWToYRow_C(const uint8* src_raw, uint8* dst_y, int width); >-void RGB565ToYRow_C(const uint8* src_rgb565, uint8* dst_y, int width); >-void ARGB1555ToYRow_C(const uint8* src_argb1555, uint8* dst_y, int width); >-void ARGB4444ToYRow_C(const uint8* src_argb4444, uint8* dst_y, int width); >-void ARGBToYRow_Any_SSSE3(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYJRow_Any_SSSE3(const uint8* src_argb, uint8* dst_y, int width); >-void BGRAToYRow_Any_SSSE3(const uint8* src_bgra, uint8* dst_y, int width); >-void ABGRToYRow_Any_SSSE3(const uint8* src_abgr, uint8* dst_y, int width); >-void RGBAToYRow_Any_SSSE3(const uint8* src_rgba, uint8* dst_y, int width); >-void RGB24ToYRow_Any_SSSE3(const uint8* src_rgb24, uint8* dst_y, int width); >-void RAWToYRow_Any_SSSE3(const uint8* src_raw, uint8* dst_y, int width); >-void ARGBToYRow_Any_NEON(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYJRow_Any_NEON(const uint8* src_argb, uint8* dst_y, int width); >-void BGRAToYRow_Any_NEON(const uint8* src_bgra, uint8* dst_y, int width); >-void ABGRToYRow_Any_NEON(const uint8* src_abgr, uint8* dst_y, int width); >-void RGBAToYRow_Any_NEON(const uint8* src_rgba, uint8* dst_y, int width); >-void RGB24ToYRow_Any_NEON(const uint8* src_rgb24, uint8* dst_y, int width); >-void RAWToYRow_Any_NEON(const uint8* src_raw, uint8* dst_y, int width); >-void RGB565ToYRow_Any_NEON(const uint8* src_rgb565, uint8* dst_y, int width); >-void ARGB1555ToYRow_Any_NEON(const uint8* src_argb1555, >- uint8* dst_y, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width); >+void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width); >+void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width); >+void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width); >+void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width); >+void RGB565ToYRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_y, int width); >+void ARGB1555ToYRow_NEON(const uint8_t* src_argb1555, >+ uint8_t* dst_y, >+ int width); >+void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, >+ uint8_t* dst_y, >+ int width); >+void BGRAToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void ABGRToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void RGBAToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void RGB24ToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void RAWToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void RGB565ToYRow_MSA(const uint8_t* src_rgb565, uint8_t* dst_y, int width); >+void ARGB1555ToYRow_MSA(const uint8_t* src_argb1555, uint8_t* dst_y, int width); >+void ARGBToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void ARGBToYJRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void BGRAToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void ABGRToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void RGBAToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void RGB24ToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void RAWToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); >+void RGB565ToYRow_C(const uint8_t* src_rgb565, uint8_t* dst_y, int width); >+void ARGB1555ToYRow_C(const uint8_t* src_argb1555, uint8_t* dst_y, int width); >+void ARGB4444ToYRow_C(const uint8_t* src_argb4444, uint8_t* dst_y, int width); >+void ARGBToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ARGBToYJRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void BGRAToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ABGRToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RGBAToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RGB24ToYRow_Any_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width); >+void RAWToYRow_Any_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width); >+void ARGBToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ARGBToYJRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void BGRAToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ABGRToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RGBAToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RGB24ToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RAWToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RGB565ToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ARGB1555ToYRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void BGRAToYRow_Any_DSPR2(const uint8* src_bgra, uint8* dst_y, int width); >-void ARGBToYRow_Any_DSPR2(const uint8* src_argb, uint8* dst_y, int width); >-void ABGRToYRow_Any_DSPR2(const uint8* src_abgr, uint8* dst_y, int width); >-void RGBAToYRow_Any_DSPR2(const uint8* src_rgba, uint8* dst_y, int width); >-void ARGB4444ToYRow_Any_NEON(const uint8* src_argb4444, >- uint8* dst_y, >+void ARGB4444ToYRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void BGRAToYRow_Any_MSA(const uint8* src_bgra, uint8* dst_y, int width); >-void ABGRToYRow_Any_MSA(const uint8* src_abgr, uint8* dst_y, int width); >-void RGBAToYRow_Any_MSA(const uint8* src_rgba, uint8* dst_y, int width); >-void ARGBToYJRow_Any_MSA(const uint8* src_argb, uint8* dst_y, int width); >-void ARGBToYRow_Any_MSA(const uint8* src_argb, uint8* dst_y, int width); >-void RGB24ToYRow_Any_MSA(const uint8* src_rgb24, uint8* dst_y, int width); >-void RAWToYRow_Any_MSA(const uint8* src_raw, uint8* dst_y, int width); >-void RGB565ToYRow_Any_MSA(const uint8* src_rgb565, uint8* dst_y, int width); >-void ARGB1555ToYRow_Any_MSA(const uint8* src_argb1555, uint8* dst_y, int width); >- >-void ARGBToUVRow_AVX2(const uint8* src_argb, >+void BGRAToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ABGRToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RGBAToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ARGBToYJRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ARGBToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RGB24ToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RAWToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RGB565ToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ARGB1555ToYRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+ >+void ARGBToUVRow_AVX2(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVJRow_AVX2(const uint8* src_argb, >+void ARGBToUVJRow_AVX2(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVRow_SSSE3(const uint8* src_argb, >+void ARGBToUVRow_SSSE3(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVJRow_SSSE3(const uint8* src_argb, >+void ARGBToUVJRow_SSSE3(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void BGRAToUVRow_SSSE3(const uint8* src_bgra, >+void BGRAToUVRow_SSSE3(const uint8_t* src_bgra0, > int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ABGRToUVRow_SSSE3(const uint8* src_abgr, >+void ABGRToUVRow_SSSE3(const uint8_t* src_abgr0, > int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGBAToUVRow_SSSE3(const uint8* src_rgba, >+void RGBAToUVRow_SSSE3(const uint8_t* src_rgba0, > int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVRow_Any_AVX2(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVRow_Any_AVX2(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVJRow_Any_AVX2(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVJRow_Any_AVX2(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVRow_Any_SSSE3(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVRow_Any_SSSE3(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVJRow_Any_SSSE3(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void BGRAToUVRow_Any_SSSE3(const uint8* src_bgra, >- int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVJRow_Any_SSSE3(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void BGRAToUVRow_Any_SSSE3(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ABGRToUVRow_Any_SSSE3(const uint8* src_abgr, >- int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >+void ABGRToUVRow_Any_SSSE3(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGBAToUVRow_Any_SSSE3(const uint8* src_rgba, >- int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >+void RGBAToUVRow_Any_SSSE3(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUV444Row_Any_NEON(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUV444Row_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVRow_Any_NEON(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUV444Row_Any_MSA(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void ARGBToUVRow_Any_MSA(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void ARGBToUVJRow_Any_NEON(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUV444Row_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void ARGBToUVRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void ARGBToUVJRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void BGRAToUVRow_Any_NEON(const uint8* src_bgra, >- int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >+void BGRAToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ABGRToUVRow_Any_NEON(const uint8* src_abgr, >- int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >+void ABGRToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGBAToUVRow_Any_NEON(const uint8* src_rgba, >- int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >+void RGBAToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGB24ToUVRow_Any_NEON(const uint8* src_rgb24, >- int src_stride_rgb24, >- uint8* dst_u, >- uint8* dst_v, >+void RGB24ToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RAWToUVRow_Any_NEON(const uint8* src_raw, >- int src_stride_raw, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void RGB565ToUVRow_Any_NEON(const uint8* src_rgb565, >- int src_stride_rgb565, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void ARGB1555ToUVRow_Any_NEON(const uint8* src_argb1555, >- int src_stride_argb1555, >- uint8* dst_u, >- uint8* dst_v, >+void RAWToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void RGB565ToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void ARGB1555ToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGB4444ToUVRow_Any_NEON(const uint8* src_argb4444, >- int src_stride_argb4444, >- uint8* dst_u, >- uint8* dst_v, >+void ARGB4444ToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVJRow_Any_MSA(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVJRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void BGRAToUVRow_Any_MSA(const uint8* src_bgra, >- int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void ABGRToUVRow_Any_MSA(const uint8* src_abgr, >- int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void RGBAToUVRow_Any_MSA(const uint8* src_rgba, >- int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void RGB24ToUVRow_Any_MSA(const uint8* src_rgb24, >- int src_stride_rgb24, >- uint8* dst_u, >- uint8* dst_v, >+void BGRAToUVRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void ABGRToUVRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void RGBAToUVRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void RGB24ToUVRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RAWToUVRow_Any_MSA(const uint8* src_raw, >- int src_stride_raw, >- uint8* dst_u, >- uint8* dst_v, >+void RAWToUVRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGB565ToUVRow_Any_MSA(const uint8* src_rgb565, >- int src_stride_rgb565, >- uint8* dst_u, >- uint8* dst_v, >+void RGB565ToUVRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGB1555ToUVRow_Any_MSA(const uint8* src_argb1555, >- int src_stride_argb1555, >- uint8* dst_u, >- uint8* dst_v, >+void ARGB1555ToUVRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void BGRAToUVRow_Any_DSPR2(const uint8* src_bgra, >- int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void ABGRToUVRow_Any_DSPR2(const uint8* src_abgr, >- int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void RGBAToUVRow_Any_DSPR2(const uint8* src_rgba, >- int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void ARGBToUVRow_Any_DSPR2(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void ARGBToUVRow_C(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVRow_C(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVJRow_C(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVJRow_C(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVRow_C(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVRow_C(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUVJRow_C(const uint8* src_argb, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUVJRow_C(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void BGRAToUVRow_C(const uint8* src_bgra, >- int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >+void BGRAToUVRow_C(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ABGRToUVRow_C(const uint8* src_abgr, >- int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >+void ABGRToUVRow_C(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGBAToUVRow_C(const uint8* src_rgba, >- int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >+void RGBAToUVRow_C(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGB24ToUVRow_C(const uint8* src_rgb24, >- int src_stride_rgb24, >- uint8* dst_u, >- uint8* dst_v, >+void RGB24ToUVRow_C(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RAWToUVRow_C(const uint8* src_raw, >- int src_stride_raw, >- uint8* dst_u, >- uint8* dst_v, >+void RAWToUVRow_C(const uint8_t* src_rgb0, >+ int src_stride_rgb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void RGB565ToUVRow_C(const uint8* src_rgb565, >+void RGB565ToUVRow_C(const uint8_t* src_rgb565, > int src_stride_rgb565, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGB1555ToUVRow_C(const uint8* src_argb1555, >+void ARGB1555ToUVRow_C(const uint8_t* src_argb1555, > int src_stride_argb1555, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGB4444ToUVRow_C(const uint8* src_argb4444, >+void ARGB4444ToUVRow_C(const uint8_t* src_argb4444, > int src_stride_argb4444, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); > >-void ARGBToUV444Row_SSSE3(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUV444Row_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void ARGBToUV444Row_Any_SSSE3(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUV444Row_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); > >-void ARGBToUV444Row_C(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUV444Row_C(const uint8_t* src_argb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); > >-void MirrorRow_AVX2(const uint8* src, uint8* dst, int width); >-void MirrorRow_SSSE3(const uint8* src, uint8* dst, int width); >-void MirrorRow_NEON(const uint8* src, uint8* dst, int width); >-void MirrorRow_DSPR2(const uint8* src, uint8* dst, int width); >-void MirrorRow_MSA(const uint8* src, uint8* dst, int width); >-void MirrorRow_C(const uint8* src, uint8* dst, int width); >-void MirrorRow_Any_AVX2(const uint8* src, uint8* dst, int width); >-void MirrorRow_Any_SSSE3(const uint8* src, uint8* dst, int width); >-void MirrorRow_Any_SSE2(const uint8* src, uint8* dst, int width); >-void MirrorRow_Any_NEON(const uint8* src, uint8* dst, int width); >-void MirrorRow_Any_MSA(const uint8* src, uint8* dst, int width); >- >-void MirrorUVRow_SSSE3(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void MirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width); >+void MirrorRow_SSSE3(const uint8_t* src, uint8_t* dst, int width); >+void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width); >+void MirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width); >+void MirrorRow_C(const uint8_t* src, uint8_t* dst, int width); >+void MirrorRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void MirrorRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void MirrorRow_Any_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void MirrorRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void MirrorRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+ >+void MirrorUVRow_SSSE3(const uint8_t* src, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void MirrorUVRow_NEON(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void MirrorUVRow_NEON(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void MirrorUVRow_DSPR2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void MirrorUVRow_MSA(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void MirrorUVRow_MSA(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void MirrorUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width); >- >-void ARGBMirrorRow_AVX2(const uint8* src, uint8* dst, int width); >-void ARGBMirrorRow_SSE2(const uint8* src, uint8* dst, int width); >-void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width); >-void ARGBMirrorRow_MSA(const uint8* src, uint8* dst, int width); >-void ARGBMirrorRow_C(const uint8* src, uint8* dst, int width); >-void ARGBMirrorRow_Any_AVX2(const uint8* src, uint8* dst, int width); >-void ARGBMirrorRow_Any_SSE2(const uint8* src, uint8* dst, int width); >-void ARGBMirrorRow_Any_NEON(const uint8* src, uint8* dst, int width); >-void ARGBMirrorRow_Any_MSA(const uint8* src, uint8* dst, int width); >- >-void SplitUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width); >-void SplitUVRow_SSE2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void MirrorUVRow_C(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+ >+void ARGBMirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width); >+void ARGBMirrorRow_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void ARGBMirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width); >+void ARGBMirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width); >+void ARGBMirrorRow_C(const uint8_t* src, uint8_t* dst, int width); >+void ARGBMirrorRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBMirrorRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBMirrorRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBMirrorRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+ >+void SplitUVRow_C(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void SplitUVRow_SSE2(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void SplitUVRow_AVX2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void SplitUVRow_AVX2(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void SplitUVRow_NEON(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void SplitUVRow_NEON(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void SplitUVRow_DSPR2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void SplitUVRow_MSA(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width); >-void SplitUVRow_Any_SSE2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void SplitUVRow_Any_AVX2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void SplitUVRow_Any_NEON(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void SplitUVRow_Any_DSPR2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void SplitUVRow_Any_MSA(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void SplitUVRow_MSA(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void SplitUVRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void SplitUVRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void SplitUVRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void SplitUVRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); > >-void MergeUVRow_C(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_C(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width); >-void MergeUVRow_SSE2(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_SSE2(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width); >-void MergeUVRow_AVX2(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_AVX2(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width); >-void MergeUVRow_NEON(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_NEON(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width); >-void MergeUVRow_MSA(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_MSA(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width); >-void MergeUVRow_Any_SSE2(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_Any_SSE2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void MergeUVRow_Any_AVX2(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void MergeUVRow_Any_NEON(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void MergeUVRow_Any_MSA(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); > >-void SplitRGBRow_C(const uint8* src_rgb, >- uint8* dst_r, >- uint8* dst_g, >- uint8* dst_b, >+void SplitRGBRow_C(const uint8_t* src_rgb, >+ uint8_t* dst_r, >+ uint8_t* dst_g, >+ uint8_t* dst_b, > int width); >-void SplitRGBRow_SSSE3(const uint8* src_rgb, >- uint8* dst_r, >- uint8* dst_g, >- uint8* dst_b, >+void SplitRGBRow_SSSE3(const uint8_t* src_rgb, >+ uint8_t* dst_r, >+ uint8_t* dst_g, >+ uint8_t* dst_b, > int width); >-void SplitRGBRow_NEON(const uint8* src_rgb, >- uint8* dst_r, >- uint8* dst_g, >- uint8* dst_b, >+void SplitRGBRow_NEON(const uint8_t* src_rgb, >+ uint8_t* dst_r, >+ uint8_t* dst_g, >+ uint8_t* dst_b, > int width); >-void SplitRGBRow_Any_SSSE3(const uint8* src_rgb, >- uint8* dst_r, >- uint8* dst_g, >- uint8* dst_b, >+void SplitRGBRow_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_r, >+ uint8_t* dst_g, >+ uint8_t* dst_b, > int width); >-void SplitRGBRow_Any_NEON(const uint8* src_rgb, >- uint8* dst_r, >- uint8* dst_g, >- uint8* dst_b, >+void SplitRGBRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_r, >+ uint8_t* dst_g, >+ uint8_t* dst_b, > int width); > >-void MergeRGBRow_C(const uint8* src_r, >- const uint8* src_g, >- const uint8* src_b, >- uint8* dst_rgb, >+void MergeRGBRow_C(const uint8_t* src_r, >+ const uint8_t* src_g, >+ const uint8_t* src_b, >+ uint8_t* dst_rgb, > int width); >-void MergeRGBRow_SSSE3(const uint8* src_r, >- const uint8* src_g, >- const uint8* src_b, >- uint8* dst_rgb, >+void MergeRGBRow_SSSE3(const uint8_t* src_r, >+ const uint8_t* src_g, >+ const uint8_t* src_b, >+ uint8_t* dst_rgb, > int width); >-void MergeRGBRow_NEON(const uint8* src_r, >- const uint8* src_g, >- const uint8* src_b, >- uint8* dst_rgb, >+void MergeRGBRow_NEON(const uint8_t* src_r, >+ const uint8_t* src_g, >+ const uint8_t* src_b, >+ uint8_t* dst_rgb, > int width); >-void MergeRGBRow_Any_SSSE3(const uint8* src_r, >- const uint8* src_g, >- const uint8* src_b, >- uint8* dst_rgb, >+void MergeRGBRow_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > int width); >-void MergeRGBRow_Any_NEON(const uint8* src_r, >- const uint8* src_g, >- const uint8* src_b, >- uint8* dst_rgb, >+void MergeRGBRow_Any_NEON(const uint8_t* src_r, >+ const uint8_t* src_g, >+ const uint8_t* src_b, >+ uint8_t* dst_rgb, > int width); > >-void MergeUVRow_16_C(const uint16* src_u, >- const uint16* src_v, >- uint16* dst_uv, >+void MergeUVRow_16_C(const uint16_t* src_u, >+ const uint16_t* src_v, >+ uint16_t* dst_uv, > int scale, /* 64 for 10 bit */ > int width); >-void MergeUVRow_16_AVX2(const uint16* src_u, >- const uint16* src_v, >- uint16* dst_uv, >+void MergeUVRow_16_AVX2(const uint16_t* src_u, >+ const uint16_t* src_v, >+ uint16_t* dst_uv, > int scale, > int width); > >-void MultiplyRow_16_AVX2(const uint16* src_y, >- uint16* dst_y, >+void MultiplyRow_16_AVX2(const uint16_t* src_y, >+ uint16_t* dst_y, > int scale, > int width); >-void MultiplyRow_16_C(const uint16* src_y, uint16* dst_y, int scale, int width); >- >-void CopyRow_SSE2(const uint8* src, uint8* dst, int count); >-void CopyRow_AVX(const uint8* src, uint8* dst, int count); >-void CopyRow_ERMS(const uint8* src, uint8* dst, int count); >-void CopyRow_NEON(const uint8* src, uint8* dst, int count); >-void CopyRow_MIPS(const uint8* src, uint8* dst, int count); >-void CopyRow_C(const uint8* src, uint8* dst, int count); >-void CopyRow_Any_SSE2(const uint8* src, uint8* dst, int count); >-void CopyRow_Any_AVX(const uint8* src, uint8* dst, int count); >-void CopyRow_Any_NEON(const uint8* src, uint8* dst, int count); >- >-void CopyRow_16_C(const uint16* src, uint16* dst, int count); >- >-void ARGBCopyAlphaRow_C(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBCopyAlphaRow_SSE2(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBCopyAlphaRow_AVX2(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBCopyAlphaRow_Any_SSE2(const uint8* src_argb, >- uint8* dst_argb, >+void MultiplyRow_16_C(const uint16_t* src_y, >+ uint16_t* dst_y, >+ int scale, >+ int width); >+ >+void Convert8To16Row_C(const uint8_t* src_y, >+ uint16_t* dst_y, >+ int scale, >+ int width); >+void Convert8To16Row_SSE2(const uint8_t* src_y, >+ uint16_t* dst_y, >+ int scale, >+ int width); >+void Convert8To16Row_AVX2(const uint8_t* src_y, >+ uint16_t* dst_y, >+ int scale, >+ int width); >+void Convert8To16Row_Any_SSE2(const uint8_t* src_ptr, >+ uint16_t* dst_ptr, >+ int scale, >+ int width); >+void Convert8To16Row_Any_AVX2(const uint8_t* src_ptr, >+ uint16_t* dst_ptr, >+ int scale, >+ int width); >+ >+void Convert16To8Row_C(const uint16_t* src_y, >+ uint8_t* dst_y, >+ int scale, >+ int width); >+void Convert16To8Row_SSSE3(const uint16_t* src_y, >+ uint8_t* dst_y, >+ int scale, >+ int width); >+void Convert16To8Row_AVX2(const uint16_t* src_y, >+ uint8_t* dst_y, >+ int scale, >+ int width); >+void Convert16To8Row_Any_SSSE3(const uint16_t* src_ptr, >+ uint8_t* dst_ptr, >+ int scale, > int width); >-void ARGBCopyAlphaRow_Any_AVX2(const uint8* src_argb, >- uint8* dst_argb, >+void Convert16To8Row_Any_AVX2(const uint16_t* src_ptr, >+ uint8_t* dst_ptr, >+ int scale, >+ int width); >+ >+void CopyRow_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void CopyRow_AVX(const uint8_t* src, uint8_t* dst, int width); >+void CopyRow_ERMS(const uint8_t* src, uint8_t* dst, int width); >+void CopyRow_NEON(const uint8_t* src, uint8_t* dst, int width); >+void CopyRow_MIPS(const uint8_t* src, uint8_t* dst, int count); >+void CopyRow_C(const uint8_t* src, uint8_t* dst, int count); >+void CopyRow_Any_SSE2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void CopyRow_Any_AVX(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void CopyRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+ >+void CopyRow_16_C(const uint16_t* src, uint16_t* dst, int count); >+ >+void ARGBCopyAlphaRow_C(const uint8_t* src, uint8_t* dst, int width); >+void ARGBCopyAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void ARGBCopyAlphaRow_AVX2(const uint8_t* src, uint8_t* dst, int width); >+void ARGBCopyAlphaRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBCopyAlphaRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); > >-void ARGBExtractAlphaRow_C(const uint8* src_argb, uint8* dst_a, int width); >-void ARGBExtractAlphaRow_SSE2(const uint8* src_argb, uint8* dst_a, int width); >-void ARGBExtractAlphaRow_AVX2(const uint8* src_argb, uint8* dst_a, int width); >-void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width); >-void ARGBExtractAlphaRow_MSA(const uint8* src_argb, uint8* dst_a, int width); >-void ARGBExtractAlphaRow_Any_SSE2(const uint8* src_argb, >- uint8* dst_a, >+void ARGBExtractAlphaRow_C(const uint8_t* src_argb, uint8_t* dst_a, int width); >+void ARGBExtractAlphaRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_a, >+ int width); >+void ARGBExtractAlphaRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_a, >+ int width); >+void ARGBExtractAlphaRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_a, >+ int width); >+void ARGBExtractAlphaRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_a, >+ int width); >+void ARGBExtractAlphaRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBExtractAlphaRow_Any_AVX2(const uint8* src_argb, >- uint8* dst_a, >+void ARGBExtractAlphaRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBExtractAlphaRow_Any_NEON(const uint8* src_argb, >- uint8* dst_a, >+void ARGBExtractAlphaRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBExtractAlphaRow_Any_MSA(const uint8* src_argb, >- uint8* dst_a, >+void ARGBExtractAlphaRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); > >-void ARGBCopyYToAlphaRow_C(const uint8* src_y, uint8* dst_argb, int width); >-void ARGBCopyYToAlphaRow_SSE2(const uint8* src_y, uint8* dst_argb, int width); >-void ARGBCopyYToAlphaRow_AVX2(const uint8* src_y, uint8* dst_argb, int width); >-void ARGBCopyYToAlphaRow_Any_SSE2(const uint8* src_y, >- uint8* dst_argb, >+void ARGBCopyYToAlphaRow_C(const uint8_t* src, uint8_t* dst, int width); >+void ARGBCopyYToAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void ARGBCopyYToAlphaRow_AVX2(const uint8_t* src, uint8_t* dst, int width); >+void ARGBCopyYToAlphaRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBCopyYToAlphaRow_Any_AVX2(const uint8* src_y, >- uint8* dst_argb, >+void ARGBCopyYToAlphaRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); > >-void SetRow_C(uint8* dst, uint8 v8, int count); >-void SetRow_MSA(uint8* dst, uint8 v8, int count); >-void SetRow_X86(uint8* dst, uint8 v8, int count); >-void SetRow_ERMS(uint8* dst, uint8 v8, int count); >-void SetRow_NEON(uint8* dst, uint8 v8, int count); >-void SetRow_Any_X86(uint8* dst, uint8 v8, int count); >-void SetRow_Any_NEON(uint8* dst, uint8 v8, int count); >- >-void ARGBSetRow_C(uint8* dst_argb, uint32 v32, int count); >-void ARGBSetRow_X86(uint8* dst_argb, uint32 v32, int count); >-void ARGBSetRow_NEON(uint8* dst_argb, uint32 v32, int count); >-void ARGBSetRow_Any_NEON(uint8* dst_argb, uint32 v32, int count); >-void ARGBSetRow_MSA(uint8* dst_argb, uint32 v32, int count); >-void ARGBSetRow_Any_MSA(uint8* dst_argb, uint32 v32, int count); >+void SetRow_C(uint8_t* dst, uint8_t v8, int width); >+void SetRow_MSA(uint8_t* dst, uint8_t v8, int width); >+void SetRow_X86(uint8_t* dst, uint8_t v8, int width); >+void SetRow_ERMS(uint8_t* dst, uint8_t v8, int width); >+void SetRow_NEON(uint8_t* dst, uint8_t v8, int width); >+void SetRow_Any_X86(uint8_t* dst_ptr, uint8_t v32, int width); >+void SetRow_Any_NEON(uint8_t* dst_ptr, uint8_t v32, int width); >+ >+void ARGBSetRow_C(uint8_t* dst_argb, uint32_t v32, int width); >+void ARGBSetRow_X86(uint8_t* dst_argb, uint32_t v32, int width); >+void ARGBSetRow_NEON(uint8_t* dst, uint32_t v32, int width); >+void ARGBSetRow_Any_NEON(uint8_t* dst_ptr, uint32_t v32, int width); >+void ARGBSetRow_MSA(uint8_t* dst_argb, uint32_t v32, int width); >+void ARGBSetRow_Any_MSA(uint8_t* dst_ptr, uint32_t v32, int width); > > // ARGBShufflers for BGRAToARGB etc. >-void ARGBShuffleRow_C(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width); >-void ARGBShuffleRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >- int width); >-void ARGBShuffleRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width); >-void ARGBShuffleRow_AVX2(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width); >-void ARGBShuffleRow_NEON(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width); >-void ARGBShuffleRow_MSA(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width); >-void ARGBShuffleRow_Any_SSE2(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >- int width); >-void ARGBShuffleRow_Any_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ const uint8_t* param, > int width); >-void ARGBShuffleRow_Any_AVX2(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ const uint8_t* param, > int width); >-void ARGBShuffleRow_Any_NEON(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ const uint8_t* param, > int width); >-void ARGBShuffleRow_Any_MSA(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >- int width); >- >-void RGB24ToARGBRow_SSSE3(const uint8* src_rgb24, uint8* dst_argb, int width); >-void RAWToARGBRow_SSSE3(const uint8* src_raw, uint8* dst_argb, int width); >-void RAWToRGB24Row_SSSE3(const uint8* src_raw, uint8* dst_rgb24, int width); >-void RGB565ToARGBRow_SSE2(const uint8* src_rgb565, uint8* dst_argb, int width); >-void ARGB1555ToARGBRow_SSE2(const uint8* src_argb1555, >- uint8* dst_argb, >- int width); >-void ARGB4444ToARGBRow_SSE2(const uint8* src_argb4444, >- uint8* dst_argb, >- int width); >-void RGB565ToARGBRow_AVX2(const uint8* src_rgb565, uint8* dst_argb, int width); >-void ARGB1555ToARGBRow_AVX2(const uint8* src_argb1555, >- uint8* dst_argb, >- int width); >-void ARGB4444ToARGBRow_AVX2(const uint8* src_argb4444, >- uint8* dst_argb, >- int width); >- >-void RGB24ToARGBRow_NEON(const uint8* src_rgb24, uint8* dst_argb, int width); >-void RGB24ToARGBRow_MSA(const uint8* src_rgb24, uint8* dst_argb, int width); >-void RAWToARGBRow_NEON(const uint8* src_raw, uint8* dst_argb, int width); >-void RAWToARGBRow_MSA(const uint8* src_raw, uint8* dst_argb, int width); >-void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width); >-void RAWToRGB24Row_MSA(const uint8* src_raw, uint8* dst_rgb24, int width); >-void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width); >-void RGB565ToARGBRow_MSA(const uint8* src_rgb565, uint8* dst_argb, int width); >-void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, >- uint8* dst_argb, >- int width); >-void ARGB1555ToARGBRow_MSA(const uint8* src_argb1555, >- uint8* dst_argb, >+void ARGBShuffleRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ const uint8_t* param, >+ int width); >+ >+void RGB24ToARGBRow_SSSE3(const uint8_t* src_rgb24, >+ uint8_t* dst_argb, >+ int width); >+void RAWToARGBRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_argb, int width); >+void RAWToRGB24Row_SSSE3(const uint8_t* src_raw, uint8_t* dst_rgb24, int width); >+void RGB565ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void ARGB1555ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void ARGB4444ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void RGB565ToARGBRow_AVX2(const uint8_t* src_rgb565, >+ uint8_t* dst_argb, >+ int width); >+void ARGB1555ToARGBRow_AVX2(const uint8_t* src_argb1555, >+ uint8_t* dst_argb, >+ int width); >+void ARGB4444ToARGBRow_AVX2(const uint8_t* src_argb4444, >+ uint8_t* dst_argb, >+ int width); >+ >+void RGB24ToARGBRow_NEON(const uint8_t* src_rgb24, >+ uint8_t* dst_argb, >+ int width); >+void RGB24ToARGBRow_MSA(const uint8_t* src_rgb24, uint8_t* dst_argb, int width); >+void RAWToARGBRow_NEON(const uint8_t* src_raw, uint8_t* dst_argb, int width); >+void RAWToARGBRow_MSA(const uint8_t* src_raw, uint8_t* dst_argb, int width); >+void RAWToRGB24Row_NEON(const uint8_t* src_raw, uint8_t* dst_rgb24, int width); >+void RAWToRGB24Row_MSA(const uint8_t* src_raw, uint8_t* dst_rgb24, int width); >+void RGB565ToARGBRow_NEON(const uint8_t* src_rgb565, >+ uint8_t* dst_argb, >+ int width); >+void RGB565ToARGBRow_MSA(const uint8_t* src_rgb565, >+ uint8_t* dst_argb, >+ int width); >+void ARGB1555ToARGBRow_NEON(const uint8_t* src_argb1555, >+ uint8_t* dst_argb, >+ int width); >+void ARGB1555ToARGBRow_MSA(const uint8_t* src_argb1555, >+ uint8_t* dst_argb, > int width); >-void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, >- uint8* dst_argb, >- int width); >-void RGB24ToARGBRow_DSPR2(const uint8* src_rgb24, uint8* dst_argb, int width); >-void RAWToARGBRow_DSPR2(const uint8* src_raw, uint8* dst_argb, int width); >-void RGB565ToARGBRow_DSPR2(const uint8* src_rgb565, uint8* dst_argb, int width); >-void ARGB1555ToARGBRow_DSPR2(const uint8* src_argb1555, >- uint8* dst_argb, >- int width); >-void ARGB4444ToARGBRow_DSPR2(const uint8* src_argb4444, >- uint8* dst_argb, >- int width); >-void ARGB4444ToARGBRow_MSA(const uint8* src_argb4444, >- uint8* dst_argb, >+void ARGB4444ToARGBRow_NEON(const uint8_t* src_argb4444, >+ uint8_t* dst_argb, >+ int width); >+void ARGB4444ToARGBRow_MSA(const uint8_t* src_argb4444, >+ uint8_t* dst_argb, > int width); >-void RGB24ToARGBRow_C(const uint8* src_rgb24, uint8* dst_argb, int width); >-void RAWToARGBRow_C(const uint8* src_raw, uint8* dst_argb, int width); >-void RAWToRGB24Row_C(const uint8* src_raw, uint8* dst_rgb24, int width); >-void RGB565ToARGBRow_C(const uint8* src_rgb, uint8* dst_argb, int width); >-void ARGB1555ToARGBRow_C(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGB4444ToARGBRow_C(const uint8* src_argb, uint8* dst_argb, int width); >-void RGB24ToARGBRow_Any_SSSE3(const uint8* src_rgb24, >- uint8* dst_argb, >+void RGB24ToARGBRow_C(const uint8_t* src_rgb24, uint8_t* dst_argb, int width); >+void RAWToARGBRow_C(const uint8_t* src_raw, uint8_t* dst_argb, int width); >+void RAWToRGB24Row_C(const uint8_t* src_raw, uint8_t* dst_rgb24, int width); >+void RGB565ToARGBRow_C(const uint8_t* src_rgb565, uint8_t* dst_argb, int width); >+void ARGB1555ToARGBRow_C(const uint8_t* src_argb1555, >+ uint8_t* dst_argb, >+ int width); >+void ARGB4444ToARGBRow_C(const uint8_t* src_argb4444, >+ uint8_t* dst_argb, >+ int width); >+void AR30ToARGBRow_C(const uint8_t* src_ar30, uint8_t* dst_argb, int width); >+void AR30ToABGRRow_C(const uint8_t* src_ar30, uint8_t* dst_abgr, int width); >+void ARGBToAR30Row_C(const uint8_t* src_argb, uint8_t* dst_ar30, int width); >+void AR30ToAB30Row_C(const uint8_t* src_ar30, uint8_t* dst_ab30, int width); >+ >+void RGB24ToARGBRow_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void RAWToARGBRow_Any_SSSE3(const uint8* src_raw, uint8* dst_argb, int width); >-void RAWToRGB24Row_Any_SSSE3(const uint8* src_raw, uint8* dst_rgb24, int width); >+void RAWToARGBRow_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void RAWToRGB24Row_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); > >-void RGB565ToARGBRow_Any_SSE2(const uint8* src_rgb565, >- uint8* dst_argb, >+void RGB565ToARGBRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGB1555ToARGBRow_Any_SSE2(const uint8* src_argb1555, >- uint8* dst_argb, >+void ARGB1555ToARGBRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGB4444ToARGBRow_Any_SSE2(const uint8* src_argb4444, >- uint8* dst_argb, >+void ARGB4444ToARGBRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void RGB565ToARGBRow_Any_AVX2(const uint8* src_rgb565, >- uint8* dst_argb, >+void RGB565ToARGBRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGB1555ToARGBRow_Any_AVX2(const uint8* src_argb1555, >- uint8* dst_argb, >+void ARGB1555ToARGBRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGB4444ToARGBRow_Any_AVX2(const uint8* src_argb4444, >- uint8* dst_argb, >+void ARGB4444ToARGBRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); > >-void RGB24ToARGBRow_Any_NEON(const uint8* src_rgb24, >- uint8* dst_argb, >+void RGB24ToARGBRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void RGB24ToARGBRow_Any_MSA(const uint8* src_rgb24, uint8* dst_argb, int width); >-void RAWToARGBRow_Any_NEON(const uint8* src_raw, uint8* dst_argb, int width); >-void RAWToARGBRow_Any_MSA(const uint8* src_raw, uint8* dst_argb, int width); >-void RAWToRGB24Row_Any_NEON(const uint8* src_raw, uint8* dst_rgb24, int width); >-void RAWToRGB24Row_Any_MSA(const uint8* src_raw, uint8* dst_rgb24, int width); >-void RGB565ToARGBRow_Any_NEON(const uint8* src_rgb565, >- uint8* dst_argb, >+void RGB24ToARGBRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void RAWToARGBRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RAWToARGBRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RAWToRGB24Row_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void RAWToRGB24Row_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void RGB565ToARGBRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void RGB565ToARGBRow_Any_MSA(const uint8* src_rgb565, >- uint8* dst_argb, >+void RGB565ToARGBRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGB1555ToARGBRow_Any_NEON(const uint8* src_argb1555, >- uint8* dst_argb, >+void ARGB1555ToARGBRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGB1555ToARGBRow_Any_MSA(const uint8* src_argb1555, >- uint8* dst_argb, >+void ARGB1555ToARGBRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGB4444ToARGBRow_Any_NEON(const uint8* src_argb4444, >- uint8* dst_argb, >+void ARGB4444ToARGBRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void RGB24ToARGBRow_Any_DSPR2(const uint8* src_rgb24, >- uint8* dst_argb, >- int width); >-void RAWToARGBRow_Any_DSPR2(const uint8* src_raw, uint8* dst_argb, int width); >-void RGB565ToARGBRow_Any_DSPR2(const uint8* src_rgb565, >- uint8* dst_argb, >- int width); >-void ARGB1555ToARGBRow_Any_DSPR2(const uint8* src_argb1555, >- uint8* dst_argb, >- int width); >-void ARGB4444ToARGBRow_Any_DSPR2(const uint8* src_argb4444, >- uint8* dst_argb, >- int width); > >-void ARGB4444ToARGBRow_Any_MSA(const uint8* src_argb4444, >- uint8* dst_argb, >+void ARGB4444ToARGBRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); > >-void ARGBToRGB24Row_SSSE3(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRAWRow_SSSE3(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRGB565Row_SSE2(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB1555Row_SSE2(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB4444Row_SSE2(const uint8* src_argb, uint8* dst_rgb, int width); >- >-void ARGBToRGB565DitherRow_C(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB24Row_SSSE3(const uint8_t* src, uint8_t* dst, int width); >+void ARGBToRAWRow_SSSE3(const uint8_t* src, uint8_t* dst, int width); >+void ARGBToRGB565Row_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void ARGBToARGB1555Row_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void ARGBToARGB4444Row_SSE2(const uint8_t* src, uint8_t* dst, int width); >+void ABGRToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width); >+void ARGBToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width); >+ >+void ARGBToRGB565DitherRow_C(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ const uint32_t dither4, > int width); >-void ARGBToRGB565DitherRow_SSE2(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_SSE2(const uint8_t* src, >+ uint8_t* dst, >+ const uint32_t dither4, > int width); >-void ARGBToRGB565DitherRow_AVX2(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_AVX2(const uint8_t* src, >+ uint8_t* dst, >+ const uint32_t dither4, > int width); > >-void ARGBToRGB565Row_AVX2(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB1555Row_AVX2(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB4444Row_AVX2(const uint8* src_argb, uint8* dst_rgb, int width); >- >-void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB1555Row_NEON(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB4444Row_NEON(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRGB565DitherRow_NEON(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB565Row_AVX2(const uint8_t* src_argb, uint8_t* dst_rgb, int width); >+void ARGBToARGB1555Row_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ int width); >+void ARGBToARGB4444Row_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ int width); >+void ABGRToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width); >+void ARGBToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width); >+ >+void ARGBToRGB24Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_rgb24, >+ int width); >+void ARGBToRAWRow_NEON(const uint8_t* src_argb, uint8_t* dst_raw, int width); >+void ARGBToRGB565Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_rgb565, >+ int width); >+void ARGBToARGB1555Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb1555, >+ int width); >+void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb4444, >+ int width); >+void ARGBToRGB565DitherRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ const uint32_t dither4, > int width); >-void ARGBToRGB24Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRAWRow_MSA(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRGB565Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB1555Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB4444Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRGB565DitherRow_MSA(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB24Row_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width); >+void ARGBToRAWRow_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width); >+void ARGBToRGB565Row_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width); >+void ARGBToARGB1555Row_MSA(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ int width); >+void ARGBToARGB4444Row_MSA(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ int width); >+void ARGBToRGB565DitherRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ const uint32_t dither4, > int width); > >-void ARGBToRGBARow_C(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRGB24Row_C(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRAWRow_C(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRGB565Row_C(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB1555Row_C(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB4444Row_C(const uint8* src_argb, uint8* dst_rgb, int width); >- >-void J400ToARGBRow_SSE2(const uint8* src_y, uint8* dst_argb, int width); >-void J400ToARGBRow_AVX2(const uint8* src_y, uint8* dst_argb, int width); >-void J400ToARGBRow_NEON(const uint8* src_y, uint8* dst_argb, int width); >-void J400ToARGBRow_MSA(const uint8* src_y, uint8* dst_argb, int width); >-void J400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width); >-void J400ToARGBRow_Any_SSE2(const uint8* src_y, uint8* dst_argb, int width); >-void J400ToARGBRow_Any_AVX2(const uint8* src_y, uint8* dst_argb, int width); >-void J400ToARGBRow_Any_NEON(const uint8* src_y, uint8* dst_argb, int width); >-void J400ToARGBRow_Any_MSA(const uint8* src_y, uint8* dst_argb, int width); >- >-void I444ToARGBRow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void ARGBToRGBARow_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); >+void ARGBToRGB24Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); >+void ARGBToRAWRow_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); >+void ARGBToRGB565Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); >+void ARGBToARGB1555Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); >+void ARGBToARGB4444Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); >+void ABGRToAR30Row_C(const uint8_t* src_abgr, uint8_t* dst_ar30, int width); >+void ARGBToAR30Row_C(const uint8_t* src_argb, uint8_t* dst_ar30, int width); >+ >+void J400ToARGBRow_SSE2(const uint8_t* src_y, uint8_t* dst_argb, int width); >+void J400ToARGBRow_AVX2(const uint8_t* src_y, uint8_t* dst_argb, int width); >+void J400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width); >+void J400ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, int width); >+void J400ToARGBRow_C(const uint8_t* src_y, uint8_t* dst_argb, int width); >+void J400ToARGBRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void J400ToARGBRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void J400ToARGBRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void J400ToARGBRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+ >+void I444ToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I422ToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I422ToAR30Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I210ToAR30Row_C(const uint16_t* src_y, >+ const uint16_t* src_u, >+ const uint16_t* src_v, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I210ToARGBRow_C(const uint16_t* src_y, >+ const uint16_t* src_u, >+ const uint16_t* src_v, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width); >-void I422AlphaToARGBRow_C(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+void I422AlphaToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ const uint8_t* src_a, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToARGBRow_C(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToRGB565Row_C(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToRGB565Row_C(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width); >-void NV21ToARGBRow_C(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV21ToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width); >-void YUY2ToARGBRow_C(const uint8* src_yuy2, >- uint8* dst_argb, >+void NV12ToRGB24Row_C(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void NV21ToRGB24Row_C(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void YUY2ToARGBRow_C(const uint8_t* src_yuy2, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width); >-void UYVYToARGBRow_C(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_C(const uint8_t* src_uyvy, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGBARow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToRGBARow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB24Row_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb24, >+void I422ToRGB24Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB4444Row_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB4444Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB1555Row_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB1555Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB565Row_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb565, >+void I422ToRGB565Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void I422ToARGBRow_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGBARow_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToRGBARow_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I444ToARGBRow_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I444ToARGBRow_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I444ToARGBRow_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I444ToARGBRow_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, >+ const struct YuvConstants* yuvconstants, >+ int width); >+ >+void I422ToAR30Row_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ar30, > const struct YuvConstants* yuvconstants, > int width); >-void I422AlphaToARGBRow_SSSE3(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+void I210ToAR30Row_SSSE3(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_ar30, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I210ToARGBRow_SSSE3(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_argb, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I422ToAR30Row_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ar30, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I210ToARGBRow_AVX2(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_argb, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I210ToAR30Row_AVX2(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_ar30, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I422AlphaToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422AlphaToARGBRow_AVX2(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+void I422AlphaToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void NV12ToARGBRow_SSSE3(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToARGBRow_AVX2(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToRGB565Row_SSSE3(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToRGB565Row_SSSE3(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToRGB565Row_AVX2(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToRGB565Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width); >-void NV21ToARGBRow_SSSE3(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV21ToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* vu_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void NV21ToARGBRow_AVX2(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV21ToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* vu_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void YUY2ToARGBRow_SSSE3(const uint8* src_yuy2, >- uint8* dst_argb, >+void YUY2ToARGBRow_SSSE3(const uint8_t* yuy2_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void UYVYToARGBRow_SSSE3(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_SSSE3(const uint8_t* uyvy_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void YUY2ToARGBRow_AVX2(const uint8* src_yuy2, >- uint8* dst_argb, >+void YUY2ToARGBRow_AVX2(const uint8_t* yuy2_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void UYVYToARGBRow_AVX2(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_AVX2(const uint8_t* uyvy_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGBARow_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToRGBARow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_rgba, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB4444Row_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGB4444Row_SSSE3(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB4444Row_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGB4444Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB1555Row_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGB1555Row_SSSE3(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB1555Row_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGB1555Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB565Row_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToRGB565Row_SSSE3(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB565Row_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToRGB565Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB24Row_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb24, >+void I422ToRGB24Row_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_rgb24, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB24Row_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb24, >+void I422ToRGB24Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb24, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_Any_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGBARow_Any_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToRGBARow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I444ToARGBRow_Any_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I444ToARGBRow_Any_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_Any_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I422ToAR30Row_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I210ToAR30Row_Any_SSSE3(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422AlphaToARGBRow_Any_SSSE3(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+void I210ToARGBRow_Any_SSSE3(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_ptr, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I422ToAR30Row_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I210ToARGBRow_Any_AVX2(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_ptr, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I210ToAR30Row_Any_AVX2(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_ptr, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void I422AlphaToARGBRow_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422AlphaToARGBRow_Any_AVX2(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+void I422AlphaToARGBRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToARGBRow_Any_SSSE3(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToARGBRow_Any_AVX2(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV21ToARGBRow_Any_SSSE3(const uint8* src_y, >- const uint8* src_vu, >- uint8* dst_argb, >+void NV21ToARGBRow_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV21ToARGBRow_Any_AVX2(const uint8* src_y, >- const uint8* src_vu, >- uint8* dst_argb, >+void NV21ToARGBRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToRGB565Row_Any_SSSE3(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToRGB565Row_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToRGB565Row_Any_AVX2(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToRGB565Row_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void YUY2ToARGBRow_Any_SSSE3(const uint8* src_yuy2, >- uint8* dst_argb, >+void YUY2ToARGBRow_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void UYVYToARGBRow_Any_SSSE3(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void YUY2ToARGBRow_Any_AVX2(const uint8* src_yuy2, >- uint8* dst_argb, >+void YUY2ToARGBRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void UYVYToARGBRow_Any_AVX2(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGBARow_Any_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToRGBARow_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB4444Row_Any_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToARGB4444Row_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB4444Row_Any_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToARGB4444Row_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB1555Row_Any_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToARGB1555Row_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB1555Row_Any_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToARGB1555Row_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB565Row_Any_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToRGB565Row_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB565Row_Any_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToRGB565Row_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB24Row_Any_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToRGB24Row_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB24Row_Any_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToRGB24Row_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); > >-void I400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width); >-void I400ToARGBRow_SSE2(const uint8* src_y, uint8* dst_argb, int width); >-void I400ToARGBRow_AVX2(const uint8* src_y, uint8* dst_argb, int width); >-void I400ToARGBRow_NEON(const uint8* src_y, uint8* dst_argb, int width); >-void I400ToARGBRow_MSA(const uint8* src_y, uint8* dst_argb, int width); >-void I400ToARGBRow_Any_SSE2(const uint8* src_y, uint8* dst_argb, int width); >-void I400ToARGBRow_Any_AVX2(const uint8* src_y, uint8* dst_argb, int width); >-void I400ToARGBRow_Any_NEON(const uint8* src_y, uint8* dst_argb, int width); >-void I400ToARGBRow_Any_MSA(const uint8* src_y, uint8* dst_argb, int width); >+void I400ToARGBRow_C(const uint8_t* src_y, uint8_t* rgb_buf, int width); >+void I400ToARGBRow_SSE2(const uint8_t* y_buf, uint8_t* dst_argb, int width); >+void I400ToARGBRow_AVX2(const uint8_t* y_buf, uint8_t* dst_argb, int width); >+void I400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width); >+void I400ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, int width); >+void I400ToARGBRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void I400ToARGBRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void I400ToARGBRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void I400ToARGBRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); > > // ARGB preattenuated alpha blend. >-void ARGBBlendRow_SSSE3(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBBlendRow_SSSE3(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBBlendRow_NEON(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBBlendRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBBlendRow_MSA(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBBlendRow_MSA(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBBlendRow_C(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBBlendRow_C(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); > > // Unattenuated planar alpha blend. >-void BlendPlaneRow_SSSE3(const uint8* src0, >- const uint8* src1, >- const uint8* alpha, >- uint8* dst, >- int width); >-void BlendPlaneRow_Any_SSSE3(const uint8* src0, >- const uint8* src1, >- const uint8* alpha, >- uint8* dst, >+void BlendPlaneRow_SSSE3(const uint8_t* src0, >+ const uint8_t* src1, >+ const uint8_t* alpha, >+ uint8_t* dst, >+ int width); >+void BlendPlaneRow_Any_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > int width); >-void BlendPlaneRow_AVX2(const uint8* src0, >- const uint8* src1, >- const uint8* alpha, >- uint8* dst, >+void BlendPlaneRow_AVX2(const uint8_t* src0, >+ const uint8_t* src1, >+ const uint8_t* alpha, >+ uint8_t* dst, > int width); >-void BlendPlaneRow_Any_AVX2(const uint8* src0, >- const uint8* src1, >- const uint8* alpha, >- uint8* dst, >- int width); >-void BlendPlaneRow_C(const uint8* src0, >- const uint8* src1, >- const uint8* alpha, >- uint8* dst, >+void BlendPlaneRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, >+ int width); >+void BlendPlaneRow_C(const uint8_t* src0, >+ const uint8_t* src1, >+ const uint8_t* alpha, >+ uint8_t* dst, > int width); > > // ARGB multiply images. Same API as Blend, but these require > // pointer and width alignment for SSE2. >-void ARGBMultiplyRow_C(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_C(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBMultiplyRow_SSE2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_SSE2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBMultiplyRow_Any_SSE2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_Any_SSE2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void ARGBMultiplyRow_AVX2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_AVX2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBMultiplyRow_Any_AVX2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void ARGBMultiplyRow_NEON(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBMultiplyRow_Any_NEON(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void ARGBMultiplyRow_MSA(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_MSA(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBMultiplyRow_Any_MSA(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); > > // ARGB add images. >-void ARGBAddRow_C(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_C(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBAddRow_SSE2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_SSE2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBAddRow_Any_SSE2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_Any_SSE2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void ARGBAddRow_AVX2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_AVX2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBAddRow_Any_AVX2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void ARGBAddRow_NEON(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBAddRow_Any_NEON(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void ARGBAddRow_MSA(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_MSA(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBAddRow_Any_MSA(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); > > // ARGB subtract images. Same API as Blend, but these require > // pointer and width alignment for SSE2. >-void ARGBSubtractRow_C(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_C(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBSubtractRow_SSE2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_SSE2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBSubtractRow_Any_SSE2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_Any_SSE2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void ARGBSubtractRow_AVX2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_AVX2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBSubtractRow_Any_AVX2(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void ARGBSubtractRow_NEON(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBSubtractRow_Any_NEON(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void ARGBSubtractRow_MSA(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_MSA(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width); >-void ARGBSubtractRow_Any_MSA(const uint8* src_argb, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); > >-void ARGBToRGB24Row_Any_SSSE3(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRAWRow_Any_SSSE3(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRGB565Row_Any_SSE2(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB1555Row_Any_SSE2(const uint8* src_argb, >- uint8* dst_rgb, >+void ARGBToRGB24Row_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBToRAWRow_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBToRGB565Row_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBToARGB1555Row_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBToARGB4444Row_Any_SSE2(const uint8* src_argb, >- uint8* dst_rgb, >+void ARGBToARGB4444Row_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >+void ABGRToAR30Row_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBToAR30Row_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); > >-void ARGBToRGB565DitherRow_Any_SSE2(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ const uint32_t param, > int width); >-void ARGBToRGB565DitherRow_Any_AVX2(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ const uint32_t param, > int width); > >-void ARGBToRGB565Row_Any_AVX2(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB1555Row_Any_AVX2(const uint8* src_argb, >- uint8* dst_rgb, >+void ARGBToRGB565Row_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBToARGB1555Row_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBToARGB4444Row_Any_AVX2(const uint8* src_argb, >- uint8* dst_rgb, >+void ARGBToARGB4444Row_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >+void ABGRToAR30Row_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBToAR30Row_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); > >-void ARGBToRGB24Row_Any_NEON(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRAWRow_Any_NEON(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRGB565Row_Any_NEON(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB1555Row_Any_NEON(const uint8* src_argb, >- uint8* dst_rgb, >+void ARGBToRGB24Row_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBToRAWRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ARGBToRGB565Row_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBToARGB1555Row_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBToARGB4444Row_Any_NEON(const uint8* src_argb, >- uint8* dst_rgb, >+void ARGBToARGB4444Row_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBToRGB565DitherRow_Any_NEON(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ const uint32_t param, > int width); >-void ARGBToRGB24Row_Any_MSA(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRAWRow_Any_MSA(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToRGB565Row_Any_MSA(const uint8* src_argb, uint8* dst_rgb, int width); >-void ARGBToARGB1555Row_Any_MSA(const uint8* src_argb, >- uint8* dst_rgb, >+void ARGBToRGB24Row_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBToRAWRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void ARGBToRGB565Row_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ int width); >+void ARGBToARGB1555Row_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBToARGB4444Row_Any_MSA(const uint8* src_argb, >- uint8* dst_rgb, >+void ARGBToARGB4444Row_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBToRGB565DitherRow_Any_MSA(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, >+ const uint32_t param, > int width); > >-void I444ToARGBRow_Any_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_Any_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422AlphaToARGBRow_Any_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- const uint8* src_a, >- uint8* dst_argb, >+void I422AlphaToARGBRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGBARow_Any_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToRGBARow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB24Row_Any_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToRGB24Row_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB4444Row_Any_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGB4444Row_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB1555Row_Any_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGB1555Row_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB565Row_Any_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToRGB565Row_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToARGBRow_Any_NEON(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV21ToARGBRow_Any_NEON(const uint8* src_y, >- const uint8* src_vu, >- uint8* dst_argb, >+void NV21ToARGBRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToRGB565Row_Any_NEON(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToRGB24Row_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void NV21ToRGB24Row_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, >+ const struct YuvConstants* yuvconstants, >+ int width); >+void NV12ToRGB565Row_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void YUY2ToARGBRow_Any_NEON(const uint8* src_yuy2, >- uint8* dst_argb, >+void YUY2ToARGBRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void UYVYToARGBRow_Any_NEON(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I444ToARGBRow_Any_DSPR2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void I422ToARGB4444Row_Any_DSPR2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void I422ToARGBRow_Any_DSPR2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void I422ToARGBRow_DSPR2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void I422ToARGB1555Row_Any_DSPR2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void I411ToARGBRow_Any_DSPR2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void NV12ToARGBRow_Any_DSPR2(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void I422ToARGBRow_DSPR2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width); >-void I444ToARGBRow_Any_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGBRow_Any_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGBARow_Any_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToRGBARow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422AlphaToARGBRow_Any_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- const uint8* src_a, >- uint8* dst_argb, >+void I422AlphaToARGBRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB24Row_Any_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb24, >+void I422ToRGB24Row_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToRGB565Row_Any_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb565, >+void I422ToRGB565Row_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB4444Row_Any_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB4444Row_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void I422ToARGB1555Row_Any_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb1555, >+void I422ToARGB1555Row_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToARGBRow_Any_MSA(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV12ToRGB565Row_Any_MSA(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToRGB565Row_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void NV21ToARGBRow_Any_MSA(const uint8* src_y, >- const uint8* src_vu, >- uint8* dst_argb, >+void NV21ToARGBRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void YUY2ToARGBRow_Any_MSA(const uint8* src_yuy2, >- uint8* dst_argb, >+void YUY2ToARGBRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); >-void UYVYToARGBRow_Any_MSA(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > const struct YuvConstants* yuvconstants, > int width); > >-void YUY2ToYRow_AVX2(const uint8* src_yuy2, uint8* dst_y, int width); >-void YUY2ToUVRow_AVX2(const uint8* src_yuy2, >+void YUY2ToYRow_AVX2(const uint8_t* src_yuy2, uint8_t* dst_y, int width); >+void YUY2ToUVRow_AVX2(const uint8_t* src_yuy2, > int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToUV422Row_AVX2(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_AVX2(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToYRow_SSE2(const uint8* src_yuy2, uint8* dst_y, int width); >-void YUY2ToUVRow_SSE2(const uint8* src_yuy2, >+void YUY2ToYRow_SSE2(const uint8_t* src_yuy2, uint8_t* dst_y, int width); >+void YUY2ToUVRow_SSE2(const uint8_t* src_yuy2, > int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToUV422Row_SSE2(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_SSE2(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width); >-void YUY2ToUVRow_NEON(const uint8* src_yuy2, >+void YUY2ToYRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_y, int width); >+void YUY2ToUVRow_NEON(const uint8_t* src_yuy2, > int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToUV422Row_NEON(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void YUY2ToYRow_MSA(const uint8* src_yuy2, uint8* dst_y, int width); >-void YUY2ToUVRow_MSA(const uint8* src_yuy2, >- int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_NEON(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void YUY2ToYRow_MSA(const uint8_t* src_yuy2, uint8_t* dst_y, int width); >+void YUY2ToUVRow_MSA(const uint8_t* src_yuy2, >+ int src_stride_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToUV422Row_MSA(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_MSA(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToYRow_C(const uint8* src_yuy2, uint8* dst_y, int width); >-void YUY2ToUVRow_C(const uint8* src_yuy2, >- int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToYRow_C(const uint8_t* src_yuy2, uint8_t* dst_y, int width); >+void YUY2ToUVRow_C(const uint8_t* src_yuy2, >+ int src_stride_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToUV422Row_C(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_C(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToYRow_Any_AVX2(const uint8* src_yuy2, uint8* dst_y, int width); >-void YUY2ToUVRow_Any_AVX2(const uint8* src_yuy2, >- int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToYRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void YUY2ToUVRow_Any_AVX2(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToUV422Row_Any_AVX2(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToYRow_Any_SSE2(const uint8* src_yuy2, uint8* dst_y, int width); >-void YUY2ToUVRow_Any_SSE2(const uint8* src_yuy2, >- int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToYRow_Any_SSE2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void YUY2ToUVRow_Any_SSE2(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToUV422Row_Any_SSE2(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToYRow_Any_NEON(const uint8* src_yuy2, uint8* dst_y, int width); >-void YUY2ToUVRow_Any_NEON(const uint8* src_yuy2, >- int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void YUY2ToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToUV422Row_Any_NEON(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void YUY2ToYRow_Any_MSA(const uint8* src_yuy2, uint8* dst_y, int width); >-void YUY2ToUVRow_Any_MSA(const uint8* src_yuy2, >- int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void YUY2ToUV422Row_Any_MSA(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void UYVYToYRow_AVX2(const uint8* src_uyvy, uint8* dst_y, int width); >-void UYVYToUVRow_AVX2(const uint8* src_uyvy, >+void YUY2ToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void YUY2ToUVRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void YUY2ToUV422Row_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void UYVYToYRow_AVX2(const uint8_t* src_uyvy, uint8_t* dst_y, int width); >+void UYVYToUVRow_AVX2(const uint8_t* src_uyvy, > int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToUV422Row_AVX2(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_AVX2(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToYRow_SSE2(const uint8* src_uyvy, uint8* dst_y, int width); >-void UYVYToUVRow_SSE2(const uint8* src_uyvy, >+void UYVYToYRow_SSE2(const uint8_t* src_uyvy, uint8_t* dst_y, int width); >+void UYVYToUVRow_SSE2(const uint8_t* src_uyvy, > int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToUV422Row_SSE2(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_SSE2(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToYRow_AVX2(const uint8* src_uyvy, uint8* dst_y, int width); >-void UYVYToUVRow_AVX2(const uint8* src_uyvy, >+void UYVYToYRow_AVX2(const uint8_t* src_uyvy, uint8_t* dst_y, int width); >+void UYVYToUVRow_AVX2(const uint8_t* src_uyvy, > int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToUV422Row_AVX2(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_AVX2(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width); >-void UYVYToUVRow_NEON(const uint8* src_uyvy, >+void UYVYToYRow_NEON(const uint8_t* src_uyvy, uint8_t* dst_y, int width); >+void UYVYToUVRow_NEON(const uint8_t* src_uyvy, > int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToUV422Row_NEON(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >- int width); >-void UYVYToYRow_MSA(const uint8* src_uyvy, uint8* dst_y, int width); >-void UYVYToUVRow_MSA(const uint8* src_uyvy, >- int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_NEON(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width); >+void UYVYToYRow_MSA(const uint8_t* src_uyvy, uint8_t* dst_y, int width); >+void UYVYToUVRow_MSA(const uint8_t* src_uyvy, >+ int src_stride_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToUV422Row_MSA(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_MSA(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); > >-void UYVYToYRow_C(const uint8* src_uyvy, uint8* dst_y, int width); >-void UYVYToUVRow_C(const uint8* src_uyvy, >- int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToYRow_C(const uint8_t* src_uyvy, uint8_t* dst_y, int width); >+void UYVYToUVRow_C(const uint8_t* src_uyvy, >+ int src_stride_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToUV422Row_C(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_C(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToYRow_Any_AVX2(const uint8* src_uyvy, uint8* dst_y, int width); >-void UYVYToUVRow_Any_AVX2(const uint8* src_uyvy, >- int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToYRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void UYVYToUVRow_Any_AVX2(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToUV422Row_Any_AVX2(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToYRow_Any_SSE2(const uint8* src_uyvy, uint8* dst_y, int width); >-void UYVYToUVRow_Any_SSE2(const uint8* src_uyvy, >- int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToYRow_Any_SSE2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void UYVYToUVRow_Any_SSE2(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToUV422Row_Any_SSE2(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToYRow_Any_NEON(const uint8* src_uyvy, uint8* dst_y, int width); >-void UYVYToUVRow_Any_NEON(const uint8* src_uyvy, >- int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void UYVYToUVRow_Any_NEON(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToUV422Row_Any_NEON(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToYRow_Any_MSA(const uint8* src_uyvy, uint8* dst_y, int width); >-void UYVYToUVRow_Any_MSA(const uint8* src_uyvy, >- int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); >+void UYVYToUVRow_Any_MSA(const uint8_t* src_ptr, >+ int src_stride_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); >-void UYVYToUV422Row_Any_MSA(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width); > >-void I422ToYUY2Row_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_yuy2, >+void I422ToYUY2Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_frame, > int width); >-void I422ToUYVYRow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uyvy, >+void I422ToUYVYRow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_frame, > int width); >-void I422ToYUY2Row_SSE2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_yuy2, >+void I422ToYUY2Row_SSE2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_yuy2, > int width); >-void I422ToUYVYRow_SSE2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uyvy, >+void I422ToUYVYRow_SSE2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uyvy, > int width); >-void I422ToYUY2Row_Any_SSE2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_yuy2, >- int width); >-void I422ToUYVYRow_Any_SSE2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uyvy, >- int width); >-void I422ToYUY2Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_yuy2, >+void I422ToYUY2Row_Any_SSE2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, >+ int width); >+void I422ToUYVYRow_Any_SSE2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, >+ int width); >+void I422ToYUY2Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_yuy2, >+ int width); >+void I422ToUYVYRow_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uyvy, >+ int width); >+void I422ToYUY2Row_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, >+ int width); >+void I422ToUYVYRow_Any_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, >+ int width); >+void I422ToYUY2Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_yuy2, > int width); >-void I422ToUYVYRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uyvy, >+void I422ToUYVYRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uyvy, > int width); >-void I422ToYUY2Row_Any_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_yuy2, >- int width); >-void I422ToUYVYRow_Any_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uyvy, >- int width); >-void I422ToYUY2Row_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_yuy2, >+void I422ToYUY2Row_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, >+ int width); >+void I422ToUYVYRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, >+ int width); >+void I422ToYUY2Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_yuy2, > int width); >-void I422ToUYVYRow_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uyvy, >+void I422ToUYVYRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uyvy, > int width); >-void I422ToYUY2Row_Any_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_yuy2, >+void I422ToYUY2Row_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > int width); >-void I422ToUYVYRow_Any_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uyvy, >+void I422ToUYVYRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ptr, > int width); > > // Effects related row functions. >-void ARGBAttenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBAttenuateRow_SSSE3(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBAttenuateRow_AVX2(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBAttenuateRow_NEON(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBAttenuateRow_MSA(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBAttenuateRow_Any_SSE2(const uint8* src_argb, >- uint8* dst_argb, >- int width); >-void ARGBAttenuateRow_Any_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBAttenuateRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width); >+void ARGBAttenuateRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width); >+void ARGBAttenuateRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width); >+void ARGBAttenuateRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width); >+void ARGBAttenuateRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width); >+void ARGBAttenuateRow_Any_SSSE3(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBAttenuateRow_Any_AVX2(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBAttenuateRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBAttenuateRow_Any_NEON(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBAttenuateRow_Any_NEON(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBAttenuateRow_Any_MSA(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBAttenuateRow_Any_MSA(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); > > // Inverse table for unattenuate, shared by C and SSE2. >-extern const uint32 fixed_invtbl8[256]; >-void ARGBUnattenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBUnattenuateRow_SSE2(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBUnattenuateRow_AVX2(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBUnattenuateRow_Any_SSE2(const uint8* src_argb, >- uint8* dst_argb, >+extern const uint32_t fixed_invtbl8[256]; >+void ARGBUnattenuateRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width); >+void ARGBUnattenuateRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width); >+void ARGBUnattenuateRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width); >+void ARGBUnattenuateRow_Any_SSE2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); >-void ARGBUnattenuateRow_Any_AVX2(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBUnattenuateRow_Any_AVX2(const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > int width); > >-void ARGBGrayRow_C(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBGrayRow_SSSE3(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBGrayRow_NEON(const uint8* src_argb, uint8* dst_argb, int width); >-void ARGBGrayRow_MSA(const uint8* src_argb, uint8* dst_argb, int width); >+void ARGBGrayRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width); >+void ARGBGrayRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_argb, int width); >+void ARGBGrayRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width); >+void ARGBGrayRow_MSA(const uint8_t* src_argb, uint8_t* dst_argb, int width); > >-void ARGBSepiaRow_C(uint8* dst_argb, int width); >-void ARGBSepiaRow_SSSE3(uint8* dst_argb, int width); >-void ARGBSepiaRow_NEON(uint8* dst_argb, int width); >-void ARGBSepiaRow_MSA(uint8* dst_argb, int width); >+void ARGBSepiaRow_C(uint8_t* dst_argb, int width); >+void ARGBSepiaRow_SSSE3(uint8_t* dst_argb, int width); >+void ARGBSepiaRow_NEON(uint8_t* dst_argb, int width); >+void ARGBSepiaRow_MSA(uint8_t* dst_argb, int width); > >-void ARGBColorMatrixRow_C(const uint8* src_argb, >- uint8* dst_argb, >- const int8* matrix_argb, >+void ARGBColorMatrixRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const int8_t* matrix_argb, > int width); >-void ARGBColorMatrixRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >- const int8* matrix_argb, >+void ARGBColorMatrixRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const int8_t* matrix_argb, > int width); >-void ARGBColorMatrixRow_NEON(const uint8* src_argb, >- uint8* dst_argb, >- const int8* matrix_argb, >+void ARGBColorMatrixRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const int8_t* matrix_argb, > int width); >-void ARGBColorMatrixRow_MSA(const uint8* src_argb, >- uint8* dst_argb, >- const int8* matrix_argb, >+void ARGBColorMatrixRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const int8_t* matrix_argb, > int width); > >-void ARGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width); >-void ARGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb, int width); >+void ARGBColorTableRow_C(uint8_t* dst_argb, >+ const uint8_t* table_argb, >+ int width); >+void ARGBColorTableRow_X86(uint8_t* dst_argb, >+ const uint8_t* table_argb, >+ int width); > >-void RGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width); >-void RGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb, int width); >+void RGBColorTableRow_C(uint8_t* dst_argb, >+ const uint8_t* table_argb, >+ int width); >+void RGBColorTableRow_X86(uint8_t* dst_argb, >+ const uint8_t* table_argb, >+ int width); > >-void ARGBQuantizeRow_C(uint8* dst_argb, >+void ARGBQuantizeRow_C(uint8_t* dst_argb, > int scale, > int interval_size, > int interval_offset, > int width); >-void ARGBQuantizeRow_SSE2(uint8* dst_argb, >+void ARGBQuantizeRow_SSE2(uint8_t* dst_argb, > int scale, > int interval_size, > int interval_offset, > int width); >-void ARGBQuantizeRow_NEON(uint8* dst_argb, >+void ARGBQuantizeRow_NEON(uint8_t* dst_argb, > int scale, > int interval_size, > int interval_offset, > int width); >-void ARGBQuantizeRow_MSA(uint8* dst_argb, >+void ARGBQuantizeRow_MSA(uint8_t* dst_argb, > int scale, > int interval_size, > int interval_offset, > int width); > >-void ARGBShadeRow_C(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBShadeRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- uint32 value); >-void ARGBShadeRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >+ uint32_t value); >+void ARGBShadeRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- uint32 value); >-void ARGBShadeRow_NEON(const uint8* src_argb, >- uint8* dst_argb, >+ uint32_t value); >+void ARGBShadeRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- uint32 value); >-void ARGBShadeRow_MSA(const uint8* src_argb, >- uint8* dst_argb, >+ uint32_t value); >+void ARGBShadeRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- uint32 value); >+ uint32_t value); > > // Used for blur. >-void CumulativeSumToAverageRow_SSE2(const int32* topleft, >- const int32* botleft, >+void CumulativeSumToAverageRow_SSE2(const int32_t* topleft, >+ const int32_t* botleft, > int width, > int area, >- uint8* dst, >+ uint8_t* dst, > int count); >-void ComputeCumulativeSumRow_SSE2(const uint8* row, >- int32* cumsum, >- const int32* previous_cumsum, >+void ComputeCumulativeSumRow_SSE2(const uint8_t* row, >+ int32_t* cumsum, >+ const int32_t* previous_cumsum, > int width); > >-void CumulativeSumToAverageRow_C(const int32* topleft, >- const int32* botleft, >- int width, >+void CumulativeSumToAverageRow_C(const int32_t* tl, >+ const int32_t* bl, >+ int w, > int area, >- uint8* dst, >+ uint8_t* dst, > int count); >-void ComputeCumulativeSumRow_C(const uint8* row, >- int32* cumsum, >- const int32* previous_cumsum, >+void ComputeCumulativeSumRow_C(const uint8_t* row, >+ int32_t* cumsum, >+ const int32_t* previous_cumsum, > int width); > > LIBYUV_API >-void ARGBAffineRow_C(const uint8* src_argb, >+void ARGBAffineRow_C(const uint8_t* src_argb, > int src_argb_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > const float* uv_dudv, > int width); > LIBYUV_API >-void ARGBAffineRow_SSE2(const uint8* src_argb, >+void ARGBAffineRow_SSE2(const uint8_t* src_argb, > int src_argb_stride, >- uint8* dst_argb, >- const float* uv_dudv, >+ uint8_t* dst_argb, >+ const float* src_dudv, > int width); > > // Used for I420Scale, ARGBScale, and ARGBInterpolate. >-void InterpolateRow_C(uint8* dst_ptr, >- const uint8* src_ptr, >- ptrdiff_t src_stride_ptr, >+void InterpolateRow_C(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, >+ ptrdiff_t src_stride, > int width, > int source_y_fraction); >-void InterpolateRow_SSSE3(uint8* dst_ptr, >- const uint8* src_ptr, >- ptrdiff_t src_stride_ptr, >- int width, >+void InterpolateRow_SSSE3(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, >+ ptrdiff_t src_stride, >+ int dst_width, > int source_y_fraction); >-void InterpolateRow_AVX2(uint8* dst_ptr, >- const uint8* src_ptr, >- ptrdiff_t src_stride_ptr, >- int width, >+void InterpolateRow_AVX2(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, >+ ptrdiff_t src_stride, >+ int dst_width, > int source_y_fraction); >-void InterpolateRow_NEON(uint8* dst_ptr, >- const uint8* src_ptr, >- ptrdiff_t src_stride_ptr, >- int width, >+void InterpolateRow_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, >+ ptrdiff_t src_stride, >+ int dst_width, > int source_y_fraction); >-void InterpolateRow_DSPR2(uint8* dst_ptr, >- const uint8* src_ptr, >- ptrdiff_t src_stride_ptr, >- int width, >- int source_y_fraction); >-void InterpolateRow_MSA(uint8* dst_ptr, >- const uint8* src_ptr, >- ptrdiff_t src_stride_ptr, >+void InterpolateRow_MSA(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, >+ ptrdiff_t src_stride, > int width, > int source_y_fraction); >-void InterpolateRow_Any_NEON(uint8* dst_ptr, >- const uint8* src_ptr, >+void InterpolateRow_Any_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride_ptr, > int width, > int source_y_fraction); >-void InterpolateRow_Any_SSSE3(uint8* dst_ptr, >- const uint8* src_ptr, >+void InterpolateRow_Any_SSSE3(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride_ptr, > int width, > int source_y_fraction); >-void InterpolateRow_Any_AVX2(uint8* dst_ptr, >- const uint8* src_ptr, >+void InterpolateRow_Any_AVX2(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride_ptr, > int width, > int source_y_fraction); >-void InterpolateRow_Any_DSPR2(uint8* dst_ptr, >- const uint8* src_ptr, >- ptrdiff_t src_stride_ptr, >- int width, >- int source_y_fraction); >-void InterpolateRow_Any_MSA(uint8* dst_ptr, >- const uint8* src_ptr, >+void InterpolateRow_Any_MSA(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride_ptr, > int width, > int source_y_fraction); > >-void InterpolateRow_16_C(uint16* dst_ptr, >- const uint16* src_ptr, >- ptrdiff_t src_stride_ptr, >+void InterpolateRow_16_C(uint16_t* dst_ptr, >+ const uint16_t* src_ptr, >+ ptrdiff_t src_stride, > int width, > int source_y_fraction); > > // Sobel images. >-void SobelXRow_C(const uint8* src_y0, >- const uint8* src_y1, >- const uint8* src_y2, >- uint8* dst_sobelx, >+void SobelXRow_C(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ const uint8_t* src_y2, >+ uint8_t* dst_sobelx, > int width); >-void SobelXRow_SSE2(const uint8* src_y0, >- const uint8* src_y1, >- const uint8* src_y2, >- uint8* dst_sobelx, >+void SobelXRow_SSE2(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ const uint8_t* src_y2, >+ uint8_t* dst_sobelx, > int width); >-void SobelXRow_NEON(const uint8* src_y0, >- const uint8* src_y1, >- const uint8* src_y2, >- uint8* dst_sobelx, >+void SobelXRow_NEON(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ const uint8_t* src_y2, >+ uint8_t* dst_sobelx, > int width); >-void SobelXRow_MSA(const uint8* src_y0, >- const uint8* src_y1, >- const uint8* src_y2, >- uint8* dst_sobelx, >+void SobelXRow_MSA(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ const uint8_t* src_y2, >+ uint8_t* dst_sobelx, > int width); >-void SobelYRow_C(const uint8* src_y0, >- const uint8* src_y1, >- uint8* dst_sobely, >+void SobelYRow_C(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ uint8_t* dst_sobely, > int width); >-void SobelYRow_SSE2(const uint8* src_y0, >- const uint8* src_y1, >- uint8* dst_sobely, >+void SobelYRow_SSE2(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ uint8_t* dst_sobely, > int width); >-void SobelYRow_NEON(const uint8* src_y0, >- const uint8* src_y1, >- uint8* dst_sobely, >+void SobelYRow_NEON(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ uint8_t* dst_sobely, > int width); >-void SobelYRow_MSA(const uint8* src_y0, >- const uint8* src_y1, >- uint8* dst_sobely, >+void SobelYRow_MSA(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ uint8_t* dst_sobely, > int width); >-void SobelRow_C(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_C(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width); >-void SobelRow_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_SSE2(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width); >-void SobelRow_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_NEON(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width); >-void SobelRow_MSA(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_MSA(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width); >-void SobelToPlaneRow_C(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_C(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_y, > int width); >-void SobelToPlaneRow_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_SSE2(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_y, > int width); >-void SobelToPlaneRow_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_NEON(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_y, > int width); >-void SobelToPlaneRow_MSA(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_MSA(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_y, > int width); >-void SobelXYRow_C(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_C(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width); >-void SobelXYRow_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_SSE2(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width); >-void SobelXYRow_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_NEON(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width); >-void SobelXYRow_MSA(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_MSA(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width); >-void SobelRow_Any_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_Any_SSE2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void SobelRow_Any_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void SobelRow_Any_MSA(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void SobelToPlaneRow_Any_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_Any_SSE2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void SobelToPlaneRow_Any_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void SobelToPlaneRow_Any_MSA(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void SobelXYRow_Any_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_Any_SSE2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void SobelXYRow_Any_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_Any_NEON(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); >-void SobelXYRow_Any_MSA(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_Any_MSA(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_ptr, > int width); > >-void ARGBPolynomialRow_C(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBPolynomialRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, > const float* poly, > int width); >-void ARGBPolynomialRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBPolynomialRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > const float* poly, > int width); >-void ARGBPolynomialRow_AVX2(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBPolynomialRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > const float* poly, > int width); > > // Scale and convert to half float. >-void HalfFloatRow_C(const uint16* src, uint16* dst, float scale, int width); >-void HalfFloatRow_SSE2(const uint16* src, uint16* dst, float scale, int width); >-void HalfFloatRow_Any_SSE2(const uint16* src, >- uint16* dst, >- float scale, >+void HalfFloatRow_C(const uint16_t* src, uint16_t* dst, float scale, int width); >+void HalfFloatRow_SSE2(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width); >+void HalfFloatRow_Any_SSE2(const uint16_t* src_ptr, >+ uint16_t* dst_ptr, >+ float param, > int width); >-void HalfFloatRow_AVX2(const uint16* src, uint16* dst, float scale, int width); >-void HalfFloatRow_Any_AVX2(const uint16* src, >- uint16* dst, >- float scale, >+void HalfFloatRow_AVX2(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width); >+void HalfFloatRow_Any_AVX2(const uint16_t* src_ptr, >+ uint16_t* dst_ptr, >+ float param, > int width); >-void HalfFloatRow_F16C(const uint16* src, uint16* dst, float scale, int width); >-void HalfFloatRow_Any_F16C(const uint16* src, >- uint16* dst, >+void HalfFloatRow_F16C(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width); >+void HalfFloatRow_Any_F16C(const uint16_t* src, >+ uint16_t* dst, > float scale, > int width); >-void HalfFloat1Row_F16C(const uint16* src, uint16* dst, float scale, int width); >-void HalfFloat1Row_Any_F16C(const uint16* src, >- uint16* dst, >+void HalfFloat1Row_F16C(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width); >+void HalfFloat1Row_Any_F16C(const uint16_t* src, >+ uint16_t* dst, > float scale, > int width); >-void HalfFloatRow_NEON(const uint16* src, uint16* dst, float scale, int width); >-void HalfFloatRow_Any_NEON(const uint16* src, >- uint16* dst, >- float scale, >+void HalfFloatRow_NEON(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width); >+void HalfFloatRow_Any_NEON(const uint16_t* src_ptr, >+ uint16_t* dst_ptr, >+ float param, > int width); >-void HalfFloat1Row_NEON(const uint16* src, uint16* dst, float scale, int width); >-void HalfFloat1Row_Any_NEON(const uint16* src, >- uint16* dst, >- float scale, >+void HalfFloat1Row_NEON(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width); >+void HalfFloat1Row_Any_NEON(const uint16_t* src_ptr, >+ uint16_t* dst_ptr, >+ float param, > int width); >-void HalfFloatRow_MSA(const uint16* src, uint16* dst, float scale, int width); >-void HalfFloatRow_Any_MSA(const uint16* src, >- uint16* dst, >- float scale, >+void HalfFloatRow_MSA(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width); >+void HalfFloatRow_Any_MSA(const uint16_t* src_ptr, >+ uint16_t* dst_ptr, >+ float param, > int width); >+void ByteToFloatRow_C(const uint8_t* src, float* dst, float scale, int width); >+void ByteToFloatRow_NEON(const uint8_t* src, >+ float* dst, >+ float scale, >+ int width); >+void ByteToFloatRow_Any_NEON(const uint8_t* src, >+ float* dst, >+ float scale, >+ int width); > >-void ARGBLumaColorTableRow_C(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBLumaColorTableRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- const uint8* luma, >- uint32 lumacoeff); >-void ARGBLumaColorTableRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >+ const uint8_t* luma, >+ uint32_t lumacoeff); >+void ARGBLumaColorTableRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- const uint8* luma, >- uint32 lumacoeff); >+ const uint8_t* luma, >+ uint32_t lumacoeff); > > float ScaleMaxSamples_C(const float* src, float* dst, float scale, int width); > float ScaleMaxSamples_NEON(const float* src, >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale.h >index 6d6b9a8583ad243987213d28054c59e290db53b4..b937d348cabcddc0ae899db859ec8be13f07ff27 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale.h >@@ -28,22 +28,22 @@ typedef enum FilterMode { > > // Scale a YUV plane. > LIBYUV_API >-void ScalePlane(const uint8* src, >+void ScalePlane(const uint8_t* src, > int src_stride, > int src_width, > int src_height, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int dst_width, > int dst_height, > enum FilterMode filtering); > > LIBYUV_API >-void ScalePlane_16(const uint16* src, >+void ScalePlane_16(const uint16_t* src, > int src_stride, > int src_width, > int src_height, >- uint16* dst, >+ uint16_t* dst, > int dst_stride, > int dst_width, > int dst_height, >@@ -60,38 +60,38 @@ void ScalePlane_16(const uint16* src, > // Returns 0 if successful. > > LIBYUV_API >-int I420Scale(const uint8* src_y, >+int I420Scale(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, > int src_width, > int src_height, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int dst_width, > int dst_height, > enum FilterMode filtering); > > LIBYUV_API >-int I420Scale_16(const uint16* src_y, >+int I420Scale_16(const uint16_t* src_y, > int src_stride_y, >- const uint16* src_u, >+ const uint16_t* src_u, > int src_stride_u, >- const uint16* src_v, >+ const uint16_t* src_v, > int src_stride_v, > int src_width, > int src_height, >- uint16* dst_y, >+ uint16_t* dst_y, > int dst_stride_y, >- uint16* dst_u, >+ uint16_t* dst_u, > int dst_stride_u, >- uint16* dst_v, >+ uint16_t* dst_v, > int dst_stride_v, > int dst_width, > int dst_height, >@@ -100,17 +100,17 @@ int I420Scale_16(const uint16* src_y, > #ifdef __cplusplus > // Legacy API. Deprecated. > LIBYUV_API >-int Scale(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >+int Scale(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, > int src_stride_y, > int src_stride_u, > int src_stride_v, > int src_width, > int src_height, >- uint8* dst_y, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_y, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int dst_stride_y, > int dst_stride_u, > int dst_stride_v, >@@ -118,17 +118,6 @@ int Scale(const uint8* src_y, > int dst_height, > LIBYUV_BOOL interpolate); > >-// Legacy API. Deprecated. >-LIBYUV_API >-int ScaleOffset(const uint8* src_i420, >- int src_width, >- int src_height, >- uint8* dst_i420, >- int dst_width, >- int dst_height, >- int dst_yoffset, >- LIBYUV_BOOL interpolate); >- > // For testing, allow disabling of specialized scalers. > LIBYUV_API > void SetUseReferenceImpl(LIBYUV_BOOL use); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale_argb.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale_argb.h >index 3d25e579cde244601f75b91c83049fda49a8397e..7641f18e3416b869172a2f2d46b07ce5d68ecad6 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale_argb.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale_argb.h >@@ -20,11 +20,11 @@ extern "C" { > #endif > > LIBYUV_API >-int ARGBScale(const uint8* src_argb, >+int ARGBScale(const uint8_t* src_argb, > int src_stride_argb, > int src_width, > int src_height, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int dst_width, > int dst_height, >@@ -32,11 +32,11 @@ int ARGBScale(const uint8* src_argb, > > // Clipped scale takes destination rectangle coordinates for clip values. > LIBYUV_API >-int ARGBScaleClip(const uint8* src_argb, >+int ARGBScaleClip(const uint8_t* src_argb, > int src_stride_argb, > int src_width, > int src_height, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int dst_width, > int dst_height, >@@ -48,18 +48,18 @@ int ARGBScaleClip(const uint8* src_argb, > > // Scale with YUV conversion to ARGB and clipping. > LIBYUV_API >-int YUVToARGBScaleClip(const uint8* src_y, >+int YUVToARGBScaleClip(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint32 src_fourcc, >+ uint32_t src_fourcc, > int src_width, > int src_height, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- uint32 dst_fourcc, >+ uint32_t dst_fourcc, > int dst_width, > int dst_height, > int clip_x, >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale_row.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale_row.h >index c4a66aa07b10e319970cb4b6889873c6a7d8b988..7194ba09f842ba7ffb5b295b06977ddf91237e31 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale_row.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/scale_row.h >@@ -19,17 +19,20 @@ namespace libyuv { > extern "C" { > #endif > >-#if defined(__pnacl__) || defined(__CLR_VER) || \ >+#if defined(__pnacl__) || defined(__CLR_VER) || \ >+ (defined(__native_client__) && defined(__x86_64__)) || \ > (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) > #define LIBYUV_DISABLE_X86 > #endif >+#if defined(__native_client__) >+#define LIBYUV_DISABLE_NEON >+#endif > // MemorySanitizer does not support assembly code yet. http://crbug.com/344505 > #if defined(__has_feature) > #if __has_feature(memory_sanitizer) > #define LIBYUV_DISABLE_X86 > #endif > #endif >- > // GCC >= 4.7.0 required for AVX2. > #if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) > #if (__GNUC__ > 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 7)) >@@ -81,7 +84,7 @@ extern "C" { > #endif > > // The following are available on Neon platforms: >-#if !defined(LIBYUV_DISABLE_NEON) && !defined(__native_client__) && \ >+#if !defined(LIBYUV_DISABLE_NEON) && \ > (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__)) > #define HAS_SCALEARGBCOLS_NEON > #define HAS_SCALEARGBROWDOWN2_NEON >@@ -94,16 +97,6 @@ extern "C" { > #define HAS_SCALEARGBFILTERCOLS_NEON > #endif > >-// The following are available on Mips platforms: >-#if !defined(LIBYUV_DISABLE_DSPR2) && !defined(__native_client__) && \ >- defined(__mips__) && defined(__mips_dsp) && (__mips_dsp_rev >= 2) >-#define HAS_SCALEROWDOWN2_DSPR2 >-#define HAS_SCALEROWDOWN4_DSPR2 >-#define HAS_SCALEROWDOWN34_DSPR2 >-#define HAS_SCALEROWDOWN38_DSPR2 >-#define HAS_SCALEADDROW_DSPR2 >-#endif >- > #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) > #define HAS_SCALEADDROW_MSA > #define HAS_SCALEARGBCOLS_MSA >@@ -123,8 +116,8 @@ void ScalePlaneVertical(int src_height, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_argb, >- uint8* dst_argb, >+ const uint8_t* src_argb, >+ uint8_t* dst_argb, > int x, > int y, > int dy, >@@ -136,8 +129,8 @@ void ScalePlaneVertical_16(int src_height, > int dst_height, > int src_stride, > int dst_stride, >- const uint16* src_argb, >- uint16* dst_argb, >+ const uint16_t* src_argb, >+ uint16_t* dst_argb, > int x, > int y, > int dy, >@@ -176,425 +169,431 @@ void ScaleSlope(int src_width, > int* dx, > int* dy); > >-void ScaleRowDown2_C(const uint8* src_ptr, >+void ScaleRowDown2_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown2_16_C(const uint16* src_ptr, >+void ScaleRowDown2_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width); >-void ScaleRowDown2Linear_C(const uint8* src_ptr, >+void ScaleRowDown2Linear_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown2Linear_16_C(const uint16* src_ptr, >+void ScaleRowDown2Linear_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width); >-void ScaleRowDown2Box_C(const uint8* src_ptr, >+void ScaleRowDown2Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown2Box_Odd_C(const uint8* src_ptr, >+void ScaleRowDown2Box_Odd_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown2Box_16_C(const uint16* src_ptr, >+void ScaleRowDown2Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width); >-void ScaleRowDown4_C(const uint8* src_ptr, >+void ScaleRowDown4_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown4_16_C(const uint16* src_ptr, >+void ScaleRowDown4_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width); >-void ScaleRowDown4Box_C(const uint8* src_ptr, >+void ScaleRowDown4Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown4Box_16_C(const uint16* src_ptr, >+void ScaleRowDown4Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width); >-void ScaleRowDown34_C(const uint8* src_ptr, >+void ScaleRowDown34_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown34_16_C(const uint16* src_ptr, >+void ScaleRowDown34_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width); >-void ScaleRowDown34_0_Box_C(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* d, >+ uint8_t* d, > int dst_width); >-void ScaleRowDown34_0_Box_16_C(const uint16* src_ptr, >+void ScaleRowDown34_0_Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* d, >+ uint16_t* d, > int dst_width); >-void ScaleRowDown34_1_Box_C(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* d, >+ uint8_t* d, > int dst_width); >-void ScaleRowDown34_1_Box_16_C(const uint16* src_ptr, >+void ScaleRowDown34_1_Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* d, >+ uint16_t* d, > int dst_width); >-void ScaleCols_C(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleCols_C(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); >-void ScaleCols_16_C(uint16* dst_ptr, >- const uint16* src_ptr, >+void ScaleCols_16_C(uint16_t* dst_ptr, >+ const uint16_t* src_ptr, > int dst_width, > int x, > int dx); >-void ScaleColsUp2_C(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleColsUp2_C(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int, > int); >-void ScaleColsUp2_16_C(uint16* dst_ptr, >- const uint16* src_ptr, >+void ScaleColsUp2_16_C(uint16_t* dst_ptr, >+ const uint16_t* src_ptr, > int dst_width, > int, > int); >-void ScaleFilterCols_C(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols_C(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); >-void ScaleFilterCols_16_C(uint16* dst_ptr, >- const uint16* src_ptr, >+void ScaleFilterCols_16_C(uint16_t* dst_ptr, >+ const uint16_t* src_ptr, > int dst_width, > int x, > int dx); >-void ScaleFilterCols64_C(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols64_C(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, >- int x, >+ int x32, > int dx); >-void ScaleFilterCols64_16_C(uint16* dst_ptr, >- const uint16* src_ptr, >+void ScaleFilterCols64_16_C(uint16_t* dst_ptr, >+ const uint16_t* src_ptr, > int dst_width, >- int x, >+ int x32, > int dx); >-void ScaleRowDown38_C(const uint8* src_ptr, >+void ScaleRowDown38_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown38_16_C(const uint16* src_ptr, >+void ScaleRowDown38_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width); >-void ScaleRowDown38_3_Box_C(const uint8* src_ptr, >+void ScaleRowDown38_3_Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown38_3_Box_16_C(const uint16* src_ptr, >+void ScaleRowDown38_3_Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst_ptr, >+ uint16_t* dst_ptr, > int dst_width); >-void ScaleRowDown38_2_Box_C(const uint8* src_ptr, >+void ScaleRowDown38_2_Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown38_2_Box_16_C(const uint16* src_ptr, >+void ScaleRowDown38_2_Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst_ptr, >+ uint16_t* dst_ptr, > int dst_width); >-void ScaleAddRow_C(const uint8* src_ptr, uint16* dst_ptr, int src_width); >-void ScaleAddRow_16_C(const uint16* src_ptr, uint32* dst_ptr, int src_width); >-void ScaleARGBRowDown2_C(const uint8* src_argb, >+void ScaleAddRow_C(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); >+void ScaleAddRow_16_C(const uint16_t* src_ptr, >+ uint32_t* dst_ptr, >+ int src_width); >+void ScaleARGBRowDown2_C(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDown2Linear_C(const uint8* src_argb, >+void ScaleARGBRowDown2Linear_C(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDown2Box_C(const uint8* src_argb, >+void ScaleARGBRowDown2Box_C(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDownEven_C(const uint8* src_argb, >+void ScaleARGBRowDownEven_C(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDownEvenBox_C(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_C(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBCols_C(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_C(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx); >-void ScaleARGBCols64_C(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols64_C(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, >- int x, >+ int x32, > int dx); >-void ScaleARGBColsUp2_C(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBColsUp2_C(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int, > int); >-void ScaleARGBFilterCols_C(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_C(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx); >-void ScaleARGBFilterCols64_C(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols64_C(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, >- int x, >+ int x32, > int dx); > > // Specialized scalers for x86. >-void ScaleRowDown2_SSSE3(const uint8* src_ptr, >+void ScaleRowDown2_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Linear_SSSE3(const uint8* src_ptr, >+void ScaleRowDown2Linear_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown2Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2_AVX2(const uint8* src_ptr, >+void ScaleRowDown2_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Linear_AVX2(const uint8* src_ptr, >+void ScaleRowDown2Linear_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Box_AVX2(const uint8* src_ptr, >+void ScaleRowDown2Box_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4_SSSE3(const uint8* src_ptr, >+void ScaleRowDown4_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown4Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4_AVX2(const uint8* src_ptr, >+void ScaleRowDown4_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4Box_AVX2(const uint8* src_ptr, >+void ScaleRowDown4Box_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > >-void ScaleRowDown34_SSSE3(const uint8* src_ptr, >+void ScaleRowDown34_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_1_Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_0_Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown38_SSSE3(const uint8* src_ptr, >+void ScaleRowDown38_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown38_3_Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown38_3_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown38_2_Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown38_2_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown2_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Linear_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown2Linear_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Box_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown2Box_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Box_Odd_SSSE3(const uint8* src_ptr, >+void ScaleRowDown2Box_Odd_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2_Any_AVX2(const uint8* src_ptr, >+void ScaleRowDown2_Any_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Linear_Any_AVX2(const uint8* src_ptr, >+void ScaleRowDown2Linear_Any_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Box_Any_AVX2(const uint8* src_ptr, >+void ScaleRowDown2Box_Any_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Box_Odd_AVX2(const uint8* src_ptr, >+void ScaleRowDown2Box_Odd_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown4_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4Box_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown4Box_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4_Any_AVX2(const uint8* src_ptr, >+void ScaleRowDown4_Any_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4Box_Any_AVX2(const uint8* src_ptr, >+void ScaleRowDown4Box_Any_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > >-void ScaleRowDown34_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown34_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_1_Box_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_0_Box_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown38_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown38_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown38_3_Box_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown38_3_Box_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown38_2_Box_Any_SSSE3(const uint8* src_ptr, >+void ScaleRowDown38_2_Box_Any_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > >-void ScaleAddRow_SSE2(const uint8* src_ptr, uint16* dst_ptr, int src_width); >-void ScaleAddRow_AVX2(const uint8* src_ptr, uint16* dst_ptr, int src_width); >-void ScaleAddRow_Any_SSE2(const uint8* src_ptr, uint16* dst_ptr, int src_width); >-void ScaleAddRow_Any_AVX2(const uint8* src_ptr, uint16* dst_ptr, int src_width); >- >-void ScaleFilterCols_SSSE3(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleAddRow_SSE2(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); >+void ScaleAddRow_AVX2(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); >+void ScaleAddRow_Any_SSE2(const uint8_t* src_ptr, >+ uint16_t* dst_ptr, >+ int src_width); >+void ScaleAddRow_Any_AVX2(const uint8_t* src_ptr, >+ uint16_t* dst_ptr, >+ int src_width); >+ >+void ScaleFilterCols_SSSE3(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); >-void ScaleColsUp2_SSE2(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleColsUp2_SSE2(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); > > // ARGB Column functions >-void ScaleARGBCols_SSE2(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_SSE2(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx); >-void ScaleARGBFilterCols_SSSE3(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_SSSE3(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx); >-void ScaleARGBColsUp2_SSE2(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBColsUp2_SSE2(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx); >-void ScaleARGBFilterCols_NEON(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_NEON(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx); >-void ScaleARGBCols_NEON(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_NEON(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx); >-void ScaleARGBFilterCols_Any_NEON(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_Any_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); >-void ScaleARGBCols_Any_NEON(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_Any_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); >-void ScaleARGBFilterCols_MSA(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_MSA(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx); >-void ScaleARGBCols_MSA(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_MSA(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx); >-void ScaleARGBFilterCols_Any_MSA(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_Any_MSA(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); >-void ScaleARGBCols_Any_MSA(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_Any_MSA(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); > > // ARGB Row functions >-void ScaleARGBRowDown2_SSE2(const uint8* src_argb, >+void ScaleARGBRowDown2_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDown2Linear_SSE2(const uint8* src_argb, >+void ScaleARGBRowDown2Linear_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDown2Box_SSE2(const uint8* src_argb, >+void ScaleARGBRowDown2Box_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDown2_NEON(const uint8* src_ptr, >+void ScaleARGBRowDown2_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleARGBRowDown2Linear_NEON(const uint8* src_argb, >+void ScaleARGBRowDown2Linear_NEON(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDown2Box_NEON(const uint8* src_ptr, >+void ScaleARGBRowDown2Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); > void ScaleARGBRowDown2_MSA(const uint8_t* src_argb, > ptrdiff_t src_stride, >@@ -608,274 +607,231 @@ void ScaleARGBRowDown2Box_MSA(const uint8_t* src_argb, > ptrdiff_t src_stride, > uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDown2_Any_SSE2(const uint8* src_argb, >+void ScaleARGBRowDown2_Any_SSE2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDown2Linear_Any_SSE2(const uint8* src_argb, >+void ScaleARGBRowDown2Linear_Any_SSE2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDown2Box_Any_SSE2(const uint8* src_argb, >+void ScaleARGBRowDown2Box_Any_SSE2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDown2_Any_NEON(const uint8* src_ptr, >+void ScaleARGBRowDown2_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDown2Linear_Any_NEON(const uint8* src_argb, >+void ScaleARGBRowDown2Linear_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDown2Box_Any_NEON(const uint8* src_ptr, >+void ScaleARGBRowDown2Box_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDown2_Any_MSA(const uint8_t* src_argb, >+void ScaleARGBRowDown2_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8_t* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDown2Linear_Any_MSA(const uint8_t* src_argb, >+void ScaleARGBRowDown2Linear_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8_t* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDown2Box_Any_MSA(const uint8_t* src_argb, >+void ScaleARGBRowDown2Box_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8_t* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); > >-void ScaleARGBRowDownEven_SSE2(const uint8* src_argb, >+void ScaleARGBRowDownEven_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDownEvenBox_SSE2(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDownEven_NEON(const uint8* src_argb, >+void ScaleARGBRowDownEven_NEON(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDownEvenBox_NEON(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_NEON(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); > void ScaleARGBRowDownEven_MSA(const uint8_t* src_argb, > ptrdiff_t src_stride, > int32_t src_stepx, > uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDownEvenBox_MSA(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_MSA(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width); >-void ScaleARGBRowDownEven_Any_SSE2(const uint8* src_argb, >+void ScaleARGBRowDownEven_Any_SSE2(const uint8_t* src_ptr, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDownEvenBox_Any_SSE2(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_Any_SSE2(const uint8_t* src_ptr, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDownEven_Any_NEON(const uint8* src_argb, >+void ScaleARGBRowDownEven_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDownEvenBox_Any_NEON(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDownEven_Any_MSA(const uint8_t* src_argb, >+void ScaleARGBRowDownEven_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, > int32_t src_stepx, >- uint8_t* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleARGBRowDownEvenBox_Any_MSA(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_ptr, > int dst_width); > > // ScaleRowDown2Box also used by planar functions > // NEON downscalers with interpolation. > > // Note - not static due to reuse in convert for 444 to 420. >-void ScaleRowDown2_NEON(const uint8* src_ptr, >+void ScaleRowDown2_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown2Linear_NEON(const uint8* src_ptr, >+void ScaleRowDown2Linear_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown2Box_NEON(const uint8* src_ptr, >+void ScaleRowDown2Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width); > >-void ScaleRowDown4_NEON(const uint8* src_ptr, >+void ScaleRowDown4_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4Box_NEON(const uint8* src_ptr, >+void ScaleRowDown4Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > > // Down scale from 4 to 3 pixels. Use the neon multilane read/write > // to load up the every 4th pixel into a 4 different registers. > // Point samples 32 pixels to 24 pixels. >-void ScaleRowDown34_NEON(const uint8* src_ptr, >+void ScaleRowDown34_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_0_Box_NEON(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_1_Box_NEON(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > > // 32 -> 12 >-void ScaleRowDown38_NEON(const uint8* src_ptr, >+void ScaleRowDown38_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > // 32x3 -> 12x1 >-void ScaleRowDown38_3_Box_NEON(const uint8* src_ptr, >+void ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > // 32x2 -> 12x1 >-void ScaleRowDown38_2_Box_NEON(const uint8* src_ptr, >+void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > >-void ScaleRowDown2_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown2_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Linear_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown2Linear_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Box_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown2Box_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown2Box_Odd_NEON(const uint8* src_ptr, >+void ScaleRowDown2Box_Odd_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown4_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown4Box_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown4Box_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown34_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_0_Box_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_1_Box_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > // 32 -> 12 >-void ScaleRowDown38_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown38_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > // 32x3 -> 12x1 >-void ScaleRowDown38_3_Box_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown38_3_Box_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > // 32x2 -> 12x1 >-void ScaleRowDown38_2_Box_Any_NEON(const uint8* src_ptr, >+void ScaleRowDown38_2_Box_Any_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > >-void ScaleAddRow_NEON(const uint8* src_ptr, uint16* dst_ptr, int src_width); >-void ScaleAddRow_Any_NEON(const uint8* src_ptr, uint16* dst_ptr, int src_width); >+void ScaleAddRow_NEON(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); >+void ScaleAddRow_Any_NEON(const uint8_t* src_ptr, >+ uint16_t* dst_ptr, >+ int src_width); > >-void ScaleFilterCols_NEON(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); > >-void ScaleFilterCols_Any_NEON(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols_Any_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); > >-void ScaleRowDown2_DSPR2(const uint8* src_ptr, >- ptrdiff_t src_stride, >- uint8* dst, >- int dst_width); >-void ScaleRowDown2Box_DSPR2(const uint8* src_ptr, >- ptrdiff_t src_stride, >- uint8* dst, >- int dst_width); >-void ScaleRowDown4_DSPR2(const uint8* src_ptr, >- ptrdiff_t src_stride, >- uint8* dst, >- int dst_width); >-void ScaleRowDown4Box_DSPR2(const uint8* src_ptr, >- ptrdiff_t src_stride, >- uint8* dst, >- int dst_width); >-void ScaleRowDown34_DSPR2(const uint8* src_ptr, >- ptrdiff_t src_stride, >- uint8* dst, >- int dst_width); >-void ScaleRowDown34_0_Box_DSPR2(const uint8* src_ptr, >- ptrdiff_t src_stride, >- uint8* d, >- int dst_width); >-void ScaleRowDown34_1_Box_DSPR2(const uint8* src_ptr, >- ptrdiff_t src_stride, >- uint8* d, >- int dst_width); >-void ScaleRowDown38_DSPR2(const uint8* src_ptr, >- ptrdiff_t src_stride, >- uint8* dst, >- int dst_width); >-void ScaleRowDown38_2_Box_DSPR2(const uint8* src_ptr, >- ptrdiff_t src_stride, >- uint8* dst_ptr, >- int dst_width); >-void ScaleRowDown38_3_Box_DSPR2(const uint8* src_ptr, >- ptrdiff_t src_stride, >- uint8* dst_ptr, >- int dst_width); >-void ScaleAddRow_DSPR2(const uint8* src_ptr, uint16* dst_ptr, int src_width); >-void ScaleAddRow_Any_DSPR2(const uint8* src_ptr, >- uint16* dst_ptr, >- int src_width); >- > void ScaleRowDown2_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, > uint8_t* dst, >@@ -909,47 +865,47 @@ void ScaleRowDown38_3_Box_MSA(const uint8_t* src_ptr, > uint8_t* dst_ptr, > int dst_width); > void ScaleAddRow_MSA(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); >-void ScaleFilterCols_MSA(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols_MSA(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); >-void ScaleRowDown34_MSA(const uint8* src_ptr, >+void ScaleRowDown34_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst, > int dst_width); >-void ScaleRowDown34_0_Box_MSA(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* d, > int dst_width); >-void ScaleRowDown34_1_Box_MSA(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* d, > int dst_width); > > void ScaleRowDown2_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8_t* dst, >+ uint8_t* dst_ptr, > int dst_width); > void ScaleRowDown2Linear_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8_t* dst, >+ uint8_t* dst_ptr, > int dst_width); > void ScaleRowDown2Box_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8_t* dst, >+ uint8_t* dst_ptr, > int dst_width); > void ScaleRowDown4_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8_t* dst, >+ uint8_t* dst_ptr, > int dst_width); > void ScaleRowDown4Box_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8_t* dst, >+ uint8_t* dst_ptr, > int dst_width); > void ScaleRowDown38_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8_t* dst, >+ uint8_t* dst_ptr, > int dst_width); > void ScaleRowDown38_2_Box_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >@@ -962,22 +918,22 @@ void ScaleRowDown38_3_Box_Any_MSA(const uint8_t* src_ptr, > void ScaleAddRow_Any_MSA(const uint8_t* src_ptr, > uint16_t* dst_ptr, > int src_width); >-void ScaleFilterCols_Any_MSA(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols_Any_MSA(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx); >-void ScaleRowDown34_Any_MSA(const uint8* src_ptr, >+void ScaleRowDown34_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_0_Box_Any_MSA(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); >-void ScaleRowDown34_1_Box_Any_MSA(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_Any_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width); > > #ifdef __cplusplus >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/version.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/version.h >index 838c70f1349a9ad8f19a4832ae9c5b14c2d65eef..21522cf351c8c53610ec2e8430ddc0a42cd58772 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/version.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/version.h >@@ -11,6 +11,6 @@ > #ifndef INCLUDE_LIBYUV_VERSION_H_ > #define INCLUDE_LIBYUV_VERSION_H_ > >-#define LIBYUV_VERSION 1678 >+#define LIBYUV_VERSION 1703 > > #endif // INCLUDE_LIBYUV_VERSION_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/video_common.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/video_common.h >index f3711c423ba3b5f0421380e8cb8e4916202fc64d..bcef378b5a4e5b2c3af9f364e153c7753671dd31 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/video_common.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/include/libyuv/video_common.h >@@ -28,13 +28,13 @@ extern "C" { > // Needs to be a macro otherwise the OS X compiler complains when the kFormat* > // constants are used in a switch. > #ifdef __cplusplus >-#define FOURCC(a, b, c, d) \ >- ((static_cast<uint32>(a)) | (static_cast<uint32>(b) << 8) | \ >- (static_cast<uint32>(c) << 16) | (static_cast<uint32>(d) << 24)) >+#define FOURCC(a, b, c, d) \ >+ ((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \ >+ (static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24)) > #else >-#define FOURCC(a, b, c, d) \ >- (((uint32)(a)) | ((uint32)(b) << 8) | /* NOLINT */ \ >- ((uint32)(c) << 16) | ((uint32)(d) << 24)) /* NOLINT */ >+#define FOURCC(a, b, c, d) \ >+ (((uint32_t)(a)) | ((uint32_t)(b) << 8) | /* NOLINT */ \ >+ ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) /* NOLINT */ > #endif > > // Some pages discussing FourCC codes: >@@ -49,25 +49,26 @@ extern "C" { > // Secondary formats are converted in 2 steps. > // Auxilliary formats call primary converters. > enum FourCC { >- // 8 Primary YUV formats: 5 planar, 2 biplanar, 2 packed. >+ // 9 Primary YUV formats: 5 planar, 2 biplanar, 2 packed. > FOURCC_I420 = FOURCC('I', '4', '2', '0'), > FOURCC_I422 = FOURCC('I', '4', '2', '2'), > FOURCC_I444 = FOURCC('I', '4', '4', '4'), >- FOURCC_I411 = FOURCC('I', '4', '1', '1'), // deprecated. > FOURCC_I400 = FOURCC('I', '4', '0', '0'), > FOURCC_NV21 = FOURCC('N', 'V', '2', '1'), > FOURCC_NV12 = FOURCC('N', 'V', '1', '2'), > FOURCC_YUY2 = FOURCC('Y', 'U', 'Y', '2'), > FOURCC_UYVY = FOURCC('U', 'Y', 'V', 'Y'), >+ FOURCC_H010 = FOURCC('H', '0', '1', '0'), // unofficial fourcc. 10 bit lsb > > // 1 Secondary YUV format: row biplanar. > FOURCC_M420 = FOURCC('M', '4', '2', '0'), >- FOURCC_Q420 = FOURCC('Q', '4', '2', '0'), // deprecated. > >- // 9 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp. >+ // 11 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp, 1 10 bpc > FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'), > FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'), > FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'), >+ FOURCC_AR30 = FOURCC('A', 'R', '3', '0'), // 10 bit per channel. 2101010. >+ FOURCC_AB30 = FOURCC('A', 'B', '3', '0'), // ABGR version of 10 bit > FOURCC_24BG = FOURCC('2', '4', 'B', 'G'), > FOURCC_RAW = FOURCC('r', 'a', 'w', ' '), > FOURCC_RGBA = FOURCC('R', 'G', 'B', 'A'), >@@ -75,16 +76,10 @@ enum FourCC { > FOURCC_RGBO = FOURCC('R', 'G', 'B', 'O'), // argb1555 LE. > FOURCC_R444 = FOURCC('R', '4', '4', '4'), // argb4444 LE. > >- // 4 Secondary RGB formats: 4 Bayer Patterns. deprecated. >- FOURCC_RGGB = FOURCC('R', 'G', 'G', 'B'), >- FOURCC_BGGR = FOURCC('B', 'G', 'G', 'R'), >- FOURCC_GRBG = FOURCC('G', 'R', 'B', 'G'), >- FOURCC_GBRG = FOURCC('G', 'B', 'R', 'G'), >- > // 1 Primary Compressed YUV format. > FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'), > >- // 5 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias. >+ // 7 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias. > FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'), > FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'), > FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'), >@@ -112,7 +107,13 @@ enum FourCC { > FOURCC_L565 = FOURCC('L', '5', '6', '5'), // Alias for RGBP. > FOURCC_5551 = FOURCC('5', '5', '5', '1'), // Alias for RGBO. > >- // 1 Auxiliary compressed YUV format set aside for capturer. >+ // deprecated formats. Not supported, but defined for backward compatibility. >+ FOURCC_I411 = FOURCC('I', '4', '1', '1'), >+ FOURCC_Q420 = FOURCC('Q', '4', '2', '0'), >+ FOURCC_RGGB = FOURCC('R', 'G', 'G', 'B'), >+ FOURCC_BGGR = FOURCC('B', 'G', 'G', 'R'), >+ FOURCC_GRBG = FOURCC('G', 'R', 'B', 'G'), >+ FOURCC_GBRG = FOURCC('G', 'B', 'R', 'G'), > FOURCC_H264 = FOURCC('H', '2', '6', '4'), > > // Match any fourcc. >@@ -136,6 +137,8 @@ enum FourCCBpp { > FOURCC_BPP_BGRA = 32, > FOURCC_BPP_ABGR = 32, > FOURCC_BPP_RGBA = 32, >+ FOURCC_BPP_AR30 = 32, >+ FOURCC_BPP_AB30 = 32, > FOURCC_BPP_24BG = 24, > FOURCC_BPP_RAW = 24, > FOURCC_BPP_RGBP = 16, >@@ -152,6 +155,7 @@ enum FourCCBpp { > FOURCC_BPP_J420 = 12, > FOURCC_BPP_J400 = 8, > FOURCC_BPP_H420 = 12, >+ FOURCC_BPP_H010 = 24, > FOURCC_BPP_MJPG = 0, // 0 means unknown. > FOURCC_BPP_H264 = 0, > FOURCC_BPP_IYUV = 12, >@@ -174,7 +178,7 @@ enum FourCCBpp { > }; > > // Converts fourcc aliases into canonical ones. >-LIBYUV_API uint32 CanonicalFourCC(uint32 fourcc); >+LIBYUV_API uint32_t CanonicalFourCC(uint32_t fourcc); > > #ifdef __cplusplus > } // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv.gyp b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv.gyp >index f73a1a4b745e4ff53cf589027674c09f70c7c395..e853ba3197a94bcad91011ac6384ce84daa1db10 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv.gyp >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv.gyp >@@ -121,7 +121,6 @@ > # Enable the following 3 macros to turn off assembly for specified CPU. > # 'LIBYUV_DISABLE_X86', > # 'LIBYUV_DISABLE_NEON', >- # 'LIBYUV_DISABLE_DSPR2', > # Enable the following macro to build libyuv as a shared library (dll). > # 'LIBYUV_USING_SHARED_LIBRARY', > # TODO(fbarchard): Make these into gyp defines. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv.gypi b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv.gypi >index ec81bc9bbab53299b6c9c45883bda0dc8988c2b4..9467adfc515d7e45e5fda706a32b565ddfe492ed 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv.gypi >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv.gypi >@@ -55,7 +55,6 @@ > 'source/rotate_argb.cc', > 'source/rotate_common.cc', > 'source/rotate_gcc.cc', >- 'source/rotate_dspr2.cc', > 'source/rotate_msa.cc', > 'source/rotate_neon.cc', > 'source/rotate_neon64.cc', >@@ -63,7 +62,6 @@ > 'source/row_any.cc', > 'source/row_common.cc', > 'source/row_gcc.cc', >- 'source/row_dspr2.cc', > 'source/row_msa.cc', > 'source/row_neon.cc', > 'source/row_neon64.cc', >@@ -73,7 +71,6 @@ > 'source/scale_argb.cc', > 'source/scale_common.cc', > 'source/scale_gcc.cc', >- 'source/scale_dspr2.cc', > 'source/scale_msa.cc', > 'source/scale_neon.cc', > 'source/scale_neon64.cc', >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv_test.gyp b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv_test.gyp >index 4222cf26da7b6d7d6e44e7a14fae20d3e0db87ae..5fe154c610a70ef9acdf0f40076d807d86856094 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv_test.gyp >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/libyuv_test.gyp >@@ -100,7 +100,6 @@ > # Enable the following 3 macros to turn off assembly for specified CPU. > # 'LIBYUV_DISABLE_X86', > # 'LIBYUV_DISABLE_NEON', >- # 'LIBYUV_DISABLE_DSPR2', > # Enable the following macro to build libyuv as a shared library (dll). > # 'LIBYUV_USING_SHARED_LIBRARY', > ], >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/linux.mk b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/linux.mk >index 7e9aa5e4e8b98795f51b58e04f3dd8429b75d3fa..b84c89f912e066416f2a2477ab720a6a477cb66f 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/linux.mk >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/linux.mk >@@ -32,14 +32,12 @@ LOCAL_OBJ_FILES := \ > source/rotate.o \ > source/rotate_common.o \ > source/rotate_gcc.o \ >- source/rotate_dspr2.o \ > source/rotate_neon64.o \ > source/rotate_neon.o \ > source/rotate_win.o \ > source/row_any.o \ > source/row_common.o \ > source/row_gcc.o \ >- source/row_dspr2.o \ > source/row_neon64.o \ > source/row_neon.o \ > source/row_win.o \ >@@ -48,7 +46,6 @@ LOCAL_OBJ_FILES := \ > source/scale.o \ > source/scale_common.o \ > source/scale_gcc.o \ >- source/scale_dspr2.o \ > source/scale_neon64.o \ > source/scale_neon.o \ > source/scale_win.o \ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare.cc >index 8c379b59cb8b309ab9282969ade25746362409df..50e3abd0556e3862a7da070e4555daa2ed4bf45c 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare.cc >@@ -29,10 +29,11 @@ extern "C" { > > // hash seed of 5381 recommended. > LIBYUV_API >-uint32 HashDjb2(const uint8* src, uint64 count, uint32 seed) { >+uint32_t HashDjb2(const uint8_t* src, uint64_t count, uint32_t seed) { > const int kBlockSize = 1 << 15; // 32768; > int remainder; >- uint32 (*HashDjb2_SSE)(const uint8* src, int count, uint32 seed) = HashDjb2_C; >+ uint32_t (*HashDjb2_SSE)(const uint8_t* src, int count, uint32_t seed) = >+ HashDjb2_C; > #if defined(HAS_HASHDJB2_SSE41) > if (TestCpuFlag(kCpuHasSSE41)) { > HashDjb2_SSE = HashDjb2_SSE41; >@@ -44,7 +45,7 @@ uint32 HashDjb2(const uint8* src, uint64 count, uint32 seed) { > } > #endif > >- while (count >= (uint64)(kBlockSize)) { >+ while (count >= (uint64_t)(kBlockSize)) { > seed = HashDjb2_SSE(src, kBlockSize, seed); > src += kBlockSize; > count -= kBlockSize; >@@ -62,7 +63,7 @@ uint32 HashDjb2(const uint8* src, uint64 count, uint32 seed) { > return seed; > } > >-static uint32 ARGBDetectRow_C(const uint8* argb, int width) { >+static uint32_t ARGBDetectRow_C(const uint8_t* argb, int width) { > int x; > for (x = 0; x < width - 1; x += 2) { > if (argb[0] != 255) { // First byte is not Alpha of 255, so not ARGB. >@@ -93,8 +94,11 @@ static uint32 ARGBDetectRow_C(const uint8* argb, int width) { > // Scan an opaque argb image and return fourcc based on alpha offset. > // Returns FOURCC_ARGB, FOURCC_BGRA, or 0 if unknown. > LIBYUV_API >-uint32 ARGBDetect(const uint8* argb, int stride_argb, int width, int height) { >- uint32 fourcc = 0; >+uint32_t ARGBDetect(const uint8_t* argb, >+ int stride_argb, >+ int width, >+ int height) { >+ uint32_t fourcc = 0; > int h; > > // Coalesce rows. >@@ -114,17 +118,17 @@ uint32 ARGBDetect(const uint8* argb, int stride_argb, int width, int height) { > // So actual maximum is 1 less loop, which is 64436 - 32 bytes. > > LIBYUV_API >-uint64 ComputeHammingDistance(const uint8* src_a, >- const uint8* src_b, >- int count) { >+uint64_t ComputeHammingDistance(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { > const int kBlockSize = 1 << 15; // 32768; > const int kSimdSize = 64; > // SIMD for multiple of 64, and C for remainder > int remainder = count & (kBlockSize - 1) & ~(kSimdSize - 1); >- uint64 diff = 0; >+ uint64_t diff = 0; > int i; >- uint32 (*HammingDistance)(const uint8* src_a, const uint8* src_b, int count) = >- HammingDistance_C; >+ uint32_t (*HammingDistance)(const uint8_t* src_a, const uint8_t* src_b, >+ int count) = HammingDistance_C; > #if defined(HAS_HAMMINGDISTANCE_NEON) > if (TestCpuFlag(kCpuHasNEON)) { > HammingDistance = HammingDistance_NEON; >@@ -172,18 +176,18 @@ uint64 ComputeHammingDistance(const uint8* src_a, > > // TODO(fbarchard): Refactor into row function. > LIBYUV_API >-uint64 ComputeSumSquareError(const uint8* src_a, >- const uint8* src_b, >- int count) { >+uint64_t ComputeSumSquareError(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { > // SumSquareError returns values 0 to 65535 for each squared difference. >- // Up to 65536 of those can be summed and remain within a uint32. >- // After each block of 65536 pixels, accumulate into a uint64. >+ // Up to 65536 of those can be summed and remain within a uint32_t. >+ // After each block of 65536 pixels, accumulate into a uint64_t. > const int kBlockSize = 65536; > int remainder = count & (kBlockSize - 1) & ~31; >- uint64 sse = 0; >+ uint64_t sse = 0; > int i; >- uint32 (*SumSquareError)(const uint8* src_a, const uint8* src_b, int count) = >- SumSquareError_C; >+ uint32_t (*SumSquareError)(const uint8_t* src_a, const uint8_t* src_b, >+ int count) = SumSquareError_C; > #if defined(HAS_SUMSQUAREERROR_NEON) > if (TestCpuFlag(kCpuHasNEON)) { > SumSquareError = SumSquareError_NEON; >@@ -227,13 +231,13 @@ uint64 ComputeSumSquareError(const uint8* src_a, > } > > LIBYUV_API >-uint64 ComputeSumSquareErrorPlane(const uint8* src_a, >- int stride_a, >- const uint8* src_b, >- int stride_b, >- int width, >- int height) { >- uint64 sse = 0; >+uint64_t ComputeSumSquareErrorPlane(const uint8_t* src_a, >+ int stride_a, >+ const uint8_t* src_b, >+ int stride_b, >+ int width, >+ int height) { >+ uint64_t sse = 0; > int h; > // Coalesce rows. > if (stride_a == width && stride_b == width) { >@@ -250,7 +254,7 @@ uint64 ComputeSumSquareErrorPlane(const uint8* src_a, > } > > LIBYUV_API >-double SumSquareErrorToPsnr(uint64 sse, uint64 count) { >+double SumSquareErrorToPsnr(uint64_t sse, uint64_t count) { > double psnr; > if (sse > 0) { > double mse = (double)count / (double)sse; >@@ -259,65 +263,67 @@ double SumSquareErrorToPsnr(uint64 sse, uint64 count) { > psnr = kMaxPsnr; // Limit to prevent divide by 0 > } > >- if (psnr > kMaxPsnr) >+ if (psnr > kMaxPsnr) { > psnr = kMaxPsnr; >+ } > > return psnr; > } > > LIBYUV_API >-double CalcFramePsnr(const uint8* src_a, >+double CalcFramePsnr(const uint8_t* src_a, > int stride_a, >- const uint8* src_b, >+ const uint8_t* src_b, > int stride_b, > int width, > int height) { >- const uint64 samples = width * height; >- const uint64 sse = ComputeSumSquareErrorPlane(src_a, stride_a, src_b, >- stride_b, width, height); >+ const uint64_t samples = (uint64_t)width * (uint64_t)height; >+ const uint64_t sse = ComputeSumSquareErrorPlane(src_a, stride_a, src_b, >+ stride_b, width, height); > return SumSquareErrorToPsnr(sse, samples); > } > > LIBYUV_API >-double I420Psnr(const uint8* src_y_a, >+double I420Psnr(const uint8_t* src_y_a, > int stride_y_a, >- const uint8* src_u_a, >+ const uint8_t* src_u_a, > int stride_u_a, >- const uint8* src_v_a, >+ const uint8_t* src_v_a, > int stride_v_a, >- const uint8* src_y_b, >+ const uint8_t* src_y_b, > int stride_y_b, >- const uint8* src_u_b, >+ const uint8_t* src_u_b, > int stride_u_b, >- const uint8* src_v_b, >+ const uint8_t* src_v_b, > int stride_v_b, > int width, > int height) { >- const uint64 sse_y = ComputeSumSquareErrorPlane(src_y_a, stride_y_a, src_y_b, >- stride_y_b, width, height); >+ const uint64_t sse_y = ComputeSumSquareErrorPlane( >+ src_y_a, stride_y_a, src_y_b, stride_y_b, width, height); > const int width_uv = (width + 1) >> 1; > const int height_uv = (height + 1) >> 1; >- const uint64 sse_u = ComputeSumSquareErrorPlane( >+ const uint64_t sse_u = ComputeSumSquareErrorPlane( > src_u_a, stride_u_a, src_u_b, stride_u_b, width_uv, height_uv); >- const uint64 sse_v = ComputeSumSquareErrorPlane( >+ const uint64_t sse_v = ComputeSumSquareErrorPlane( > src_v_a, stride_v_a, src_v_b, stride_v_b, width_uv, height_uv); >- const uint64 samples = width * height + 2 * (width_uv * height_uv); >- const uint64 sse = sse_y + sse_u + sse_v; >+ const uint64_t samples = (uint64_t)width * (uint64_t)height + >+ 2 * ((uint64_t)width_uv * (uint64_t)height_uv); >+ const uint64_t sse = sse_y + sse_u + sse_v; > return SumSquareErrorToPsnr(sse, samples); > } > >-static const int64 cc1 = 26634; // (64^2*(.01*255)^2 >-static const int64 cc2 = 239708; // (64^2*(.03*255)^2 >+static const int64_t cc1 = 26634; // (64^2*(.01*255)^2 >+static const int64_t cc2 = 239708; // (64^2*(.03*255)^2 > >-static double Ssim8x8_C(const uint8* src_a, >+static double Ssim8x8_C(const uint8_t* src_a, > int stride_a, >- const uint8* src_b, >+ const uint8_t* src_b, > int stride_b) { >- int64 sum_a = 0; >- int64 sum_b = 0; >- int64 sum_sq_a = 0; >- int64 sum_sq_b = 0; >- int64 sum_axb = 0; >+ int64_t sum_a = 0; >+ int64_t sum_b = 0; >+ int64_t sum_sq_a = 0; >+ int64_t sum_sq_b = 0; >+ int64_t sum_axb = 0; > > int i; > for (i = 0; i < 8; ++i) { >@@ -335,20 +341,20 @@ static double Ssim8x8_C(const uint8* src_a, > } > > { >- const int64 count = 64; >+ const int64_t count = 64; > // scale the constants by number of pixels >- const int64 c1 = (cc1 * count * count) >> 12; >- const int64 c2 = (cc2 * count * count) >> 12; >+ const int64_t c1 = (cc1 * count * count) >> 12; >+ const int64_t c2 = (cc2 * count * count) >> 12; > >- const int64 sum_a_x_sum_b = sum_a * sum_b; >+ const int64_t sum_a_x_sum_b = sum_a * sum_b; > >- const int64 ssim_n = (2 * sum_a_x_sum_b + c1) * >- (2 * count * sum_axb - 2 * sum_a_x_sum_b + c2); >+ const int64_t ssim_n = (2 * sum_a_x_sum_b + c1) * >+ (2 * count * sum_axb - 2 * sum_a_x_sum_b + c2); > >- const int64 sum_a_sq = sum_a * sum_a; >- const int64 sum_b_sq = sum_b * sum_b; >+ const int64_t sum_a_sq = sum_a * sum_a; >+ const int64_t sum_b_sq = sum_b * sum_b; > >- const int64 ssim_d = >+ const int64_t ssim_d = > (sum_a_sq + sum_b_sq + c1) * > (count * sum_sq_a - sum_a_sq + count * sum_sq_b - sum_b_sq + c2); > >@@ -363,15 +369,15 @@ static double Ssim8x8_C(const uint8* src_a, > // on the 4x4 pixel grid. Such arrangement allows the windows to overlap > // block boundaries to penalize blocking artifacts. > LIBYUV_API >-double CalcFrameSsim(const uint8* src_a, >+double CalcFrameSsim(const uint8_t* src_a, > int stride_a, >- const uint8* src_b, >+ const uint8_t* src_b, > int stride_b, > int width, > int height) { > int samples = 0; > double ssim_total = 0; >- double (*Ssim8x8)(const uint8* src_a, int stride_a, const uint8* src_b, >+ double (*Ssim8x8)(const uint8_t* src_a, int stride_a, const uint8_t* src_b, > int stride_b) = Ssim8x8_C; > > // sample point start with each 4x4 location >@@ -392,17 +398,17 @@ double CalcFrameSsim(const uint8* src_a, > } > > LIBYUV_API >-double I420Ssim(const uint8* src_y_a, >+double I420Ssim(const uint8_t* src_y_a, > int stride_y_a, >- const uint8* src_u_a, >+ const uint8_t* src_u_a, > int stride_u_a, >- const uint8* src_v_a, >+ const uint8_t* src_v_a, > int stride_v_a, >- const uint8* src_y_b, >+ const uint8_t* src_y_b, > int stride_y_b, >- const uint8* src_u_b, >+ const uint8_t* src_u_b, > int stride_u_b, >- const uint8* src_v_b, >+ const uint8_t* src_v_b, > int stride_v_b, > int width, > int height) { >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_common.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_common.cc >index 83564a1bcb5a98b63ad963abcc9b6c55562a4451..633466addb53e48b4ae839187c6b59cdd23c8eb6 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_common.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_common.cc >@@ -18,8 +18,10 @@ extern "C" { > #endif > > #if ORIGINAL_OPT >-uint32 HammingDistance_C1(const uint8* src_a, const uint8* src_b, int count) { >- uint32 diff = 0u; >+uint32_t HammingDistance_C1(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t diff = 0u; > > int i; > for (i = 0; i < count; ++i) { >@@ -46,13 +48,15 @@ uint32 HammingDistance_C1(const uint8* src_a, const uint8* src_b, int count) { > #endif > > // Hakmem method for hamming distance. >-uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) { >- uint32 diff = 0u; >+uint32_t HammingDistance_C(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t diff = 0u; > > int i; > for (i = 0; i < count - 3; i += 4) { >- uint32 x = *((uint32*)src_a) ^ *((uint32*)src_b); >- uint32 u = x - ((x >> 1) & 0x55555555); >+ uint32_t x = *((uint32_t*)src_a) ^ *((uint32_t*)src_b); // NOLINT >+ uint32_t u = x - ((x >> 1) & 0x55555555); > u = ((u >> 2) & 0x33333333) + (u & 0x33333333); > diff += ((((u + (u >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24); > src_a += 4; >@@ -60,8 +64,8 @@ uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) { > } > > for (; i < count; ++i) { >- uint32 x = *src_a ^ *src_b; >- uint32 u = x - ((x >> 1) & 0x55); >+ uint32_t x = *src_a ^ *src_b; >+ uint32_t u = x - ((x >> 1) & 0x55); > u = ((u >> 2) & 0x33) + (u & 0x33); > diff += (u + (u >> 4)) & 0x0f; > src_a += 1; >@@ -71,20 +75,22 @@ uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) { > return diff; > } > >-uint32 SumSquareError_C(const uint8* src_a, const uint8* src_b, int count) { >- uint32 sse = 0u; >+uint32_t SumSquareError_C(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t sse = 0u; > int i; > for (i = 0; i < count; ++i) { > int diff = src_a[i] - src_b[i]; >- sse += (uint32)(diff * diff); >+ sse += (uint32_t)(diff * diff); > } > return sse; > } > > // hash seed of 5381 recommended. > // Internal C version of HashDjb2 with int sized count for efficiency. >-uint32 HashDjb2_C(const uint8* src, int count, uint32 seed) { >- uint32 hash = seed; >+uint32_t HashDjb2_C(const uint8_t* src, int count, uint32_t seed) { >+ uint32_t hash = seed; > int i; > for (i = 0; i < count; ++i) { > hash += (hash << 5) + src[i]; >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_gcc.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_gcc.cc >index 595c8ec4ae2aef0ba24f85d671e4197c0a37f4f7..676527c1b1b3b83fea70133153cd77a1c077ad4a 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_gcc.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_gcc.cc >@@ -23,10 +23,10 @@ extern "C" { > (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) > > #if defined(__x86_64__) >-uint32 HammingDistance_SSE42(const uint8* src_a, >- const uint8* src_b, >- int count) { >- uint64 diff = 0u; >+uint32_t HammingDistance_SSE42(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint64_t diff = 0u; > > asm volatile( > "xor %3,%3 \n" >@@ -68,13 +68,13 @@ uint32 HammingDistance_SSE42(const uint8* src_a, > : > : "memory", "cc", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10"); > >- return static_cast<uint32>(diff); >+ return static_cast<uint32_t>(diff); > } > #else >-uint32 HammingDistance_SSE42(const uint8* src_a, >- const uint8* src_b, >- int count) { >- uint32 diff = 0u; >+uint32_t HammingDistance_SSE42(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t diff = 0u; > > asm volatile( > // Process 16 bytes per loop. >@@ -111,14 +111,14 @@ uint32 HammingDistance_SSE42(const uint8* src_a, > } > #endif > >-static vec8 kNibbleMask = {15, 15, 15, 15, 15, 15, 15, 15, >- 15, 15, 15, 15, 15, 15, 15, 15}; >-static vec8 kBitCount = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; >+static const vec8 kNibbleMask = {15, 15, 15, 15, 15, 15, 15, 15, >+ 15, 15, 15, 15, 15, 15, 15, 15}; >+static const vec8 kBitCount = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; > >-uint32 HammingDistance_SSSE3(const uint8* src_a, >- const uint8* src_b, >- int count) { >- uint32 diff = 0u; >+uint32_t HammingDistance_SSSE3(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t diff = 0u; > > asm volatile( > "movdqa %4,%%xmm2 \n" >@@ -174,8 +174,10 @@ uint32 HammingDistance_SSSE3(const uint8* src_a, > } > > #ifdef HAS_HAMMINGDISTANCE_AVX2 >-uint32 HammingDistance_AVX2(const uint8* src_a, const uint8* src_b, int count) { >- uint32 diff = 0u; >+uint32_t HammingDistance_AVX2(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t diff = 0u; > > asm volatile( > "vbroadcastf128 %4,%%ymm2 \n" >@@ -227,124 +229,127 @@ uint32 HammingDistance_AVX2(const uint8* src_a, const uint8* src_b, int count) { > } > #endif // HAS_HAMMINGDISTANCE_AVX2 > >-uint32 SumSquareError_SSE2(const uint8* src_a, const uint8* src_b, int count) { >- uint32 sse; >- asm volatile ( >- "pxor %%xmm0,%%xmm0 \n" >- "pxor %%xmm5,%%xmm5 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm1 \n" >- "lea " MEMLEA(0x10, 0) ",%0 \n" >- "movdqu " MEMACCESS(1) ",%%xmm2 \n" >- "lea " MEMLEA(0x10, 1) ",%1 \n" >- "movdqa %%xmm1,%%xmm3 \n" >- "psubusb %%xmm2,%%xmm1 \n" >- "psubusb %%xmm3,%%xmm2 \n" >- "por %%xmm2,%%xmm1 \n" >- "movdqa %%xmm1,%%xmm2 \n" >- "punpcklbw %%xmm5,%%xmm1 \n" >- "punpckhbw %%xmm5,%%xmm2 \n" >- "pmaddwd %%xmm1,%%xmm1 \n" >- "pmaddwd %%xmm2,%%xmm2 \n" >- "paddd %%xmm1,%%xmm0 \n" >- "paddd %%xmm2,%%xmm0 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >+uint32_t SumSquareError_SSE2(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t sse; >+ asm volatile( >+ "pxor %%xmm0,%%xmm0 \n" >+ "pxor %%xmm5,%%xmm5 \n" > >- "pshufd $0xee,%%xmm0,%%xmm1 \n" >- "paddd %%xmm1,%%xmm0 \n" >- "pshufd $0x1,%%xmm0,%%xmm1 \n" >- "paddd %%xmm1,%%xmm0 \n" >- "movd %%xmm0,%3 \n" >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm1 \n" >+ "lea 0x10(%0),%0 \n" >+ "movdqu (%1),%%xmm2 \n" >+ "lea 0x10(%1),%1 \n" >+ "movdqa %%xmm1,%%xmm3 \n" >+ "psubusb %%xmm2,%%xmm1 \n" >+ "psubusb %%xmm3,%%xmm2 \n" >+ "por %%xmm2,%%xmm1 \n" >+ "movdqa %%xmm1,%%xmm2 \n" >+ "punpcklbw %%xmm5,%%xmm1 \n" >+ "punpckhbw %%xmm5,%%xmm2 \n" >+ "pmaddwd %%xmm1,%%xmm1 \n" >+ "pmaddwd %%xmm2,%%xmm2 \n" >+ "paddd %%xmm1,%%xmm0 \n" >+ "paddd %%xmm2,%%xmm0 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" > >- : "+r"(src_a), // %0 >- "+r"(src_b), // %1 >- "+r"(count), // %2 >- "=g"(sse) // %3 >- :: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ "pshufd $0xee,%%xmm0,%%xmm1 \n" >+ "paddd %%xmm1,%%xmm0 \n" >+ "pshufd $0x1,%%xmm0,%%xmm1 \n" >+ "paddd %%xmm1,%%xmm0 \n" >+ "movd %%xmm0,%3 \n" >+ >+ : "+r"(src_a), // %0 >+ "+r"(src_b), // %1 >+ "+r"(count), // %2 >+ "=g"(sse) // %3 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > return sse; > } > >-static uvec32 kHash16x33 = {0x92d9e201, 0, 0, 0}; // 33 ^ 16 >-static uvec32 kHashMul0 = { >+static const uvec32 kHash16x33 = {0x92d9e201, 0, 0, 0}; // 33 ^ 16 >+static const uvec32 kHashMul0 = { > 0x0c3525e1, // 33 ^ 15 > 0xa3476dc1, // 33 ^ 14 > 0x3b4039a1, // 33 ^ 13 > 0x4f5f0981, // 33 ^ 12 > }; >-static uvec32 kHashMul1 = { >+static const uvec32 kHashMul1 = { > 0x30f35d61, // 33 ^ 11 > 0x855cb541, // 33 ^ 10 > 0x040a9121, // 33 ^ 9 > 0x747c7101, // 33 ^ 8 > }; >-static uvec32 kHashMul2 = { >+static const uvec32 kHashMul2 = { > 0xec41d4e1, // 33 ^ 7 > 0x4cfa3cc1, // 33 ^ 6 > 0x025528a1, // 33 ^ 5 > 0x00121881, // 33 ^ 4 > }; >-static uvec32 kHashMul3 = { >+static const uvec32 kHashMul3 = { > 0x00008c61, // 33 ^ 3 > 0x00000441, // 33 ^ 2 > 0x00000021, // 33 ^ 1 > 0x00000001, // 33 ^ 0 > }; > >-uint32 HashDjb2_SSE41(const uint8* src, int count, uint32 seed) { >- uint32 hash; >- asm volatile ( >- "movd %2,%%xmm0 \n" >- "pxor %%xmm7,%%xmm7 \n" >- "movdqa %4,%%xmm6 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm1 \n" >- "lea " MEMLEA(0x10, 0) ",%0 \n" >- "pmulld %%xmm6,%%xmm0 \n" >- "movdqa %5,%%xmm5 \n" >- "movdqa %%xmm1,%%xmm2 \n" >- "punpcklbw %%xmm7,%%xmm2 \n" >- "movdqa %%xmm2,%%xmm3 \n" >- "punpcklwd %%xmm7,%%xmm3 \n" >- "pmulld %%xmm5,%%xmm3 \n" >- "movdqa %6,%%xmm5 \n" >- "movdqa %%xmm2,%%xmm4 \n" >- "punpckhwd %%xmm7,%%xmm4 \n" >- "pmulld %%xmm5,%%xmm4 \n" >- "movdqa %7,%%xmm5 \n" >- "punpckhbw %%xmm7,%%xmm1 \n" >- "movdqa %%xmm1,%%xmm2 \n" >- "punpcklwd %%xmm7,%%xmm2 \n" >- "pmulld %%xmm5,%%xmm2 \n" >- "movdqa %8,%%xmm5 \n" >- "punpckhwd %%xmm7,%%xmm1 \n" >- "pmulld %%xmm5,%%xmm1 \n" >- "paddd %%xmm4,%%xmm3 \n" >- "paddd %%xmm2,%%xmm1 \n" >- "paddd %%xmm3,%%xmm1 \n" >- "pshufd $0xe,%%xmm1,%%xmm2 \n" >- "paddd %%xmm2,%%xmm1 \n" >- "pshufd $0x1,%%xmm1,%%xmm2 \n" >- "paddd %%xmm2,%%xmm1 \n" >- "paddd %%xmm1,%%xmm0 \n" >- "sub $0x10,%1 \n" >- "jg 1b \n" >- "movd %%xmm0,%3 \n" >- : "+r"(src), // %0 >- "+r"(count), // %1 >- "+rm"(seed), // %2 >- "=g"(hash) // %3 >- : "m"(kHash16x33), // %4 >- "m"(kHashMul0), // %5 >- "m"(kHashMul1), // %6 >- "m"(kHashMul2), // %7 >- "m"(kHashMul3) // %8 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+uint32_t HashDjb2_SSE41(const uint8_t* src, int count, uint32_t seed) { >+ uint32_t hash; >+ asm volatile( >+ "movd %2,%%xmm0 \n" >+ "pxor %%xmm7,%%xmm7 \n" >+ "movdqa %4,%%xmm6 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm1 \n" >+ "lea 0x10(%0),%0 \n" >+ "pmulld %%xmm6,%%xmm0 \n" >+ "movdqa %5,%%xmm5 \n" >+ "movdqa %%xmm1,%%xmm2 \n" >+ "punpcklbw %%xmm7,%%xmm2 \n" >+ "movdqa %%xmm2,%%xmm3 \n" >+ "punpcklwd %%xmm7,%%xmm3 \n" >+ "pmulld %%xmm5,%%xmm3 \n" >+ "movdqa %6,%%xmm5 \n" >+ "movdqa %%xmm2,%%xmm4 \n" >+ "punpckhwd %%xmm7,%%xmm4 \n" >+ "pmulld %%xmm5,%%xmm4 \n" >+ "movdqa %7,%%xmm5 \n" >+ "punpckhbw %%xmm7,%%xmm1 \n" >+ "movdqa %%xmm1,%%xmm2 \n" >+ "punpcklwd %%xmm7,%%xmm2 \n" >+ "pmulld %%xmm5,%%xmm2 \n" >+ "movdqa %8,%%xmm5 \n" >+ "punpckhwd %%xmm7,%%xmm1 \n" >+ "pmulld %%xmm5,%%xmm1 \n" >+ "paddd %%xmm4,%%xmm3 \n" >+ "paddd %%xmm2,%%xmm1 \n" >+ "paddd %%xmm3,%%xmm1 \n" >+ "pshufd $0xe,%%xmm1,%%xmm2 \n" >+ "paddd %%xmm2,%%xmm1 \n" >+ "pshufd $0x1,%%xmm1,%%xmm2 \n" >+ "paddd %%xmm2,%%xmm1 \n" >+ "paddd %%xmm1,%%xmm0 \n" >+ "sub $0x10,%1 \n" >+ "jg 1b \n" >+ "movd %%xmm0,%3 \n" >+ : "+r"(src), // %0 >+ "+r"(count), // %1 >+ "+rm"(seed), // %2 >+ "=g"(hash) // %3 >+ : "m"(kHash16x33), // %4 >+ "m"(kHashMul0), // %5 >+ "m"(kHashMul1), // %6 >+ "m"(kHashMul2), // %7 >+ "m"(kHashMul3) // %8 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > return hash; > } > #endif // defined(__x86_64__) || (defined(__i386__) && !defined(__pic__))) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_msa.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_msa.cc >index efb5185aac7ea31dee05bf86e08234d225caee14..e944235f02060baaae70f29da4c427d549dd810c 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_msa.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_msa.cc >@@ -22,8 +22,10 @@ namespace libyuv { > extern "C" { > #endif > >-uint32 HammingDistance_MSA(const uint8* src_a, const uint8* src_b, int count) { >- uint32 diff = 0u; >+uint32_t HammingDistance_MSA(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t diff = 0u; > int i; > v16u8 src0, src1, src2, src3; > v2i64 vec0 = {0}, vec1 = {0}; >@@ -42,13 +44,15 @@ uint32 HammingDistance_MSA(const uint8* src_a, const uint8* src_b, int count) { > } > > vec0 += vec1; >- diff = (uint32)__msa_copy_u_w((v4i32)vec0, 0); >- diff += (uint32)__msa_copy_u_w((v4i32)vec0, 2); >+ diff = (uint32_t)__msa_copy_u_w((v4i32)vec0, 0); >+ diff += (uint32_t)__msa_copy_u_w((v4i32)vec0, 2); > return diff; > } > >-uint32 SumSquareError_MSA(const uint8* src_a, const uint8* src_b, int count) { >- uint32 sse = 0u; >+uint32_t SumSquareError_MSA(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t sse = 0u; > int i; > v16u8 src0, src1, src2, src3; > v8i16 vec0, vec1, vec2, vec3; >@@ -80,8 +84,8 @@ uint32 SumSquareError_MSA(const uint8* src_a, const uint8* src_b, int count) { > reg2 += reg3; > reg0 += reg2; > tmp0 = __msa_hadd_s_d(reg0, reg0); >- sse = (uint32)__msa_copy_u_w((v4i32)tmp0, 0); >- sse += (uint32)__msa_copy_u_w((v4i32)tmp0, 2); >+ sse = (uint32_t)__msa_copy_u_w((v4i32)tmp0, 0); >+ sse += (uint32_t)__msa_copy_u_w((v4i32)tmp0, 2); > return sse; > } > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_neon.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_neon.cc >index 5dfa71edcbfd1c1b991e0c4c1e70f31479e5a310..2a2181e0cb37fdd5ab68bcc6fa50d91b9e1a66d0 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_neon.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_neon.cc >@@ -23,8 +23,10 @@ extern "C" { > > // 256 bits at a time > // uses short accumulator which restricts count to 131 KB >-uint32 HammingDistance_NEON(const uint8* src_a, const uint8* src_b, int count) { >- uint32 diff; >+uint32_t HammingDistance_NEON(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t diff; > > asm volatile( > "vmov.u16 q4, #0 \n" // accumulator >@@ -52,8 +54,10 @@ uint32 HammingDistance_NEON(const uint8* src_a, const uint8* src_b, int count) { > return diff; > } > >-uint32 SumSquareError_NEON(const uint8* src_a, const uint8* src_b, int count) { >- uint32 sse; >+uint32_t SumSquareError_NEON(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t sse; > asm volatile( > "vmov.u8 q8, #0 \n" > "vmov.u8 q10, #0 \n" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_neon64.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_neon64.cc >index ddf98fa68b2ba057aca4d8c7ebb92d7b00b01410..6e8f672ab73ae41cc6e30c6c508f3093650edbff 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_neon64.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_neon64.cc >@@ -22,8 +22,10 @@ extern "C" { > > // 256 bits at a time > // uses short accumulator which restricts count to 131 KB >-uint32 HammingDistance_NEON(const uint8* src_a, const uint8* src_b, int count) { >- uint32 diff; >+uint32_t HammingDistance_NEON(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t diff; > asm volatile( > "movi v4.8h, #0 \n" > >@@ -47,8 +49,10 @@ uint32 HammingDistance_NEON(const uint8* src_a, const uint8* src_b, int count) { > return diff; > } > >-uint32 SumSquareError_NEON(const uint8* src_a, const uint8* src_b, int count) { >- uint32 sse; >+uint32_t SumSquareError_NEON(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t sse; > asm volatile( > "eor v16.16b, v16.16b, v16.16b \n" > "eor v18.16b, v18.16b, v18.16b \n" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_win.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_win.cc >index bcd6a88ebbb753ddfc39f8fb3a1c9b51a32022df..d57d3d9d1c8edf3cbc94bc73c28de1c3081c5b95 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_win.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/compare_win.cc >@@ -25,14 +25,14 @@ extern "C" { > // This module is for 32 bit Visual C x86 and clangcl > #if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) > >-uint32 HammingDistance_SSE42(const uint8* src_a, >- const uint8* src_b, >- int count) { >- uint32 diff = 0u; >+uint32_t HammingDistance_SSE42(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t diff = 0u; > > int i; > for (i = 0; i < count - 3; i += 4) { >- uint32 x = *((uint32*)src_a) ^ *((uint32*)src_b); >+ uint32_t x = *((uint32_t*)src_a) ^ *((uint32_t*)src_b); // NOLINT > src_a += 4; > src_b += 4; > diff += __popcnt(x); >@@ -40,8 +40,8 @@ uint32 HammingDistance_SSE42(const uint8* src_a, > return diff; > } > >-__declspec(naked) uint32 >- SumSquareError_SSE2(const uint8* src_a, const uint8* src_b, int count) { >+__declspec(naked) uint32_t >+ SumSquareError_SSE2(const uint8_t* src_a, const uint8_t* src_b, int count) { > __asm { > mov eax, [esp + 4] // src_a > mov edx, [esp + 8] // src_b >@@ -81,8 +81,8 @@ __declspec(naked) uint32 > #if _MSC_VER >= 1700 > // C4752: found Intel(R) Advanced Vector Extensions; consider using /arch:AVX. > #pragma warning(disable : 4752) >-__declspec(naked) uint32 >- SumSquareError_AVX2(const uint8* src_a, const uint8* src_b, int count) { >+__declspec(naked) uint32_t >+ SumSquareError_AVX2(const uint8_t* src_a, const uint8_t* src_b, int count) { > __asm { > mov eax, [esp + 4] // src_a > mov edx, [esp + 8] // src_b >@@ -146,8 +146,8 @@ uvec32 kHashMul3 = { > 0x00000001, // 33 ^ 0 > }; > >-__declspec(naked) uint32 >- HashDjb2_SSE41(const uint8* src, int count, uint32 seed) { >+__declspec(naked) uint32_t >+ HashDjb2_SSE41(const uint8_t* src, int count, uint32_t seed) { > __asm { > mov eax, [esp + 4] // src > mov ecx, [esp + 8] // count >@@ -197,8 +197,8 @@ __declspec(naked) uint32 > > // Visual C 2012 required for AVX2. > #if _MSC_VER >= 1700 >-__declspec(naked) uint32 >- HashDjb2_AVX2(const uint8* src, int count, uint32 seed) { >+__declspec(naked) uint32_t >+ HashDjb2_AVX2(const uint8_t* src, int count, uint32_t seed) { > __asm { > mov eax, [esp + 4] // src > mov ecx, [esp + 8] // count >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert.cc >index dfa83a5a6d8680df1e066b8e4339d527b3e298fc..375cc732c1d710ebd8ccbc44ac1d4ff4a8a81e2f 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert.cc >@@ -28,17 +28,17 @@ static __inline int Abs(int v) { > } > > // Any I4xx To I420 format with mirroring. >-static int I4xxToI420(const uint8* src_y, >+static int I4xxToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int src_y_width, > int src_y_height, >@@ -62,21 +62,21 @@ static int I4xxToI420(const uint8* src_y, > return 0; > } > >-// Copy I420 with optional flipping >+// Copy I420 with optional flipping. > // TODO(fbarchard): Use Scale plane which supports mirroring, but ensure > // is does row coalescing. > LIBYUV_API >-int I420Copy(const uint8* src_y, >+int I420Copy(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -106,20 +106,106 @@ int I420Copy(const uint8* src_y, > return 0; > } > >+// Copy I010 with optional flipping. >+LIBYUV_API >+int I010Copy(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint16_t* dst_y, >+ int dst_stride_y, >+ uint16_t* dst_u, >+ int dst_stride_u, >+ uint16_t* dst_v, >+ int dst_stride_v, >+ int width, >+ int height) { >+ int halfwidth = (width + 1) >> 1; >+ int halfheight = (height + 1) >> 1; >+ if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ halfheight = (height + 1) >> 1; >+ src_y = src_y + (height - 1) * src_stride_y; >+ src_u = src_u + (halfheight - 1) * src_stride_u; >+ src_v = src_v + (halfheight - 1) * src_stride_v; >+ src_stride_y = -src_stride_y; >+ src_stride_u = -src_stride_u; >+ src_stride_v = -src_stride_v; >+ } >+ >+ if (dst_y) { >+ CopyPlane_16(src_y, src_stride_y, dst_y, dst_stride_y, width, height); >+ } >+ // Copy UV planes. >+ CopyPlane_16(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight); >+ CopyPlane_16(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight); >+ return 0; >+} >+ >+// Convert 10 bit YUV to 8 bit. >+LIBYUV_API >+int I010ToI420(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_y, >+ int dst_stride_y, >+ uint8_t* dst_u, >+ int dst_stride_u, >+ uint8_t* dst_v, >+ int dst_stride_v, >+ int width, >+ int height) { >+ int halfwidth = (width + 1) >> 1; >+ int halfheight = (height + 1) >> 1; >+ if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ halfheight = (height + 1) >> 1; >+ src_y = src_y + (height - 1) * src_stride_y; >+ src_u = src_u + (halfheight - 1) * src_stride_u; >+ src_v = src_v + (halfheight - 1) * src_stride_v; >+ src_stride_y = -src_stride_y; >+ src_stride_u = -src_stride_u; >+ src_stride_v = -src_stride_v; >+ } >+ >+ // Convert Y plane. >+ Convert16To8Plane(src_y, src_stride_y, dst_y, dst_stride_y, 16384, width, >+ height); >+ // Convert UV planes. >+ Convert16To8Plane(src_u, src_stride_u, dst_u, dst_stride_u, 16384, halfwidth, >+ halfheight); >+ Convert16To8Plane(src_v, src_stride_v, dst_v, dst_stride_v, 16384, halfwidth, >+ halfheight); >+ return 0; >+} >+ > // 422 chroma is 1/2 width, 1x height > // 420 chroma is 1/2 width, 1/2 height > LIBYUV_API >-int I422ToI420(const uint8* src_y, >+int I422ToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -132,17 +218,17 @@ int I422ToI420(const uint8* src_y, > // 444 chroma is 1x width, 1x height > // 420 chroma is 1/2 width, 1/2 height > LIBYUV_API >-int I444ToI420(const uint8* src_y, >+int I444ToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -153,13 +239,13 @@ int I444ToI420(const uint8* src_y, > > // I400 is greyscale typically used in MJPG > LIBYUV_API >-int I400ToI420(const uint8* src_y, >+int I400ToI420(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -183,15 +269,15 @@ int I400ToI420(const uint8* src_y, > return 0; > } > >-static void CopyPlane2(const uint8* src, >+static void CopyPlane2(const uint8_t* src, > int src_stride_0, > int src_stride_1, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height) { > int y; >- void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; >+ void (*CopyRow)(const uint8_t* src, uint8_t* dst, int width) = CopyRow_C; > #if defined(HAS_COPYROW_SSE2) > if (TestCpuFlag(kCpuHasSSE2)) { > CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; >@@ -212,11 +298,6 @@ static void CopyPlane2(const uint8* src, > CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON; > } > #endif >-#if defined(HAS_COPYROW_MIPS) >- if (TestCpuFlag(kCpuHasMIPS)) { >- CopyRow = CopyRow_MIPS; >- } >-#endif > > // Copy plane > for (y = 0; y < height - 1; y += 2) { >@@ -239,16 +320,16 @@ static void CopyPlane2(const uint8* src, > // src_stride_m420 is row planar. Normally this will be the width in pixels. > // The UV plane is half width, but 2 values, so src_stride_m420 applies to > // this as well as the two Y planes. >-static int X420ToI420(const uint8* src_y, >+static int X420ToI420(const uint8_t* src_y, > int src_stride_y0, > int src_stride_y1, >- const uint8* src_uv, >+ const uint8_t* src_uv, > int src_stride_uv, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -303,15 +384,15 @@ static int X420ToI420(const uint8* src_y, > > // Convert NV12 to I420. > LIBYUV_API >-int NV12ToI420(const uint8* src_y, >+int NV12ToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_uv, >+ const uint8_t* src_uv, > int src_stride_uv, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -322,15 +403,15 @@ int NV12ToI420(const uint8* src_y, > > // Convert NV21 to I420. Same as NV12 but u and v pointers swapped. > LIBYUV_API >-int NV21ToI420(const uint8* src_y, >+int NV21ToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_vu, >+ const uint8_t* src_vu, > int src_stride_vu, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -341,13 +422,13 @@ int NV21ToI420(const uint8* src_y, > > // Convert M420 to I420. > LIBYUV_API >-int M420ToI420(const uint8* src_m420, >+int M420ToI420(const uint8_t* src_m420, > int src_stride_m420, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -359,20 +440,21 @@ int M420ToI420(const uint8* src_m420, > > // Convert YUY2 to I420. > LIBYUV_API >-int YUY2ToI420(const uint8* src_yuy2, >+int YUY2ToI420(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*YUY2ToUVRow)(const uint8* src_yuy2, int src_stride_yuy2, uint8* dst_u, >- uint8* dst_v, int width) = YUY2ToUVRow_C; >- void (*YUY2ToYRow)(const uint8* src_yuy2, uint8* dst_y, int width) = >+ void (*YUY2ToUVRow)(const uint8_t* src_yuy2, int src_stride_yuy2, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ YUY2ToUVRow_C; >+ void (*YUY2ToYRow)(const uint8_t* src_yuy2, uint8_t* dst_y, int width) = > YUY2ToYRow_C; > // Negative height means invert the image. > if (height < 0) { >@@ -439,20 +521,21 @@ int YUY2ToI420(const uint8* src_yuy2, > > // Convert UYVY to I420. > LIBYUV_API >-int UYVYToI420(const uint8* src_uyvy, >+int UYVYToI420(const uint8_t* src_uyvy, > int src_stride_uyvy, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*UYVYToUVRow)(const uint8* src_uyvy, int src_stride_uyvy, uint8* dst_u, >- uint8* dst_v, int width) = UYVYToUVRow_C; >- void (*UYVYToYRow)(const uint8* src_uyvy, uint8* dst_y, int width) = >+ void (*UYVYToUVRow)(const uint8_t* src_uyvy, int src_stride_uyvy, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ UYVYToUVRow_C; >+ void (*UYVYToYRow)(const uint8_t* src_uyvy, uint8_t* dst_y, int width) = > UYVYToYRow_C; > // Negative height means invert the image. > if (height < 0) { >@@ -519,20 +602,21 @@ int UYVYToI420(const uint8* src_uyvy, > > // Convert ARGB to I420. > LIBYUV_API >-int ARGBToI420(const uint8* src_argb, >+int ARGBToI420(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; > if (!src_argb || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; >@@ -579,14 +663,6 @@ int ARGBToI420(const uint8* src_argb, > } > } > #endif >-#if defined(HAS_ARGBTOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToYRow = ARGBToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- ARGBToYRow = ARGBToYRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_ARGBTOYROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > ARGBToYRow = ARGBToYRow_Any_MSA; >@@ -595,14 +671,6 @@ int ARGBToI420(const uint8* src_argb, > } > } > #endif >-#if defined(HAS_ARGBTOUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToUVRow = ARGBToUVRow_Any_DSPR2; >- if (IS_ALIGNED(width, 16)) { >- ARGBToUVRow = ARGBToUVRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_ARGBTOUVROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > ARGBToUVRow = ARGBToUVRow_Any_MSA; >@@ -630,20 +698,21 @@ int ARGBToI420(const uint8* src_argb, > > // Convert BGRA to I420. > LIBYUV_API >-int BGRAToI420(const uint8* src_bgra, >+int BGRAToI420(const uint8_t* src_bgra, > int src_stride_bgra, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*BGRAToUVRow)(const uint8* src_bgra0, int src_stride_bgra, uint8* dst_u, >- uint8* dst_v, int width) = BGRAToUVRow_C; >- void (*BGRAToYRow)(const uint8* src_bgra, uint8* dst_y, int width) = >+ void (*BGRAToUVRow)(const uint8_t* src_bgra0, int src_stride_bgra, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ BGRAToUVRow_C; >+ void (*BGRAToYRow)(const uint8_t* src_bgra, uint8_t* dst_y, int width) = > BGRAToYRow_C; > if (!src_bgra || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; >@@ -680,22 +749,6 @@ int BGRAToI420(const uint8* src_bgra, > } > } > #endif >-#if defined(HAS_BGRATOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- BGRAToYRow = BGRAToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- BGRAToYRow = BGRAToYRow_DSPR2; >- } >- } >-#endif >-#if defined(HAS_BGRATOUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- BGRAToUVRow = BGRAToUVRow_Any_DSPR2; >- if (IS_ALIGNED(width, 16)) { >- BGRAToUVRow = BGRAToUVRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_BGRATOYROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > BGRAToYRow = BGRAToYRow_Any_MSA; >@@ -731,20 +784,21 @@ int BGRAToI420(const uint8* src_bgra, > > // Convert ABGR to I420. > LIBYUV_API >-int ABGRToI420(const uint8* src_abgr, >+int ABGRToI420(const uint8_t* src_abgr, > int src_stride_abgr, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*ABGRToUVRow)(const uint8* src_abgr0, int src_stride_abgr, uint8* dst_u, >- uint8* dst_v, int width) = ABGRToUVRow_C; >- void (*ABGRToYRow)(const uint8* src_abgr, uint8* dst_y, int width) = >+ void (*ABGRToUVRow)(const uint8_t* src_abgr0, int src_stride_abgr, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ABGRToUVRow_C; >+ void (*ABGRToYRow)(const uint8_t* src_abgr, uint8_t* dst_y, int width) = > ABGRToYRow_C; > if (!src_abgr || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; >@@ -781,22 +835,6 @@ int ABGRToI420(const uint8* src_abgr, > } > } > #endif >-#if defined(HAS_ABGRTOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ABGRToYRow = ABGRToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- ABGRToYRow = ABGRToYRow_DSPR2; >- } >- } >-#endif >-#if defined(HAS_ABGRTOUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ABGRToUVRow = ABGRToUVRow_Any_DSPR2; >- if (IS_ALIGNED(width, 16)) { >- ABGRToUVRow = ABGRToUVRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_ABGRTOYROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > ABGRToYRow = ABGRToYRow_Any_MSA; >@@ -832,20 +870,21 @@ int ABGRToI420(const uint8* src_abgr, > > // Convert RGBA to I420. > LIBYUV_API >-int RGBAToI420(const uint8* src_rgba, >+int RGBAToI420(const uint8_t* src_rgba, > int src_stride_rgba, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*RGBAToUVRow)(const uint8* src_rgba0, int src_stride_rgba, uint8* dst_u, >- uint8* dst_v, int width) = RGBAToUVRow_C; >- void (*RGBAToYRow)(const uint8* src_rgba, uint8* dst_y, int width) = >+ void (*RGBAToUVRow)(const uint8_t* src_rgba0, int src_stride_rgba, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ RGBAToUVRow_C; >+ void (*RGBAToYRow)(const uint8_t* src_rgba, uint8_t* dst_y, int width) = > RGBAToYRow_C; > if (!src_rgba || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; >@@ -882,22 +921,6 @@ int RGBAToI420(const uint8* src_rgba, > } > } > #endif >-#if defined(HAS_RGBATOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- RGBAToYRow = RGBAToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- RGBAToYRow = RGBAToYRow_DSPR2; >- } >- } >-#endif >-#if defined(HAS_RGBATOUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- RGBAToUVRow = RGBAToUVRow_Any_DSPR2; >- if (IS_ALIGNED(width, 16)) { >- RGBAToUVRow = RGBAToUVRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_RGBATOYROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > RGBAToYRow = RGBAToYRow_Any_MSA; >@@ -933,28 +956,30 @@ int RGBAToI420(const uint8* src_rgba, > > // Convert RGB24 to I420. > LIBYUV_API >-int RGB24ToI420(const uint8* src_rgb24, >+int RGB24ToI420(const uint8_t* src_rgb24, > int src_stride_rgb24, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; > #if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA)) >- void (*RGB24ToUVRow)(const uint8* src_rgb24, int src_stride_rgb24, >- uint8* dst_u, uint8* dst_v, int width) = RGB24ToUVRow_C; >- void (*RGB24ToYRow)(const uint8* src_rgb24, uint8* dst_y, int width) = >+ void (*RGB24ToUVRow)(const uint8_t* src_rgb24, int src_stride_rgb24, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ RGB24ToUVRow_C; >+ void (*RGB24ToYRow)(const uint8_t* src_rgb24, uint8_t* dst_y, int width) = > RGB24ToYRow_C; > #else >- void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int width) = >+ void (*RGB24ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) = > RGB24ToARGBRow_C; >- void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; > #endif > if (!src_rgb24 || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { >@@ -1063,28 +1088,29 @@ int RGB24ToI420(const uint8* src_rgb24, > > // Convert RAW to I420. > LIBYUV_API >-int RAWToI420(const uint8* src_raw, >+int RAWToI420(const uint8_t* src_raw, > int src_stride_raw, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; > #if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA)) >- void (*RAWToUVRow)(const uint8* src_raw, int src_stride_raw, uint8* dst_u, >- uint8* dst_v, int width) = RAWToUVRow_C; >- void (*RAWToYRow)(const uint8* src_raw, uint8* dst_y, int width) = >+ void (*RAWToUVRow)(const uint8_t* src_raw, int src_stride_raw, uint8_t* dst_u, >+ uint8_t* dst_v, int width) = RAWToUVRow_C; >+ void (*RAWToYRow)(const uint8_t* src_raw, uint8_t* dst_y, int width) = > RAWToYRow_C; > #else >- void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int width) = >+ void (*RAWToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) = > RAWToARGBRow_C; >- void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; > #endif > if (!src_raw || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { >@@ -1193,29 +1219,30 @@ int RAWToI420(const uint8* src_raw, > > // Convert RGB565 to I420. > LIBYUV_API >-int RGB565ToI420(const uint8* src_rgb565, >+int RGB565ToI420(const uint8_t* src_rgb565, > int src_stride_rgb565, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; > #if (defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA)) >- void (*RGB565ToUVRow)(const uint8* src_rgb565, int src_stride_rgb565, >- uint8* dst_u, uint8* dst_v, int width) = >+ void (*RGB565ToUVRow)(const uint8_t* src_rgb565, int src_stride_rgb565, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = > RGB565ToUVRow_C; >- void (*RGB565ToYRow)(const uint8* src_rgb565, uint8* dst_y, int width) = >+ void (*RGB565ToYRow)(const uint8_t* src_rgb565, uint8_t* dst_y, int width) = > RGB565ToYRow_C; > #else >- void (*RGB565ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int width) = >- RGB565ToARGBRow_C; >- void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*RGB565ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, >+ int width) = RGB565ToARGBRow_C; >+ void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; > #endif > if (!src_rgb565 || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { >@@ -1287,14 +1314,6 @@ int RGB565ToI420(const uint8* src_rgb565, > } > } > #endif >-#if defined(HAS_RGB565TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- RGB565ToARGBRow = RGB565ToARGBRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- RGB565ToARGBRow = RGB565ToARGBRow_DSPR2; >- } >- } >-#endif > #endif > { > #if !(defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA)) >@@ -1338,29 +1357,30 @@ int RGB565ToI420(const uint8* src_rgb565, > > // Convert ARGB1555 to I420. > LIBYUV_API >-int ARGB1555ToI420(const uint8* src_argb1555, >+int ARGB1555ToI420(const uint8_t* src_argb1555, > int src_stride_argb1555, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; > #if (defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA)) >- void (*ARGB1555ToUVRow)(const uint8* src_argb1555, int src_stride_argb1555, >- uint8* dst_u, uint8* dst_v, int width) = >+ void (*ARGB1555ToUVRow)(const uint8_t* src_argb1555, int src_stride_argb1555, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = > ARGB1555ToUVRow_C; >- void (*ARGB1555ToYRow)(const uint8* src_argb1555, uint8* dst_y, int width) = >- ARGB1555ToYRow_C; >+ void (*ARGB1555ToYRow)(const uint8_t* src_argb1555, uint8_t* dst_y, >+ int width) = ARGB1555ToYRow_C; > #else >- void (*ARGB1555ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int width) = >- ARGB1555ToARGBRow_C; >- void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGB1555ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, >+ int width) = ARGB1555ToARGBRow_C; >+ void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; > #endif > if (!src_argb1555 || !dst_y || !dst_u || !dst_v || width <= 0 || >@@ -1479,29 +1499,30 @@ int ARGB1555ToI420(const uint8* src_argb1555, > > // Convert ARGB4444 to I420. > LIBYUV_API >-int ARGB4444ToI420(const uint8* src_argb4444, >+int ARGB4444ToI420(const uint8_t* src_argb4444, > int src_stride_argb4444, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; > #if defined(HAS_ARGB4444TOYROW_NEON) >- void (*ARGB4444ToUVRow)(const uint8* src_argb4444, int src_stride_argb4444, >- uint8* dst_u, uint8* dst_v, int width) = >+ void (*ARGB4444ToUVRow)(const uint8_t* src_argb4444, int src_stride_argb4444, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = > ARGB4444ToUVRow_C; >- void (*ARGB4444ToYRow)(const uint8* src_argb4444, uint8* dst_y, int width) = >- ARGB4444ToYRow_C; >+ void (*ARGB4444ToYRow)(const uint8_t* src_argb4444, uint8_t* dst_y, >+ int width) = ARGB4444ToYRow_C; > #else >- void (*ARGB4444ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int width) = >- ARGB4444ToARGBRow_C; >- void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGB4444ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, >+ int width) = ARGB4444ToARGBRow_C; >+ void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; > #endif > if (!src_argb4444 || !dst_y || !dst_u || !dst_v || width <= 0 || >@@ -1630,9 +1651,9 @@ int ARGB4444ToI420(const uint8* src_argb4444, > return 0; > } > >-static void SplitPixels(const uint8* src_u, >+static void SplitPixels(const uint8_t* src_u, > int src_pixel_stride_uv, >- uint8* dst_u, >+ uint8_t* dst_u, > int width) { > int i; > for (i = 0; i < width; ++i) { >@@ -1644,18 +1665,18 @@ static void SplitPixels(const uint8* src_u, > > // Convert Android420 to I420. > LIBYUV_API >-int Android420ToI420(const uint8* src_y, >+int Android420ToI420(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, > int src_pixel_stride_uv, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -1688,14 +1709,15 @@ int Android420ToI420(const uint8* src_y, > CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight); > return 0; > // Split UV planes - NV21 >- } else if (src_pixel_stride_uv == 2 && vu_off == -1 && >- src_stride_u == src_stride_v) { >+ } >+ if (src_pixel_stride_uv == 2 && vu_off == -1 && >+ src_stride_u == src_stride_v) { > SplitUVPlane(src_v, src_stride_v, dst_v, dst_stride_v, dst_u, dst_stride_u, > halfwidth, halfheight); > return 0; > // Split UV planes - NV12 >- } else if (src_pixel_stride_uv == 2 && vu_off == 1 && >- src_stride_u == src_stride_v) { >+ } >+ if (src_pixel_stride_uv == 2 && vu_off == 1 && src_stride_u == src_stride_v) { > SplitUVPlane(src_u, src_stride_u, dst_u, dst_stride_u, dst_v, dst_stride_v, > halfwidth, halfheight); > return 0; >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_argb.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_argb.cc >index 5007bdb970877d9a34f7e3747c07cadb44123474..4c317ae30c68d61d00fad58c4b3e8a62d8c33b04 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_argb.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_argb.cc >@@ -26,9 +26,9 @@ extern "C" { > > // Copy ARGB with optional flipping > LIBYUV_API >-int ARGBCopy(const uint8* src_argb, >+int ARGBCopy(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >@@ -47,21 +47,21 @@ int ARGBCopy(const uint8* src_argb, > return 0; > } > >-// Convert I422 to ARGB with matrix >-static int I420ToARGBMatrix(const uint8* src_y, >+// Convert I420 to ARGB with matrix >+static int I420ToARGBMatrix(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > const struct YuvConstants* yuvconstants, > int width, > int height) { > int y; >- void (*I422ToARGBRow)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, int width) = > I422ToARGBRow_C; > if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { >@@ -97,15 +97,6 @@ static int I420ToARGBMatrix(const uint8* src_y, > } > } > #endif >-#if defined(HAS_I422TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) && >- IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && >- IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && >- IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) && >- IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) { >- I422ToARGBRow = I422ToARGBRow_DSPR2; >- } >-#endif > #if defined(HAS_I422TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422ToARGBRow = I422ToARGBRow_Any_MSA; >@@ -129,13 +120,13 @@ static int I420ToARGBMatrix(const uint8* src_y, > > // Convert I420 to ARGB. > LIBYUV_API >-int I420ToARGB(const uint8* src_y, >+int I420ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >@@ -146,13 +137,13 @@ int I420ToARGB(const uint8* src_y, > > // Convert I420 to ABGR. > LIBYUV_API >-int I420ToABGR(const uint8* src_y, >+int I420ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height) { >@@ -165,13 +156,13 @@ int I420ToABGR(const uint8* src_y, > > // Convert J420 to ARGB. > LIBYUV_API >-int J420ToARGB(const uint8* src_y, >+int J420ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >@@ -182,13 +173,13 @@ int J420ToARGB(const uint8* src_y, > > // Convert J420 to ABGR. > LIBYUV_API >-int J420ToABGR(const uint8* src_y, >+int J420ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height) { >@@ -201,13 +192,13 @@ int J420ToABGR(const uint8* src_y, > > // Convert H420 to ARGB. > LIBYUV_API >-int H420ToARGB(const uint8* src_y, >+int H420ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >@@ -218,13 +209,13 @@ int H420ToARGB(const uint8* src_y, > > // Convert H420 to ABGR. > LIBYUV_API >-int H420ToABGR(const uint8* src_y, >+int H420ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height) { >@@ -236,20 +227,20 @@ int H420ToABGR(const uint8* src_y, > } > > // Convert I422 to ARGB with matrix >-static int I422ToARGBMatrix(const uint8* src_y, >+static int I422ToARGBMatrix(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > const struct YuvConstants* yuvconstants, > int width, > int height) { > int y; >- void (*I422ToARGBRow)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, int width) = > I422ToARGBRow_C; > if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { >@@ -292,15 +283,6 @@ static int I422ToARGBMatrix(const uint8* src_y, > } > } > #endif >-#if defined(HAS_I422TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) && >- IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && >- IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && >- IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) && >- IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) { >- I422ToARGBRow = I422ToARGBRow_DSPR2; >- } >-#endif > #if defined(HAS_I422TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422ToARGBRow = I422ToARGBRow_Any_MSA; >@@ -322,13 +304,13 @@ static int I422ToARGBMatrix(const uint8* src_y, > > // Convert I422 to ARGB. > LIBYUV_API >-int I422ToARGB(const uint8* src_y, >+int I422ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >@@ -339,13 +321,13 @@ int I422ToARGB(const uint8* src_y, > > // Convert I422 to ABGR. > LIBYUV_API >-int I422ToABGR(const uint8* src_y, >+int I422ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height) { >@@ -358,13 +340,13 @@ int I422ToABGR(const uint8* src_y, > > // Convert J422 to ARGB. > LIBYUV_API >-int J422ToARGB(const uint8* src_y, >+int J422ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >@@ -375,13 +357,13 @@ int J422ToARGB(const uint8* src_y, > > // Convert J422 to ABGR. > LIBYUV_API >-int J422ToABGR(const uint8* src_y, >+int J422ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height) { >@@ -394,13 +376,13 @@ int J422ToABGR(const uint8* src_y, > > // Convert H422 to ARGB. > LIBYUV_API >-int H422ToARGB(const uint8* src_y, >+int H422ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >@@ -411,13 +393,13 @@ int H422ToARGB(const uint8* src_y, > > // Convert H422 to ABGR. > LIBYUV_API >-int H422ToABGR(const uint8* src_y, >+int H422ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height) { >@@ -428,21 +410,271 @@ int H422ToABGR(const uint8* src_y, > width, height); > } > >+// Convert 10 bit YUV to ARGB with matrix >+// TODO(fbarchard): Consider passing scale multiplier to I210ToARGB to >+// multiply 10 bit yuv into high bits to allow any number of bits. >+static int I010ToAR30Matrix(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ const struct YuvConstants* yuvconstants, >+ int width, >+ int height) { >+ int y; >+ void (*I210ToAR30Row)(const uint16_t* y_buf, const uint16_t* u_buf, >+ const uint16_t* v_buf, uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, int width) = >+ I210ToAR30Row_C; >+ if (!src_y || !src_u || !src_v || !dst_ar30 || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ dst_ar30 = dst_ar30 + (height - 1) * dst_stride_ar30; >+ dst_stride_ar30 = -dst_stride_ar30; >+ } >+#if defined(HAS_I210TOAR30ROW_SSSE3) >+ if (TestCpuFlag(kCpuHasSSSE3)) { >+ I210ToAR30Row = I210ToAR30Row_Any_SSSE3; >+ if (IS_ALIGNED(width, 8)) { >+ I210ToAR30Row = I210ToAR30Row_SSSE3; >+ } >+ } >+#endif >+#if defined(HAS_I210TOAR30ROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ I210ToAR30Row = I210ToAR30Row_Any_AVX2; >+ if (IS_ALIGNED(width, 16)) { >+ I210ToAR30Row = I210ToAR30Row_AVX2; >+ } >+ } >+#endif >+ for (y = 0; y < height; ++y) { >+ I210ToAR30Row(src_y, src_u, src_v, dst_ar30, yuvconstants, width); >+ dst_ar30 += dst_stride_ar30; >+ src_y += src_stride_y; >+ if (y & 1) { >+ src_u += src_stride_u; >+ src_v += src_stride_v; >+ } >+ } >+ return 0; >+} >+ >+// Convert I010 to AR30. >+LIBYUV_API >+int I010ToAR30(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height) { >+ return I010ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, >+ src_stride_v, dst_ar30, dst_stride_ar30, >+ &kYuvI601Constants, width, height); >+} >+ >+// Convert H010 to AR30. >+LIBYUV_API >+int H010ToAR30(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height) { >+ return I010ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, >+ src_stride_v, dst_ar30, dst_stride_ar30, >+ &kYuvH709Constants, width, height); >+} >+ >+// Convert I010 to AB30. >+LIBYUV_API >+int I010ToAB30(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ab30, >+ int dst_stride_ab30, >+ int width, >+ int height) { >+ return I010ToAR30Matrix(src_y, src_stride_y, src_v, src_stride_v, src_u, >+ src_stride_u, dst_ab30, dst_stride_ab30, >+ &kYvuI601Constants, width, height); >+} >+ >+// Convert H010 to AB30. >+LIBYUV_API >+int H010ToAB30(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ab30, >+ int dst_stride_ab30, >+ int width, >+ int height) { >+ return I010ToAR30Matrix(src_y, src_stride_y, src_v, src_stride_v, src_u, >+ src_stride_u, dst_ab30, dst_stride_ab30, >+ &kYvuH709Constants, width, height); >+} >+ >+// Convert 10 bit YUV to ARGB with matrix >+static int I010ToARGBMatrix(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ const struct YuvConstants* yuvconstants, >+ int width, >+ int height) { >+ int y; >+ void (*I210ToARGBRow)(const uint16_t* y_buf, const uint16_t* u_buf, >+ const uint16_t* v_buf, uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, int width) = >+ I210ToARGBRow_C; >+ if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ dst_argb = dst_argb + (height - 1) * dst_stride_argb; >+ dst_stride_argb = -dst_stride_argb; >+ } >+#if defined(HAS_I210TOARGBROW_SSSE3) >+ if (TestCpuFlag(kCpuHasSSSE3)) { >+ I210ToARGBRow = I210ToARGBRow_Any_SSSE3; >+ if (IS_ALIGNED(width, 8)) { >+ I210ToARGBRow = I210ToARGBRow_SSSE3; >+ } >+ } >+#endif >+#if defined(HAS_I210TOARGBROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ I210ToARGBRow = I210ToARGBRow_Any_AVX2; >+ if (IS_ALIGNED(width, 16)) { >+ I210ToARGBRow = I210ToARGBRow_AVX2; >+ } >+ } >+#endif >+ for (y = 0; y < height; ++y) { >+ I210ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); >+ dst_argb += dst_stride_argb; >+ src_y += src_stride_y; >+ if (y & 1) { >+ src_u += src_stride_u; >+ src_v += src_stride_v; >+ } >+ } >+ return 0; >+} >+ >+// Convert I010 to ARGB. >+LIBYUV_API >+int I010ToARGB(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int width, >+ int height) { >+ return I010ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, >+ src_stride_v, dst_argb, dst_stride_argb, >+ &kYuvI601Constants, width, height); >+} >+ >+// Convert I010 to ABGR. >+LIBYUV_API >+int I010ToABGR(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height) { >+ return I010ToARGBMatrix(src_y, src_stride_y, src_v, >+ src_stride_v, // Swap U and V >+ src_u, src_stride_u, dst_abgr, dst_stride_abgr, >+ &kYvuI601Constants, // Use Yvu matrix >+ width, height); >+} >+ >+// Convert H010 to ARGB. >+LIBYUV_API >+int H010ToARGB(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int width, >+ int height) { >+ return I010ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, >+ src_stride_v, dst_argb, dst_stride_argb, >+ &kYuvH709Constants, width, height); >+} >+ >+// Convert H010 to ABGR. >+LIBYUV_API >+int H010ToABGR(const uint16_t* src_y, >+ int src_stride_y, >+ const uint16_t* src_u, >+ int src_stride_u, >+ const uint16_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height) { >+ return I010ToARGBMatrix(src_y, src_stride_y, src_v, >+ src_stride_v, // Swap U and V >+ src_u, src_stride_u, dst_abgr, dst_stride_abgr, >+ &kYvuH709Constants, // Use Yvu matrix >+ width, height); >+} >+ > // Convert I444 to ARGB with matrix >-static int I444ToARGBMatrix(const uint8* src_y, >+static int I444ToARGBMatrix(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > const struct YuvConstants* yuvconstants, > int width, > int height) { > int y; >- void (*I444ToARGBRow)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I444ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, int width) = > I444ToARGBRow_C; > if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { >@@ -485,14 +717,6 @@ static int I444ToARGBMatrix(const uint8* src_y, > } > } > #endif >-#if defined(HAS_I444TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- I444ToARGBRow = I444ToARGBRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- I444ToARGBRow = I444ToARGBRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_I444TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I444ToARGBRow = I444ToARGBRow_Any_MSA; >@@ -514,13 +738,13 @@ static int I444ToARGBMatrix(const uint8* src_y, > > // Convert I444 to ARGB. > LIBYUV_API >-int I444ToARGB(const uint8* src_y, >+int I444ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >@@ -531,13 +755,13 @@ int I444ToARGB(const uint8* src_y, > > // Convert I444 to ABGR. > LIBYUV_API >-int I444ToABGR(const uint8* src_y, >+int I444ToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height) { >@@ -550,13 +774,13 @@ int I444ToABGR(const uint8* src_y, > > // Convert J444 to ARGB. > LIBYUV_API >-int J444ToARGB(const uint8* src_y, >+int J444ToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >@@ -566,28 +790,28 @@ int J444ToARGB(const uint8* src_y, > } > > // Convert I420 with Alpha to preattenuated ARGB. >-static int I420AlphaToARGBMatrix(const uint8* src_y, >+static int I420AlphaToARGBMatrix(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- const uint8* src_a, >+ const uint8_t* src_a, > int src_stride_a, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > const struct YuvConstants* yuvconstants, > int width, > int height, > int attenuate) { > int y; >- void (*I422AlphaToARGBRow)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, const uint8* a_buf, >- uint8* dst_argb, >+ void (*I422AlphaToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, const uint8_t* a_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) = I422AlphaToARGBRow_C; >- void (*ARGBAttenuateRow)(const uint8* src_argb, uint8* dst_argb, int width) = >- ARGBAttenuateRow_C; >+ void (*ARGBAttenuateRow)(const uint8_t* src_argb, uint8_t* dst_argb, >+ int width) = ARGBAttenuateRow_C; > if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -621,15 +845,6 @@ static int I420AlphaToARGBMatrix(const uint8* src_y, > } > } > #endif >-#if defined(HAS_I422ALPHATOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) && >- IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && >- IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && >- IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) && >- IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) { >- I422AlphaToARGBRow = I422AlphaToARGBRow_DSPR2; >- } >-#endif > #if defined(HAS_I422ALPHATOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422AlphaToARGBRow = I422AlphaToARGBRow_Any_MSA; >@@ -690,15 +905,15 @@ static int I420AlphaToARGBMatrix(const uint8* src_y, > > // Convert I420 with Alpha to ARGB. > LIBYUV_API >-int I420AlphaToARGB(const uint8* src_y, >+int I420AlphaToARGB(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- const uint8* src_a, >+ const uint8_t* src_a, > int src_stride_a, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height, >@@ -711,15 +926,15 @@ int I420AlphaToARGB(const uint8* src_y, > > // Convert I420 with Alpha to ABGR. > LIBYUV_API >-int I420AlphaToABGR(const uint8* src_y, >+int I420AlphaToABGR(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- const uint8* src_a, >+ const uint8_t* src_a, > int src_stride_a, >- uint8* dst_abgr, >+ uint8_t* dst_abgr, > int dst_stride_abgr, > int width, > int height, >@@ -733,14 +948,14 @@ int I420AlphaToABGR(const uint8* src_y, > > // Convert I400 to ARGB. > LIBYUV_API >-int I400ToARGB(const uint8* src_y, >+int I400ToARGB(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*I400ToARGBRow)(const uint8* y_buf, uint8* rgb_buf, int width) = >+ void (*I400ToARGBRow)(const uint8_t* y_buf, uint8_t* rgb_buf, int width) = > I400ToARGBRow_C; > if (!src_y || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -800,14 +1015,14 @@ int I400ToARGB(const uint8* src_y, > > // Convert J400 to ARGB. > LIBYUV_API >-int J400ToARGB(const uint8* src_y, >+int J400ToARGB(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*J400ToARGBRow)(const uint8* src_y, uint8* dst_argb, int width) = >+ void (*J400ToARGBRow)(const uint8_t* src_y, uint8_t* dst_argb, int width) = > J400ToARGBRow_C; > if (!src_y || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -865,87 +1080,87 @@ int J400ToARGB(const uint8* src_y, > } > > // Shuffle table for converting BGRA to ARGB. >-static uvec8 kShuffleMaskBGRAToARGB = {3u, 2u, 1u, 0u, 7u, 6u, 5u, 4u, >- 11u, 10u, 9u, 8u, 15u, 14u, 13u, 12u}; >+static const uvec8 kShuffleMaskBGRAToARGB = { >+ 3u, 2u, 1u, 0u, 7u, 6u, 5u, 4u, 11u, 10u, 9u, 8u, 15u, 14u, 13u, 12u}; > > // Shuffle table for converting ABGR to ARGB. >-static uvec8 kShuffleMaskABGRToARGB = {2u, 1u, 0u, 3u, 6u, 5u, 4u, 7u, >- 10u, 9u, 8u, 11u, 14u, 13u, 12u, 15u}; >+static const uvec8 kShuffleMaskABGRToARGB = { >+ 2u, 1u, 0u, 3u, 6u, 5u, 4u, 7u, 10u, 9u, 8u, 11u, 14u, 13u, 12u, 15u}; > > // Shuffle table for converting RGBA to ARGB. >-static uvec8 kShuffleMaskRGBAToARGB = {1u, 2u, 3u, 0u, 5u, 6u, 7u, 4u, >- 9u, 10u, 11u, 8u, 13u, 14u, 15u, 12u}; >+static const uvec8 kShuffleMaskRGBAToARGB = { >+ 1u, 2u, 3u, 0u, 5u, 6u, 7u, 4u, 9u, 10u, 11u, 8u, 13u, 14u, 15u, 12u}; > > // Convert BGRA to ARGB. > LIBYUV_API >-int BGRAToARGB(const uint8* src_bgra, >+int BGRAToARGB(const uint8_t* src_bgra, > int src_stride_bgra, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > return ARGBShuffle(src_bgra, src_stride_bgra, dst_argb, dst_stride_argb, >- (const uint8*)(&kShuffleMaskBGRAToARGB), width, height); >+ (const uint8_t*)(&kShuffleMaskBGRAToARGB), width, height); > } > > // Convert ARGB to BGRA (same as BGRAToARGB). > LIBYUV_API >-int ARGBToBGRA(const uint8* src_bgra, >+int ARGBToBGRA(const uint8_t* src_bgra, > int src_stride_bgra, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > return ARGBShuffle(src_bgra, src_stride_bgra, dst_argb, dst_stride_argb, >- (const uint8*)(&kShuffleMaskBGRAToARGB), width, height); >+ (const uint8_t*)(&kShuffleMaskBGRAToARGB), width, height); > } > > // Convert ABGR to ARGB. > LIBYUV_API >-int ABGRToARGB(const uint8* src_abgr, >+int ABGRToARGB(const uint8_t* src_abgr, > int src_stride_abgr, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > return ARGBShuffle(src_abgr, src_stride_abgr, dst_argb, dst_stride_argb, >- (const uint8*)(&kShuffleMaskABGRToARGB), width, height); >+ (const uint8_t*)(&kShuffleMaskABGRToARGB), width, height); > } > > // Convert ARGB to ABGR to (same as ABGRToARGB). > LIBYUV_API >-int ARGBToABGR(const uint8* src_abgr, >+int ARGBToABGR(const uint8_t* src_abgr, > int src_stride_abgr, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > return ARGBShuffle(src_abgr, src_stride_abgr, dst_argb, dst_stride_argb, >- (const uint8*)(&kShuffleMaskABGRToARGB), width, height); >+ (const uint8_t*)(&kShuffleMaskABGRToARGB), width, height); > } > > // Convert RGBA to ARGB. > LIBYUV_API >-int RGBAToARGB(const uint8* src_rgba, >+int RGBAToARGB(const uint8_t* src_rgba, > int src_stride_rgba, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > return ARGBShuffle(src_rgba, src_stride_rgba, dst_argb, dst_stride_argb, >- (const uint8*)(&kShuffleMaskRGBAToARGB), width, height); >+ (const uint8_t*)(&kShuffleMaskRGBAToARGB), width, height); > } > > // Convert RGB24 to ARGB. > LIBYUV_API >-int RGB24ToARGB(const uint8* src_rgb24, >+int RGB24ToARGB(const uint8_t* src_rgb24, > int src_stride_rgb24, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int width) = >+ void (*RGB24ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) = > RGB24ToARGBRow_C; > if (!src_rgb24 || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -978,14 +1193,6 @@ int RGB24ToARGB(const uint8* src_rgb24, > } > } > #endif >-#if defined(HAS_RGB24TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- RGB24ToARGBRow = RGB24ToARGBRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- RGB24ToARGBRow = RGB24ToARGBRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_RGB24TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > RGB24ToARGBRow = RGB24ToARGBRow_Any_MSA; >@@ -1005,14 +1212,14 @@ int RGB24ToARGB(const uint8* src_rgb24, > > // Convert RAW to ARGB. > LIBYUV_API >-int RAWToARGB(const uint8* src_raw, >+int RAWToARGB(const uint8_t* src_raw, > int src_stride_raw, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int width) = >+ void (*RAWToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) = > RAWToARGBRow_C; > if (!src_raw || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -1045,14 +1252,6 @@ int RAWToARGB(const uint8* src_raw, > } > } > #endif >-#if defined(HAS_RAWTOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- RAWToARGBRow = RAWToARGBRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- RAWToARGBRow = RAWToARGBRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_RAWTOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > RAWToARGBRow = RAWToARGBRow_Any_MSA; >@@ -1072,15 +1271,15 @@ int RAWToARGB(const uint8* src_raw, > > // Convert RGB565 to ARGB. > LIBYUV_API >-int RGB565ToARGB(const uint8* src_rgb565, >+int RGB565ToARGB(const uint8_t* src_rgb565, > int src_stride_rgb565, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*RGB565ToARGBRow)(const uint8* src_rgb565, uint8* dst_argb, int width) = >- RGB565ToARGBRow_C; >+ void (*RGB565ToARGBRow)(const uint8_t* src_rgb565, uint8_t* dst_argb, >+ int width) = RGB565ToARGBRow_C; > if (!src_rgb565 || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -1120,14 +1319,6 @@ int RGB565ToARGB(const uint8* src_rgb565, > } > } > #endif >-#if defined(HAS_RGB565TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- RGB565ToARGBRow = RGB565ToARGBRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- RGB565ToARGBRow = RGB565ToARGBRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_RGB565TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > RGB565ToARGBRow = RGB565ToARGBRow_Any_MSA; >@@ -1147,14 +1338,14 @@ int RGB565ToARGB(const uint8* src_rgb565, > > // Convert ARGB1555 to ARGB. > LIBYUV_API >-int ARGB1555ToARGB(const uint8* src_argb1555, >+int ARGB1555ToARGB(const uint8_t* src_argb1555, > int src_stride_argb1555, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGB1555ToARGBRow)(const uint8* src_argb1555, uint8* dst_argb, >+ void (*ARGB1555ToARGBRow)(const uint8_t* src_argb1555, uint8_t* dst_argb, > int width) = ARGB1555ToARGBRow_C; > if (!src_argb1555 || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -1195,14 +1386,6 @@ int ARGB1555ToARGB(const uint8* src_argb1555, > } > } > #endif >-#if defined(HAS_ARGB1555TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_DSPR2; >- if (IS_ALIGNED(width, 4)) { >- ARGB1555ToARGBRow = ARGB1555ToARGBRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_ARGB1555TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_MSA; >@@ -1222,14 +1405,14 @@ int ARGB1555ToARGB(const uint8* src_argb1555, > > // Convert ARGB4444 to ARGB. > LIBYUV_API >-int ARGB4444ToARGB(const uint8* src_argb4444, >+int ARGB4444ToARGB(const uint8_t* src_argb4444, > int src_stride_argb4444, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGB4444ToARGBRow)(const uint8* src_argb4444, uint8* dst_argb, >+ void (*ARGB4444ToARGBRow)(const uint8_t* src_argb4444, uint8_t* dst_argb, > int width) = ARGB4444ToARGBRow_C; > if (!src_argb4444 || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -1270,14 +1453,6 @@ int ARGB4444ToARGB(const uint8* src_argb4444, > } > } > #endif >-#if defined(HAS_ARGB4444TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_DSPR2; >- if (IS_ALIGNED(width, 4)) { >- ARGB4444ToARGBRow = ARGB4444ToARGBRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_ARGB4444TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_MSA; >@@ -1295,20 +1470,116 @@ int ARGB4444ToARGB(const uint8* src_argb4444, > return 0; > } > >-// Convert NV12 to ARGB. >+// Convert AR30 to ARGB. > LIBYUV_API >-int NV12ToARGB(const uint8* src_y, >- int src_stride_y, >- const uint8* src_uv, >- int src_stride_uv, >- uint8* dst_argb, >+int AR30ToARGB(const uint8_t* src_ar30, >+ int src_stride_ar30, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*NV12ToARGBRow)(const uint8* y_buf, const uint8* uv_buf, uint8* rgb_buf, >- const struct YuvConstants* yuvconstants, int width) = >- NV12ToARGBRow_C; >+ if (!src_ar30 || !dst_argb || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ src_ar30 = src_ar30 + (height - 1) * src_stride_ar30; >+ src_stride_ar30 = -src_stride_ar30; >+ } >+ // Coalesce rows. >+ if (src_stride_ar30 == width * 4 && dst_stride_argb == width * 4) { >+ width *= height; >+ height = 1; >+ src_stride_ar30 = dst_stride_argb = 0; >+ } >+ for (y = 0; y < height; ++y) { >+ AR30ToARGBRow_C(src_ar30, dst_argb, width); >+ src_ar30 += src_stride_ar30; >+ dst_argb += dst_stride_argb; >+ } >+ return 0; >+} >+ >+// Convert AR30 to ABGR. >+LIBYUV_API >+int AR30ToABGR(const uint8_t* src_ar30, >+ int src_stride_ar30, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height) { >+ int y; >+ if (!src_ar30 || !dst_abgr || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ src_ar30 = src_ar30 + (height - 1) * src_stride_ar30; >+ src_stride_ar30 = -src_stride_ar30; >+ } >+ // Coalesce rows. >+ if (src_stride_ar30 == width * 4 && dst_stride_abgr == width * 4) { >+ width *= height; >+ height = 1; >+ src_stride_ar30 = dst_stride_abgr = 0; >+ } >+ for (y = 0; y < height; ++y) { >+ AR30ToABGRRow_C(src_ar30, dst_abgr, width); >+ src_ar30 += src_stride_ar30; >+ dst_abgr += dst_stride_abgr; >+ } >+ return 0; >+} >+ >+// Convert AR30 to AB30. >+LIBYUV_API >+int AR30ToAB30(const uint8_t* src_ar30, >+ int src_stride_ar30, >+ uint8_t* dst_ab30, >+ int dst_stride_ab30, >+ int width, >+ int height) { >+ int y; >+ if (!src_ar30 || !dst_ab30 || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ src_ar30 = src_ar30 + (height - 1) * src_stride_ar30; >+ src_stride_ar30 = -src_stride_ar30; >+ } >+ // Coalesce rows. >+ if (src_stride_ar30 == width * 4 && dst_stride_ab30 == width * 4) { >+ width *= height; >+ height = 1; >+ src_stride_ar30 = dst_stride_ab30 = 0; >+ } >+ for (y = 0; y < height; ++y) { >+ AR30ToAB30Row_C(src_ar30, dst_ab30, width); >+ src_ar30 += src_stride_ar30; >+ dst_ab30 += dst_stride_ab30; >+ } >+ return 0; >+} >+ >+// Convert NV12 to ARGB with matrix >+static int NV12ToARGBMatrix(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_uv, >+ int src_stride_uv, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ const struct YuvConstants* yuvconstants, >+ int width, >+ int height) { >+ int y; >+ void (*NV12ToARGBRow)( >+ const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, int width) = NV12ToARGBRow_C; > if (!src_y || !src_uv || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -1342,14 +1613,6 @@ int NV12ToARGB(const uint8* src_y, > } > } > #endif >-#if defined(HAS_NV12TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- NV12ToARGBRow = NV12ToARGBRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- NV12ToARGBRow = NV12ToARGBRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_NV12TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > NV12ToARGBRow = NV12ToARGBRow_Any_MSA; >@@ -1360,7 +1623,7 @@ int NV12ToARGB(const uint8* src_y, > #endif > > for (y = 0; y < height; ++y) { >- NV12ToARGBRow(src_y, src_uv, dst_argb, &kYuvI601Constants, width); >+ NV12ToARGBRow(src_y, src_uv, dst_argb, yuvconstants, width); > dst_argb += dst_stride_argb; > src_y += src_stride_y; > if (y & 1) { >@@ -1370,21 +1633,21 @@ int NV12ToARGB(const uint8* src_y, > return 0; > } > >-// Convert NV21 to ARGB. >-LIBYUV_API >-int NV21ToARGB(const uint8* src_y, >- int src_stride_y, >- const uint8* src_uv, >- int src_stride_uv, >- uint8* dst_argb, >- int dst_stride_argb, >- int width, >- int height) { >+// Convert NV21 to ARGB with matrix >+static int NV21ToARGBMatrix(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_vu, >+ int src_stride_vu, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ const struct YuvConstants* yuvconstants, >+ int width, >+ int height) { > int y; >- void (*NV21ToARGBRow)(const uint8* y_buf, const uint8* uv_buf, uint8* rgb_buf, >- const struct YuvConstants* yuvconstants, int width) = >- NV21ToARGBRow_C; >- if (!src_y || !src_uv || !dst_argb || width <= 0 || height == 0) { >+ void (*NV21ToARGBRow)( >+ const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, int width) = NV21ToARGBRow_C; >+ if (!src_y || !src_vu || !dst_argb || width <= 0 || height == 0) { > return -1; > } > // Negative height means invert the image. >@@ -1427,9 +1690,110 @@ int NV21ToARGB(const uint8* src_y, > #endif > > for (y = 0; y < height; ++y) { >- NV21ToARGBRow(src_y, src_uv, dst_argb, &kYuvI601Constants, width); >+ NV21ToARGBRow(src_y, src_vu, dst_argb, yuvconstants, width); > dst_argb += dst_stride_argb; > src_y += src_stride_y; >+ if (y & 1) { >+ src_vu += src_stride_vu; >+ } >+ } >+ return 0; >+} >+ >+// Convert NV12 to ARGB. >+LIBYUV_API >+int NV12ToARGB(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_uv, >+ int src_stride_uv, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int width, >+ int height) { >+ return NV12ToARGBMatrix(src_y, src_stride_y, src_uv, src_stride_uv, dst_argb, >+ dst_stride_argb, &kYuvI601Constants, width, height); >+} >+ >+// Convert NV21 to ARGB. >+LIBYUV_API >+int NV21ToARGB(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_vu, >+ int src_stride_vu, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int width, >+ int height) { >+ return NV21ToARGBMatrix(src_y, src_stride_y, src_vu, src_stride_vu, dst_argb, >+ dst_stride_argb, &kYuvI601Constants, width, height); >+} >+ >+// Convert NV12 to ABGR. >+// To output ABGR instead of ARGB swap the UV and use a mirrrored yuc matrix. >+// To swap the UV use NV12 instead of NV21.LIBYUV_API >+int NV12ToABGR(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_uv, >+ int src_stride_uv, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height) { >+ return NV21ToARGBMatrix(src_y, src_stride_y, src_uv, src_stride_uv, dst_abgr, >+ dst_stride_abgr, &kYvuI601Constants, width, height); >+} >+ >+// Convert NV21 to ABGR. >+LIBYUV_API >+int NV21ToABGR(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_vu, >+ int src_stride_vu, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height) { >+ return NV12ToARGBMatrix(src_y, src_stride_y, src_vu, src_stride_vu, dst_abgr, >+ dst_stride_abgr, &kYvuI601Constants, width, height); >+} >+ >+// TODO(fbarchard): Consider SSSE3 2 step conversion. >+// Convert NV12 to RGB24 with matrix >+static int NV12ToRGB24Matrix(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_uv, >+ int src_stride_uv, >+ uint8_t* dst_rgb24, >+ int dst_stride_rgb24, >+ const struct YuvConstants* yuvconstants, >+ int width, >+ int height) { >+ int y; >+ void (*NV12ToRGB24Row)( >+ const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, int width) = NV12ToRGB24Row_C; >+ if (!src_y || !src_uv || !dst_rgb24 || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ dst_rgb24 = dst_rgb24 + (height - 1) * dst_stride_rgb24; >+ dst_stride_rgb24 = -dst_stride_rgb24; >+ } >+#if defined(HAS_NV12TORGB24ROW_NEON) >+ if (TestCpuFlag(kCpuHasNEON)) { >+ NV12ToRGB24Row = NV12ToRGB24Row_Any_NEON; >+ if (IS_ALIGNED(width, 8)) { >+ NV12ToRGB24Row = NV12ToRGB24Row_NEON; >+ } >+ } >+#endif >+ >+ for (y = 0; y < height; ++y) { >+ NV12ToRGB24Row(src_y, src_uv, dst_rgb24, yuvconstants, width); >+ dst_rgb24 += dst_stride_rgb24; >+ src_y += src_stride_y; > if (y & 1) { > src_uv += src_stride_uv; > } >@@ -1437,18 +1801,92 @@ int NV21ToARGB(const uint8* src_y, > return 0; > } > >+// Convert NV21 to RGB24 with matrix >+static int NV21ToRGB24Matrix(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_vu, >+ int src_stride_vu, >+ uint8_t* dst_rgb24, >+ int dst_stride_rgb24, >+ const struct YuvConstants* yuvconstants, >+ int width, >+ int height) { >+ int y; >+ void (*NV21ToRGB24Row)( >+ const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, int width) = NV21ToRGB24Row_C; >+ if (!src_y || !src_vu || !dst_rgb24 || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ dst_rgb24 = dst_rgb24 + (height - 1) * dst_stride_rgb24; >+ dst_stride_rgb24 = -dst_stride_rgb24; >+ } >+#if defined(HAS_NV21TORGB24ROW_NEON) >+ if (TestCpuFlag(kCpuHasNEON)) { >+ NV21ToRGB24Row = NV21ToRGB24Row_Any_NEON; >+ if (IS_ALIGNED(width, 8)) { >+ NV21ToRGB24Row = NV21ToRGB24Row_NEON; >+ } >+ } >+#endif >+ >+ for (y = 0; y < height; ++y) { >+ NV21ToRGB24Row(src_y, src_vu, dst_rgb24, yuvconstants, width); >+ dst_rgb24 += dst_stride_rgb24; >+ src_y += src_stride_y; >+ if (y & 1) { >+ src_vu += src_stride_vu; >+ } >+ } >+ return 0; >+} >+ >+// TODO(fbarchard): \(fbarchard): NV12ToRAW can be implemented by mirrored >+// matrix. Convert NV12 to RGB24. >+LIBYUV_API >+int NV12ToRGB24(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_uv, >+ int src_stride_uv, >+ uint8_t* dst_rgb24, >+ int dst_stride_rgb24, >+ int width, >+ int height) { >+ return NV12ToRGB24Matrix(src_y, src_stride_y, src_uv, src_stride_uv, >+ dst_rgb24, dst_stride_rgb24, &kYuvI601Constants, >+ width, height); >+} >+ >+// Convert NV21 to RGB24. >+LIBYUV_API >+int NV21ToRGB24(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_vu, >+ int src_stride_vu, >+ uint8_t* dst_rgb24, >+ int dst_stride_rgb24, >+ int width, >+ int height) { >+ return NV21ToRGB24Matrix(src_y, src_stride_y, src_vu, src_stride_vu, >+ dst_rgb24, dst_stride_rgb24, &kYuvI601Constants, >+ width, height); >+} >+ > // Convert M420 to ARGB. > LIBYUV_API >-int M420ToARGB(const uint8* src_m420, >+int M420ToARGB(const uint8_t* src_m420, > int src_stride_m420, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*NV12ToARGBRow)(const uint8* y_buf, const uint8* uv_buf, uint8* rgb_buf, >- const struct YuvConstants* yuvconstants, int width) = >- NV12ToARGBRow_C; >+ void (*NV12ToARGBRow)( >+ const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, int width) = NV12ToARGBRow_C; > if (!src_m420 || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -1482,14 +1920,6 @@ int M420ToARGB(const uint8* src_m420, > } > } > #endif >-#if defined(HAS_NV12TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- NV12ToARGBRow = NV12ToARGBRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- NV12ToARGBRow = NV12ToARGBRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_NV12TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > NV12ToARGBRow = NV12ToARGBRow_Any_MSA; >@@ -1516,14 +1946,14 @@ int M420ToARGB(const uint8* src_m420, > > // Convert YUY2 to ARGB. > LIBYUV_API >-int YUY2ToARGB(const uint8* src_yuy2, >+int YUY2ToARGB(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*YUY2ToARGBRow)(const uint8* src_yuy2, uint8* dst_argb, >+ void (*YUY2ToARGBRow)(const uint8_t* src_yuy2, uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, int width) = > YUY2ToARGBRow_C; > if (!src_yuy2 || !dst_argb || width <= 0 || height == 0) { >@@ -1583,14 +2013,14 @@ int YUY2ToARGB(const uint8* src_yuy2, > > // Convert UYVY to ARGB. > LIBYUV_API >-int UYVYToARGB(const uint8* src_uyvy, >+int UYVYToARGB(const uint8_t* src_uyvy, > int src_stride_uyvy, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*UYVYToARGBRow)(const uint8* src_uyvy, uint8* dst_argb, >+ void (*UYVYToARGBRow)(const uint8_t* src_uyvy, uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, int width) = > UYVYToARGBRow_C; > if (!src_uyvy || !dst_argb || width <= 0 || height == 0) { >@@ -1647,6 +2077,121 @@ int UYVYToARGB(const uint8* src_uyvy, > } > return 0; > } >+static void WeavePixels(const uint8_t* src_u, >+ const uint8_t* src_v, >+ int src_pixel_stride_uv, >+ uint8_t* dst_uv, >+ int width) { >+ int i; >+ for (i = 0; i < width; ++i) { >+ dst_uv[0] = *src_u; >+ dst_uv[1] = *src_v; >+ dst_uv += 2; >+ src_u += src_pixel_stride_uv; >+ src_v += src_pixel_stride_uv; >+ } >+} >+ >+// Convert Android420 to ARGB. >+LIBYUV_API >+int Android420ToARGBMatrix(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ int src_pixel_stride_uv, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ const struct YuvConstants* yuvconstants, >+ int width, >+ int height) { >+ int y; >+ uint8_t* dst_uv; >+ const ptrdiff_t vu_off = src_v - src_u; >+ int halfwidth = (width + 1) >> 1; >+ int halfheight = (height + 1) >> 1; >+ if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ halfheight = (height + 1) >> 1; >+ dst_argb = dst_argb + (height - 1) * dst_stride_argb; >+ dst_stride_argb = -dst_stride_argb; >+ } >+ >+ // I420 >+ if (src_pixel_stride_uv == 1) { >+ return I420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, >+ src_stride_v, dst_argb, dst_stride_argb, >+ yuvconstants, width, height); >+ // NV21 >+ } >+ if (src_pixel_stride_uv == 2 && vu_off == -1 && >+ src_stride_u == src_stride_v) { >+ return NV21ToARGBMatrix(src_y, src_stride_y, src_v, src_stride_v, dst_argb, >+ dst_stride_argb, yuvconstants, width, height); >+ // NV12 >+ } >+ if (src_pixel_stride_uv == 2 && vu_off == 1 && src_stride_u == src_stride_v) { >+ return NV12ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, dst_argb, >+ dst_stride_argb, yuvconstants, width, height); >+ } >+ >+ // General case fallback creates NV12 >+ align_buffer_64(plane_uv, halfwidth * 2 * halfheight); >+ dst_uv = plane_uv; >+ for (y = 0; y < halfheight; ++y) { >+ WeavePixels(src_u, src_v, src_pixel_stride_uv, dst_uv, halfwidth); >+ src_u += src_stride_u; >+ src_v += src_stride_v; >+ dst_uv += halfwidth * 2; >+ } >+ NV12ToARGBMatrix(src_y, src_stride_y, plane_uv, halfwidth * 2, dst_argb, >+ dst_stride_argb, yuvconstants, width, height); >+ free_aligned_buffer_64(plane_uv); >+ return 0; >+} >+ >+// Convert Android420 to ARGB. >+LIBYUV_API >+int Android420ToARGB(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ int src_pixel_stride_uv, >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int width, >+ int height) { >+ return Android420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, >+ src_stride_v, src_pixel_stride_uv, dst_argb, >+ dst_stride_argb, &kYuvI601Constants, width, >+ height); >+} >+ >+// Convert Android420 to ABGR. >+LIBYUV_API >+int Android420ToABGR(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ int src_pixel_stride_uv, >+ uint8_t* dst_abgr, >+ int dst_stride_abgr, >+ int width, >+ int height) { >+ return Android420ToARGBMatrix(src_y, src_stride_y, src_v, src_stride_v, src_u, >+ src_stride_u, src_pixel_stride_uv, dst_abgr, >+ dst_stride_abgr, &kYvuI601Constants, width, >+ height); >+} > > #ifdef __cplusplus > } // extern "C" >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_from.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_from.cc >index 0f52f9ef9e0e920abb2fe50c97f25dacc028b360..b5587ced625702f13d0bb3b353fa1ecedf61ffe6 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_from.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_from.cc >@@ -30,17 +30,17 @@ static __inline int Abs(int v) { > } > > // I420 To any I4xx YUV format with mirroring. >-static int I420ToI4xx(const uint8* src_y, >+static int I420ToI4xx(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int src_y_width, > int src_y_height, >@@ -65,20 +65,64 @@ static int I420ToI4xx(const uint8* src_y, > return 0; > } > >+// Convert 8 bit YUV to 10 bit. >+LIBYUV_API >+int I420ToI010(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ uint16_t* dst_y, >+ int dst_stride_y, >+ uint16_t* dst_u, >+ int dst_stride_u, >+ uint16_t* dst_v, >+ int dst_stride_v, >+ int width, >+ int height) { >+ int halfwidth = (width + 1) >> 1; >+ int halfheight = (height + 1) >> 1; >+ if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ halfheight = (height + 1) >> 1; >+ src_y = src_y + (height - 1) * src_stride_y; >+ src_u = src_u + (halfheight - 1) * src_stride_u; >+ src_v = src_v + (halfheight - 1) * src_stride_v; >+ src_stride_y = -src_stride_y; >+ src_stride_u = -src_stride_u; >+ src_stride_v = -src_stride_v; >+ } >+ >+ // Convert Y plane. >+ Convert8To16Plane(src_y, src_stride_y, dst_y, dst_stride_y, 1024, width, >+ height); >+ // Convert UV planes. >+ Convert8To16Plane(src_u, src_stride_u, dst_u, dst_stride_u, 1024, halfwidth, >+ halfheight); >+ Convert8To16Plane(src_v, src_stride_v, dst_v, dst_stride_v, 1024, halfwidth, >+ halfheight); >+ return 0; >+} >+ > // 420 chroma is 1/2 width, 1/2 height > // 422 chroma is 1/2 width, 1x height > LIBYUV_API >-int I420ToI422(const uint8* src_y, >+int I420ToI422(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -93,17 +137,17 @@ int I420ToI422(const uint8* src_y, > // 420 chroma is 1/2 width, 1/2 height > // 444 chroma is 1x width, 1x height > LIBYUV_API >-int I420ToI444(const uint8* src_y, >+int I420ToI444(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -117,9 +161,9 @@ int I420ToI444(const uint8* src_y, > > // Copy to I400. Source can be I420,422,444,400,NV12,NV21 > LIBYUV_API >-int I400Copy(const uint8* src_y, >+int I400Copy(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height) { >@@ -137,19 +181,19 @@ int I400Copy(const uint8* src_y, > } > > LIBYUV_API >-int I422ToYUY2(const uint8* src_y, >+int I422ToYUY2(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_yuy2, >+ uint8_t* dst_yuy2, > int dst_stride_yuy2, > int width, > int height) { > int y; >- void (*I422ToYUY2Row)(const uint8* src_y, const uint8* src_u, >- const uint8* src_v, uint8* dst_yuy2, int width) = >+ void (*I422ToYUY2Row)(const uint8_t* src_y, const uint8_t* src_u, >+ const uint8_t* src_v, uint8_t* dst_yuy2, int width) = > I422ToYUY2Row_C; > if (!src_y || !src_u || !src_v || !dst_yuy2 || width <= 0 || height == 0) { > return -1; >@@ -175,6 +219,14 @@ int I422ToYUY2(const uint8* src_y, > } > } > #endif >+#if defined(HAS_I422TOYUY2ROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ I422ToYUY2Row = I422ToYUY2Row_Any_AVX2; >+ if (IS_ALIGNED(width, 32)) { >+ I422ToYUY2Row = I422ToYUY2Row_AVX2; >+ } >+ } >+#endif > #if defined(HAS_I422TOYUY2ROW_NEON) > if (TestCpuFlag(kCpuHasNEON)) { > I422ToYUY2Row = I422ToYUY2Row_Any_NEON; >@@ -195,19 +247,19 @@ int I422ToYUY2(const uint8* src_y, > } > > LIBYUV_API >-int I420ToYUY2(const uint8* src_y, >+int I420ToYUY2(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_yuy2, >+ uint8_t* dst_yuy2, > int dst_stride_yuy2, > int width, > int height) { > int y; >- void (*I422ToYUY2Row)(const uint8* src_y, const uint8* src_u, >- const uint8* src_v, uint8* dst_yuy2, int width) = >+ void (*I422ToYUY2Row)(const uint8_t* src_y, const uint8_t* src_u, >+ const uint8_t* src_v, uint8_t* dst_yuy2, int width) = > I422ToYUY2Row_C; > if (!src_y || !src_u || !src_v || !dst_yuy2 || width <= 0 || height == 0) { > return -1; >@@ -226,6 +278,14 @@ int I420ToYUY2(const uint8* src_y, > } > } > #endif >+#if defined(HAS_I422TOYUY2ROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ I422ToYUY2Row = I422ToYUY2Row_Any_AVX2; >+ if (IS_ALIGNED(width, 32)) { >+ I422ToYUY2Row = I422ToYUY2Row_AVX2; >+ } >+ } >+#endif > #if defined(HAS_I422TOYUY2ROW_NEON) > if (TestCpuFlag(kCpuHasNEON)) { > I422ToYUY2Row = I422ToYUY2Row_Any_NEON; >@@ -259,19 +319,19 @@ int I420ToYUY2(const uint8* src_y, > } > > LIBYUV_API >-int I422ToUYVY(const uint8* src_y, >+int I422ToUYVY(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_uyvy, >+ uint8_t* dst_uyvy, > int dst_stride_uyvy, > int width, > int height) { > int y; >- void (*I422ToUYVYRow)(const uint8* src_y, const uint8* src_u, >- const uint8* src_v, uint8* dst_uyvy, int width) = >+ void (*I422ToUYVYRow)(const uint8_t* src_y, const uint8_t* src_u, >+ const uint8_t* src_v, uint8_t* dst_uyvy, int width) = > I422ToUYVYRow_C; > if (!src_y || !src_u || !src_v || !dst_uyvy || width <= 0 || height == 0) { > return -1; >@@ -297,6 +357,14 @@ int I422ToUYVY(const uint8* src_y, > } > } > #endif >+#if defined(HAS_I422TOUYVYROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ I422ToUYVYRow = I422ToUYVYRow_Any_AVX2; >+ if (IS_ALIGNED(width, 32)) { >+ I422ToUYVYRow = I422ToUYVYRow_AVX2; >+ } >+ } >+#endif > #if defined(HAS_I422TOUYVYROW_NEON) > if (TestCpuFlag(kCpuHasNEON)) { > I422ToUYVYRow = I422ToUYVYRow_Any_NEON; >@@ -325,19 +393,19 @@ int I422ToUYVY(const uint8* src_y, > } > > LIBYUV_API >-int I420ToUYVY(const uint8* src_y, >+int I420ToUYVY(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_uyvy, >+ uint8_t* dst_uyvy, > int dst_stride_uyvy, > int width, > int height) { > int y; >- void (*I422ToUYVYRow)(const uint8* src_y, const uint8* src_u, >- const uint8* src_v, uint8* dst_uyvy, int width) = >+ void (*I422ToUYVYRow)(const uint8_t* src_y, const uint8_t* src_u, >+ const uint8_t* src_v, uint8_t* dst_uyvy, int width) = > I422ToUYVYRow_C; > if (!src_y || !src_u || !src_v || !dst_uyvy || width <= 0 || height == 0) { > return -1; >@@ -356,6 +424,14 @@ int I420ToUYVY(const uint8* src_y, > } > } > #endif >+#if defined(HAS_I422TOUYVYROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ I422ToUYVYRow = I422ToUYVYRow_Any_AVX2; >+ if (IS_ALIGNED(width, 32)) { >+ I422ToUYVYRow = I422ToUYVYRow_AVX2; >+ } >+ } >+#endif > #if defined(HAS_I422TOUYVYROW_NEON) > if (TestCpuFlag(kCpuHasNEON)) { > I422ToUYVYRow = I422ToUYVYRow_Any_NEON; >@@ -390,15 +466,15 @@ int I420ToUYVY(const uint8* src_y, > > // TODO(fbarchard): test negative height for invert. > LIBYUV_API >-int I420ToNV12(const uint8* src_y, >+int I420ToNV12(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int dst_stride_uv, > int width, > int height) { >@@ -417,15 +493,15 @@ int I420ToNV12(const uint8* src_y, > } > > LIBYUV_API >-int I420ToNV21(const uint8* src_y, >+int I420ToNV21(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_vu, >+ uint8_t* dst_vu, > int dst_stride_vu, > int width, > int height) { >@@ -435,20 +511,20 @@ int I420ToNV21(const uint8* src_y, > } > > // Convert I422 to RGBA with matrix >-static int I420ToRGBAMatrix(const uint8* src_y, >+static int I420ToRGBAMatrix(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgba, >+ uint8_t* dst_rgba, > int dst_stride_rgba, > const struct YuvConstants* yuvconstants, > int width, > int height) { > int y; >- void (*I422ToRGBARow)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I422ToRGBARow)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, int width) = > I422ToRGBARow_C; > if (!src_y || !src_u || !src_v || !dst_rgba || width <= 0 || height == 0) { >@@ -484,15 +560,6 @@ static int I420ToRGBAMatrix(const uint8* src_y, > } > } > #endif >-#if defined(HAS_I422TORGBAROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) && >- IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && >- IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && >- IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) && >- IS_ALIGNED(dst_rgba, 4) && IS_ALIGNED(dst_stride_rgba, 4)) { >- I422ToRGBARow = I422ToRGBARow_DSPR2; >- } >-#endif > #if defined(HAS_I422TORGBAROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422ToRGBARow = I422ToRGBARow_Any_MSA; >@@ -516,13 +583,13 @@ static int I420ToRGBAMatrix(const uint8* src_y, > > // Convert I420 to RGBA. > LIBYUV_API >-int I420ToRGBA(const uint8* src_y, >+int I420ToRGBA(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgba, >+ uint8_t* dst_rgba, > int dst_stride_rgba, > int width, > int height) { >@@ -533,13 +600,13 @@ int I420ToRGBA(const uint8* src_y, > > // Convert I420 to BGRA. > LIBYUV_API >-int I420ToBGRA(const uint8* src_y, >+int I420ToBGRA(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_bgra, >+ uint8_t* dst_bgra, > int dst_stride_bgra, > int width, > int height) { >@@ -551,20 +618,20 @@ int I420ToBGRA(const uint8* src_y, > } > > // Convert I420 to RGB24 with matrix >-static int I420ToRGB24Matrix(const uint8* src_y, >+static int I420ToRGB24Matrix(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgb24, >+ uint8_t* dst_rgb24, > int dst_stride_rgb24, > const struct YuvConstants* yuvconstants, > int width, > int height) { > int y; >- void (*I422ToRGB24Row)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I422ToRGB24Row)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, int width) = > I422ToRGB24Row_C; > if (!src_y || !src_u || !src_v || !dst_rgb24 || width <= 0 || height == 0) { >@@ -623,13 +690,13 @@ static int I420ToRGB24Matrix(const uint8* src_y, > > // Convert I420 to RGB24. > LIBYUV_API >-int I420ToRGB24(const uint8* src_y, >+int I420ToRGB24(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgb24, >+ uint8_t* dst_rgb24, > int dst_stride_rgb24, > int width, > int height) { >@@ -640,13 +707,13 @@ int I420ToRGB24(const uint8* src_y, > > // Convert I420 to RAW. > LIBYUV_API >-int I420ToRAW(const uint8* src_y, >+int I420ToRAW(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_raw, >+ uint8_t* dst_raw, > int dst_stride_raw, > int width, > int height) { >@@ -659,13 +726,13 @@ int I420ToRAW(const uint8* src_y, > > // Convert H420 to RGB24. > LIBYUV_API >-int H420ToRGB24(const uint8* src_y, >+int H420ToRGB24(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgb24, >+ uint8_t* dst_rgb24, > int dst_stride_rgb24, > int width, > int height) { >@@ -676,13 +743,13 @@ int H420ToRGB24(const uint8* src_y, > > // Convert H420 to RAW. > LIBYUV_API >-int H420ToRAW(const uint8* src_y, >+int H420ToRAW(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_raw, >+ uint8_t* dst_raw, > int dst_stride_raw, > int width, > int height) { >@@ -695,19 +762,19 @@ int H420ToRAW(const uint8* src_y, > > // Convert I420 to ARGB1555. > LIBYUV_API >-int I420ToARGB1555(const uint8* src_y, >+int I420ToARGB1555(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb1555, >+ uint8_t* dst_argb1555, > int dst_stride_argb1555, > int width, > int height) { > int y; >- void (*I422ToARGB1555Row)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I422ToARGB1555Row)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) = I422ToARGB1555Row_C; > if (!src_y || !src_u || !src_v || !dst_argb1555 || width <= 0 || >@@ -744,14 +811,6 @@ int I420ToARGB1555(const uint8* src_y, > } > } > #endif >-#if defined(HAS_I422TOARGB1555ROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- I422ToARGB1555Row = I422ToARGB1555Row_Any_DSPR2; >- if (IS_ALIGNED(width, 4)) { >- I422ToARGB1555Row = I422ToARGB1555Row_DSPR2; >- } >- } >-#endif > #if defined(HAS_I422TOARGB1555ROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422ToARGB1555Row = I422ToARGB1555Row_Any_MSA; >@@ -776,19 +835,19 @@ int I420ToARGB1555(const uint8* src_y, > > // Convert I420 to ARGB4444. > LIBYUV_API >-int I420ToARGB4444(const uint8* src_y, >+int I420ToARGB4444(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_argb4444, >+ uint8_t* dst_argb4444, > int dst_stride_argb4444, > int width, > int height) { > int y; >- void (*I422ToARGB4444Row)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I422ToARGB4444Row)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) = I422ToARGB4444Row_C; > if (!src_y || !src_u || !src_v || !dst_argb4444 || width <= 0 || >@@ -825,14 +884,6 @@ int I420ToARGB4444(const uint8* src_y, > } > } > #endif >-#if defined(HAS_I422TOARGB4444ROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- I422ToARGB4444Row = I422ToARGB4444Row_Any_DSPR2; >- if (IS_ALIGNED(width, 4)) { >- I422ToARGB4444Row = I422ToARGB4444Row_DSPR2; >- } >- } >-#endif > #if defined(HAS_I422TOARGB4444ROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422ToARGB4444Row = I422ToARGB4444Row_Any_MSA; >@@ -857,19 +908,19 @@ int I420ToARGB4444(const uint8* src_y, > > // Convert I420 to RGB565. > LIBYUV_API >-int I420ToRGB565(const uint8* src_y, >+int I420ToRGB565(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgb565, >+ uint8_t* dst_rgb565, > int dst_stride_rgb565, > int width, > int height) { > int y; >- void (*I422ToRGB565Row)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I422ToRGB565Row)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, int width) = > I422ToRGB565Row_C; > if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { >@@ -928,19 +979,19 @@ int I420ToRGB565(const uint8* src_y, > > // Convert I422 to RGB565. > LIBYUV_API >-int I422ToRGB565(const uint8* src_y, >+int I422ToRGB565(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgb565, >+ uint8_t* dst_rgb565, > int dst_stride_rgb565, > int width, > int height) { > int y; >- void (*I422ToRGB565Row)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I422ToRGB565Row)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, int width) = > I422ToRGB565Row_C; > if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { >@@ -996,30 +1047,30 @@ int I422ToRGB565(const uint8* src_y, > } > > // Ordered 8x8 dither for 888 to 565. Values from 0 to 7. >-static const uint8 kDither565_4x4[16] = { >+static const uint8_t kDither565_4x4[16] = { > 0, 4, 1, 5, 6, 2, 7, 3, 1, 5, 0, 4, 7, 3, 6, 2, > }; > > // Convert I420 to RGB565 with dithering. > LIBYUV_API >-int I420ToRGB565Dither(const uint8* src_y, >+int I420ToRGB565Dither(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgb565, >+ uint8_t* dst_rgb565, > int dst_stride_rgb565, >- const uint8* dither4x4, >+ const uint8_t* dither4x4, > int width, > int height) { > int y; >- void (*I422ToARGBRow)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, int width) = > I422ToARGBRow_C; >- void (*ARGBToRGB565DitherRow)(const uint8* src_argb, uint8* dst_rgb, >- const uint32 dither4, int width) = >+ void (*ARGBToRGB565DitherRow)(const uint8_t* src_argb, uint8_t* dst_rgb, >+ const uint32_t dither4, int width) = > ARGBToRGB565DitherRow_C; > if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { > return -1; >@@ -1057,14 +1108,6 @@ int I420ToRGB565Dither(const uint8* src_y, > } > } > #endif >-#if defined(HAS_I422TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) && >- IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && >- IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && >- IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2)) { >- I422ToARGBRow = I422ToARGBRow_DSPR2; >- } >-#endif > #if defined(HAS_I422TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422ToARGBRow = I422ToARGBRow_Any_MSA; >@@ -1111,8 +1154,8 @@ int I420ToRGB565Dither(const uint8* src_y, > for (y = 0; y < height; ++y) { > I422ToARGBRow(src_y, src_u, src_v, row_argb, &kYuvI601Constants, width); > ARGBToRGB565DitherRow(row_argb, dst_rgb565, >- *(uint32*)(dither4x4 + ((y & 3) << 2)), // NOLINT >- width); // NOLINT >+ *(uint32_t*)(dither4x4 + ((y & 3) << 2)), // NOLINT >+ width); // NOLINT > dst_rgb565 += dst_stride_rgb565; > src_y += src_stride_y; > if (y & 1) { >@@ -1125,20 +1168,111 @@ int I420ToRGB565Dither(const uint8* src_y, > return 0; > } > >+// Convert I420 to AR30 with matrix >+static int I420ToAR30Matrix(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ const struct YuvConstants* yuvconstants, >+ int width, >+ int height) { >+ int y; >+ void (*I422ToAR30Row)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, int width) = >+ I422ToAR30Row_C; >+ >+ if (!src_y || !src_u || !src_v || !dst_ar30 || width <= 0 || height == 0) { >+ return -1; >+ } >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ dst_ar30 = dst_ar30 + (height - 1) * dst_stride_ar30; >+ dst_stride_ar30 = -dst_stride_ar30; >+ } >+ >+#if defined(HAS_I422TOAR30ROW_SSSE3) >+ if (TestCpuFlag(kCpuHasSSSE3)) { >+ I422ToAR30Row = I422ToAR30Row_Any_SSSE3; >+ if (IS_ALIGNED(width, 8)) { >+ I422ToAR30Row = I422ToAR30Row_SSSE3; >+ } >+ } >+#endif >+#if defined(HAS_I422TOAR30ROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ I422ToAR30Row = I422ToAR30Row_Any_AVX2; >+ if (IS_ALIGNED(width, 16)) { >+ I422ToAR30Row = I422ToAR30Row_AVX2; >+ } >+ } >+#endif >+ >+ for (y = 0; y < height; ++y) { >+ I422ToAR30Row(src_y, src_u, src_v, dst_ar30, yuvconstants, width); >+ dst_ar30 += dst_stride_ar30; >+ src_y += src_stride_y; >+ if (y & 1) { >+ src_u += src_stride_u; >+ src_v += src_stride_v; >+ } >+ } >+ return 0; >+} >+ >+// Convert I420 to AR30. >+LIBYUV_API >+int I420ToAR30(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height) { >+ return I420ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, >+ src_stride_v, dst_ar30, dst_stride_ar30, >+ &kYuvI601Constants, width, height); >+} >+ >+// Convert H420 to AR30. >+LIBYUV_API >+int H420ToAR30(const uint8_t* src_y, >+ int src_stride_y, >+ const uint8_t* src_u, >+ int src_stride_u, >+ const uint8_t* src_v, >+ int src_stride_v, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height) { >+ return I420ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, >+ src_stride_v, dst_ar30, dst_stride_ar30, >+ &kYvuH709Constants, width, height); >+} >+ > // Convert I420 to specified format > LIBYUV_API >-int ConvertFromI420(const uint8* y, >+int ConvertFromI420(const uint8_t* y, > int y_stride, >- const uint8* u, >+ const uint8_t* u, > int u_stride, >- const uint8* v, >+ const uint8_t* v, > int v_stride, >- uint8* dst_sample, >+ uint8_t* dst_sample, > int dst_sample_stride, > int width, > int height, >- uint32 fourcc) { >- uint32 format = CanonicalFourCC(fourcc); >+ uint32_t fourcc) { >+ uint32_t format = CanonicalFourCC(fourcc); > int r = 0; > if (!y || !u || !v || !dst_sample || width <= 0 || height == 0) { > return -1; >@@ -1200,13 +1334,18 @@ int ConvertFromI420(const uint8* y, > dst_sample_stride ? dst_sample_stride : width * 4, width, > height); > break; >+ case FOURCC_AR30: >+ r = I420ToAR30(y, y_stride, u, u_stride, v, v_stride, dst_sample, >+ dst_sample_stride ? dst_sample_stride : width * 4, width, >+ height); >+ break; > case FOURCC_I400: > r = I400Copy(y, y_stride, dst_sample, > dst_sample_stride ? dst_sample_stride : width, width, > height); > break; > case FOURCC_NV12: { >- uint8* dst_uv = dst_sample + width * height; >+ uint8_t* dst_uv = dst_sample + width * height; > r = I420ToNV12(y, y_stride, u, u_stride, v, v_stride, dst_sample, > dst_sample_stride ? dst_sample_stride : width, dst_uv, > dst_sample_stride ? dst_sample_stride : width, width, >@@ -1214,7 +1353,7 @@ int ConvertFromI420(const uint8* y, > break; > } > case FOURCC_NV21: { >- uint8* dst_vu = dst_sample + width * height; >+ uint8_t* dst_vu = dst_sample + width * height; > r = I420ToNV21(y, y_stride, u, u_stride, v, v_stride, dst_sample, > dst_sample_stride ? dst_sample_stride : width, dst_vu, > dst_sample_stride ? dst_sample_stride : width, width, >@@ -1228,8 +1367,8 @@ int ConvertFromI420(const uint8* y, > dst_sample_stride = dst_sample_stride ? dst_sample_stride : width; > int halfstride = (dst_sample_stride + 1) / 2; > int halfheight = (height + 1) / 2; >- uint8* dst_u; >- uint8* dst_v; >+ uint8_t* dst_u; >+ uint8_t* dst_v; > if (format == FOURCC_YV12) { > dst_v = dst_sample + dst_sample_stride * height; > dst_u = dst_v + halfstride * halfheight; >@@ -1246,8 +1385,8 @@ int ConvertFromI420(const uint8* y, > case FOURCC_YV16: { > dst_sample_stride = dst_sample_stride ? dst_sample_stride : width; > int halfstride = (dst_sample_stride + 1) / 2; >- uint8* dst_u; >- uint8* dst_v; >+ uint8_t* dst_u; >+ uint8_t* dst_v; > if (format == FOURCC_YV16) { > dst_v = dst_sample + dst_sample_stride * height; > dst_u = dst_v + halfstride * height; >@@ -1263,8 +1402,8 @@ int ConvertFromI420(const uint8* y, > case FOURCC_I444: > case FOURCC_YV24: { > dst_sample_stride = dst_sample_stride ? dst_sample_stride : width; >- uint8* dst_u; >- uint8* dst_v; >+ uint8_t* dst_u; >+ uint8_t* dst_v; > if (format == FOURCC_YV24) { > dst_v = dst_sample + dst_sample_stride * height; > dst_u = dst_v + dst_sample_stride * height; >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_from_argb.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_from_argb.cc >index 88f38279ace2f54555b76d0fce50585fb6cbcea3..16b838458f02d07767e23468d94b612d5dab2849 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_from_argb.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_from_argb.cc >@@ -22,21 +22,21 @@ extern "C" { > > // ARGB little endian (bgra in memory) to I444 > LIBYUV_API >-int ARGBToI444(const uint8* src_argb, >+int ARGBToI444(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; >- void (*ARGBToUV444Row)(const uint8* src_argb, uint8* dst_u, uint8* dst_v, >- int width) = ARGBToUV444Row_C; >+ void (*ARGBToUV444Row)(const uint8_t* src_argb, uint8_t* dst_u, >+ uint8_t* dst_v, int width) = ARGBToUV444Row_C; > if (!src_argb || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; > } >@@ -100,14 +100,6 @@ int ARGBToI444(const uint8* src_argb, > } > } > #endif >-#if defined(HAS_ARGBTOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToYRow = ARGBToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- ARGBToYRow = ARGBToYRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_ARGBTOYROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > ARGBToYRow = ARGBToYRow_Any_MSA; >@@ -130,20 +122,21 @@ int ARGBToI444(const uint8* src_argb, > > // ARGB little endian (bgra in memory) to I422 > LIBYUV_API >-int ARGBToI422(const uint8* src_argb, >+int ARGBToI422(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; > if (!src_argb || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; >@@ -197,22 +190,6 @@ int ARGBToI422(const uint8* src_argb, > } > } > #endif >-#if defined(HAS_ARGBTOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToYRow = ARGBToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- ARGBToYRow = ARGBToYRow_DSPR2; >- } >- } >-#endif >-#if defined(HAS_ARGBTOUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToUVRow = ARGBToUVRow_Any_DSPR2; >- if (IS_ALIGNED(width, 16)) { >- ARGBToUVRow = ARGBToUVRow_DSPR2; >- } >- } >-#endif > > #if defined(HAS_ARGBTOYROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { >@@ -243,22 +220,23 @@ int ARGBToI422(const uint8* src_argb, > } > > LIBYUV_API >-int ARGBToNV12(const uint8* src_argb, >+int ARGBToNV12(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int dst_stride_uv, > int width, > int height) { > int y; > int halfwidth = (width + 1) >> 1; >- void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; >- void (*MergeUVRow_)(const uint8* src_u, const uint8* src_v, uint8* dst_uv, >- int width) = MergeUVRow_C; >+ void (*MergeUVRow_)(const uint8_t* src_u, const uint8_t* src_v, >+ uint8_t* dst_uv, int width) = MergeUVRow_C; > if (!src_argb || !dst_y || !dst_uv || width <= 0 || height == 0) { > return -1; > } >@@ -344,22 +322,6 @@ int ARGBToNV12(const uint8* src_argb, > } > } > #endif >-#if defined(HAS_ARGBTOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToYRow = ARGBToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- ARGBToYRow = ARGBToYRow_DSPR2; >- } >- } >-#endif >-#if defined(HAS_ARGBTOUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToUVRow = ARGBToUVRow_Any_DSPR2; >- if (IS_ALIGNED(width, 16)) { >- ARGBToUVRow = ARGBToUVRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_MERGEUVROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > MergeUVRow_ = MergeUVRow_Any_MSA; >@@ -371,7 +333,7 @@ int ARGBToNV12(const uint8* src_argb, > { > // Allocate a rows of uv. > align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2); >- uint8* row_v = row_u + ((halfwidth + 31) & ~31); >+ uint8_t* row_v = row_u + ((halfwidth + 31) & ~31); > > for (y = 0; y < height - 1; y += 2) { > ARGBToUVRow(src_argb, src_stride_argb, row_u, row_v, width); >@@ -394,23 +356,24 @@ int ARGBToNV12(const uint8* src_argb, > > // Same as NV12 but U and V swapped. > LIBYUV_API >-int ARGBToNV21(const uint8* src_argb, >+int ARGBToNV21(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_uv, >- int dst_stride_uv, >+ uint8_t* dst_vu, >+ int dst_stride_vu, > int width, > int height) { > int y; > int halfwidth = (width + 1) >> 1; >- void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; >- void (*MergeUVRow_)(const uint8* src_u, const uint8* src_v, uint8* dst_uv, >- int width) = MergeUVRow_C; >- if (!src_argb || !dst_y || !dst_uv || width <= 0 || height == 0) { >+ void (*MergeUVRow_)(const uint8_t* src_u, const uint8_t* src_v, >+ uint8_t* dst_vu, int width) = MergeUVRow_C; >+ if (!src_argb || !dst_y || !dst_vu || width <= 0 || height == 0) { > return -1; > } > // Negative height means invert the image. >@@ -495,22 +458,6 @@ int ARGBToNV21(const uint8* src_argb, > } > } > #endif >-#if defined(HAS_ARGBTOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToYRow = ARGBToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- ARGBToYRow = ARGBToYRow_DSPR2; >- } >- } >-#endif >-#if defined(HAS_ARGBTOUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToUVRow = ARGBToUVRow_Any_DSPR2; >- if (IS_ALIGNED(width, 16)) { >- ARGBToUVRow = ARGBToUVRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_MERGEUVROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > MergeUVRow_ = MergeUVRow_Any_MSA; >@@ -522,20 +469,20 @@ int ARGBToNV21(const uint8* src_argb, > { > // Allocate a rows of uv. > align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2); >- uint8* row_v = row_u + ((halfwidth + 31) & ~31); >+ uint8_t* row_v = row_u + ((halfwidth + 31) & ~31); > > for (y = 0; y < height - 1; y += 2) { > ARGBToUVRow(src_argb, src_stride_argb, row_u, row_v, width); >- MergeUVRow_(row_v, row_u, dst_uv, halfwidth); >+ MergeUVRow_(row_v, row_u, dst_vu, halfwidth); > ARGBToYRow(src_argb, dst_y, width); > ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width); > src_argb += src_stride_argb * 2; > dst_y += dst_stride_y * 2; >- dst_uv += dst_stride_uv; >+ dst_vu += dst_stride_vu; > } > if (height & 1) { > ARGBToUVRow(src_argb, 0, row_u, row_v, width); >- MergeUVRow_(row_v, row_u, dst_uv, halfwidth); >+ MergeUVRow_(row_v, row_u, dst_vu, halfwidth); > ARGBToYRow(src_argb, dst_y, width); > } > free_aligned_buffer_64(row_u); >@@ -545,19 +492,20 @@ int ARGBToNV21(const uint8* src_argb, > > // Convert ARGB to YUY2. > LIBYUV_API >-int ARGBToYUY2(const uint8* src_argb, >+int ARGBToYUY2(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_yuy2, >+ uint8_t* dst_yuy2, > int dst_stride_yuy2, > int width, > int height) { > int y; >- void (*ARGBToUVRow)(const uint8* src_argb, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGBToUVRow)(const uint8_t* src_argb, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; >- void (*I422ToYUY2Row)(const uint8* src_y, const uint8* src_u, >- const uint8* src_v, uint8* dst_yuy2, int width) = >+ void (*I422ToYUY2Row)(const uint8_t* src_y, const uint8_t* src_u, >+ const uint8_t* src_v, uint8_t* dst_yuy2, int width) = > I422ToYUY2Row_C; > > if (!src_argb || !dst_yuy2 || width <= 0 || height == 0) { >@@ -635,6 +583,14 @@ int ARGBToYUY2(const uint8* src_argb, > } > } > #endif >+#if defined(HAS_I422TOYUY2ROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ I422ToYUY2Row = I422ToYUY2Row_Any_AVX2; >+ if (IS_ALIGNED(width, 32)) { >+ I422ToYUY2Row = I422ToYUY2Row_AVX2; >+ } >+ } >+#endif > #if defined(HAS_I422TOYUY2ROW_NEON) > if (TestCpuFlag(kCpuHasNEON)) { > I422ToYUY2Row = I422ToYUY2Row_Any_NEON; >@@ -643,22 +599,6 @@ int ARGBToYUY2(const uint8* src_argb, > } > } > #endif >-#if defined(HAS_ARGBTOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToYRow = ARGBToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- ARGBToYRow = ARGBToYRow_DSPR2; >- } >- } >-#endif >-#if defined(HAS_ARGBTOUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToUVRow = ARGBToUVRow_Any_DSPR2; >- if (IS_ALIGNED(width, 16)) { >- ARGBToUVRow = ARGBToUVRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_I422TOYUY2ROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422ToYUY2Row = I422ToYUY2Row_Any_MSA; >@@ -671,8 +611,8 @@ int ARGBToYUY2(const uint8* src_argb, > { > // Allocate a rows of yuv. > align_buffer_64(row_y, ((width + 63) & ~63) * 2); >- uint8* row_u = row_y + ((width + 63) & ~63); >- uint8* row_v = row_u + ((width + 63) & ~63) / 2; >+ uint8_t* row_u = row_y + ((width + 63) & ~63); >+ uint8_t* row_v = row_u + ((width + 63) & ~63) / 2; > > for (y = 0; y < height; ++y) { > ARGBToUVRow(src_argb, 0, row_u, row_v, width); >@@ -689,19 +629,20 @@ int ARGBToYUY2(const uint8* src_argb, > > // Convert ARGB to UYVY. > LIBYUV_API >-int ARGBToUYVY(const uint8* src_argb, >+int ARGBToUYVY(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_uyvy, >+ uint8_t* dst_uyvy, > int dst_stride_uyvy, > int width, > int height) { > int y; >- void (*ARGBToUVRow)(const uint8* src_argb, int src_stride_argb, uint8* dst_u, >- uint8* dst_v, int width) = ARGBToUVRow_C; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGBToUVRow)(const uint8_t* src_argb, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVRow_C; >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; >- void (*I422ToUYVYRow)(const uint8* src_y, const uint8* src_u, >- const uint8* src_v, uint8* dst_uyvy, int width) = >+ void (*I422ToUYVYRow)(const uint8_t* src_y, const uint8_t* src_u, >+ const uint8_t* src_v, uint8_t* dst_uyvy, int width) = > I422ToUYVYRow_C; > > if (!src_argb || !dst_uyvy || width <= 0 || height == 0) { >@@ -779,6 +720,14 @@ int ARGBToUYVY(const uint8* src_argb, > } > } > #endif >+#if defined(HAS_I422TOUYVYROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ I422ToUYVYRow = I422ToUYVYRow_Any_AVX2; >+ if (IS_ALIGNED(width, 32)) { >+ I422ToUYVYRow = I422ToUYVYRow_AVX2; >+ } >+ } >+#endif > #if defined(HAS_I422TOUYVYROW_NEON) > if (TestCpuFlag(kCpuHasNEON)) { > I422ToUYVYRow = I422ToUYVYRow_Any_NEON; >@@ -787,22 +736,6 @@ int ARGBToUYVY(const uint8* src_argb, > } > } > #endif >-#if defined(HAS_ARGBTOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToYRow = ARGBToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- ARGBToYRow = ARGBToYRow_DSPR2; >- } >- } >-#endif >-#if defined(HAS_ARGBTOUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToUVRow = ARGBToUVRow_Any_DSPR2; >- if (IS_ALIGNED(width, 16)) { >- ARGBToUVRow = ARGBToUVRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_I422TOUYVYROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422ToUYVYRow = I422ToUYVYRow_Any_MSA; >@@ -815,8 +748,8 @@ int ARGBToUYVY(const uint8* src_argb, > { > // Allocate a rows of yuv. > align_buffer_64(row_y, ((width + 63) & ~63) * 2); >- uint8* row_u = row_y + ((width + 63) & ~63); >- uint8* row_v = row_u + ((width + 63) & ~63) / 2; >+ uint8_t* row_u = row_y + ((width + 63) & ~63); >+ uint8_t* row_v = row_u + ((width + 63) & ~63) / 2; > > for (y = 0; y < height; ++y) { > ARGBToUVRow(src_argb, 0, row_u, row_v, width); >@@ -833,14 +766,14 @@ int ARGBToUYVY(const uint8* src_argb, > > // Convert ARGB to I400. > LIBYUV_API >-int ARGBToI400(const uint8* src_argb, >+int ARGBToI400(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height) { > int y; >- void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) = >+ void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = > ARGBToYRow_C; > if (!src_argb || !dst_y || width <= 0 || height == 0) { > return -1; >@@ -880,14 +813,6 @@ int ARGBToI400(const uint8* src_argb, > } > } > #endif >-#if defined(HAS_ARGBTOYROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ARGBToYRow = ARGBToYRow_Any_DSPR2; >- if (IS_ALIGNED(width, 8)) { >- ARGBToYRow = ARGBToYRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_ARGBTOYROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > ARGBToYRow = ARGBToYRow_Any_MSA; >@@ -906,31 +831,31 @@ int ARGBToI400(const uint8* src_argb, > } > > // Shuffle table for converting ARGB to RGBA. >-static uvec8 kShuffleMaskARGBToRGBA = {3u, 0u, 1u, 2u, 7u, 4u, 5u, 6u, >- 11u, 8u, 9u, 10u, 15u, 12u, 13u, 14u}; >+static const uvec8 kShuffleMaskARGBToRGBA = { >+ 3u, 0u, 1u, 2u, 7u, 4u, 5u, 6u, 11u, 8u, 9u, 10u, 15u, 12u, 13u, 14u}; > > // Convert ARGB to RGBA. > LIBYUV_API >-int ARGBToRGBA(const uint8* src_argb, >+int ARGBToRGBA(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_rgba, >+ uint8_t* dst_rgba, > int dst_stride_rgba, > int width, > int height) { > return ARGBShuffle(src_argb, src_stride_argb, dst_rgba, dst_stride_rgba, >- (const uint8*)(&kShuffleMaskARGBToRGBA), width, height); >+ (const uint8_t*)(&kShuffleMaskARGBToRGBA), width, height); > } > > // Convert ARGB To RGB24. > LIBYUV_API >-int ARGBToRGB24(const uint8* src_argb, >+int ARGBToRGB24(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_rgb24, >+ uint8_t* dst_rgb24, > int dst_stride_rgb24, > int width, > int height) { > int y; >- void (*ARGBToRGB24Row)(const uint8* src_argb, uint8* dst_rgb, int width) = >+ void (*ARGBToRGB24Row)(const uint8_t* src_argb, uint8_t* dst_rgb, int width) = > ARGBToRGB24Row_C; > if (!src_argb || !dst_rgb24 || width <= 0 || height == 0) { > return -1; >@@ -981,14 +906,14 @@ int ARGBToRGB24(const uint8* src_argb, > > // Convert ARGB To RAW. > LIBYUV_API >-int ARGBToRAW(const uint8* src_argb, >+int ARGBToRAW(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_raw, >+ uint8_t* dst_raw, > int dst_stride_raw, > int width, > int height) { > int y; >- void (*ARGBToRAWRow)(const uint8* src_argb, uint8* dst_rgb, int width) = >+ void (*ARGBToRAWRow)(const uint8_t* src_argb, uint8_t* dst_rgb, int width) = > ARGBToRAWRow_C; > if (!src_argb || !dst_raw || width <= 0 || height == 0) { > return -1; >@@ -1038,22 +963,22 @@ int ARGBToRAW(const uint8* src_argb, > } > > // Ordered 8x8 dither for 888 to 565. Values from 0 to 7. >-static const uint8 kDither565_4x4[16] = { >+static const uint8_t kDither565_4x4[16] = { > 0, 4, 1, 5, 6, 2, 7, 3, 1, 5, 0, 4, 7, 3, 6, 2, > }; > > // Convert ARGB To RGB565 with 4x4 dither matrix (16 bytes). > LIBYUV_API >-int ARGBToRGB565Dither(const uint8* src_argb, >+int ARGBToRGB565Dither(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_rgb565, >+ uint8_t* dst_rgb565, > int dst_stride_rgb565, >- const uint8* dither4x4, >+ const uint8_t* dither4x4, > int width, > int height) { > int y; >- void (*ARGBToRGB565DitherRow)(const uint8* src_argb, uint8* dst_rgb, >- const uint32 dither4, int width) = >+ void (*ARGBToRGB565DitherRow)(const uint8_t* src_argb, uint8_t* dst_rgb, >+ const uint32_t dither4, int width) = > ARGBToRGB565DitherRow_C; > if (!src_argb || !dst_rgb565 || width <= 0 || height == 0) { > return -1; >@@ -1101,7 +1026,7 @@ int ARGBToRGB565Dither(const uint8* src_argb, > > for (y = 0; y < height; ++y) { > ARGBToRGB565DitherRow(src_argb, dst_rgb565, >- *(uint32*)(dither4x4 + ((y & 3) << 2)), >+ *(uint32_t*)(dither4x4 + ((y & 3) << 2)), // NOLINT > width); /* NOLINT */ > src_argb += src_stride_argb; > dst_rgb565 += dst_stride_rgb565; >@@ -1112,15 +1037,15 @@ int ARGBToRGB565Dither(const uint8* src_argb, > // Convert ARGB To RGB565. > // TODO(fbarchard): Consider using dither function low level with zeros. > LIBYUV_API >-int ARGBToRGB565(const uint8* src_argb, >+int ARGBToRGB565(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_rgb565, >+ uint8_t* dst_rgb565, > int dst_stride_rgb565, > int width, > int height) { > int y; >- void (*ARGBToRGB565Row)(const uint8* src_argb, uint8* dst_rgb, int width) = >- ARGBToRGB565Row_C; >+ void (*ARGBToRGB565Row)(const uint8_t* src_argb, uint8_t* dst_rgb, >+ int width) = ARGBToRGB565Row_C; > if (!src_argb || !dst_rgb565 || width <= 0 || height == 0) { > return -1; > } >@@ -1178,15 +1103,15 @@ int ARGBToRGB565(const uint8* src_argb, > > // Convert ARGB To ARGB1555. > LIBYUV_API >-int ARGBToARGB1555(const uint8* src_argb, >+int ARGBToARGB1555(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb1555, >+ uint8_t* dst_argb1555, > int dst_stride_argb1555, > int width, > int height) { > int y; >- void (*ARGBToARGB1555Row)(const uint8* src_argb, uint8* dst_rgb, int width) = >- ARGBToARGB1555Row_C; >+ void (*ARGBToARGB1555Row)(const uint8_t* src_argb, uint8_t* dst_rgb, >+ int width) = ARGBToARGB1555Row_C; > if (!src_argb || !dst_argb1555 || width <= 0 || height == 0) { > return -1; > } >@@ -1244,15 +1169,15 @@ int ARGBToARGB1555(const uint8* src_argb, > > // Convert ARGB To ARGB4444. > LIBYUV_API >-int ARGBToARGB4444(const uint8* src_argb, >+int ARGBToARGB4444(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb4444, >+ uint8_t* dst_argb4444, > int dst_stride_argb4444, > int width, > int height) { > int y; >- void (*ARGBToARGB4444Row)(const uint8* src_argb, uint8* dst_rgb, int width) = >- ARGBToARGB4444Row_C; >+ void (*ARGBToARGB4444Row)(const uint8_t* src_argb, uint8_t* dst_rgb, >+ int width) = ARGBToARGB4444Row_C; > if (!src_argb || !dst_argb4444 || width <= 0 || height == 0) { > return -1; > } >@@ -1308,22 +1233,121 @@ int ARGBToARGB4444(const uint8* src_argb, > return 0; > } > >+// Convert ABGR To AR30. >+LIBYUV_API >+int ABGRToAR30(const uint8_t* src_abgr, >+ int src_stride_abgr, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height) { >+ int y; >+ void (*ABGRToAR30Row)(const uint8_t* src_abgr, uint8_t* dst_rgb, int width) = >+ ABGRToAR30Row_C; >+ if (!src_abgr || !dst_ar30 || width <= 0 || height == 0) { >+ return -1; >+ } >+ if (height < 0) { >+ height = -height; >+ src_abgr = src_abgr + (height - 1) * src_stride_abgr; >+ src_stride_abgr = -src_stride_abgr; >+ } >+ // Coalesce rows. >+ if (src_stride_abgr == width * 4 && dst_stride_ar30 == width * 4) { >+ width *= height; >+ height = 1; >+ src_stride_abgr = dst_stride_ar30 = 0; >+ } >+#if defined(HAS_ABGRTOAR30ROW_SSSE3) >+ if (TestCpuFlag(kCpuHasSSSE3)) { >+ ABGRToAR30Row = ABGRToAR30Row_Any_SSSE3; >+ if (IS_ALIGNED(width, 4)) { >+ ABGRToAR30Row = ABGRToAR30Row_SSSE3; >+ } >+ } >+#endif >+#if defined(HAS_ABGRTOAR30ROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ ABGRToAR30Row = ABGRToAR30Row_Any_AVX2; >+ if (IS_ALIGNED(width, 8)) { >+ ABGRToAR30Row = ABGRToAR30Row_AVX2; >+ } >+ } >+#endif >+ for (y = 0; y < height; ++y) { >+ ABGRToAR30Row(src_abgr, dst_ar30, width); >+ src_abgr += src_stride_abgr; >+ dst_ar30 += dst_stride_ar30; >+ } >+ return 0; >+} >+ >+// Convert ARGB To AR30. >+LIBYUV_API >+int ARGBToAR30(const uint8_t* src_argb, >+ int src_stride_argb, >+ uint8_t* dst_ar30, >+ int dst_stride_ar30, >+ int width, >+ int height) { >+ int y; >+ void (*ARGBToAR30Row)(const uint8_t* src_argb, uint8_t* dst_rgb, int width) = >+ ARGBToAR30Row_C; >+ if (!src_argb || !dst_ar30 || width <= 0 || height == 0) { >+ return -1; >+ } >+ if (height < 0) { >+ height = -height; >+ src_argb = src_argb + (height - 1) * src_stride_argb; >+ src_stride_argb = -src_stride_argb; >+ } >+ // Coalesce rows. >+ if (src_stride_argb == width * 4 && dst_stride_ar30 == width * 4) { >+ width *= height; >+ height = 1; >+ src_stride_argb = dst_stride_ar30 = 0; >+ } >+#if defined(HAS_ARGBTOAR30ROW_SSSE3) >+ if (TestCpuFlag(kCpuHasSSSE3)) { >+ ARGBToAR30Row = ARGBToAR30Row_Any_SSSE3; >+ if (IS_ALIGNED(width, 4)) { >+ ARGBToAR30Row = ARGBToAR30Row_SSSE3; >+ } >+ } >+#endif >+#if defined(HAS_ARGBTOAR30ROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ ARGBToAR30Row = ARGBToAR30Row_Any_AVX2; >+ if (IS_ALIGNED(width, 8)) { >+ ARGBToAR30Row = ARGBToAR30Row_AVX2; >+ } >+ } >+#endif >+ for (y = 0; y < height; ++y) { >+ ARGBToAR30Row(src_argb, dst_ar30, width); >+ src_argb += src_stride_argb; >+ dst_ar30 += dst_stride_ar30; >+ } >+ return 0; >+} >+ > // Convert ARGB to J420. (JPeg full range I420). > LIBYUV_API >-int ARGBToJ420(const uint8* src_argb, >+int ARGBToJ420(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_yj, >+ uint8_t* dst_yj, > int dst_stride_yj, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*ARGBToUVJRow)(const uint8* src_argb0, int src_stride_argb, >- uint8* dst_u, uint8* dst_v, int width) = ARGBToUVJRow_C; >- void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_yj, int width) = >+ void (*ARGBToUVJRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVJRow_C; >+ void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_yj, int width) = > ARGBToYJRow_C; > if (!src_argb || !dst_yj || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; >@@ -1403,20 +1427,21 @@ int ARGBToJ420(const uint8* src_argb, > > // Convert ARGB to J422. (JPeg full range I422). > LIBYUV_API >-int ARGBToJ422(const uint8* src_argb, >+int ARGBToJ422(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_yj, >+ uint8_t* dst_yj, > int dst_stride_yj, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*ARGBToUVJRow)(const uint8* src_argb0, int src_stride_argb, >- uint8* dst_u, uint8* dst_v, int width) = ARGBToUVJRow_C; >- void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_yj, int width) = >+ void (*ARGBToUVJRow)(const uint8_t* src_argb0, int src_stride_argb, >+ uint8_t* dst_u, uint8_t* dst_v, int width) = >+ ARGBToUVJRow_C; >+ void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_yj, int width) = > ARGBToYJRow_C; > if (!src_argb || !dst_yj || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; >@@ -1498,14 +1523,14 @@ int ARGBToJ422(const uint8* src_argb, > > // Convert ARGB to J400. > LIBYUV_API >-int ARGBToJ400(const uint8* src_argb, >+int ARGBToJ400(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_yj, >+ uint8_t* dst_yj, > int dst_stride_yj, > int width, > int height) { > int y; >- void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_yj, int width) = >+ void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_yj, int width) = > ARGBToYJRow_C; > if (!src_argb || !dst_yj || width <= 0 || height == 0) { > return -1; >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_jpeg.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_jpeg.cc >index 216a9f26d8723481d1d4c578a24a436975ae32c0..ae3cc18cd247c2fe976ef7d7ebe48b8da67a6727 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_jpeg.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_jpeg.cc >@@ -22,18 +22,18 @@ extern "C" { > > #ifdef HAVE_JPEG > struct I420Buffers { >- uint8* y; >+ uint8_t* y; > int y_stride; >- uint8* u; >+ uint8_t* u; > int u_stride; >- uint8* v; >+ uint8_t* v; > int v_stride; > int w; > int h; > }; > > static void JpegCopyI420(void* opaque, >- const uint8* const* data, >+ const uint8_t* const* data, > const int* strides, > int rows) { > I420Buffers* dest = (I420Buffers*)(opaque); >@@ -47,7 +47,7 @@ static void JpegCopyI420(void* opaque, > } > > static void JpegI422ToI420(void* opaque, >- const uint8* const* data, >+ const uint8_t* const* data, > const int* strides, > int rows) { > I420Buffers* dest = (I420Buffers*)(opaque); >@@ -61,7 +61,7 @@ static void JpegI422ToI420(void* opaque, > } > > static void JpegI444ToI420(void* opaque, >- const uint8* const* data, >+ const uint8_t* const* data, > const int* strides, > int rows) { > I420Buffers* dest = (I420Buffers*)(opaque); >@@ -75,7 +75,7 @@ static void JpegI444ToI420(void* opaque, > } > > static void JpegI400ToI420(void* opaque, >- const uint8* const* data, >+ const uint8_t* const* data, > const int* strides, > int rows) { > I420Buffers* dest = (I420Buffers*)(opaque); >@@ -89,7 +89,10 @@ static void JpegI400ToI420(void* opaque, > > // Query size of MJPG in pixels. > LIBYUV_API >-int MJPGSize(const uint8* sample, size_t sample_size, int* width, int* height) { >+int MJPGSize(const uint8_t* sample, >+ size_t sample_size, >+ int* width, >+ int* height) { > MJpegDecoder mjpeg_decoder; > LIBYUV_BOOL ret = mjpeg_decoder.LoadFrame(sample, sample_size); > if (ret) { >@@ -101,20 +104,21 @@ int MJPGSize(const uint8* sample, size_t sample_size, int* width, int* height) { > } > > // MJPG (Motion JPeg) to I420 >-// TODO(fbarchard): review w and h requirement. dw and dh may be enough. >+// TODO(fbarchard): review src_width and src_height requirement. dst_width and >+// dst_height may be enough. > LIBYUV_API >-int MJPGToI420(const uint8* sample, >+int MJPGToI420(const uint8_t* sample, > size_t sample_size, >- uint8* y, >- int y_stride, >- uint8* u, >- int u_stride, >- uint8* v, >- int v_stride, >- int w, >- int h, >- int dw, >- int dh) { >+ uint8_t* dst_y, >+ int dst_stride_y, >+ uint8_t* dst_u, >+ int dst_stride_u, >+ uint8_t* dst_v, >+ int dst_stride_v, >+ int src_width, >+ int src_height, >+ int dst_width, >+ int dst_height) { > if (sample_size == kUnknownDataSize) { > // ERROR: MJPEG frame size unknown > return -1; >@@ -123,14 +127,15 @@ int MJPGToI420(const uint8* sample, > // TODO(fbarchard): Port MJpeg to C. > MJpegDecoder mjpeg_decoder; > LIBYUV_BOOL ret = mjpeg_decoder.LoadFrame(sample, sample_size); >- if (ret && >- (mjpeg_decoder.GetWidth() != w || mjpeg_decoder.GetHeight() != h)) { >+ if (ret && (mjpeg_decoder.GetWidth() != src_width || >+ mjpeg_decoder.GetHeight() != src_height)) { > // ERROR: MJPEG frame has unexpected dimensions > mjpeg_decoder.UnloadFrame(); > return 1; // runtime failure > } > if (ret) { >- I420Buffers bufs = {y, y_stride, u, u_stride, v, v_stride, dw, dh}; >+ I420Buffers bufs = {dst_y, dst_stride_y, dst_u, dst_stride_u, >+ dst_v, dst_stride_v, dst_width, dst_height}; > // YUV420 > if (mjpeg_decoder.GetColorSpace() == MJpegDecoder::kColorSpaceYCbCr && > mjpeg_decoder.GetNumComponents() == 3 && >@@ -140,7 +145,8 @@ int MJPGToI420(const uint8* sample, > mjpeg_decoder.GetHorizSampFactor(1) == 1 && > mjpeg_decoder.GetVertSampFactor(2) == 1 && > mjpeg_decoder.GetHorizSampFactor(2) == 1) { >- ret = mjpeg_decoder.DecodeToCallback(&JpegCopyI420, &bufs, dw, dh); >+ ret = mjpeg_decoder.DecodeToCallback(&JpegCopyI420, &bufs, dst_width, >+ dst_height); > // YUV422 > } else if (mjpeg_decoder.GetColorSpace() == > MJpegDecoder::kColorSpaceYCbCr && >@@ -151,7 +157,8 @@ int MJPGToI420(const uint8* sample, > mjpeg_decoder.GetHorizSampFactor(1) == 1 && > mjpeg_decoder.GetVertSampFactor(2) == 1 && > mjpeg_decoder.GetHorizSampFactor(2) == 1) { >- ret = mjpeg_decoder.DecodeToCallback(&JpegI422ToI420, &bufs, dw, dh); >+ ret = mjpeg_decoder.DecodeToCallback(&JpegI422ToI420, &bufs, dst_width, >+ dst_height); > // YUV444 > } else if (mjpeg_decoder.GetColorSpace() == > MJpegDecoder::kColorSpaceYCbCr && >@@ -162,14 +169,16 @@ int MJPGToI420(const uint8* sample, > mjpeg_decoder.GetHorizSampFactor(1) == 1 && > mjpeg_decoder.GetVertSampFactor(2) == 1 && > mjpeg_decoder.GetHorizSampFactor(2) == 1) { >- ret = mjpeg_decoder.DecodeToCallback(&JpegI444ToI420, &bufs, dw, dh); >+ ret = mjpeg_decoder.DecodeToCallback(&JpegI444ToI420, &bufs, dst_width, >+ dst_height); > // YUV400 > } else if (mjpeg_decoder.GetColorSpace() == > MJpegDecoder::kColorSpaceGrayscale && > mjpeg_decoder.GetNumComponents() == 1 && > mjpeg_decoder.GetVertSampFactor(0) == 1 && > mjpeg_decoder.GetHorizSampFactor(0) == 1) { >- ret = mjpeg_decoder.DecodeToCallback(&JpegI400ToI420, &bufs, dw, dh); >+ ret = mjpeg_decoder.DecodeToCallback(&JpegI400ToI420, &bufs, dst_width, >+ dst_height); > } else { > // TODO(fbarchard): Implement conversion for any other colorspace/sample > // factors that occur in practice. >@@ -183,14 +192,14 @@ int MJPGToI420(const uint8* sample, > > #ifdef HAVE_JPEG > struct ARGBBuffers { >- uint8* argb; >+ uint8_t* argb; > int argb_stride; > int w; > int h; > }; > > static void JpegI420ToARGB(void* opaque, >- const uint8* const* data, >+ const uint8_t* const* data, > const int* strides, > int rows) { > ARGBBuffers* dest = (ARGBBuffers*)(opaque); >@@ -201,7 +210,7 @@ static void JpegI420ToARGB(void* opaque, > } > > static void JpegI422ToARGB(void* opaque, >- const uint8* const* data, >+ const uint8_t* const* data, > const int* strides, > int rows) { > ARGBBuffers* dest = (ARGBBuffers*)(opaque); >@@ -212,7 +221,7 @@ static void JpegI422ToARGB(void* opaque, > } > > static void JpegI444ToARGB(void* opaque, >- const uint8* const* data, >+ const uint8_t* const* data, > const int* strides, > int rows) { > ARGBBuffers* dest = (ARGBBuffers*)(opaque); >@@ -223,7 +232,7 @@ static void JpegI444ToARGB(void* opaque, > } > > static void JpegI400ToARGB(void* opaque, >- const uint8* const* data, >+ const uint8_t* const* data, > const int* strides, > int rows) { > ARGBBuffers* dest = (ARGBBuffers*)(opaque); >@@ -233,16 +242,17 @@ static void JpegI400ToARGB(void* opaque, > } > > // MJPG (Motion JPeg) to ARGB >-// TODO(fbarchard): review w and h requirement. dw and dh may be enough. >+// TODO(fbarchard): review src_width and src_height requirement. dst_width and >+// dst_height may be enough. > LIBYUV_API >-int MJPGToARGB(const uint8* sample, >+int MJPGToARGB(const uint8_t* sample, > size_t sample_size, >- uint8* argb, >- int argb_stride, >- int w, >- int h, >- int dw, >- int dh) { >+ uint8_t* dst_argb, >+ int dst_stride_argb, >+ int src_width, >+ int src_height, >+ int dst_width, >+ int dst_height) { > if (sample_size == kUnknownDataSize) { > // ERROR: MJPEG frame size unknown > return -1; >@@ -251,14 +261,14 @@ int MJPGToARGB(const uint8* sample, > // TODO(fbarchard): Port MJpeg to C. > MJpegDecoder mjpeg_decoder; > LIBYUV_BOOL ret = mjpeg_decoder.LoadFrame(sample, sample_size); >- if (ret && >- (mjpeg_decoder.GetWidth() != w || mjpeg_decoder.GetHeight() != h)) { >+ if (ret && (mjpeg_decoder.GetWidth() != src_width || >+ mjpeg_decoder.GetHeight() != src_height)) { > // ERROR: MJPEG frame has unexpected dimensions > mjpeg_decoder.UnloadFrame(); > return 1; // runtime failure > } > if (ret) { >- ARGBBuffers bufs = {argb, argb_stride, dw, dh}; >+ ARGBBuffers bufs = {dst_argb, dst_stride_argb, dst_width, dst_height}; > // YUV420 > if (mjpeg_decoder.GetColorSpace() == MJpegDecoder::kColorSpaceYCbCr && > mjpeg_decoder.GetNumComponents() == 3 && >@@ -268,7 +278,8 @@ int MJPGToARGB(const uint8* sample, > mjpeg_decoder.GetHorizSampFactor(1) == 1 && > mjpeg_decoder.GetVertSampFactor(2) == 1 && > mjpeg_decoder.GetHorizSampFactor(2) == 1) { >- ret = mjpeg_decoder.DecodeToCallback(&JpegI420ToARGB, &bufs, dw, dh); >+ ret = mjpeg_decoder.DecodeToCallback(&JpegI420ToARGB, &bufs, dst_width, >+ dst_height); > // YUV422 > } else if (mjpeg_decoder.GetColorSpace() == > MJpegDecoder::kColorSpaceYCbCr && >@@ -279,7 +290,8 @@ int MJPGToARGB(const uint8* sample, > mjpeg_decoder.GetHorizSampFactor(1) == 1 && > mjpeg_decoder.GetVertSampFactor(2) == 1 && > mjpeg_decoder.GetHorizSampFactor(2) == 1) { >- ret = mjpeg_decoder.DecodeToCallback(&JpegI422ToARGB, &bufs, dw, dh); >+ ret = mjpeg_decoder.DecodeToCallback(&JpegI422ToARGB, &bufs, dst_width, >+ dst_height); > // YUV444 > } else if (mjpeg_decoder.GetColorSpace() == > MJpegDecoder::kColorSpaceYCbCr && >@@ -290,14 +302,16 @@ int MJPGToARGB(const uint8* sample, > mjpeg_decoder.GetHorizSampFactor(1) == 1 && > mjpeg_decoder.GetVertSampFactor(2) == 1 && > mjpeg_decoder.GetHorizSampFactor(2) == 1) { >- ret = mjpeg_decoder.DecodeToCallback(&JpegI444ToARGB, &bufs, dw, dh); >+ ret = mjpeg_decoder.DecodeToCallback(&JpegI444ToARGB, &bufs, dst_width, >+ dst_height); > // YUV400 > } else if (mjpeg_decoder.GetColorSpace() == > MJpegDecoder::kColorSpaceGrayscale && > mjpeg_decoder.GetNumComponents() == 1 && > mjpeg_decoder.GetVertSampFactor(0) == 1 && > mjpeg_decoder.GetHorizSampFactor(0) == 1) { >- ret = mjpeg_decoder.DecodeToCallback(&JpegI400ToARGB, &bufs, dw, dh); >+ ret = mjpeg_decoder.DecodeToCallback(&JpegI400ToARGB, &bufs, dst_width, >+ dst_height); > } else { > // TODO(fbarchard): Implement conversion for any other colorspace/sample > // factors that occur in practice. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_to_argb.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_to_argb.cc >index 63a5104b3c70bb75392d710525de70cdf7d4b37a..677e5d56fcc98481af504b10a2708435a6cebf9d 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_to_argb.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_to_argb.cc >@@ -29,10 +29,10 @@ extern "C" { > // sample_size is measured in bytes and is the size of the frame. > // With MJPEG it is the compressed size of the frame. > LIBYUV_API >-int ConvertToARGB(const uint8* sample, >+int ConvertToARGB(const uint8_t* sample, > size_t sample_size, >- uint8* crop_argb, >- int argb_stride, >+ uint8_t* dst_argb, >+ int dst_stride_argb, > int crop_x, > int crop_y, > int src_width, >@@ -40,11 +40,11 @@ int ConvertToARGB(const uint8* sample, > int crop_width, > int crop_height, > enum RotationMode rotation, >- uint32 fourcc) { >- uint32 format = CanonicalFourCC(fourcc); >+ uint32_t fourcc) { >+ uint32_t format = CanonicalFourCC(fourcc); > int aligned_src_width = (src_width + 1) & ~1; >- const uint8* src; >- const uint8* src_uv; >+ const uint8_t* src; >+ const uint8_t* src_uv; > int abs_src_height = (src_height < 0) ? -src_height : src_height; > int inv_crop_height = (crop_height < 0) ? -crop_height : crop_height; > int r = 0; >@@ -52,17 +52,17 @@ int ConvertToARGB(const uint8* sample, > // One pass rotation is available for some formats. For the rest, convert > // to ARGB (with optional vertical flipping) into a temporary ARGB buffer, > // and then rotate the ARGB to the final destination buffer. >- // For in-place conversion, if destination crop_argb is same as source sample, >+ // For in-place conversion, if destination dst_argb is same as source sample, > // also enable temporary buffer. > LIBYUV_BOOL need_buf = >- (rotation && format != FOURCC_ARGB) || crop_argb == sample; >- uint8* dest_argb = crop_argb; >- int dest_argb_stride = argb_stride; >- uint8* rotate_buffer = NULL; >+ (rotation && format != FOURCC_ARGB) || dst_argb == sample; >+ uint8_t* dest_argb = dst_argb; >+ int dest_dst_stride_argb = dst_stride_argb; >+ uint8_t* rotate_buffer = NULL; > int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height; > >- if (crop_argb == NULL || sample == NULL || src_width <= 0 || >- crop_width <= 0 || src_height == 0 || crop_height == 0) { >+ if (dst_argb == NULL || sample == NULL || src_width <= 0 || crop_width <= 0 || >+ src_height == 0 || crop_height == 0) { > return -1; > } > if (src_height < 0) { >@@ -71,76 +71,76 @@ int ConvertToARGB(const uint8* sample, > > if (need_buf) { > int argb_size = crop_width * 4 * abs_crop_height; >- rotate_buffer = (uint8*)malloc(argb_size); /* NOLINT */ >+ rotate_buffer = (uint8_t*)malloc(argb_size); /* NOLINT */ > if (!rotate_buffer) { > return 1; // Out of memory runtime error. > } >- crop_argb = rotate_buffer; >- argb_stride = crop_width * 4; >+ dst_argb = rotate_buffer; >+ dst_stride_argb = crop_width * 4; > } > > switch (format) { > // Single plane formats > case FOURCC_YUY2: > src = sample + (aligned_src_width * crop_y + crop_x) * 2; >- r = YUY2ToARGB(src, aligned_src_width * 2, crop_argb, argb_stride, >+ r = YUY2ToARGB(src, aligned_src_width * 2, dst_argb, dst_stride_argb, > crop_width, inv_crop_height); > break; > case FOURCC_UYVY: > src = sample + (aligned_src_width * crop_y + crop_x) * 2; >- r = UYVYToARGB(src, aligned_src_width * 2, crop_argb, argb_stride, >+ r = UYVYToARGB(src, aligned_src_width * 2, dst_argb, dst_stride_argb, > crop_width, inv_crop_height); > break; > case FOURCC_24BG: > src = sample + (src_width * crop_y + crop_x) * 3; >- r = RGB24ToARGB(src, src_width * 3, crop_argb, argb_stride, crop_width, >+ r = RGB24ToARGB(src, src_width * 3, dst_argb, dst_stride_argb, crop_width, > inv_crop_height); > break; > case FOURCC_RAW: > src = sample + (src_width * crop_y + crop_x) * 3; >- r = RAWToARGB(src, src_width * 3, crop_argb, argb_stride, crop_width, >+ r = RAWToARGB(src, src_width * 3, dst_argb, dst_stride_argb, crop_width, > inv_crop_height); > break; > case FOURCC_ARGB: > if (!need_buf && !rotation) { > src = sample + (src_width * crop_y + crop_x) * 4; >- r = ARGBToARGB(src, src_width * 4, crop_argb, argb_stride, crop_width, >- inv_crop_height); >+ r = ARGBToARGB(src, src_width * 4, dst_argb, dst_stride_argb, >+ crop_width, inv_crop_height); > } > break; > case FOURCC_BGRA: > src = sample + (src_width * crop_y + crop_x) * 4; >- r = BGRAToARGB(src, src_width * 4, crop_argb, argb_stride, crop_width, >+ r = BGRAToARGB(src, src_width * 4, dst_argb, dst_stride_argb, crop_width, > inv_crop_height); > break; > case FOURCC_ABGR: > src = sample + (src_width * crop_y + crop_x) * 4; >- r = ABGRToARGB(src, src_width * 4, crop_argb, argb_stride, crop_width, >+ r = ABGRToARGB(src, src_width * 4, dst_argb, dst_stride_argb, crop_width, > inv_crop_height); > break; > case FOURCC_RGBA: > src = sample + (src_width * crop_y + crop_x) * 4; >- r = RGBAToARGB(src, src_width * 4, crop_argb, argb_stride, crop_width, >+ r = RGBAToARGB(src, src_width * 4, dst_argb, dst_stride_argb, crop_width, > inv_crop_height); > break; > case FOURCC_RGBP: > src = sample + (src_width * crop_y + crop_x) * 2; >- r = RGB565ToARGB(src, src_width * 2, crop_argb, argb_stride, crop_width, >- inv_crop_height); >+ r = RGB565ToARGB(src, src_width * 2, dst_argb, dst_stride_argb, >+ crop_width, inv_crop_height); > break; > case FOURCC_RGBO: > src = sample + (src_width * crop_y + crop_x) * 2; >- r = ARGB1555ToARGB(src, src_width * 2, crop_argb, argb_stride, crop_width, >- inv_crop_height); >+ r = ARGB1555ToARGB(src, src_width * 2, dst_argb, dst_stride_argb, >+ crop_width, inv_crop_height); > break; > case FOURCC_R444: > src = sample + (src_width * crop_y + crop_x) * 2; >- r = ARGB4444ToARGB(src, src_width * 2, crop_argb, argb_stride, crop_width, >- inv_crop_height); >+ r = ARGB4444ToARGB(src, src_width * 2, dst_argb, dst_stride_argb, >+ crop_width, inv_crop_height); > break; > case FOURCC_I400: > src = sample + src_width * crop_y + crop_x; >- r = I400ToARGB(src, src_width, crop_argb, argb_stride, crop_width, >+ r = I400ToARGB(src, src_width, dst_argb, dst_stride_argb, crop_width, > inv_crop_height); > break; > >@@ -148,27 +148,27 @@ int ConvertToARGB(const uint8* sample, > case FOURCC_NV12: > src = sample + (src_width * crop_y + crop_x); > src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; >- r = NV12ToARGB(src, src_width, src_uv, aligned_src_width, crop_argb, >- argb_stride, crop_width, inv_crop_height); >+ r = NV12ToARGB(src, src_width, src_uv, aligned_src_width, dst_argb, >+ dst_stride_argb, crop_width, inv_crop_height); > break; > case FOURCC_NV21: > src = sample + (src_width * crop_y + crop_x); > src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; > // Call NV12 but with u and v parameters swapped. >- r = NV21ToARGB(src, src_width, src_uv, aligned_src_width, crop_argb, >- argb_stride, crop_width, inv_crop_height); >+ r = NV21ToARGB(src, src_width, src_uv, aligned_src_width, dst_argb, >+ dst_stride_argb, crop_width, inv_crop_height); > break; > case FOURCC_M420: > src = sample + (src_width * crop_y) * 12 / 8 + crop_x; >- r = M420ToARGB(src, src_width, crop_argb, argb_stride, crop_width, >+ r = M420ToARGB(src, src_width, dst_argb, dst_stride_argb, crop_width, > inv_crop_height); > break; > // Triplanar formats > case FOURCC_I420: > case FOURCC_YV12: { >- const uint8* src_y = sample + (src_width * crop_y + crop_x); >- const uint8* src_u; >- const uint8* src_v; >+ const uint8_t* src_y = sample + (src_width * crop_y + crop_x); >+ const uint8_t* src_u; >+ const uint8_t* src_v; > int halfwidth = (src_width + 1) / 2; > int halfheight = (abs_src_height + 1) / 2; > if (format == FOURCC_YV12) { >@@ -183,14 +183,14 @@ int ConvertToARGB(const uint8* sample, > halfwidth * (halfheight + crop_y / 2) + crop_x / 2; > } > r = I420ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth, >- crop_argb, argb_stride, crop_width, inv_crop_height); >+ dst_argb, dst_stride_argb, crop_width, inv_crop_height); > break; > } > > case FOURCC_J420: { >- const uint8* src_y = sample + (src_width * crop_y + crop_x); >- const uint8* src_u; >- const uint8* src_v; >+ const uint8_t* src_y = sample + (src_width * crop_y + crop_x); >+ const uint8_t* src_u; >+ const uint8_t* src_v; > int halfwidth = (src_width + 1) / 2; > int halfheight = (abs_src_height + 1) / 2; > src_u = sample + src_width * abs_src_height + >@@ -198,15 +198,15 @@ int ConvertToARGB(const uint8* sample, > src_v = sample + src_width * abs_src_height + > halfwidth * (halfheight + crop_y / 2) + crop_x / 2; > r = J420ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth, >- crop_argb, argb_stride, crop_width, inv_crop_height); >+ dst_argb, dst_stride_argb, crop_width, inv_crop_height); > break; > } > > case FOURCC_I422: > case FOURCC_YV16: { >- const uint8* src_y = sample + src_width * crop_y + crop_x; >- const uint8* src_u; >- const uint8* src_v; >+ const uint8_t* src_y = sample + src_width * crop_y + crop_x; >+ const uint8_t* src_u; >+ const uint8_t* src_v; > int halfwidth = (src_width + 1) / 2; > if (format == FOURCC_YV16) { > src_v = sample + src_width * abs_src_height + halfwidth * crop_y + >@@ -220,14 +220,14 @@ int ConvertToARGB(const uint8* sample, > halfwidth * (abs_src_height + crop_y) + crop_x / 2; > } > r = I422ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth, >- crop_argb, argb_stride, crop_width, inv_crop_height); >+ dst_argb, dst_stride_argb, crop_width, inv_crop_height); > break; > } > case FOURCC_I444: > case FOURCC_YV24: { >- const uint8* src_y = sample + src_width * crop_y + crop_x; >- const uint8* src_u; >- const uint8* src_v; >+ const uint8_t* src_y = sample + src_width * crop_y + crop_x; >+ const uint8_t* src_u; >+ const uint8_t* src_v; > if (format == FOURCC_YV24) { > src_v = sample + src_width * (abs_src_height + crop_y) + crop_x; > src_u = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; >@@ -236,12 +236,12 @@ int ConvertToARGB(const uint8* sample, > src_v = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; > } > r = I444ToARGB(src_y, src_width, src_u, src_width, src_v, src_width, >- crop_argb, argb_stride, crop_width, inv_crop_height); >+ dst_argb, dst_stride_argb, crop_width, inv_crop_height); > break; > } > #ifdef HAVE_JPEG > case FOURCC_MJPG: >- r = MJPGToARGB(sample, sample_size, crop_argb, argb_stride, src_width, >+ r = MJPGToARGB(sample, sample_size, dst_argb, dst_stride_argb, src_width, > abs_src_height, crop_width, inv_crop_height); > break; > #endif >@@ -251,13 +251,13 @@ int ConvertToARGB(const uint8* sample, > > if (need_buf) { > if (!r) { >- r = ARGBRotate(crop_argb, argb_stride, dest_argb, dest_argb_stride, >+ r = ARGBRotate(dst_argb, dst_stride_argb, dest_argb, dest_dst_stride_argb, > crop_width, abs_crop_height, rotation); > } > free(rotate_buffer); > } else if (rotation) { > src = sample + (src_width * crop_y + crop_x) * 4; >- r = ARGBRotate(src, src_width * 4, crop_argb, argb_stride, crop_width, >+ r = ARGBRotate(src, src_width * 4, dst_argb, dst_stride_argb, crop_width, > inv_crop_height, rotation); > } > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_to_i420.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_to_i420.cc >index a50689db949a8f1eecefcb543d562f0f4987f41e..1bed9d6440db92a696b2167c88873963e4c29f05 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_to_i420.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/convert_to_i420.cc >@@ -25,14 +25,14 @@ extern "C" { > // sample_size is measured in bytes and is the size of the frame. > // With MJPEG it is the compressed size of the frame. > LIBYUV_API >-int ConvertToI420(const uint8* sample, >+int ConvertToI420(const uint8_t* sample, > size_t sample_size, >- uint8* y, >- int y_stride, >- uint8* u, >- int u_stride, >- uint8* v, >- int v_stride, >+ uint8_t* dst_y, >+ int dst_stride_y, >+ uint8_t* dst_u, >+ int dst_stride_u, >+ uint8_t* dst_v, >+ int dst_stride_v, > int crop_x, > int crop_y, > int src_width, >@@ -40,11 +40,11 @@ int ConvertToI420(const uint8* sample, > int crop_width, > int crop_height, > enum RotationMode rotation, >- uint32 fourcc) { >- uint32 format = CanonicalFourCC(fourcc); >+ uint32_t fourcc) { >+ uint32_t format = CanonicalFourCC(fourcc); > int aligned_src_width = (src_width + 1) & ~1; >- const uint8* src; >- const uint8* src_uv; >+ const uint8_t* src; >+ const uint8_t* src_uv; > const int abs_src_height = (src_height < 0) ? -src_height : src_height; > // TODO(nisse): Why allow crop_height < 0? > const int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height; >@@ -52,132 +52,143 @@ int ConvertToI420(const uint8* sample, > LIBYUV_BOOL need_buf = > (rotation && format != FOURCC_I420 && format != FOURCC_NV12 && > format != FOURCC_NV21 && format != FOURCC_YV12) || >- y == sample; >- uint8* tmp_y = y; >- uint8* tmp_u = u; >- uint8* tmp_v = v; >- int tmp_y_stride = y_stride; >- int tmp_u_stride = u_stride; >- int tmp_v_stride = v_stride; >- uint8* rotate_buffer = NULL; >+ dst_y == sample; >+ uint8_t* tmp_y = dst_y; >+ uint8_t* tmp_u = dst_u; >+ uint8_t* tmp_v = dst_v; >+ int tmp_y_stride = dst_stride_y; >+ int tmp_u_stride = dst_stride_u; >+ int tmp_v_stride = dst_stride_v; >+ uint8_t* rotate_buffer = NULL; > const int inv_crop_height = > (src_height < 0) ? -abs_crop_height : abs_crop_height; > >- if (!y || !u || !v || !sample || src_width <= 0 || crop_width <= 0 || >- src_height == 0 || crop_height == 0) { >+ if (!dst_y || !dst_u || !dst_v || !sample || src_width <= 0 || >+ crop_width <= 0 || src_height == 0 || crop_height == 0) { > return -1; > } > > // One pass rotation is available for some formats. For the rest, convert > // to I420 (with optional vertical flipping) into a temporary I420 buffer, > // and then rotate the I420 to the final destination buffer. >- // For in-place conversion, if destination y is same as source sample, >+ // For in-place conversion, if destination dst_y is same as source sample, > // also enable temporary buffer. > if (need_buf) { > int y_size = crop_width * abs_crop_height; > int uv_size = ((crop_width + 1) / 2) * ((abs_crop_height + 1) / 2); >- rotate_buffer = (uint8*)malloc(y_size + uv_size * 2); /* NOLINT */ >+ rotate_buffer = (uint8_t*)malloc(y_size + uv_size * 2); /* NOLINT */ > if (!rotate_buffer) { > return 1; // Out of memory runtime error. > } >- y = rotate_buffer; >- u = y + y_size; >- v = u + uv_size; >- y_stride = crop_width; >- u_stride = v_stride = ((crop_width + 1) / 2); >+ dst_y = rotate_buffer; >+ dst_u = dst_y + y_size; >+ dst_v = dst_u + uv_size; >+ dst_stride_y = crop_width; >+ dst_stride_u = dst_stride_v = ((crop_width + 1) / 2); > } > > switch (format) { > // Single plane formats > case FOURCC_YUY2: > src = sample + (aligned_src_width * crop_y + crop_x) * 2; >- r = YUY2ToI420(src, aligned_src_width * 2, y, y_stride, u, u_stride, v, >- v_stride, crop_width, inv_crop_height); >+ r = YUY2ToI420(src, aligned_src_width * 2, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_UYVY: > src = sample + (aligned_src_width * crop_y + crop_x) * 2; >- r = UYVYToI420(src, aligned_src_width * 2, y, y_stride, u, u_stride, v, >- v_stride, crop_width, inv_crop_height); >+ r = UYVYToI420(src, aligned_src_width * 2, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_RGBP: > src = sample + (src_width * crop_y + crop_x) * 2; >- r = RGB565ToI420(src, src_width * 2, y, y_stride, u, u_stride, v, >- v_stride, crop_width, inv_crop_height); >+ r = RGB565ToI420(src, src_width * 2, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_RGBO: > src = sample + (src_width * crop_y + crop_x) * 2; >- r = ARGB1555ToI420(src, src_width * 2, y, y_stride, u, u_stride, v, >- v_stride, crop_width, inv_crop_height); >+ r = ARGB1555ToI420(src, src_width * 2, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_R444: > src = sample + (src_width * crop_y + crop_x) * 2; >- r = ARGB4444ToI420(src, src_width * 2, y, y_stride, u, u_stride, v, >- v_stride, crop_width, inv_crop_height); >+ r = ARGB4444ToI420(src, src_width * 2, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_24BG: > src = sample + (src_width * crop_y + crop_x) * 3; >- r = RGB24ToI420(src, src_width * 3, y, y_stride, u, u_stride, v, v_stride, >- crop_width, inv_crop_height); >+ r = RGB24ToI420(src, src_width * 3, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_RAW: > src = sample + (src_width * crop_y + crop_x) * 3; >- r = RAWToI420(src, src_width * 3, y, y_stride, u, u_stride, v, v_stride, >- crop_width, inv_crop_height); >+ r = RAWToI420(src, src_width * 3, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_ARGB: > src = sample + (src_width * crop_y + crop_x) * 4; >- r = ARGBToI420(src, src_width * 4, y, y_stride, u, u_stride, v, v_stride, >- crop_width, inv_crop_height); >+ r = ARGBToI420(src, src_width * 4, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_BGRA: > src = sample + (src_width * crop_y + crop_x) * 4; >- r = BGRAToI420(src, src_width * 4, y, y_stride, u, u_stride, v, v_stride, >- crop_width, inv_crop_height); >+ r = BGRAToI420(src, src_width * 4, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_ABGR: > src = sample + (src_width * crop_y + crop_x) * 4; >- r = ABGRToI420(src, src_width * 4, y, y_stride, u, u_stride, v, v_stride, >- crop_width, inv_crop_height); >+ r = ABGRToI420(src, src_width * 4, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_RGBA: > src = sample + (src_width * crop_y + crop_x) * 4; >- r = RGBAToI420(src, src_width * 4, y, y_stride, u, u_stride, v, v_stride, >- crop_width, inv_crop_height); >+ r = RGBAToI420(src, src_width * 4, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, crop_width, >+ inv_crop_height); > break; > case FOURCC_I400: > src = sample + src_width * crop_y + crop_x; >- r = I400ToI420(src, src_width, y, y_stride, u, u_stride, v, v_stride, >- crop_width, inv_crop_height); >+ r = I400ToI420(src, src_width, dst_y, dst_stride_y, dst_u, dst_stride_u, >+ dst_v, dst_stride_v, crop_width, inv_crop_height); > break; > // Biplanar formats > case FOURCC_NV12: > src = sample + (src_width * crop_y + crop_x); > src_uv = sample + (src_width * src_height) + > ((crop_y / 2) * aligned_src_width) + ((crop_x / 2) * 2); >- r = NV12ToI420Rotate(src, src_width, src_uv, aligned_src_width, y, >- y_stride, u, u_stride, v, v_stride, crop_width, >- inv_crop_height, rotation); >+ r = NV12ToI420Rotate(src, src_width, src_uv, aligned_src_width, dst_y, >+ dst_stride_y, dst_u, dst_stride_u, dst_v, >+ dst_stride_v, crop_width, inv_crop_height, rotation); > break; > case FOURCC_NV21: > src = sample + (src_width * crop_y + crop_x); > src_uv = sample + (src_width * src_height) + > ((crop_y / 2) * aligned_src_width) + ((crop_x / 2) * 2); >- // Call NV12 but with u and v parameters swapped. >- r = NV12ToI420Rotate(src, src_width, src_uv, aligned_src_width, y, >- y_stride, v, v_stride, u, u_stride, crop_width, >- inv_crop_height, rotation); >+ // Call NV12 but with dst_u and dst_v parameters swapped. >+ r = NV12ToI420Rotate(src, src_width, src_uv, aligned_src_width, dst_y, >+ dst_stride_y, dst_v, dst_stride_v, dst_u, >+ dst_stride_u, crop_width, inv_crop_height, rotation); > break; > case FOURCC_M420: > src = sample + (src_width * crop_y) * 12 / 8 + crop_x; >- r = M420ToI420(src, src_width, y, y_stride, u, u_stride, v, v_stride, >- crop_width, inv_crop_height); >+ r = M420ToI420(src, src_width, dst_y, dst_stride_y, dst_u, dst_stride_u, >+ dst_v, dst_stride_v, crop_width, inv_crop_height); > break; > // Triplanar formats > case FOURCC_I420: > case FOURCC_YV12: { >- const uint8* src_y = sample + (src_width * crop_y + crop_x); >- const uint8* src_u; >- const uint8* src_v; >+ const uint8_t* src_y = sample + (src_width * crop_y + crop_x); >+ const uint8_t* src_u; >+ const uint8_t* src_v; > int halfwidth = (src_width + 1) / 2; > int halfheight = (abs_src_height + 1) / 2; > if (format == FOURCC_YV12) { >@@ -191,16 +202,16 @@ int ConvertToI420(const uint8* sample, > src_v = sample + src_width * abs_src_height + > halfwidth * (halfheight + crop_y / 2) + crop_x / 2; > } >- r = I420Rotate(src_y, src_width, src_u, halfwidth, src_v, halfwidth, y, >- y_stride, u, u_stride, v, v_stride, crop_width, >- inv_crop_height, rotation); >+ r = I420Rotate(src_y, src_width, src_u, halfwidth, src_v, halfwidth, >+ dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, >+ dst_stride_v, crop_width, inv_crop_height, rotation); > break; > } > case FOURCC_I422: > case FOURCC_YV16: { >- const uint8* src_y = sample + src_width * crop_y + crop_x; >- const uint8* src_u; >- const uint8* src_v; >+ const uint8_t* src_y = sample + src_width * crop_y + crop_x; >+ const uint8_t* src_u; >+ const uint8_t* src_v; > int halfwidth = (src_width + 1) / 2; > if (format == FOURCC_YV16) { > src_v = sample + src_width * abs_src_height + halfwidth * crop_y + >@@ -213,16 +224,16 @@ int ConvertToI420(const uint8* sample, > src_v = sample + src_width * abs_src_height + > halfwidth * (abs_src_height + crop_y) + crop_x / 2; > } >- r = I422ToI420(src_y, src_width, src_u, halfwidth, src_v, halfwidth, y, >- y_stride, u, u_stride, v, v_stride, crop_width, >- inv_crop_height); >+ r = I422ToI420(src_y, src_width, src_u, halfwidth, src_v, halfwidth, >+ dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, >+ dst_stride_v, crop_width, inv_crop_height); > break; > } > case FOURCC_I444: > case FOURCC_YV24: { >- const uint8* src_y = sample + src_width * crop_y + crop_x; >- const uint8* src_u; >- const uint8* src_v; >+ const uint8_t* src_y = sample + src_width * crop_y + crop_x; >+ const uint8_t* src_u; >+ const uint8_t* src_v; > if (format == FOURCC_YV24) { > src_v = sample + src_width * (abs_src_height + crop_y) + crop_x; > src_u = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; >@@ -230,15 +241,16 @@ int ConvertToI420(const uint8* sample, > src_u = sample + src_width * (abs_src_height + crop_y) + crop_x; > src_v = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; > } >- r = I444ToI420(src_y, src_width, src_u, src_width, src_v, src_width, y, >- y_stride, u, u_stride, v, v_stride, crop_width, >- inv_crop_height); >+ r = I444ToI420(src_y, src_width, src_u, src_width, src_v, src_width, >+ dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, >+ dst_stride_v, crop_width, inv_crop_height); > break; > } > #ifdef HAVE_JPEG > case FOURCC_MJPG: >- r = MJPGToI420(sample, sample_size, y, y_stride, u, u_stride, v, v_stride, >- src_width, abs_src_height, crop_width, inv_crop_height); >+ r = MJPGToI420(sample, sample_size, dst_y, dst_stride_y, dst_u, >+ dst_stride_u, dst_v, dst_stride_v, src_width, >+ abs_src_height, crop_width, inv_crop_height); > break; > #endif > default: >@@ -247,9 +259,10 @@ int ConvertToI420(const uint8* sample, > > if (need_buf) { > if (!r) { >- r = I420Rotate(y, y_stride, u, u_stride, v, v_stride, tmp_y, tmp_y_stride, >- tmp_u, tmp_u_stride, tmp_v, tmp_v_stride, crop_width, >- abs_crop_height, rotation); >+ r = I420Rotate(dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, >+ dst_stride_v, tmp_y, tmp_y_stride, tmp_u, tmp_u_stride, >+ tmp_v, tmp_v_stride, crop_width, abs_crop_height, >+ rotation); > } > free(rotate_buffer); > } >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/cpu_id.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/cpu_id.cc >index 344f3c06a2b75b10aa141fc5452c29d39c0da747..446aad12078b4e4a963ff58335efb8018c32c713 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/cpu_id.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/cpu_id.cc >@@ -27,8 +27,6 @@ > #include <stdio.h> > #include <string.h> > >-#include "libyuv/basic_types.h" // For CPU_X86 >- > #ifdef __cplusplus > namespace libyuv { > extern "C" { >@@ -179,7 +177,7 @@ LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name, > if (strcmp(ase, " msa") == 0) { > return kCpuHasMSA; > } >- return kCpuHasDSPR2; >+ return 0; > } > while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) { > if (memcmp(cpuinfo_line, "ASEs implemented", 16) == 0) { >@@ -189,7 +187,7 @@ LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name, > if (strcmp(ase, " msa") == 0) { > return kCpuHasMSA; > } >- return kCpuHasDSPR2; >+ return 0; > } > } > } >@@ -218,7 +216,9 @@ static LIBYUV_BOOL TestEnv(const char*) { > > static SAFEBUFFERS int GetCpuFlags(void) { > int cpu_info = 0; >-#if !defined(__pnacl__) && !defined(__CLR_VER) && defined(CPU_X86) >+#if !defined(__pnacl__) && !defined(__CLR_VER) && \ >+ (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ >+ defined(_M_IX86)) > int cpu_info0[4] = {0, 0, 0, 0}; > int cpu_info1[4] = {0, 0, 0, 0}; > int cpu_info7[4] = {0, 0, 0, 0}; >@@ -290,16 +290,10 @@ static SAFEBUFFERS int GetCpuFlags(void) { > > #endif > #if defined(__mips__) && defined(__linux__) >-#if defined(__mips_dspr2) >- cpu_info |= kCpuHasDSPR2; >-#endif > #if defined(__mips_msa) > cpu_info = MipsCpuCaps("/proc/cpuinfo", " msa"); > #endif > cpu_info |= kCpuHasMIPS; >- if (getenv("LIBYUV_DISABLE_DSPR2")) { >- cpu_info &= ~kCpuHasDSPR2; >- } > if (getenv("LIBYUV_DISABLE_MSA")) { > cpu_info &= ~kCpuHasMSA; > } >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/mjpeg_decoder.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/mjpeg_decoder.cc >index b43c008bdd2dd11d0166b45e2124b8e3832fae37..eaf2530130b20b4114b1236a468abf50deb44d6a 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/mjpeg_decoder.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/mjpeg_decoder.cc >@@ -102,7 +102,7 @@ MJpegDecoder::~MJpegDecoder() { > DestroyOutputBuffers(); > } > >-LIBYUV_BOOL MJpegDecoder::LoadFrame(const uint8* src, size_t src_len) { >+LIBYUV_BOOL MJpegDecoder::LoadFrame(const uint8_t* src, size_t src_len) { > if (!ValidateJpeg(src, src_len)) { > return LIBYUV_FALSE; > } >@@ -129,7 +129,7 @@ LIBYUV_BOOL MJpegDecoder::LoadFrame(const uint8* src, size_t src_len) { > if (scanlines_[i]) { > delete scanlines_[i]; > } >- scanlines_[i] = new uint8*[scanlines_size]; >+ scanlines_[i] = new uint8_t*[scanlines_size]; > scanlines_sizes_[i] = scanlines_size; > } > >@@ -145,7 +145,7 @@ LIBYUV_BOOL MJpegDecoder::LoadFrame(const uint8* src, size_t src_len) { > if (databuf_[i]) { > delete databuf_[i]; > } >- databuf_[i] = new uint8[databuf_size]; >+ databuf_[i] = new uint8_t[databuf_size]; > databuf_strides_[i] = databuf_stride; > } > >@@ -243,7 +243,7 @@ LIBYUV_BOOL MJpegDecoder::UnloadFrame() { > } > > // TODO(fbarchard): Allow rectangle to be specified: x, y, width, height. >-LIBYUV_BOOL MJpegDecoder::DecodeToBuffers(uint8** planes, >+LIBYUV_BOOL MJpegDecoder::DecodeToBuffers(uint8_t** planes, > int dst_width, > int dst_height) { > if (dst_width != GetWidth() || dst_height > GetHeight()) { >@@ -469,9 +469,9 @@ void MJpegDecoder::AllocOutputBuffers(int num_outbufs) { > // it. > DestroyOutputBuffers(); > >- scanlines_ = new uint8**[num_outbufs]; >+ scanlines_ = new uint8_t**[num_outbufs]; > scanlines_sizes_ = new int[num_outbufs]; >- databuf_ = new uint8*[num_outbufs]; >+ databuf_ = new uint8_t*[num_outbufs]; > databuf_strides_ = new int[num_outbufs]; > > for (int i = 0; i < num_outbufs; ++i) { >@@ -527,9 +527,9 @@ LIBYUV_BOOL MJpegDecoder::FinishDecode() { > return LIBYUV_TRUE; > } > >-void MJpegDecoder::SetScanlinePointers(uint8** data) { >+void MJpegDecoder::SetScanlinePointers(uint8_t** data) { > for (int i = 0; i < num_outbufs_; ++i) { >- uint8* data_i = data[i]; >+ uint8_t* data_i = data[i]; > for (int j = 0; j < scanlines_sizes_[i]; ++j) { > scanlines_[i][j] = data_i; > data_i += GetComponentStride(i); >@@ -552,13 +552,13 @@ JpegSubsamplingType MJpegDecoder::JpegSubsamplingTypeHelper( > if (subsample_x[0] == 1 && subsample_y[0] == 1 && subsample_x[1] == 2 && > subsample_y[1] == 2 && subsample_x[2] == 2 && subsample_y[2] == 2) { > return kJpegYuv420; >- } else if (subsample_x[0] == 1 && subsample_y[0] == 1 && >- subsample_x[1] == 2 && subsample_y[1] == 1 && >- subsample_x[2] == 2 && subsample_y[2] == 1) { >+ } >+ if (subsample_x[0] == 1 && subsample_y[0] == 1 && subsample_x[1] == 2 && >+ subsample_y[1] == 1 && subsample_x[2] == 2 && subsample_y[2] == 1) { > return kJpegYuv422; >- } else if (subsample_x[0] == 1 && subsample_y[0] == 1 && >- subsample_x[1] == 1 && subsample_y[1] == 1 && >- subsample_x[2] == 1 && subsample_y[2] == 1) { >+ } >+ if (subsample_x[0] == 1 && subsample_y[0] == 1 && subsample_x[1] == 1 && >+ subsample_y[1] == 1 && subsample_x[2] == 1 && subsample_y[2] == 1) { > return kJpegYuv444; > } > } else if (number_of_components == 1) { // Grey-scale images. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/mjpeg_validate.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/mjpeg_validate.cc >index bd760425359cf1e90414ebb02e58850bb26dbd96..80c2cc0cb9bed5f4ce635ba71311989334a4a05b 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/mjpeg_validate.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/mjpeg_validate.cc >@@ -18,13 +18,13 @@ extern "C" { > #endif > > // Helper function to scan for EOI marker (0xff 0xd9). >-static LIBYUV_BOOL ScanEOI(const uint8* sample, size_t sample_size) { >+static LIBYUV_BOOL ScanEOI(const uint8_t* sample, size_t sample_size) { > if (sample_size >= 2) { >- const uint8* end = sample + sample_size - 1; >- const uint8* it = sample; >+ const uint8_t* end = sample + sample_size - 1; >+ const uint8_t* it = sample; > while (it < end) { > // TODO(fbarchard): scan for 0xd9 instead. >- it = (const uint8*)(memchr(it, 0xff, end - it)); >+ it = (const uint8_t*)(memchr(it, 0xff, end - it)); > if (it == NULL) { > break; > } >@@ -39,7 +39,7 @@ static LIBYUV_BOOL ScanEOI(const uint8* sample, size_t sample_size) { > } > > // Helper function to validate the jpeg appears intact. >-LIBYUV_BOOL ValidateJpeg(const uint8* sample, size_t sample_size) { >+LIBYUV_BOOL ValidateJpeg(const uint8_t* sample, size_t sample_size) { > // Maximum size that ValidateJpeg will consider valid. > const size_t kMaxJpegSize = 0x7fffffffull; > const size_t kBackSearchSize = 1024; >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/planar_functions.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/planar_functions.cc >index dd311d1f08e28ce5606c5bd64cb3f047c8072d2d..5eae3f763a7290aa83b0031aa6725bbb367a6f18 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/planar_functions.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/planar_functions.cc >@@ -26,14 +26,14 @@ extern "C" { > > // Copy a plane of data > LIBYUV_API >-void CopyPlane(const uint8* src_y, >+void CopyPlane(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height) { > int y; >- void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; >+ void (*CopyRow)(const uint8_t* src, uint8_t* dst, int width) = CopyRow_C; > // Negative height means invert the image. > if (height < 0) { > height = -height; >@@ -50,6 +50,7 @@ void CopyPlane(const uint8* src_y, > if (src_y == dst_y && src_stride_y == dst_stride_y) { > return; > } >+ > #if defined(HAS_COPYROW_SSE2) > if (TestCpuFlag(kCpuHasSSE2)) { > CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; >@@ -70,11 +71,6 @@ void CopyPlane(const uint8* src_y, > CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON; > } > #endif >-#if defined(HAS_COPYROW_MIPS) >- if (TestCpuFlag(kCpuHasMIPS)) { >- CopyRow = CopyRow_MIPS; >- } >-#endif > > // Copy plane > for (y = 0; y < height; ++y) { >@@ -87,14 +83,14 @@ void CopyPlane(const uint8* src_y, > // TODO(fbarchard): Consider support for negative height. > // TODO(fbarchard): Consider stride measured in bytes. > LIBYUV_API >-void CopyPlane_16(const uint16* src_y, >+void CopyPlane_16(const uint16_t* src_y, > int src_stride_y, >- uint16* dst_y, >+ uint16_t* dst_y, > int dst_stride_y, > int width, > int height) { > int y; >- void (*CopyRow)(const uint16* src, uint16* dst, int width) = CopyRow_16_C; >+ void (*CopyRow)(const uint16_t* src, uint16_t* dst, int width) = CopyRow_16_C; > // Coalesce rows. > if (src_stride_y == width && dst_stride_y == width) { > width *= height; >@@ -116,11 +112,6 @@ void CopyPlane_16(const uint16* src_y, > CopyRow = CopyRow_16_NEON; > } > #endif >-#if defined(HAS_COPYROW_16_MIPS) >- if (TestCpuFlag(kCpuHasMIPS)) { >- CopyRow = CopyRow_16_MIPS; >- } >-#endif > > // Copy plane > for (y = 0; y < height; ++y) { >@@ -130,19 +121,119 @@ void CopyPlane_16(const uint16* src_y, > } > } > >+// Convert a plane of 16 bit data to 8 bit >+LIBYUV_API >+void Convert16To8Plane(const uint16_t* src_y, >+ int src_stride_y, >+ uint8_t* dst_y, >+ int dst_stride_y, >+ int scale, // 16384 for 10 bits >+ int width, >+ int height) { >+ int y; >+ void (*Convert16To8Row)(const uint16_t* src_y, uint8_t* dst_y, int scale, >+ int width) = Convert16To8Row_C; >+ >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ dst_y = dst_y + (height - 1) * dst_stride_y; >+ dst_stride_y = -dst_stride_y; >+ } >+ // Coalesce rows. >+ if (src_stride_y == width && dst_stride_y == width) { >+ width *= height; >+ height = 1; >+ src_stride_y = dst_stride_y = 0; >+ } >+#if defined(HAS_CONVERT16TO8ROW_SSSE3) >+ if (TestCpuFlag(kCpuHasSSSE3)) { >+ Convert16To8Row = Convert16To8Row_Any_SSSE3; >+ if (IS_ALIGNED(width, 16)) { >+ Convert16To8Row = Convert16To8Row_SSSE3; >+ } >+ } >+#endif >+#if defined(HAS_CONVERT16TO8ROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ Convert16To8Row = Convert16To8Row_Any_AVX2; >+ if (IS_ALIGNED(width, 32)) { >+ Convert16To8Row = Convert16To8Row_AVX2; >+ } >+ } >+#endif >+ >+ // Convert plane >+ for (y = 0; y < height; ++y) { >+ Convert16To8Row(src_y, dst_y, scale, width); >+ src_y += src_stride_y; >+ dst_y += dst_stride_y; >+ } >+} >+ >+// Convert a plane of 8 bit data to 16 bit >+LIBYUV_API >+void Convert8To16Plane(const uint8_t* src_y, >+ int src_stride_y, >+ uint16_t* dst_y, >+ int dst_stride_y, >+ int scale, // 16384 for 10 bits >+ int width, >+ int height) { >+ int y; >+ void (*Convert8To16Row)(const uint8_t* src_y, uint16_t* dst_y, int scale, >+ int width) = Convert8To16Row_C; >+ >+ // Negative height means invert the image. >+ if (height < 0) { >+ height = -height; >+ dst_y = dst_y + (height - 1) * dst_stride_y; >+ dst_stride_y = -dst_stride_y; >+ } >+ // Coalesce rows. >+ if (src_stride_y == width && dst_stride_y == width) { >+ width *= height; >+ height = 1; >+ src_stride_y = dst_stride_y = 0; >+ } >+#if defined(HAS_CONVERT8TO16ROW_SSE2) >+ if (TestCpuFlag(kCpuHasSSE2)) { >+ Convert8To16Row = Convert8To16Row_Any_SSE2; >+ if (IS_ALIGNED(width, 16)) { >+ Convert8To16Row = Convert8To16Row_SSE2; >+ } >+ } >+#endif >+#if defined(HAS_CONVERT8TO16ROW_AVX2) >+ if (TestCpuFlag(kCpuHasAVX2)) { >+ Convert8To16Row = Convert8To16Row_Any_AVX2; >+ if (IS_ALIGNED(width, 32)) { >+ Convert8To16Row = Convert8To16Row_AVX2; >+ } >+ } >+#endif >+ >+ // Convert plane >+ for (y = 0; y < height; ++y) { >+ Convert8To16Row(src_y, dst_y, scale, width); >+ src_y += src_stride_y; >+ dst_y += dst_stride_y; >+ } >+} >+ > // Copy I422. > LIBYUV_API >-int I422Copy(const uint8* src_y, >+int I422Copy(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -171,17 +262,17 @@ int I422Copy(const uint8* src_y, > > // Copy I444. > LIBYUV_API >-int I444Copy(const uint8* src_y, >+int I444Copy(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -209,9 +300,9 @@ int I444Copy(const uint8* src_y, > > // Copy I400. > LIBYUV_API >-int I400ToI400(const uint8* src_y, >+int I400ToI400(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height) { >@@ -230,13 +321,13 @@ int I400ToI400(const uint8* src_y, > > // Convert I420 to I400. > LIBYUV_API >-int I420ToI400(const uint8* src_y, >+int I420ToI400(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height) { >@@ -261,16 +352,16 @@ int I420ToI400(const uint8* src_y, > // Support function for NV12 etc UV channels. > // Width and height are plane sizes (typically half pixel width). > LIBYUV_API >-void SplitUVPlane(const uint8* src_uv, >+void SplitUVPlane(const uint8_t* src_uv, > int src_stride_uv, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, >+ void (*SplitUVRow)(const uint8_t* src_uv, uint8_t* dst_u, uint8_t* dst_v, > int width) = SplitUVRow_C; > // Negative height means invert the image. > if (height < 0) { >@@ -311,16 +402,6 @@ void SplitUVPlane(const uint8* src_uv, > } > } > #endif >-#if defined(HAS_SPLITUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(dst_u, 4) && >- IS_ALIGNED(dst_stride_u, 4) && IS_ALIGNED(dst_v, 4) && >- IS_ALIGNED(dst_stride_v, 4)) { >- SplitUVRow = SplitUVRow_Any_DSPR2; >- if (IS_ALIGNED(width, 16)) { >- SplitUVRow = SplitUVRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_SPLITUVROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > SplitUVRow = SplitUVRow_Any_MSA; >@@ -340,17 +421,17 @@ void SplitUVPlane(const uint8* src_uv, > } > > LIBYUV_API >-void MergeUVPlane(const uint8* src_u, >+void MergeUVPlane(const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int dst_stride_uv, > int width, > int height) { > int y; >- void (*MergeUVRow)(const uint8* src_u, const uint8* src_v, uint8* dst_uv, >- int width) = MergeUVRow_C; >+ void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v, >+ uint8_t* dst_uv, int width) = MergeUVRow_C; > // Coalesce rows. > // Negative height means invert the image. > if (height < 0) { >@@ -410,19 +491,19 @@ void MergeUVPlane(const uint8* src_u, > // Support function for NV12 etc RGB channels. > // Width and height are plane sizes (typically half pixel width). > LIBYUV_API >-void SplitRGBPlane(const uint8* src_rgb, >+void SplitRGBPlane(const uint8_t* src_rgb, > int src_stride_rgb, >- uint8* dst_r, >+ uint8_t* dst_r, > int dst_stride_r, >- uint8* dst_g, >+ uint8_t* dst_g, > int dst_stride_g, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height) { > int y; >- void (*SplitRGBRow)(const uint8* src_rgb, uint8* dst_r, uint8* dst_g, >- uint8* dst_b, int width) = SplitRGBRow_C; >+ void (*SplitRGBRow)(const uint8_t* src_rgb, uint8_t* dst_r, uint8_t* dst_g, >+ uint8_t* dst_b, int width) = SplitRGBRow_C; > // Negative height means invert the image. > if (height < 0) { > height = -height; >@@ -468,19 +549,19 @@ void SplitRGBPlane(const uint8* src_rgb, > } > > LIBYUV_API >-void MergeRGBPlane(const uint8* src_r, >+void MergeRGBPlane(const uint8_t* src_r, > int src_stride_r, >- const uint8* src_g, >+ const uint8_t* src_g, > int src_stride_g, >- const uint8* src_b, >+ const uint8_t* src_b, > int src_stride_b, >- uint8* dst_rgb, >+ uint8_t* dst_rgb, > int dst_stride_rgb, > int width, > int height) { > int y; >- void (*MergeRGBRow)(const uint8* src_r, const uint8* src_g, >- const uint8* src_b, uint8* dst_rgb, int width) = >+ void (*MergeRGBRow)(const uint8_t* src_r, const uint8_t* src_g, >+ const uint8_t* src_b, uint8_t* dst_rgb, int width) = > MergeRGBRow_C; > // Coalesce rows. > // Negative height means invert the image. >@@ -524,14 +605,14 @@ void MergeRGBPlane(const uint8* src_r, > } > > // Mirror a plane of data. >-void MirrorPlane(const uint8* src_y, >+void MirrorPlane(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height) { > int y; >- void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C; >+ void (*MirrorRow)(const uint8_t* src, uint8_t* dst, int width) = MirrorRow_C; > // Negative height means invert the image. > if (height < 0) { > height = -height; >@@ -562,14 +643,6 @@ void MirrorPlane(const uint8* src_y, > } > } > #endif >-// TODO(fbarchard): Mirror on mips handle unaligned memory. >-#if defined(HAS_MIRRORROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src_y, 4) && >- IS_ALIGNED(src_stride_y, 4) && IS_ALIGNED(dst_y, 4) && >- IS_ALIGNED(dst_stride_y, 4)) { >- MirrorRow = MirrorRow_DSPR2; >- } >-#endif > #if defined(HAS_MIRRORROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > MirrorRow = MirrorRow_Any_MSA; >@@ -589,20 +662,20 @@ void MirrorPlane(const uint8* src_y, > > // Convert YUY2 to I422. > LIBYUV_API >-int YUY2ToI422(const uint8* src_yuy2, >+int YUY2ToI422(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*YUY2ToUV422Row)(const uint8* src_yuy2, uint8* dst_u, uint8* dst_v, >- int width) = YUY2ToUV422Row_C; >- void (*YUY2ToYRow)(const uint8* src_yuy2, uint8* dst_y, int width) = >+ void (*YUY2ToUV422Row)(const uint8_t* src_yuy2, uint8_t* dst_u, >+ uint8_t* dst_v, int width) = YUY2ToUV422Row_C; >+ void (*YUY2ToYRow)(const uint8_t* src_yuy2, uint8_t* dst_y, int width) = > YUY2ToYRow_C; > if (!src_yuy2 || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; >@@ -675,20 +748,20 @@ int YUY2ToI422(const uint8* src_yuy2, > > // Convert UYVY to I422. > LIBYUV_API >-int UYVYToI422(const uint8* src_uyvy, >+int UYVYToI422(const uint8_t* src_uyvy, > int src_stride_uyvy, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; >- void (*UYVYToUV422Row)(const uint8* src_uyvy, uint8* dst_u, uint8* dst_v, >- int width) = UYVYToUV422Row_C; >- void (*UYVYToYRow)(const uint8* src_uyvy, uint8* dst_y, int width) = >+ void (*UYVYToUV422Row)(const uint8_t* src_uyvy, uint8_t* dst_u, >+ uint8_t* dst_v, int width) = UYVYToUV422Row_C; >+ void (*UYVYToYRow)(const uint8_t* src_uyvy, uint8_t* dst_y, int width) = > UYVYToYRow_C; > if (!src_uyvy || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; >@@ -761,14 +834,14 @@ int UYVYToI422(const uint8* src_uyvy, > > // Convert YUY2 to Y. > LIBYUV_API >-int YUY2ToY(const uint8* src_yuy2, >+int YUY2ToY(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height) { > int y; >- void (*YUY2ToYRow)(const uint8* src_yuy2, uint8* dst_y, int width) = >+ void (*YUY2ToYRow)(const uint8_t* src_yuy2, uint8_t* dst_y, int width) = > YUY2ToYRow_C; > if (!src_yuy2 || !dst_y || width <= 0 || height == 0) { > return -1; >@@ -828,9 +901,9 @@ int YUY2ToY(const uint8* src_yuy2, > > // Mirror I400 with optional flipping > LIBYUV_API >-int I400Mirror(const uint8* src_y, >+int I400Mirror(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height) { >@@ -850,17 +923,17 @@ int I400Mirror(const uint8* src_y, > > // Mirror I420 with optional flipping > LIBYUV_API >-int I420Mirror(const uint8* src_y, >+int I420Mirror(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { >@@ -892,14 +965,14 @@ int I420Mirror(const uint8* src_y, > > // ARGB mirror. > LIBYUV_API >-int ARGBMirror(const uint8* src_argb, >+int ARGBMirror(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGBMirrorRow)(const uint8* src, uint8* dst, int width) = >+ void (*ARGBMirrorRow)(const uint8_t* src, uint8_t* dst, int width) = > ARGBMirrorRow_C; > if (!src_argb || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -957,8 +1030,8 @@ int ARGBMirror(const uint8* src_argb, > // the same blend function for all pixels if possible. > LIBYUV_API > ARGBBlendRow GetARGBBlend() { >- void (*ARGBBlendRow)(const uint8* src_argb, const uint8* src_argb1, >- uint8* dst_argb, int width) = ARGBBlendRow_C; >+ void (*ARGBBlendRow)(const uint8_t* src_argb, const uint8_t* src_argb1, >+ uint8_t* dst_argb, int width) = ARGBBlendRow_C; > #if defined(HAS_ARGBBLENDROW_SSSE3) > if (TestCpuFlag(kCpuHasSSSE3)) { > ARGBBlendRow = ARGBBlendRow_SSSE3; >@@ -980,17 +1053,17 @@ ARGBBlendRow GetARGBBlend() { > > // Alpha Blend 2 ARGB images and store to destination. > LIBYUV_API >-int ARGBBlend(const uint8* src_argb0, >+int ARGBBlend(const uint8_t* src_argb0, > int src_stride_argb0, >- const uint8* src_argb1, >+ const uint8_t* src_argb1, > int src_stride_argb1, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGBBlendRow)(const uint8* src_argb, const uint8* src_argb1, >- uint8* dst_argb, int width) = GetARGBBlend(); >+ void (*ARGBBlendRow)(const uint8_t* src_argb, const uint8_t* src_argb1, >+ uint8_t* dst_argb, int width) = GetARGBBlend(); > if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -1019,19 +1092,19 @@ int ARGBBlend(const uint8* src_argb0, > > // Alpha Blend plane and store to destination. > LIBYUV_API >-int BlendPlane(const uint8* src_y0, >+int BlendPlane(const uint8_t* src_y0, > int src_stride_y0, >- const uint8* src_y1, >+ const uint8_t* src_y1, > int src_stride_y1, >- const uint8* alpha, >+ const uint8_t* alpha, > int alpha_stride, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height) { > int y; >- void (*BlendPlaneRow)(const uint8* src0, const uint8* src1, >- const uint8* alpha, uint8* dst, int width) = >+ void (*BlendPlaneRow)(const uint8_t* src0, const uint8_t* src1, >+ const uint8_t* alpha, uint8_t* dst, int width) = > BlendPlaneRow_C; > if (!src_y0 || !src_y1 || !alpha || !dst_y || width <= 0 || height == 0) { > return -1; >@@ -1081,36 +1154,36 @@ int BlendPlane(const uint8* src_y0, > #define MAXTWIDTH 2048 > // Alpha Blend YUV images and store to destination. > LIBYUV_API >-int I420Blend(const uint8* src_y0, >+int I420Blend(const uint8_t* src_y0, > int src_stride_y0, >- const uint8* src_u0, >+ const uint8_t* src_u0, > int src_stride_u0, >- const uint8* src_v0, >+ const uint8_t* src_v0, > int src_stride_v0, >- const uint8* src_y1, >+ const uint8_t* src_y1, > int src_stride_y1, >- const uint8* src_u1, >+ const uint8_t* src_u1, > int src_stride_u1, >- const uint8* src_v1, >+ const uint8_t* src_v1, > int src_stride_v1, >- const uint8* alpha, >+ const uint8_t* alpha, > int alpha_stride, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height) { > int y; > // Half width/height for UV. > int halfwidth = (width + 1) >> 1; >- void (*BlendPlaneRow)(const uint8* src0, const uint8* src1, >- const uint8* alpha, uint8* dst, int width) = >+ void (*BlendPlaneRow)(const uint8_t* src0, const uint8_t* src1, >+ const uint8_t* alpha, uint8_t* dst, int width) = > BlendPlaneRow_C; >- void (*ScaleRowDown2)(const uint8* src_ptr, ptrdiff_t src_stride, >- uint8* dst_ptr, int dst_width) = ScaleRowDown2Box_C; >+ void (*ScaleRowDown2)(const uint8_t* src_ptr, ptrdiff_t src_stride, >+ uint8_t* dst_ptr, int dst_width) = ScaleRowDown2Box_C; > if (!src_y0 || !src_u0 || !src_v0 || !src_y1 || !src_u1 || !src_v1 || > !alpha || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { > return -1; >@@ -1205,17 +1278,17 @@ int I420Blend(const uint8* src_y0, > > // Multiply 2 ARGB images and store to destination. > LIBYUV_API >-int ARGBMultiply(const uint8* src_argb0, >+int ARGBMultiply(const uint8_t* src_argb0, > int src_stride_argb0, >- const uint8* src_argb1, >+ const uint8_t* src_argb1, > int src_stride_argb1, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGBMultiplyRow)(const uint8* src0, const uint8* src1, uint8* dst, >- int width) = ARGBMultiplyRow_C; >+ void (*ARGBMultiplyRow)(const uint8_t* src0, const uint8_t* src1, >+ uint8_t* dst, int width) = ARGBMultiplyRow_C; > if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -1277,16 +1350,16 @@ int ARGBMultiply(const uint8* src_argb0, > > // Add 2 ARGB images and store to destination. > LIBYUV_API >-int ARGBAdd(const uint8* src_argb0, >+int ARGBAdd(const uint8_t* src_argb0, > int src_stride_argb0, >- const uint8* src_argb1, >+ const uint8_t* src_argb1, > int src_stride_argb1, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGBAddRow)(const uint8* src0, const uint8* src1, uint8* dst, >+ void (*ARGBAddRow)(const uint8_t* src0, const uint8_t* src1, uint8_t* dst, > int width) = ARGBAddRow_C; > if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -1354,17 +1427,17 @@ int ARGBAdd(const uint8* src_argb0, > > // Subtract 2 ARGB images and store to destination. > LIBYUV_API >-int ARGBSubtract(const uint8* src_argb0, >+int ARGBSubtract(const uint8_t* src_argb0, > int src_stride_argb0, >- const uint8* src_argb1, >+ const uint8_t* src_argb1, > int src_stride_argb1, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGBSubtractRow)(const uint8* src0, const uint8* src1, uint8* dst, >- int width) = ARGBSubtractRow_C; >+ void (*ARGBSubtractRow)(const uint8_t* src0, const uint8_t* src1, >+ uint8_t* dst, int width) = ARGBSubtractRow_C; > if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -1424,20 +1497,20 @@ int ARGBSubtract(const uint8* src_argb0, > return 0; > } > // Convert I422 to RGBA with matrix >-static int I422ToRGBAMatrix(const uint8* src_y, >+static int I422ToRGBAMatrix(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgba, >+ uint8_t* dst_rgba, > int dst_stride_rgba, > const struct YuvConstants* yuvconstants, > int width, > int height) { > int y; >- void (*I422ToRGBARow)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, >+ void (*I422ToRGBARow)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, int width) = > I422ToRGBARow_C; > if (!src_y || !src_u || !src_v || !dst_rgba || width <= 0 || height == 0) { >@@ -1473,15 +1546,6 @@ static int I422ToRGBAMatrix(const uint8* src_y, > } > } > #endif >-#if defined(HAS_I422TORGBAROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) && >- IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && >- IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && >- IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) && >- IS_ALIGNED(dst_rgba, 4) && IS_ALIGNED(dst_stride_rgba, 4)) { >- I422ToRGBARow = I422ToRGBARow_DSPR2; >- } >-#endif > #if defined(HAS_I422TORGBAROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422ToRGBARow = I422ToRGBARow_Any_MSA; >@@ -1503,13 +1567,13 @@ static int I422ToRGBAMatrix(const uint8* src_y, > > // Convert I422 to RGBA. > LIBYUV_API >-int I422ToRGBA(const uint8* src_y, >+int I422ToRGBA(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_rgba, >+ uint8_t* dst_rgba, > int dst_stride_rgba, > int width, > int height) { >@@ -1520,13 +1584,13 @@ int I422ToRGBA(const uint8* src_y, > > // Convert I422 to BGRA. > LIBYUV_API >-int I422ToBGRA(const uint8* src_y, >+int I422ToBGRA(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_bgra, >+ uint8_t* dst_bgra, > int dst_stride_bgra, > int width, > int height) { >@@ -1539,17 +1603,17 @@ int I422ToBGRA(const uint8* src_y, > > // Convert NV12 to RGB565. > LIBYUV_API >-int NV12ToRGB565(const uint8* src_y, >+int NV12ToRGB565(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_uv, >+ const uint8_t* src_uv, > int src_stride_uv, >- uint8* dst_rgb565, >+ uint8_t* dst_rgb565, > int dst_stride_rgb565, > int width, > int height) { > int y; > void (*NV12ToRGB565Row)( >- const uint8* y_buf, const uint8* uv_buf, uint8* rgb_buf, >+ const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, int width) = NV12ToRGB565Row_C; > if (!src_y || !src_uv || !dst_rgb565 || width <= 0 || height == 0) { > return -1; >@@ -1606,14 +1670,14 @@ int NV12ToRGB565(const uint8* src_y, > > // Convert RAW to RGB24. > LIBYUV_API >-int RAWToRGB24(const uint8* src_raw, >+int RAWToRGB24(const uint8_t* src_raw, > int src_stride_raw, >- uint8* dst_rgb24, >+ uint8_t* dst_rgb24, > int dst_stride_rgb24, > int width, > int height) { > int y; >- void (*RAWToRGB24Row)(const uint8* src_rgb, uint8* dst_rgb24, int width) = >+ void (*RAWToRGB24Row)(const uint8_t* src_rgb, uint8_t* dst_rgb24, int width) = > RAWToRGB24Row_C; > if (!src_raw || !dst_rgb24 || width <= 0 || height == 0) { > return -1; >@@ -1664,13 +1728,13 @@ int RAWToRGB24(const uint8* src_raw, > } > > LIBYUV_API >-void SetPlane(uint8* dst_y, >+void SetPlane(uint8_t* dst_y, > int dst_stride_y, > int width, > int height, >- uint32 value) { >+ uint32_t value) { > int y; >- void (*SetRow)(uint8 * dst, uint8 value, int width) = SetRow_C; >+ void (*SetRow)(uint8_t * dst, uint8_t value, int width) = SetRow_C; > if (height < 0) { > height = -height; > dst_y = dst_y + (height - 1) * dst_stride_y; >@@ -1718,11 +1782,11 @@ void SetPlane(uint8* dst_y, > > // Draw a rectangle into I420 > LIBYUV_API >-int I420Rect(uint8* dst_y, >+int I420Rect(uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int x, > int y, >@@ -1733,9 +1797,9 @@ int I420Rect(uint8* dst_y, > int value_v) { > int halfwidth = (width + 1) >> 1; > int halfheight = (height + 1) >> 1; >- uint8* start_y = dst_y + y * dst_stride_y + x; >- uint8* start_u = dst_u + (y / 2) * dst_stride_u + (x / 2); >- uint8* start_v = dst_v + (y / 2) * dst_stride_v + (x / 2); >+ uint8_t* start_y = dst_y + y * dst_stride_y + x; >+ uint8_t* start_u = dst_u + (y / 2) * dst_stride_u + (x / 2); >+ uint8_t* start_v = dst_v + (y / 2) * dst_stride_v + (x / 2); > if (!dst_y || !dst_u || !dst_v || width <= 0 || height == 0 || x < 0 || > y < 0 || value_y < 0 || value_y > 255 || value_u < 0 || value_u > 255 || > value_v < 0 || value_v > 255) { >@@ -1750,15 +1814,16 @@ int I420Rect(uint8* dst_y, > > // Draw a rectangle into ARGB > LIBYUV_API >-int ARGBRect(uint8* dst_argb, >+int ARGBRect(uint8_t* dst_argb, > int dst_stride_argb, > int dst_x, > int dst_y, > int width, > int height, >- uint32 value) { >+ uint32_t value) { > int y; >- void (*ARGBSetRow)(uint8 * dst_argb, uint32 value, int width) = ARGBSetRow_C; >+ void (*ARGBSetRow)(uint8_t * dst_argb, uint32_t value, int width) = >+ ARGBSetRow_C; > if (!dst_argb || width <= 0 || height == 0 || dst_x < 0 || dst_y < 0) { > return -1; > } >@@ -1819,15 +1884,15 @@ int ARGBRect(uint8* dst_argb, > // f is foreground pixel premultiplied by alpha > > LIBYUV_API >-int ARGBAttenuate(const uint8* src_argb, >+int ARGBAttenuate(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGBAttenuateRow)(const uint8* src_argb, uint8* dst_argb, int width) = >- ARGBAttenuateRow_C; >+ void (*ARGBAttenuateRow)(const uint8_t* src_argb, uint8_t* dst_argb, >+ int width) = ARGBAttenuateRow_C; > if (!src_argb || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -1885,14 +1950,14 @@ int ARGBAttenuate(const uint8* src_argb, > > // Convert preattentuated ARGB to unattenuated ARGB. > LIBYUV_API >-int ARGBUnattenuate(const uint8* src_argb, >+int ARGBUnattenuate(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGBUnattenuateRow)(const uint8* src_argb, uint8* dst_argb, >+ void (*ARGBUnattenuateRow)(const uint8_t* src_argb, uint8_t* dst_argb, > int width) = ARGBUnattenuateRow_C; > if (!src_argb || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -1936,14 +2001,14 @@ int ARGBUnattenuate(const uint8* src_argb, > > // Convert ARGB to Grayed ARGB. > LIBYUV_API >-int ARGBGrayTo(const uint8* src_argb, >+int ARGBGrayTo(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGBGrayRow)(const uint8* src_argb, uint8* dst_argb, int width) = >+ void (*ARGBGrayRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width) = > ARGBGrayRow_C; > if (!src_argb || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -1985,16 +2050,16 @@ int ARGBGrayTo(const uint8* src_argb, > > // Make a rectangle of ARGB gray scale. > LIBYUV_API >-int ARGBGray(uint8* dst_argb, >+int ARGBGray(uint8_t* dst_argb, > int dst_stride_argb, > int dst_x, > int dst_y, > int width, > int height) { > int y; >- void (*ARGBGrayRow)(const uint8* src_argb, uint8* dst_argb, int width) = >+ void (*ARGBGrayRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width) = > ARGBGrayRow_C; >- uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; >+ uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; > if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0) { > return -1; > } >@@ -2029,15 +2094,15 @@ int ARGBGray(uint8* dst_argb, > > // Make a rectangle of ARGB Sepia tone. > LIBYUV_API >-int ARGBSepia(uint8* dst_argb, >+int ARGBSepia(uint8_t* dst_argb, > int dst_stride_argb, > int dst_x, > int dst_y, > int width, > int height) { > int y; >- void (*ARGBSepiaRow)(uint8 * dst_argb, int width) = ARGBSepiaRow_C; >- uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; >+ void (*ARGBSepiaRow)(uint8_t * dst_argb, int width) = ARGBSepiaRow_C; >+ uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; > if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0) { > return -1; > } >@@ -2073,16 +2138,16 @@ int ARGBSepia(uint8* dst_argb, > // Apply a 4x4 matrix to each ARGB pixel. > // Note: Normally for shading, but can be used to swizzle or invert. > LIBYUV_API >-int ARGBColorMatrix(const uint8* src_argb, >+int ARGBColorMatrix(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- const int8* matrix_argb, >+ const int8_t* matrix_argb, > int width, > int height) { > int y; >- void (*ARGBColorMatrixRow)(const uint8* src_argb, uint8* dst_argb, >- const int8* matrix_argb, int width) = >+ void (*ARGBColorMatrixRow)(const uint8_t* src_argb, uint8_t* dst_argb, >+ const int8_t* matrix_argb, int width) = > ARGBColorMatrixRow_C; > if (!src_argb || !dst_argb || !matrix_argb || width <= 0 || height == 0) { > return -1; >@@ -2124,15 +2189,15 @@ int ARGBColorMatrix(const uint8* src_argb, > // Apply a 4x3 matrix to each ARGB pixel. > // Deprecated. > LIBYUV_API >-int RGBColorMatrix(uint8* dst_argb, >+int RGBColorMatrix(uint8_t* dst_argb, > int dst_stride_argb, >- const int8* matrix_rgb, >+ const int8_t* matrix_rgb, > int dst_x, > int dst_y, > int width, > int height) { >- SIMD_ALIGNED(int8 matrix_argb[16]); >- uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; >+ SIMD_ALIGNED(int8_t matrix_argb[16]); >+ uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; > if (!dst_argb || !matrix_rgb || width <= 0 || height <= 0 || dst_x < 0 || > dst_y < 0) { > return -1; >@@ -2154,24 +2219,24 @@ int RGBColorMatrix(uint8* dst_argb, > matrix_argb[14] = matrix_argb[13] = matrix_argb[12] = 0; > matrix_argb[15] = 64; // 1.0 > >- return ARGBColorMatrix((const uint8*)(dst), dst_stride_argb, dst, >+ return ARGBColorMatrix((const uint8_t*)(dst), dst_stride_argb, dst, > dst_stride_argb, &matrix_argb[0], width, height); > } > > // Apply a color table each ARGB pixel. > // Table contains 256 ARGB values. > LIBYUV_API >-int ARGBColorTable(uint8* dst_argb, >+int ARGBColorTable(uint8_t* dst_argb, > int dst_stride_argb, >- const uint8* table_argb, >+ const uint8_t* table_argb, > int dst_x, > int dst_y, > int width, > int height) { > int y; >- void (*ARGBColorTableRow)(uint8 * dst_argb, const uint8* table_argb, >+ void (*ARGBColorTableRow)(uint8_t * dst_argb, const uint8_t* table_argb, > int width) = ARGBColorTableRow_C; >- uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; >+ uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; > if (!dst_argb || !table_argb || width <= 0 || height <= 0 || dst_x < 0 || > dst_y < 0) { > return -1; >@@ -2197,17 +2262,17 @@ int ARGBColorTable(uint8* dst_argb, > // Apply a color table each ARGB pixel but preserve destination alpha. > // Table contains 256 ARGB values. > LIBYUV_API >-int RGBColorTable(uint8* dst_argb, >+int RGBColorTable(uint8_t* dst_argb, > int dst_stride_argb, >- const uint8* table_argb, >+ const uint8_t* table_argb, > int dst_x, > int dst_y, > int width, > int height) { > int y; >- void (*RGBColorTableRow)(uint8 * dst_argb, const uint8* table_argb, >+ void (*RGBColorTableRow)(uint8_t * dst_argb, const uint8_t* table_argb, > int width) = RGBColorTableRow_C; >- uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; >+ uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; > if (!dst_argb || !table_argb || width <= 0 || height <= 0 || dst_x < 0 || > dst_y < 0) { > return -1; >@@ -2240,7 +2305,7 @@ int RGBColorTable(uint8* dst_argb, > // Caveat - although SSE2 saturates, the C function does not and should be used > // with care if doing anything but quantization. > LIBYUV_API >-int ARGBQuantize(uint8* dst_argb, >+int ARGBQuantize(uint8_t* dst_argb, > int dst_stride_argb, > int scale, > int interval_size, >@@ -2250,9 +2315,9 @@ int ARGBQuantize(uint8* dst_argb, > int width, > int height) { > int y; >- void (*ARGBQuantizeRow)(uint8 * dst_argb, int scale, int interval_size, >+ void (*ARGBQuantizeRow)(uint8_t * dst_argb, int scale, int interval_size, > int interval_offset, int width) = ARGBQuantizeRow_C; >- uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; >+ uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; > if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0 || > interval_size < 1 || interval_size > 255) { > return -1; >@@ -2288,17 +2353,17 @@ int ARGBQuantize(uint8* dst_argb, > // Computes table of cumulative sum for image where the value is the sum > // of all values above and to the left of the entry. Used by ARGBBlur. > LIBYUV_API >-int ARGBComputeCumulativeSum(const uint8* src_argb, >+int ARGBComputeCumulativeSum(const uint8_t* src_argb, > int src_stride_argb, >- int32* dst_cumsum, >+ int32_t* dst_cumsum, > int dst_stride32_cumsum, > int width, > int height) { > int y; >- void (*ComputeCumulativeSumRow)(const uint8* row, int32* cumsum, >- const int32* previous_cumsum, int width) = >+ void (*ComputeCumulativeSumRow)(const uint8_t* row, int32_t* cumsum, >+ const int32_t* previous_cumsum, int width) = > ComputeCumulativeSumRow_C; >- int32* previous_cumsum = dst_cumsum; >+ int32_t* previous_cumsum = dst_cumsum; > if (!dst_cumsum || !src_argb || width <= 0 || height <= 0) { > return -1; > } >@@ -2322,25 +2387,25 @@ int ARGBComputeCumulativeSum(const uint8* src_argb, > // aligned to 16 byte boundary. height can be radius * 2 + 2 to save memory > // as the buffer is treated as circular. > LIBYUV_API >-int ARGBBlur(const uint8* src_argb, >+int ARGBBlur(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- int32* dst_cumsum, >+ int32_t* dst_cumsum, > int dst_stride32_cumsum, > int width, > int height, > int radius) { > int y; >- void (*ComputeCumulativeSumRow)(const uint8* row, int32* cumsum, >- const int32* previous_cumsum, int width) = >+ void (*ComputeCumulativeSumRow)(const uint8_t* row, int32_t* cumsum, >+ const int32_t* previous_cumsum, int width) = > ComputeCumulativeSumRow_C; >- void (*CumulativeSumToAverageRow)(const int32* topleft, const int32* botleft, >- int width, int area, uint8* dst, >- int count) = CumulativeSumToAverageRow_C; >- int32* cumsum_bot_row; >- int32* max_cumsum_bot_row; >- int32* cumsum_top_row; >+ void (*CumulativeSumToAverageRow)( >+ const int32_t* topleft, const int32_t* botleft, int width, int area, >+ uint8_t* dst, int count) = CumulativeSumToAverageRow_C; >+ int32_t* cumsum_bot_row; >+ int32_t* max_cumsum_bot_row; >+ int32_t* cumsum_top_row; > > if (!src_argb || !dst_argb || width <= 0 || height == 0) { > return -1; >@@ -2394,7 +2459,7 @@ int ARGBBlur(const uint8* src_argb, > // Increment cumsum_bot_row pointer with circular buffer wrap around and > // then fill in a row of CumulativeSum. > if ((y + radius) < height) { >- const int32* prev_cumsum_bot_row = cumsum_bot_row; >+ const int32_t* prev_cumsum_bot_row = cumsum_bot_row; > cumsum_bot_row += dst_stride32_cumsum; > if (cumsum_bot_row >= max_cumsum_bot_row) { > cumsum_bot_row = dst_cumsum; >@@ -2432,16 +2497,16 @@ int ARGBBlur(const uint8* src_argb, > > // Multiply ARGB image by a specified ARGB value. > LIBYUV_API >-int ARGBShade(const uint8* src_argb, >+int ARGBShade(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height, >- uint32 value) { >+ uint32_t value) { > int y; >- void (*ARGBShadeRow)(const uint8* src_argb, uint8* dst_argb, int width, >- uint32 value) = ARGBShadeRow_C; >+ void (*ARGBShadeRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width, >+ uint32_t value) = ARGBShadeRow_C; > if (!src_argb || !dst_argb || width <= 0 || height == 0 || value == 0u) { > return -1; > } >@@ -2482,17 +2547,17 @@ int ARGBShade(const uint8* src_argb, > > // Interpolate 2 planes by specified amount (0 to 255). > LIBYUV_API >-int InterpolatePlane(const uint8* src0, >+int InterpolatePlane(const uint8_t* src0, > int src_stride0, >- const uint8* src1, >+ const uint8_t* src1, > int src_stride1, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height, > int interpolation) { > int y; >- void (*InterpolateRow)(uint8 * dst_ptr, const uint8* src_ptr, >+ void (*InterpolateRow)(uint8_t * dst_ptr, const uint8_t* src_ptr, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_C; > if (!src0 || !src1 || !dst || width <= 0 || height == 0) { >@@ -2534,14 +2599,6 @@ int InterpolatePlane(const uint8* src0, > } > } > #endif >-#if defined(HAS_INTERPOLATEROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src0, 4) && >- IS_ALIGNED(src_stride0, 4) && IS_ALIGNED(src1, 4) && >- IS_ALIGNED(src_stride1, 4) && IS_ALIGNED(dst, 4) && >- IS_ALIGNED(dst_stride, 4) && IS_ALIGNED(width, 4)) { >- InterpolateRow = InterpolateRow_DSPR2; >- } >-#endif > #if defined(HAS_INTERPOLATEROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > InterpolateRow = InterpolateRow_Any_MSA; >@@ -2562,11 +2619,11 @@ int InterpolatePlane(const uint8* src0, > > // Interpolate 2 ARGB images by specified amount (0 to 255). > LIBYUV_API >-int ARGBInterpolate(const uint8* src_argb0, >+int ARGBInterpolate(const uint8_t* src_argb0, > int src_stride_argb0, >- const uint8* src_argb1, >+ const uint8_t* src_argb1, > int src_stride_argb1, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height, >@@ -2578,23 +2635,23 @@ int ARGBInterpolate(const uint8* src_argb0, > > // Interpolate 2 YUV images by specified amount (0 to 255). > LIBYUV_API >-int I420Interpolate(const uint8* src0_y, >+int I420Interpolate(const uint8_t* src0_y, > int src0_stride_y, >- const uint8* src0_u, >+ const uint8_t* src0_u, > int src0_stride_u, >- const uint8* src0_v, >+ const uint8_t* src0_v, > int src0_stride_v, >- const uint8* src1_y, >+ const uint8_t* src1_y, > int src1_stride_y, >- const uint8* src1_u, >+ const uint8_t* src1_u, > int src1_stride_u, >- const uint8* src1_v, >+ const uint8_t* src1_v, > int src1_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height, >@@ -2616,16 +2673,16 @@ int I420Interpolate(const uint8* src0_y, > > // Shuffle ARGB channel order. e.g. BGRA to ARGB. > LIBYUV_API >-int ARGBShuffle(const uint8* src_bgra, >+int ARGBShuffle(const uint8_t* src_bgra, > int src_stride_bgra, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- const uint8* shuffler, >+ const uint8_t* shuffler, > int width, > int height) { > int y; >- void (*ARGBShuffleRow)(const uint8* src_bgra, uint8* dst_argb, >- const uint8* shuffler, int width) = ARGBShuffleRow_C; >+ void (*ARGBShuffleRow)(const uint8_t* src_bgra, uint8_t* dst_argb, >+ const uint8_t* shuffler, int width) = ARGBShuffleRow_C; > if (!src_bgra || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -2641,14 +2698,6 @@ int ARGBShuffle(const uint8* src_bgra, > height = 1; > src_stride_bgra = dst_stride_argb = 0; > } >-#if defined(HAS_ARGBSHUFFLEROW_SSE2) >- if (TestCpuFlag(kCpuHasSSE2)) { >- ARGBShuffleRow = ARGBShuffleRow_Any_SSE2; >- if (IS_ALIGNED(width, 4)) { >- ARGBShuffleRow = ARGBShuffleRow_SSE2; >- } >- } >-#endif > #if defined(HAS_ARGBSHUFFLEROW_SSSE3) > if (TestCpuFlag(kCpuHasSSSE3)) { > ARGBShuffleRow = ARGBShuffleRow_Any_SSSE3; >@@ -2691,23 +2740,23 @@ int ARGBShuffle(const uint8* src_bgra, > } > > // Sobel ARGB effect. >-static int ARGBSobelize(const uint8* src_argb, >+static int ARGBSobelize(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height, >- void (*SobelRow)(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst, >+ void (*SobelRow)(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst, > int width)) { > int y; >- void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_g, int width) = >+ void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_g, int width) = > ARGBToYJRow_C; >- void (*SobelYRow)(const uint8* src_y0, const uint8* src_y1, uint8* dst_sobely, >- int width) = SobelYRow_C; >- void (*SobelXRow)(const uint8* src_y0, const uint8* src_y1, >- const uint8* src_y2, uint8* dst_sobely, int width) = >+ void (*SobelYRow)(const uint8_t* src_y0, const uint8_t* src_y1, >+ uint8_t* dst_sobely, int width) = SobelYRow_C; >+ void (*SobelXRow)(const uint8_t* src_y0, const uint8_t* src_y1, >+ const uint8_t* src_y2, uint8_t* dst_sobely, int width) = > SobelXRow_C; > const int kEdge = 16; // Extra pixels at start of row for extrude/align. > if (!src_argb || !dst_argb || width <= 0 || height == 0) { >@@ -2787,14 +2836,14 @@ static int ARGBSobelize(const uint8* src_argb, > // 3 rows with edges before/after. > const int kRowSize = (width + kEdge + 31) & ~31; > align_buffer_64(rows, kRowSize * 2 + (kEdge + kRowSize * 3 + kEdge)); >- uint8* row_sobelx = rows; >- uint8* row_sobely = rows + kRowSize; >- uint8* row_y = rows + kRowSize * 2; >+ uint8_t* row_sobelx = rows; >+ uint8_t* row_sobely = rows + kRowSize; >+ uint8_t* row_y = rows + kRowSize * 2; > > // Convert first row. >- uint8* row_y0 = row_y + kEdge; >- uint8* row_y1 = row_y0 + kRowSize; >- uint8* row_y2 = row_y1 + kRowSize; >+ uint8_t* row_y0 = row_y + kEdge; >+ uint8_t* row_y1 = row_y0 + kRowSize; >+ uint8_t* row_y2 = row_y1 + kRowSize; > ARGBToYJRow(src_argb, row_y0, width); > row_y0[-1] = row_y0[0]; > memset(row_y0 + width, row_y0[width - 1], 16); // Extrude 16 for valgrind. >@@ -2818,7 +2867,7 @@ static int ARGBSobelize(const uint8* src_argb, > > // Cycle thru circular queue of 3 row_y buffers. > { >- uint8* row_yt = row_y0; >+ uint8_t* row_yt = row_y0; > row_y0 = row_y1; > row_y1 = row_y2; > row_y2 = row_yt; >@@ -2833,14 +2882,14 @@ static int ARGBSobelize(const uint8* src_argb, > > // Sobel ARGB effect. > LIBYUV_API >-int ARGBSobel(const uint8* src_argb, >+int ARGBSobel(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >- void (*SobelRow)(const uint8* src_sobelx, const uint8* src_sobely, >- uint8* dst_argb, int width) = SobelRow_C; >+ void (*SobelRow)(const uint8_t* src_sobelx, const uint8_t* src_sobely, >+ uint8_t* dst_argb, int width) = SobelRow_C; > #if defined(HAS_SOBELROW_SSE2) > if (TestCpuFlag(kCpuHasSSE2)) { > SobelRow = SobelRow_Any_SSE2; >@@ -2871,14 +2920,14 @@ int ARGBSobel(const uint8* src_argb, > > // Sobel ARGB effect with planar output. > LIBYUV_API >-int ARGBSobelToPlane(const uint8* src_argb, >+int ARGBSobelToPlane(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, > int width, > int height) { >- void (*SobelToPlaneRow)(const uint8* src_sobelx, const uint8* src_sobely, >- uint8* dst_, int width) = SobelToPlaneRow_C; >+ void (*SobelToPlaneRow)(const uint8_t* src_sobelx, const uint8_t* src_sobely, >+ uint8_t* dst_, int width) = SobelToPlaneRow_C; > #if defined(HAS_SOBELTOPLANEROW_SSE2) > if (TestCpuFlag(kCpuHasSSE2)) { > SobelToPlaneRow = SobelToPlaneRow_Any_SSE2; >@@ -2910,14 +2959,14 @@ int ARGBSobelToPlane(const uint8* src_argb, > // SobelXY ARGB effect. > // Similar to Sobel, but also stores Sobel X in R and Sobel Y in B. G = Sobel. > LIBYUV_API >-int ARGBSobelXY(const uint8* src_argb, >+int ARGBSobelXY(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { >- void (*SobelXYRow)(const uint8* src_sobelx, const uint8* src_sobely, >- uint8* dst_argb, int width) = SobelXYRow_C; >+ void (*SobelXYRow)(const uint8_t* src_sobelx, const uint8_t* src_sobely, >+ uint8_t* dst_argb, int width) = SobelXYRow_C; > #if defined(HAS_SOBELXYROW_SSE2) > if (TestCpuFlag(kCpuHasSSE2)) { > SobelXYRow = SobelXYRow_Any_SSE2; >@@ -2948,15 +2997,15 @@ int ARGBSobelXY(const uint8* src_argb, > > // Apply a 4x4 polynomial to each ARGB pixel. > LIBYUV_API >-int ARGBPolynomial(const uint8* src_argb, >+int ARGBPolynomial(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > const float* poly, > int width, > int height) { > int y; >- void (*ARGBPolynomialRow)(const uint8* src_argb, uint8* dst_argb, >+ void (*ARGBPolynomialRow)(const uint8_t* src_argb, uint8_t* dst_argb, > const float* poly, int width) = ARGBPolynomialRow_C; > if (!src_argb || !dst_argb || !poly || width <= 0 || height == 0) { > return -1; >@@ -2996,16 +3045,16 @@ int ARGBPolynomial(const uint8* src_argb, > // Convert plane of 16 bit shorts to half floats. > // Source values are multiplied by scale before storing as half float. > LIBYUV_API >-int HalfFloatPlane(const uint16* src_y, >+int HalfFloatPlane(const uint16_t* src_y, > int src_stride_y, >- uint16* dst_y, >+ uint16_t* dst_y, > int dst_stride_y, > float scale, > int width, > int height) { > int y; >- void (*HalfFloatRow)(const uint16* src, uint16* dst, float scale, int width) = >- HalfFloatRow_C; >+ void (*HalfFloatRow)(const uint16_t* src, uint16_t* dst, float scale, >+ int width) = HalfFloatRow_C; > if (!src_y || !dst_y || width <= 0 || height == 0) { > return -1; > } >@@ -3074,19 +3123,40 @@ int HalfFloatPlane(const uint16* src_y, > return 0; > } > >+// Convert a buffer of bytes to floats, scale the values and store as floats. >+LIBYUV_API >+int ByteToFloat(const uint8_t* src_y, float* dst_y, float scale, int width) { >+ void (*ByteToFloatRow)(const uint8_t* src, float* dst, float scale, >+ int width) = ByteToFloatRow_C; >+ if (!src_y || !dst_y || width <= 0) { >+ return -1; >+ } >+#if defined(HAS_BYTETOFLOATROW_NEON) >+ if (TestCpuFlag(kCpuHasNEON)) { >+ ByteToFloatRow = ByteToFloatRow_Any_NEON; >+ if (IS_ALIGNED(width, 8)) { >+ ByteToFloatRow = ByteToFloatRow_NEON; >+ } >+ } >+#endif >+ >+ ByteToFloatRow(src_y, dst_y, scale, width); >+ return 0; >+} >+ > // Apply a lumacolortable to each ARGB pixel. > LIBYUV_API >-int ARGBLumaColorTable(const uint8* src_argb, >+int ARGBLumaColorTable(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- const uint8* luma, >+ const uint8_t* luma, > int width, > int height) { > int y; > void (*ARGBLumaColorTableRow)( >- const uint8* src_argb, uint8* dst_argb, int width, const uint8* luma, >- const uint32 lumacoeff) = ARGBLumaColorTableRow_C; >+ const uint8_t* src_argb, uint8_t* dst_argb, int width, >+ const uint8_t* luma, const uint32_t lumacoeff) = ARGBLumaColorTableRow_C; > if (!src_argb || !dst_argb || !luma || width <= 0 || height == 0) { > return -1; > } >@@ -3118,15 +3188,15 @@ int ARGBLumaColorTable(const uint8* src_argb, > > // Copy Alpha from one ARGB image to another. > LIBYUV_API >-int ARGBCopyAlpha(const uint8* src_argb, >+int ARGBCopyAlpha(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGBCopyAlphaRow)(const uint8* src_argb, uint8* dst_argb, int width) = >- ARGBCopyAlphaRow_C; >+ void (*ARGBCopyAlphaRow)(const uint8_t* src_argb, uint8_t* dst_argb, >+ int width) = ARGBCopyAlphaRow_C; > if (!src_argb || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -3169,10 +3239,10 @@ int ARGBCopyAlpha(const uint8* src_argb, > > // Extract just the alpha channel from ARGB. > LIBYUV_API >-int ARGBExtractAlpha(const uint8* src_argb, >- int src_stride, >- uint8* dst_a, >- int dst_stride, >+int ARGBExtractAlpha(const uint8_t* src_argb, >+ int src_stride_argb, >+ uint8_t* dst_a, >+ int dst_stride_a, > int width, > int height) { > if (!src_argb || !dst_a || width <= 0 || height == 0) { >@@ -3181,17 +3251,17 @@ int ARGBExtractAlpha(const uint8* src_argb, > // Negative height means invert the image. > if (height < 0) { > height = -height; >- src_argb += (height - 1) * src_stride; >- src_stride = -src_stride; >+ src_argb += (height - 1) * src_stride_argb; >+ src_stride_argb = -src_stride_argb; > } > // Coalesce rows. >- if (src_stride == width * 4 && dst_stride == width) { >+ if (src_stride_argb == width * 4 && dst_stride_a == width) { > width *= height; > height = 1; >- src_stride = dst_stride = 0; >+ src_stride_argb = dst_stride_a = 0; > } >- void (*ARGBExtractAlphaRow)(const uint8* src_argb, uint8* dst_a, int width) = >- ARGBExtractAlphaRow_C; >+ void (*ARGBExtractAlphaRow)(const uint8_t* src_argb, uint8_t* dst_a, >+ int width) = ARGBExtractAlphaRow_C; > #if defined(HAS_ARGBEXTRACTALPHAROW_SSE2) > if (TestCpuFlag(kCpuHasSSE2)) { > ARGBExtractAlphaRow = IS_ALIGNED(width, 8) ? ARGBExtractAlphaRow_SSE2 >@@ -3219,23 +3289,23 @@ int ARGBExtractAlpha(const uint8* src_argb, > > for (int y = 0; y < height; ++y) { > ARGBExtractAlphaRow(src_argb, dst_a, width); >- src_argb += src_stride; >- dst_a += dst_stride; >+ src_argb += src_stride_argb; >+ dst_a += dst_stride_a; > } > return 0; > } > > // Copy a planar Y channel to the alpha channel of a destination ARGB image. > LIBYUV_API >-int ARGBCopyYToAlpha(const uint8* src_y, >+int ARGBCopyYToAlpha(const uint8_t* src_y, > int src_stride_y, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height) { > int y; >- void (*ARGBCopyYToAlphaRow)(const uint8* src_y, uint8* dst_argb, int width) = >- ARGBCopyYToAlphaRow_C; >+ void (*ARGBCopyYToAlphaRow)(const uint8_t* src_y, uint8_t* dst_argb, >+ int width) = ARGBCopyYToAlphaRow_C; > if (!src_y || !dst_argb || width <= 0 || height == 0) { > return -1; > } >@@ -3280,19 +3350,19 @@ int ARGBCopyYToAlpha(const uint8* src_y, > // directly. A SplitUVRow_Odd function could copy the remaining chroma. > > LIBYUV_API >-int YUY2ToNV12(const uint8* src_yuy2, >+int YUY2ToNV12(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int dst_stride_uv, > int width, > int height) { > int y; > int halfwidth = (width + 1) >> 1; >- void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, >+ void (*SplitUVRow)(const uint8_t* src_uv, uint8_t* dst_u, uint8_t* dst_v, > int width) = SplitUVRow_C; >- void (*InterpolateRow)(uint8 * dst_ptr, const uint8* src_ptr, >+ void (*InterpolateRow)(uint8_t * dst_ptr, const uint8_t* src_ptr, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_C; > if (!src_yuy2 || !dst_y || !dst_uv || width <= 0 || height == 0) { >@@ -3396,19 +3466,19 @@ int YUY2ToNV12(const uint8* src_yuy2, > } > > LIBYUV_API >-int UYVYToNV12(const uint8* src_uyvy, >+int UYVYToNV12(const uint8_t* src_uyvy, > int src_stride_uyvy, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int dst_stride_uv, > int width, > int height) { > int y; > int halfwidth = (width + 1) >> 1; >- void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, >+ void (*SplitUVRow)(const uint8_t* src_uv, uint8_t* dst_u, uint8_t* dst_v, > int width) = SplitUVRow_C; >- void (*InterpolateRow)(uint8 * dst_ptr, const uint8* src_ptr, >+ void (*InterpolateRow)(uint8_t * dst_ptr, const uint8_t* src_ptr, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_C; > if (!src_uyvy || !dst_y || !dst_uv || width <= 0 || height == 0) { >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate.cc >index b16af5071853491f17004cfaec858bbf1bc150aa..f2bed85b7552f250d419ec2889c1920ba540298a 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate.cc >@@ -22,18 +22,18 @@ extern "C" { > #endif > > LIBYUV_API >-void TransposePlane(const uint8* src, >+void TransposePlane(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height) { > int i = height; > #if defined(HAS_TRANSPOSEWX16_MSA) >- void (*TransposeWx16)(const uint8* src, int src_stride, uint8* dst, >+ void (*TransposeWx16)(const uint8_t* src, int src_stride, uint8_t* dst, > int dst_stride, int width) = TransposeWx16_C; > #else >- void (*TransposeWx8)(const uint8* src, int src_stride, uint8* dst, >+ void (*TransposeWx8)(const uint8_t* src, int src_stride, uint8_t* dst, > int dst_stride, int width) = TransposeWx8_C; > #endif > #if defined(HAS_TRANSPOSEWX8_NEON) >@@ -57,16 +57,6 @@ void TransposePlane(const uint8* src, > } > } > #endif >-#if defined(HAS_TRANSPOSEWX8_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- if (IS_ALIGNED(width, 4) && IS_ALIGNED(src, 4) && >- IS_ALIGNED(src_stride, 4)) { >- TransposeWx8 = TransposeWx8_Fast_DSPR2; >- } else { >- TransposeWx8 = TransposeWx8_DSPR2; >- } >- } >-#endif > #if defined(HAS_TRANSPOSEWX16_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > TransposeWx16 = TransposeWx16_Any_MSA; >@@ -100,9 +90,9 @@ void TransposePlane(const uint8* src, > } > > LIBYUV_API >-void RotatePlane90(const uint8* src, >+void RotatePlane90(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height) { >@@ -115,9 +105,9 @@ void RotatePlane90(const uint8* src, > } > > LIBYUV_API >-void RotatePlane270(const uint8* src, >+void RotatePlane270(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height) { >@@ -130,20 +120,20 @@ void RotatePlane270(const uint8* src, > } > > LIBYUV_API >-void RotatePlane180(const uint8* src, >+void RotatePlane180(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height) { > // Swap first and last row and mirror the content. Uses a temporary row. > align_buffer_64(row, width); >- const uint8* src_bot = src + src_stride * (height - 1); >- uint8* dst_bot = dst + dst_stride * (height - 1); >+ const uint8_t* src_bot = src + src_stride * (height - 1); >+ uint8_t* dst_bot = dst + dst_stride * (height - 1); > int half_height = (height + 1) >> 1; > int y; >- void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C; >- void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; >+ void (*MirrorRow)(const uint8_t* src, uint8_t* dst, int width) = MirrorRow_C; >+ void (*CopyRow)(const uint8_t* src, uint8_t* dst, int width) = CopyRow_C; > #if defined(HAS_MIRRORROW_NEON) > if (TestCpuFlag(kCpuHasNEON)) { > MirrorRow = MirrorRow_Any_NEON; >@@ -168,14 +158,6 @@ void RotatePlane180(const uint8* src, > } > } > #endif >-// TODO(fbarchard): Mirror on mips handle unaligned memory. >-#if defined(HAS_MIRRORROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src, 4) && >- IS_ALIGNED(src_stride, 4) && IS_ALIGNED(dst, 4) && >- IS_ALIGNED(dst_stride, 4)) { >- MirrorRow = MirrorRow_DSPR2; >- } >-#endif > #if defined(HAS_MIRRORROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > MirrorRow = MirrorRow_Any_MSA; >@@ -204,11 +186,6 @@ void RotatePlane180(const uint8* src, > CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON; > } > #endif >-#if defined(HAS_COPYROW_MIPS) >- if (TestCpuFlag(kCpuHasMIPS)) { >- CopyRow = CopyRow_MIPS; >- } >-#endif > > // Odd height will harmlessly mirror the middle row twice. > for (y = 0; y < half_height; ++y) { >@@ -224,22 +201,22 @@ void RotatePlane180(const uint8* src, > } > > LIBYUV_API >-void TransposeUV(const uint8* src, >+void TransposeUV(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height) { > int i = height; > #if defined(HAS_TRANSPOSEUVWX16_MSA) >- void (*TransposeUVWx16)(const uint8* src, int src_stride, uint8* dst_a, >- int dst_stride_a, uint8* dst_b, int dst_stride_b, >+ void (*TransposeUVWx16)(const uint8_t* src, int src_stride, uint8_t* dst_a, >+ int dst_stride_a, uint8_t* dst_b, int dst_stride_b, > int width) = TransposeUVWx16_C; > #else >- void (*TransposeUVWx8)(const uint8* src, int src_stride, uint8* dst_a, >- int dst_stride_a, uint8* dst_b, int dst_stride_b, >+ void (*TransposeUVWx8)(const uint8_t* src, int src_stride, uint8_t* dst_a, >+ int dst_stride_a, uint8_t* dst_b, int dst_stride_b, > int width) = TransposeUVWx8_C; > #endif > #if defined(HAS_TRANSPOSEUVWX8_NEON) >@@ -255,12 +232,6 @@ void TransposeUV(const uint8* src, > } > } > #endif >-#if defined(HAS_TRANSPOSEUVWX8_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 2) && IS_ALIGNED(src, 4) && >- IS_ALIGNED(src_stride, 4)) { >- TransposeUVWx8 = TransposeUVWx8_DSPR2; >- } >-#endif > #if defined(HAS_TRANSPOSEUVWX16_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > TransposeUVWx16 = TransposeUVWx16_Any_MSA; >@@ -299,11 +270,11 @@ void TransposeUV(const uint8* src, > } > > LIBYUV_API >-void RotateUV90(const uint8* src, >+void RotateUV90(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height) { >@@ -315,11 +286,11 @@ void RotateUV90(const uint8* src, > } > > LIBYUV_API >-void RotateUV270(const uint8* src, >+void RotateUV270(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height) { >@@ -334,17 +305,17 @@ void RotateUV270(const uint8* src, > > // Rotate 180 is a horizontal and vertical flip. > LIBYUV_API >-void RotateUV180(const uint8* src, >+void RotateUV180(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height) { > int i; >- void (*MirrorUVRow)(const uint8* src, uint8* dst_u, uint8* dst_v, int width) = >- MirrorUVRow_C; >+ void (*MirrorUVRow)(const uint8_t* src, uint8_t* dst_u, uint8_t* dst_v, >+ int width) = MirrorUVRow_C; > #if defined(HAS_MIRRORUVROW_NEON) > if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { > MirrorUVRow = MirrorUVRow_NEON; >@@ -355,12 +326,6 @@ void RotateUV180(const uint8* src, > MirrorUVRow = MirrorUVRow_SSSE3; > } > #endif >-#if defined(HAS_MIRRORUVROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src, 4) && >- IS_ALIGNED(src_stride, 4)) { >- MirrorUVRow = MirrorUVRow_DSPR2; >- } >-#endif > #if defined(HAS_MIRRORUVROW_MSA) > if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 32)) { > MirrorUVRow = MirrorUVRow_MSA; >@@ -379,9 +344,9 @@ void RotateUV180(const uint8* src, > } > > LIBYUV_API >-int RotatePlane(const uint8* src, >+int RotatePlane(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height, >@@ -418,17 +383,17 @@ int RotatePlane(const uint8* src, > } > > LIBYUV_API >-int I420Rotate(const uint8* src_y, >+int I420Rotate(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height, >@@ -486,15 +451,15 @@ int I420Rotate(const uint8* src_y, > } > > LIBYUV_API >-int NV12ToI420Rotate(const uint8* src_y, >+int NV12ToI420Rotate(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_uv, >+ const uint8_t* src_uv, > int src_stride_uv, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int width, > int height, >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_any.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_any.cc >index 562096b926c2b5183725adeb29ea70725a2c06b6..c2752e6222c02df6824aa8511fc3d0c5832de3a7 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_any.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_any.cc >@@ -19,8 +19,8 @@ extern "C" { > #endif > > #define TANY(NAMEANY, TPOS_SIMD, MASK) \ >- void NAMEANY(const uint8* src, int src_stride, uint8* dst, int dst_stride, \ >- int width) { \ >+ void NAMEANY(const uint8_t* src, int src_stride, uint8_t* dst, \ >+ int dst_stride, int width) { \ > int r = width & MASK; \ > int n = width - r; \ > if (n > 0) { \ >@@ -38,17 +38,15 @@ TANY(TransposeWx8_Any_SSSE3, TransposeWx8_SSSE3, 7) > #ifdef HAS_TRANSPOSEWX8_FAST_SSSE3 > TANY(TransposeWx8_Fast_Any_SSSE3, TransposeWx8_Fast_SSSE3, 15) > #endif >-#ifdef HAS_TRANSPOSEWX8_DSPR2 >-TANY(TransposeWx8_Any_DSPR2, TransposeWx8_DSPR2, 7) >-#endif > #ifdef HAS_TRANSPOSEWX16_MSA > TANY(TransposeWx16_Any_MSA, TransposeWx16_MSA, 15) > #endif > #undef TANY > > #define TUVANY(NAMEANY, TPOS_SIMD, MASK) \ >- void NAMEANY(const uint8* src, int src_stride, uint8* dst_a, \ >- int dst_stride_a, uint8* dst_b, int dst_stride_b, int width) { \ >+ void NAMEANY(const uint8_t* src, int src_stride, uint8_t* dst_a, \ >+ int dst_stride_a, uint8_t* dst_b, int dst_stride_b, \ >+ int width) { \ > int r = width & MASK; \ > int n = width - r; \ > if (n > 0) { \ >@@ -64,9 +62,6 @@ TUVANY(TransposeUVWx8_Any_NEON, TransposeUVWx8_NEON, 7) > #ifdef HAS_TRANSPOSEUVWX8_SSE2 > TUVANY(TransposeUVWx8_Any_SSE2, TransposeUVWx8_SSE2, 7) > #endif >-#ifdef HAS_TRANSPOSEUVWX8_DSPR2 >-TUVANY(TransposeUVWx8_Any_DSPR2, TransposeUVWx8_DSPR2, 7) >-#endif > #ifdef HAS_TRANSPOSEUVWX16_MSA > TUVANY(TransposeUVWx16_Any_MSA, TransposeUVWx16_MSA, 7) > #endif >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_argb.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_argb.cc >index ede4eafa6c2c67f017b8742617d700047f44a01d..5a6e05376f17690040900a2c49afb13344828f50 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_argb.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_argb.cc >@@ -14,113 +14,102 @@ > #include "libyuv/cpu_id.h" > #include "libyuv/planar_functions.h" > #include "libyuv/row.h" >+#include "libyuv/scale_row.h" /* for ScaleARGBRowDownEven_ */ > > #ifdef __cplusplus > namespace libyuv { > extern "C" { > #endif > >-// ARGBScale has a function to copy pixels to a row, striding each source >-// pixel by a constant. >-#if !defined(LIBYUV_DISABLE_X86) && \ >- (defined(_M_IX86) || \ >- (defined(__x86_64__) && !defined(__native_client__)) || \ >- defined(__i386__)) >-#define HAS_SCALEARGBROWDOWNEVEN_SSE2 >-void ScaleARGBRowDownEven_SSE2(const uint8* src_ptr, >- int src_stride, >- int src_stepx, >- uint8* dst_ptr, >- int dst_width); >-#endif >-#if !defined(LIBYUV_DISABLE_NEON) && !defined(__native_client__) && \ >- (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__)) >-#define HAS_SCALEARGBROWDOWNEVEN_NEON >-void ScaleARGBRowDownEven_NEON(const uint8* src_ptr, >- int src_stride, >- int src_stepx, >- uint8* dst_ptr, >- int dst_width); >-#endif >- >-void ScaleARGBRowDownEven_C(const uint8* src_ptr, >- int, >- int src_stepx, >- uint8* dst_ptr, >- int dst_width); >- >-static void ARGBTranspose(const uint8* src, >- int src_stride, >- uint8* dst, >- int dst_stride, >+static void ARGBTranspose(const uint8_t* src_argb, >+ int src_stride_argb, >+ uint8_t* dst_argb, >+ int dst_stride_argb, > int width, > int height) { > int i; >- int src_pixel_step = src_stride >> 2; >- void (*ScaleARGBRowDownEven)(const uint8* src_ptr, int src_stride, >- int src_step, uint8* dst_ptr, int dst_width) = >- ScaleARGBRowDownEven_C; >+ int src_pixel_step = src_stride_argb >> 2; >+ void (*ScaleARGBRowDownEven)( >+ const uint8_t* src_argb, ptrdiff_t src_stride_argb, int src_step, >+ uint8_t* dst_argb, int dst_width) = ScaleARGBRowDownEven_C; > #if defined(HAS_SCALEARGBROWDOWNEVEN_SSE2) >- if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(height, 4)) { // Width of dest. >- ScaleARGBRowDownEven = ScaleARGBRowDownEven_SSE2; >+ if (TestCpuFlag(kCpuHasSSE2)) { >+ ScaleARGBRowDownEven = ScaleARGBRowDownEven_Any_SSE2; >+ if (IS_ALIGNED(height, 4)) { // Width of dest. >+ ScaleARGBRowDownEven = ScaleARGBRowDownEven_SSE2; >+ } > } > #endif > #if defined(HAS_SCALEARGBROWDOWNEVEN_NEON) >- if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(height, 4)) { // Width of dest. >- ScaleARGBRowDownEven = ScaleARGBRowDownEven_NEON; >+ if (TestCpuFlag(kCpuHasNEON)) { >+ ScaleARGBRowDownEven = ScaleARGBRowDownEven_Any_NEON; >+ if (IS_ALIGNED(height, 4)) { // Width of dest. >+ ScaleARGBRowDownEven = ScaleARGBRowDownEven_NEON; >+ } >+ } >+#endif >+#if defined(HAS_SCALEARGBROWDOWNEVEN_MSA) >+ if (TestCpuFlag(kCpuHasMSA)) { >+ ScaleARGBRowDownEven = ScaleARGBRowDownEven_Any_MSA; >+ if (IS_ALIGNED(height, 4)) { // Width of dest. >+ ScaleARGBRowDownEven = ScaleARGBRowDownEven_MSA; >+ } > } > #endif > > for (i = 0; i < width; ++i) { // column of source to row of dest. >- ScaleARGBRowDownEven(src, 0, src_pixel_step, dst, height); >- dst += dst_stride; >- src += 4; >+ ScaleARGBRowDownEven(src_argb, 0, src_pixel_step, dst_argb, height); >+ dst_argb += dst_stride_argb; >+ src_argb += 4; > } > } > >-void ARGBRotate90(const uint8* src, >- int src_stride, >- uint8* dst, >- int dst_stride, >+void ARGBRotate90(const uint8_t* src_argb, >+ int src_stride_argb, >+ uint8_t* dst_argb, >+ int dst_stride_argb, > int width, > int height) { > // Rotate by 90 is a ARGBTranspose with the source read > // from bottom to top. So set the source pointer to the end > // of the buffer and flip the sign of the source stride. >- src += src_stride * (height - 1); >- src_stride = -src_stride; >- ARGBTranspose(src, src_stride, dst, dst_stride, width, height); >+ src_argb += src_stride_argb * (height - 1); >+ src_stride_argb = -src_stride_argb; >+ ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, >+ height); > } > >-void ARGBRotate270(const uint8* src, >- int src_stride, >- uint8* dst, >- int dst_stride, >+void ARGBRotate270(const uint8_t* src_argb, >+ int src_stride_argb, >+ uint8_t* dst_argb, >+ int dst_stride_argb, > int width, > int height) { > // Rotate by 270 is a ARGBTranspose with the destination written > // from bottom to top. So set the destination pointer to the end > // of the buffer and flip the sign of the destination stride. >- dst += dst_stride * (width - 1); >- dst_stride = -dst_stride; >- ARGBTranspose(src, src_stride, dst, dst_stride, width, height); >+ dst_argb += dst_stride_argb * (width - 1); >+ dst_stride_argb = -dst_stride_argb; >+ ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, >+ height); > } > >-void ARGBRotate180(const uint8* src, >- int src_stride, >- uint8* dst, >- int dst_stride, >+void ARGBRotate180(const uint8_t* src_argb, >+ int src_stride_argb, >+ uint8_t* dst_argb, >+ int dst_stride_argb, > int width, > int height) { > // Swap first and last row and mirror the content. Uses a temporary row. > align_buffer_64(row, width * 4); >- const uint8* src_bot = src + src_stride * (height - 1); >- uint8* dst_bot = dst + dst_stride * (height - 1); >+ const uint8_t* src_bot = src_argb + src_stride_argb * (height - 1); >+ uint8_t* dst_bot = dst_argb + dst_stride_argb * (height - 1); > int half_height = (height + 1) >> 1; > int y; >- void (*ARGBMirrorRow)(const uint8* src, uint8* dst, int width) = >+ void (*ARGBMirrorRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width) = > ARGBMirrorRow_C; >- void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; >+ void (*CopyRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width) = >+ CopyRow_C; > #if defined(HAS_ARGBMIRRORROW_NEON) > if (TestCpuFlag(kCpuHasNEON)) { > ARGBMirrorRow = ARGBMirrorRow_Any_NEON; >@@ -173,29 +162,24 @@ void ARGBRotate180(const uint8* src, > CopyRow = IS_ALIGNED(width * 4, 32) ? CopyRow_NEON : CopyRow_Any_NEON; > } > #endif >-#if defined(HAS_COPYROW_MIPS) >- if (TestCpuFlag(kCpuHasMIPS)) { >- CopyRow = CopyRow_MIPS; >- } >-#endif > > // Odd height will harmlessly mirror the middle row twice. > for (y = 0; y < half_height; ++y) { >- ARGBMirrorRow(src, row, width); // Mirror first row into a buffer >- ARGBMirrorRow(src_bot, dst, width); // Mirror last row into first row >- CopyRow(row, dst_bot, width * 4); // Copy first mirrored row into last >- src += src_stride; >- dst += dst_stride; >- src_bot -= src_stride; >- dst_bot -= dst_stride; >+ ARGBMirrorRow(src_argb, row, width); // Mirror first row into a buffer >+ ARGBMirrorRow(src_bot, dst_argb, width); // Mirror last row into first row >+ CopyRow(row, dst_bot, width * 4); // Copy first mirrored row into last >+ src_argb += src_stride_argb; >+ dst_argb += dst_stride_argb; >+ src_bot -= src_stride_argb; >+ dst_bot -= dst_stride_argb; > } > free_aligned_buffer_64(row); > } > > LIBYUV_API >-int ARGBRotate(const uint8* src_argb, >+int ARGBRotate(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int width, > int height, >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_common.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_common.cc >index 89357e732d28e4174b2acf6462c2f954726b3328..ff212adebc4dc67f04137112cba4f1c7611c839b 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_common.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_common.cc >@@ -16,9 +16,9 @@ namespace libyuv { > extern "C" { > #endif > >-void TransposeWx8_C(const uint8* src, >+void TransposeWx8_C(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width) { > int i; >@@ -36,11 +36,11 @@ void TransposeWx8_C(const uint8* src, > } > } > >-void TransposeUVWx8_C(const uint8* src, >+void TransposeUVWx8_C(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width) { > int i; >@@ -67,9 +67,9 @@ void TransposeUVWx8_C(const uint8* src, > } > } > >-void TransposeWxH_C(const uint8* src, >+void TransposeWxH_C(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width, > int height) { >@@ -82,11 +82,11 @@ void TransposeWxH_C(const uint8* src, > } > } > >-void TransposeUVWxH_C(const uint8* src, >+void TransposeUVWxH_C(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width, > int height) { >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_gcc.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_gcc.cc >index 74b48ac4084c1d39c7a62d47bac584935f218b67..04e19e29eefba590dbb8149bad172ce6c16f996a 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_gcc.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_gcc.cc >@@ -22,9 +22,9 @@ extern "C" { > > // Transpose 8x8. 32 or 64 bit, but not NaCL for 64 bit. > #if defined(HAS_TRANSPOSEWX8_SSSE3) >-void TransposeWx8_SSSE3(const uint8* src, >+void TransposeWx8_SSSE3(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width) { > asm volatile( >@@ -112,9 +112,9 @@ void TransposeWx8_SSSE3(const uint8* src, > > // Transpose 16x8. 64 bit > #if defined(HAS_TRANSPOSEWX8_FAST_SSSE3) >-void TransposeWx8_Fast_SSSE3(const uint8* src, >+void TransposeWx8_Fast_SSSE3(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width) { > asm volatile( >@@ -255,11 +255,11 @@ void TransposeWx8_Fast_SSSE3(const uint8* src, > > // Transpose UV 8x8. 64 bit. > #if defined(HAS_TRANSPOSEUVWX8_SSE2) >-void TransposeUVWx8_SSE2(const uint8* src, >+void TransposeUVWx8_SSE2(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width) { > asm volatile( >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_msa.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_msa.cc >index 8907765aba70cad2a99858765b57cc3c8ab3fe44..99bdca65b32c72ea007ef69188930b5a58127e17 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_msa.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_msa.cc >@@ -51,9 +51,9 @@ extern "C" { > out3 = (v16u8)__msa_ilvl_d((v2i64)in3, (v2i64)in2); \ > } > >-void TransposeWx16_C(const uint8* src, >+void TransposeWx16_C(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width) { > TransposeWx8_C(src, src_stride, dst, dst_stride, width); >@@ -61,11 +61,11 @@ void TransposeWx16_C(const uint8* src, > width); > } > >-void TransposeUVWx16_C(const uint8* src, >+void TransposeUVWx16_C(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width) { > TransposeUVWx8_C(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, >@@ -74,13 +74,13 @@ void TransposeUVWx16_C(const uint8* src, > dst_stride_a, (dst_b + 8), dst_stride_b, width); > } > >-void TransposeWx16_MSA(const uint8* src, >+void TransposeWx16_MSA(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width) { > int x; >- const uint8* s; >+ const uint8_t* s; > v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3, vec0, vec1, vec2, vec3; > v16u8 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; > v16u8 res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; >@@ -153,15 +153,15 @@ void TransposeWx16_MSA(const uint8* src, > } > } > >-void TransposeUVWx16_MSA(const uint8* src, >+void TransposeUVWx16_MSA(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width) { > int x; >- const uint8* s; >+ const uint8_t* s; > v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3, vec0, vec1, vec2, vec3; > v16u8 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; > v16u8 res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_neon.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_neon.cc >index d9bbc78cdab6d5535534825eb9e7268b24d74589..fdc0dd476c6d2933d8df0f251135dc0880eacfab 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_neon.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_neon.cc >@@ -21,15 +21,15 @@ extern "C" { > #if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__) && \ > !defined(__aarch64__) > >-static uvec8 kVTbl4x4Transpose = {0, 4, 8, 12, 1, 5, 9, 13, >- 2, 6, 10, 14, 3, 7, 11, 15}; >+static const uvec8 kVTbl4x4Transpose = {0, 4, 8, 12, 1, 5, 9, 13, >+ 2, 6, 10, 14, 3, 7, 11, 15}; > >-void TransposeWx8_NEON(const uint8* src, >+void TransposeWx8_NEON(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width) { >- const uint8* src_temp; >+ const uint8_t* src_temp; > asm volatile( > // loops are on blocks of 8. loop will stop when > // counter gets to or below 0. starting the counter >@@ -189,17 +189,17 @@ void TransposeWx8_NEON(const uint8* src, > : "memory", "cc", "q0", "q1", "q2", "q3"); > } > >-static uvec8 kVTbl4x4TransposeDi = {0, 8, 1, 9, 2, 10, 3, 11, >- 4, 12, 5, 13, 6, 14, 7, 15}; >+static const uvec8 kVTbl4x4TransposeDi = {0, 8, 1, 9, 2, 10, 3, 11, >+ 4, 12, 5, 13, 6, 14, 7, 15}; > >-void TransposeUVWx8_NEON(const uint8* src, >+void TransposeUVWx8_NEON(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width) { >- const uint8* src_temp; >+ const uint8_t* src_temp; > asm volatile( > // loops are on blocks of 8. loop will stop when > // counter gets to or below 0. starting the counter >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_neon64.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_neon64.cc >index 59db7f9f3da9af88460ade2f70f47a989ff628ec..f469baacf689b027c429da913d59b8a9f9a97ee3 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_neon64.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_neon64.cc >@@ -21,15 +21,15 @@ extern "C" { > // This module is for GCC Neon armv8 64 bit. > #if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) > >-static uvec8 kVTbl4x4Transpose = {0, 4, 8, 12, 1, 5, 9, 13, >- 2, 6, 10, 14, 3, 7, 11, 15}; >+static const uvec8 kVTbl4x4Transpose = {0, 4, 8, 12, 1, 5, 9, 13, >+ 2, 6, 10, 14, 3, 7, 11, 15}; > >-void TransposeWx8_NEON(const uint8* src, >+void TransposeWx8_NEON(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width) { >- const uint8* src_temp; >+ const uint8_t* src_temp; > asm volatile( > // loops are on blocks of 8. loop will stop when > // counter gets to or below 0. starting the counter >@@ -196,18 +196,18 @@ void TransposeWx8_NEON(const uint8* src, > "v17", "v18", "v19", "v20", "v21", "v22", "v23"); > } > >-static uint8 kVTbl4x4TransposeDi[32] = { >+static const uint8_t kVTbl4x4TransposeDi[32] = { > 0, 16, 32, 48, 2, 18, 34, 50, 4, 20, 36, 52, 6, 22, 38, 54, > 1, 17, 33, 49, 3, 19, 35, 51, 5, 21, 37, 53, 7, 23, 39, 55}; > >-void TransposeUVWx8_NEON(const uint8* src, >+void TransposeUVWx8_NEON(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int width) { >- const uint8* src_temp; >+ const uint8_t* src_temp; > asm volatile( > // loops are on blocks of 8. loop will stop when > // counter gets to or below 0. starting the counter >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_win.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_win.cc >index fb052f6521224fa15e7e07aa32bb925bd421c437..e887dd525c753a76f2257be9d2059edb115cee1f 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_win.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/rotate_win.cc >@@ -19,9 +19,9 @@ extern "C" { > // This module is for 32 bit Visual C x86 and clangcl > #if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) > >-__declspec(naked) void TransposeWx8_SSSE3(const uint8* src, >+__declspec(naked) void TransposeWx8_SSSE3(const uint8_t* src, > int src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int width) { > __asm { >@@ -112,11 +112,11 @@ __declspec(naked) void TransposeWx8_SSSE3(const uint8* src, > } > } > >-__declspec(naked) void TransposeUVWx8_SSE2(const uint8* src, >+__declspec(naked) void TransposeUVWx8_SSE2(const uint8_t* src, > int src_stride, >- uint8* dst_a, >+ uint8_t* dst_a, > int dst_stride_a, >- uint8* dst_b, >+ uint8_t* dst_b, > int dst_stride_b, > int w) { > __asm { >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_any.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_any.cc >index 8b31ac9fccc07b1397e125b743ae3ddb3c141542..cc5914dd29d0d0106177e583598b87053f6dc721 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_any.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_any.cc >@@ -31,25 +31,25 @@ extern "C" { > #define SS(width, shift) (((width) + (1 << (shift)) - 1) >> (shift)) > > // Any 4 planes to 1 with yuvconstants >-#define ANY41C(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, BPP, MASK) \ >- void NAMEANY(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, \ >- const uint8* a_buf, uint8* dst_ptr, \ >- const struct YuvConstants* yuvconstants, int width) { \ >- SIMD_ALIGNED(uint8 temp[64 * 5]); \ >- memset(temp, 0, 64 * 4); /* for msan */ \ >- int r = width & MASK; \ >- int n = width & ~MASK; \ >- if (n > 0) { \ >- ANY_SIMD(y_buf, u_buf, v_buf, a_buf, dst_ptr, yuvconstants, n); \ >- } \ >- memcpy(temp, y_buf + n, r); \ >- memcpy(temp + 64, u_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ >- memcpy(temp + 128, v_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ >- memcpy(temp + 192, a_buf + n, r); \ >- ANY_SIMD(temp, temp + 64, temp + 128, temp + 192, temp + 256, \ >- yuvconstants, MASK + 1); \ >- memcpy(dst_ptr + (n >> DUVSHIFT) * BPP, temp + 256, \ >- SS(r, DUVSHIFT) * BPP); \ >+#define ANY41C(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, BPP, MASK) \ >+ void NAMEANY(const uint8_t* y_buf, const uint8_t* u_buf, \ >+ const uint8_t* v_buf, const uint8_t* a_buf, uint8_t* dst_ptr, \ >+ const struct YuvConstants* yuvconstants, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[64 * 5]); \ >+ memset(temp, 0, 64 * 4); /* for msan */ \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(y_buf, u_buf, v_buf, a_buf, dst_ptr, yuvconstants, n); \ >+ } \ >+ memcpy(temp, y_buf + n, r); \ >+ memcpy(temp + 64, u_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ >+ memcpy(temp + 128, v_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ >+ memcpy(temp + 192, a_buf + n, r); \ >+ ANY_SIMD(temp, temp + 64, temp + 128, temp + 192, temp + 256, \ >+ yuvconstants, MASK + 1); \ >+ memcpy(dst_ptr + (n >> DUVSHIFT) * BPP, temp + 256, \ >+ SS(r, DUVSHIFT) * BPP); \ > } > > #ifdef HAS_I422ALPHATOARGBROW_SSSE3 >@@ -67,22 +67,22 @@ ANY41C(I422AlphaToARGBRow_Any_MSA, I422AlphaToARGBRow_MSA, 1, 0, 4, 7) > #undef ANY41C > > // Any 3 planes to 1. >-#define ANY31(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, BPP, MASK) \ >- void NAMEANY(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, \ >- uint8* dst_ptr, int width) { \ >- SIMD_ALIGNED(uint8 temp[64 * 4]); \ >- memset(temp, 0, 64 * 3); /* for YUY2 and msan */ \ >- int r = width & MASK; \ >- int n = width & ~MASK; \ >- if (n > 0) { \ >- ANY_SIMD(y_buf, u_buf, v_buf, dst_ptr, n); \ >- } \ >- memcpy(temp, y_buf + n, r); \ >- memcpy(temp + 64, u_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ >- memcpy(temp + 128, v_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ >- ANY_SIMD(temp, temp + 64, temp + 128, temp + 192, MASK + 1); \ >- memcpy(dst_ptr + (n >> DUVSHIFT) * BPP, temp + 192, \ >- SS(r, DUVSHIFT) * BPP); \ >+#define ANY31(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, BPP, MASK) \ >+ void NAMEANY(const uint8_t* y_buf, const uint8_t* u_buf, \ >+ const uint8_t* v_buf, uint8_t* dst_ptr, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[64 * 4]); \ >+ memset(temp, 0, 64 * 3); /* for YUY2 and msan */ \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(y_buf, u_buf, v_buf, dst_ptr, n); \ >+ } \ >+ memcpy(temp, y_buf + n, r); \ >+ memcpy(temp + 64, u_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ >+ memcpy(temp + 128, v_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ >+ ANY_SIMD(temp, temp + 64, temp + 128, temp + 192, MASK + 1); \ >+ memcpy(dst_ptr + (n >> DUVSHIFT) * BPP, temp + 192, \ >+ SS(r, DUVSHIFT) * BPP); \ > } > > // Merge functions. >@@ -96,6 +96,10 @@ ANY31(MergeRGBRow_Any_NEON, MergeRGBRow_NEON, 0, 0, 3, 15) > ANY31(I422ToYUY2Row_Any_SSE2, I422ToYUY2Row_SSE2, 1, 1, 4, 15) > ANY31(I422ToUYVYRow_Any_SSE2, I422ToUYVYRow_SSE2, 1, 1, 4, 15) > #endif >+#ifdef HAS_I422TOYUY2ROW_AVX2 >+ANY31(I422ToYUY2Row_Any_AVX2, I422ToYUY2Row_AVX2, 1, 1, 4, 31) >+ANY31(I422ToUYVYRow_Any_AVX2, I422ToUYVYRow_AVX2, 1, 1, 4, 31) >+#endif > #ifdef HAS_I422TOYUY2ROW_NEON > ANY31(I422ToYUY2Row_Any_NEON, I422ToYUY2Row_NEON, 1, 1, 4, 15) > #endif >@@ -120,10 +124,10 @@ ANY31(BlendPlaneRow_Any_SSSE3, BlendPlaneRow_SSSE3, 0, 0, 1, 7) > // on arm that subsamples 444 to 422 internally. > // Any 3 planes to 1 with yuvconstants > #define ANY31C(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, BPP, MASK) \ >- void NAMEANY(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, \ >- uint8* dst_ptr, const struct YuvConstants* yuvconstants, \ >- int width) { \ >- SIMD_ALIGNED(uint8 temp[64 * 4]); \ >+ void NAMEANY(const uint8_t* y_buf, const uint8_t* u_buf, \ >+ const uint8_t* v_buf, uint8_t* dst_ptr, \ >+ const struct YuvConstants* yuvconstants, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[64 * 4]); \ > memset(temp, 0, 64 * 3); /* for YUY2 and msan */ \ > int r = width & MASK; \ > int n = width & ~MASK; \ >@@ -145,6 +149,12 @@ ANY31(BlendPlaneRow_Any_SSSE3, BlendPlaneRow_SSSE3, 0, 0, 1, 7) > #ifdef HAS_I422TOARGBROW_SSSE3 > ANY31C(I422ToARGBRow_Any_SSSE3, I422ToARGBRow_SSSE3, 1, 0, 4, 7) > #endif >+#ifdef HAS_I422TOAR30ROW_SSSE3 >+ANY31C(I422ToAR30Row_Any_SSSE3, I422ToAR30Row_SSSE3, 1, 0, 4, 7) >+#endif >+#ifdef HAS_I422TOAR30ROW_AVX2 >+ANY31C(I422ToAR30Row_Any_AVX2, I422ToAR30Row_AVX2, 1, 0, 4, 15) >+#endif > #ifdef HAS_I444TOARGBROW_SSSE3 > ANY31C(I444ToARGBRow_Any_SSSE3, I444ToARGBRow_SSSE3, 0, 0, 4, 7) > ANY31C(I422ToRGBARow_Any_SSSE3, I422ToRGBARow_SSSE3, 1, 0, 4, 7) >@@ -183,12 +193,6 @@ ANY31C(I422ToARGB4444Row_Any_NEON, I422ToARGB4444Row_NEON, 1, 0, 2, 7) > ANY31C(I422ToARGB1555Row_Any_NEON, I422ToARGB1555Row_NEON, 1, 0, 2, 7) > ANY31C(I422ToRGB565Row_Any_NEON, I422ToRGB565Row_NEON, 1, 0, 2, 7) > #endif >-#ifdef HAS_I422TOARGBROW_DSPR2 >-ANY31C(I444ToARGBRow_Any_DSPR2, I444ToARGBRow_DSPR2, 0, 0, 4, 7) >-ANY31C(I422ToARGBRow_Any_DSPR2, I422ToARGBRow_DSPR2, 1, 0, 4, 7) >-ANY31C(I422ToARGB4444Row_Any_DSPR2, I422ToARGB4444Row_DSPR2, 1, 0, 2, 7) >-ANY31C(I422ToARGB1555Row_Any_DSPR2, I422ToARGB1555Row_DSPR2, 1, 0, 2, 7) >-#endif > #ifdef HAS_I422TOARGBROW_MSA > ANY31C(I444ToARGBRow_Any_MSA, I444ToARGBRow_MSA, 0, 0, 4, 7) > ANY31C(I422ToARGBRow_Any_MSA, I422ToARGBRow_MSA, 1, 0, 4, 7) >@@ -200,22 +204,57 @@ ANY31C(I422ToRGB565Row_Any_MSA, I422ToRGB565Row_MSA, 1, 0, 2, 7) > #endif > #undef ANY31C > >+// Any 3 planes of 16 bit to 1 with yuvconstants >+// TODO(fbarchard): consider sharing this code with ANY31C >+#define ANY31CT(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, T, SBPP, BPP, MASK) \ >+ void NAMEANY(const T* y_buf, const T* u_buf, const T* v_buf, \ >+ uint8_t* dst_ptr, const struct YuvConstants* yuvconstants, \ >+ int width) { \ >+ SIMD_ALIGNED(T temp[16 * 3]); \ >+ SIMD_ALIGNED(uint8_t out[64]); \ >+ memset(temp, 0, 16 * 3 * SBPP); /* for YUY2 and msan */ \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(y_buf, u_buf, v_buf, dst_ptr, yuvconstants, n); \ >+ } \ >+ memcpy(temp, y_buf + n, r * SBPP); \ >+ memcpy(temp + 16, u_buf + (n >> UVSHIFT), SS(r, UVSHIFT) * SBPP); \ >+ memcpy(temp + 32, v_buf + (n >> UVSHIFT), SS(r, UVSHIFT) * SBPP); \ >+ ANY_SIMD(temp, temp + 16, temp + 32, out, yuvconstants, MASK + 1); \ >+ memcpy(dst_ptr + (n >> DUVSHIFT) * BPP, out, SS(r, DUVSHIFT) * BPP); \ >+ } >+ >+#ifdef HAS_I210TOAR30ROW_SSSE3 >+ANY31CT(I210ToAR30Row_Any_SSSE3, I210ToAR30Row_SSSE3, 1, 0, uint16_t, 2, 4, 7) >+#endif >+#ifdef HAS_I210TOARGBROW_SSSE3 >+ANY31CT(I210ToARGBRow_Any_SSSE3, I210ToARGBRow_SSSE3, 1, 0, uint16_t, 2, 4, 7) >+#endif >+#ifdef HAS_I210TOARGBROW_AVX2 >+ANY31CT(I210ToARGBRow_Any_AVX2, I210ToARGBRow_AVX2, 1, 0, uint16_t, 2, 4, 15) >+#endif >+#ifdef HAS_I210TOAR30ROW_AVX2 >+ANY31CT(I210ToAR30Row_Any_AVX2, I210ToAR30Row_AVX2, 1, 0, uint16_t, 2, 4, 15) >+#endif >+#undef ANY31CT >+ > // Any 2 planes to 1. >-#define ANY21(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, SBPP2, BPP, MASK) \ >- void NAMEANY(const uint8* y_buf, const uint8* uv_buf, uint8* dst_ptr, \ >- int width) { \ >- SIMD_ALIGNED(uint8 temp[64 * 3]); \ >- memset(temp, 0, 64 * 2); /* for msan */ \ >- int r = width & MASK; \ >- int n = width & ~MASK; \ >- if (n > 0) { \ >- ANY_SIMD(y_buf, uv_buf, dst_ptr, n); \ >- } \ >- memcpy(temp, y_buf + n * SBPP, r * SBPP); \ >- memcpy(temp + 64, uv_buf + (n >> UVSHIFT) * SBPP2, \ >- SS(r, UVSHIFT) * SBPP2); \ >- ANY_SIMD(temp, temp + 64, temp + 128, MASK + 1); \ >- memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \ >+#define ANY21(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, SBPP2, BPP, MASK) \ >+ void NAMEANY(const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* dst_ptr, \ >+ int width) { \ >+ SIMD_ALIGNED(uint8_t temp[64 * 3]); \ >+ memset(temp, 0, 64 * 2); /* for msan */ \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(y_buf, uv_buf, dst_ptr, n); \ >+ } \ >+ memcpy(temp, y_buf + n * SBPP, r * SBPP); \ >+ memcpy(temp + 64, uv_buf + (n >> UVSHIFT) * SBPP2, \ >+ SS(r, UVSHIFT) * SBPP2); \ >+ ANY_SIMD(temp, temp + 64, temp + 128, MASK + 1); \ >+ memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \ > } > > // Merge functions. >@@ -299,21 +338,21 @@ ANY21(SobelXYRow_Any_MSA, SobelXYRow_MSA, 0, 1, 1, 4, 15) > #undef ANY21 > > // Any 2 planes to 1 with yuvconstants >-#define ANY21C(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, SBPP2, BPP, MASK) \ >- void NAMEANY(const uint8* y_buf, const uint8* uv_buf, uint8* dst_ptr, \ >- const struct YuvConstants* yuvconstants, int width) { \ >- SIMD_ALIGNED(uint8 temp[64 * 3]); \ >- memset(temp, 0, 64 * 2); /* for msan */ \ >- int r = width & MASK; \ >- int n = width & ~MASK; \ >- if (n > 0) { \ >- ANY_SIMD(y_buf, uv_buf, dst_ptr, yuvconstants, n); \ >- } \ >- memcpy(temp, y_buf + n * SBPP, r * SBPP); \ >- memcpy(temp + 64, uv_buf + (n >> UVSHIFT) * SBPP2, \ >- SS(r, UVSHIFT) * SBPP2); \ >- ANY_SIMD(temp, temp + 64, temp + 128, yuvconstants, MASK + 1); \ >- memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \ >+#define ANY21C(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, SBPP2, BPP, MASK) \ >+ void NAMEANY(const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* dst_ptr, \ >+ const struct YuvConstants* yuvconstants, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[64 * 3]); \ >+ memset(temp, 0, 64 * 2); /* for msan */ \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(y_buf, uv_buf, dst_ptr, yuvconstants, n); \ >+ } \ >+ memcpy(temp, y_buf + n * SBPP, r * SBPP); \ >+ memcpy(temp + 64, uv_buf + (n >> UVSHIFT) * SBPP2, \ >+ SS(r, UVSHIFT) * SBPP2); \ >+ ANY_SIMD(temp, temp + 64, temp + 128, yuvconstants, MASK + 1); \ >+ memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \ > } > > // Biplanar to RGB. >@@ -326,9 +365,6 @@ ANY21C(NV12ToARGBRow_Any_AVX2, NV12ToARGBRow_AVX2, 1, 1, 2, 4, 15) > #ifdef HAS_NV12TOARGBROW_NEON > ANY21C(NV12ToARGBRow_Any_NEON, NV12ToARGBRow_NEON, 1, 1, 2, 4, 7) > #endif >-#ifdef HAS_NV12TOARGBROW_DSPR2 >-ANY21C(NV12ToARGBRow_Any_DSPR2, NV12ToARGBRow_DSPR2, 1, 1, 2, 4, 7) >-#endif > #ifdef HAS_NV12TOARGBROW_MSA > ANY21C(NV12ToARGBRow_Any_MSA, NV12ToARGBRow_MSA, 1, 1, 2, 4, 7) > #endif >@@ -344,6 +380,12 @@ ANY21C(NV21ToARGBRow_Any_NEON, NV21ToARGBRow_NEON, 1, 1, 2, 4, 7) > #ifdef HAS_NV21TOARGBROW_MSA > ANY21C(NV21ToARGBRow_Any_MSA, NV21ToARGBRow_MSA, 1, 1, 2, 4, 7) > #endif >+#ifdef HAS_NV12TORGB24ROW_NEON >+ANY21C(NV12ToRGB24Row_Any_NEON, NV12ToRGB24Row_NEON, 1, 1, 2, 3, 7) >+#endif >+#ifdef HAS_NV21TORGB24ROW_NEON >+ANY21C(NV21ToRGB24Row_Any_NEON, NV21ToRGB24Row_NEON, 1, 1, 2, 3, 7) >+#endif > #ifdef HAS_NV12TORGB565ROW_SSSE3 > ANY21C(NV12ToRGB565Row_Any_SSSE3, NV12ToRGB565Row_SSSE3, 1, 1, 2, 2, 7) > #endif >@@ -360,8 +402,8 @@ ANY21C(NV12ToRGB565Row_Any_MSA, NV12ToRGB565Row_MSA, 1, 1, 2, 2, 7) > > // Any 1 to 1. > #define ANY11(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \ >- void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, int width) { \ >- SIMD_ALIGNED(uint8 temp[128 * 2]); \ >+ void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[128 * 2]); \ > memset(temp, 0, 128); /* for YUY2 and msan */ \ > int r = width & MASK; \ > int n = width & ~MASK; \ >@@ -396,6 +438,18 @@ ANY11(ARGBToRGB565Row_Any_AVX2, ARGBToRGB565Row_AVX2, 0, 4, 2, 7) > ANY11(ARGBToARGB1555Row_Any_AVX2, ARGBToARGB1555Row_AVX2, 0, 4, 2, 7) > ANY11(ARGBToARGB4444Row_Any_AVX2, ARGBToARGB4444Row_AVX2, 0, 4, 2, 7) > #endif >+#if defined(HAS_ABGRTOAR30ROW_SSSE3) >+ANY11(ABGRToAR30Row_Any_SSSE3, ABGRToAR30Row_SSSE3, 0, 4, 4, 3) >+#endif >+#if defined(HAS_ARGBTOAR30ROW_SSSE3) >+ANY11(ARGBToAR30Row_Any_SSSE3, ARGBToAR30Row_SSSE3, 0, 4, 4, 3) >+#endif >+#if defined(HAS_ABGRTOAR30ROW_AVX2) >+ANY11(ABGRToAR30Row_Any_AVX2, ABGRToAR30Row_AVX2, 0, 4, 4, 7) >+#endif >+#if defined(HAS_ARGBTOAR30ROW_AVX2) >+ANY11(ARGBToAR30Row_Any_AVX2, ARGBToAR30Row_AVX2, 0, 4, 4, 7) >+#endif > #if defined(HAS_J400TOARGBROW_SSE2) > ANY11(J400ToARGBRow_Any_SSE2, J400ToARGBRow_SSE2, 0, 1, 4, 7) > #endif >@@ -572,33 +626,6 @@ ANY11(ARGB1555ToARGBRow_Any_MSA, ARGB1555ToARGBRow_MSA, 0, 2, 4, 15) > #ifdef HAS_ARGB4444TOARGBROW_NEON > ANY11(ARGB4444ToARGBRow_Any_NEON, ARGB4444ToARGBRow_NEON, 0, 2, 4, 7) > #endif >-#ifdef HAS_RGB24TOARGBROW_DSPR2 >-ANY11(RGB24ToARGBRow_Any_DSPR2, RGB24ToARGBRow_DSPR2, 0, 3, 4, 7) >-#endif >-#ifdef HAS_RAWTOARGBROW_DSPR2 >-ANY11(RAWToARGBRow_Any_DSPR2, RAWToARGBRow_DSPR2, 0, 3, 4, 7) >-#endif >-#ifdef HAS_RGB565TOARGBROW_DSPR2 >-ANY11(RGB565ToARGBRow_Any_DSPR2, RGB565ToARGBRow_DSPR2, 0, 2, 4, 7) >-#endif >-#ifdef HAS_ARGB1555TOARGBROW_DSPR2 >-ANY11(ARGB1555ToARGBRow_Any_DSPR2, ARGB1555ToARGBRow_DSPR2, 0, 2, 4, 7) >-#endif >-#ifdef HAS_ARGB4444TOARGBROW_DSPR2 >-ANY11(ARGB4444ToARGBRow_Any_DSPR2, ARGB4444ToARGBRow_DSPR2, 0, 2, 4, 7) >-#endif >-#ifdef HAS_BGRATOYROW_DSPR2 >-ANY11(BGRAToYRow_Any_DSPR2, BGRAToYRow_DSPR2, 0, 4, 1, 7) >-#endif >-#ifdef HAS_ARGBTOYROW_DSPR2 >-ANY11(ARGBToYRow_Any_DSPR2, ARGBToYRow_DSPR2, 0, 4, 1, 7) >-#endif >-#ifdef HAS_ABGRTOYROW_DSPR2 >-ANY11(ABGRToYRow_Any_DSPR2, ABGRToYRow_DSPR2, 0, 4, 1, 7) >-#endif >-#ifdef HAS_RGBATOYROW_DSPR2 >-ANY11(RGBAToYRow_Any_DSPR2, RGBAToYRow_DSPR2, 0, 4, 1, 7) >-#endif > #ifdef HAS_ARGB4444TOARGBROW_MSA > ANY11(ARGB4444ToARGBRow_Any_MSA, ARGB4444ToARGBRow_MSA, 0, 2, 4, 15) > #endif >@@ -636,8 +663,8 @@ ANY11(ARGBExtractAlphaRow_Any_MSA, ARGBExtractAlphaRow_MSA, 0, 4, 1, 15) > > // Any 1 to 1 blended. Destination is read, modify, write. > #define ANY11B(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \ >- void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, int width) { \ >- SIMD_ALIGNED(uint8 temp[64 * 2]); \ >+ void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[64 * 2]); \ > memset(temp, 0, 64 * 2); /* for msan */ \ > int r = width & MASK; \ > int n = width & ~MASK; \ >@@ -665,24 +692,24 @@ ANY11B(ARGBCopyYToAlphaRow_Any_SSE2, ARGBCopyYToAlphaRow_SSE2, 0, 1, 4, 7) > #undef ANY11B > > // Any 1 to 1 with parameter. >-#define ANY11P(NAMEANY, ANY_SIMD, T, SBPP, BPP, MASK) \ >- void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, T param, int width) { \ >- SIMD_ALIGNED(uint8 temp[64 * 2]); \ >- memset(temp, 0, 64); /* for msan */ \ >- int r = width & MASK; \ >- int n = width & ~MASK; \ >- if (n > 0) { \ >- ANY_SIMD(src_ptr, dst_ptr, param, n); \ >- } \ >- memcpy(temp, src_ptr + n * SBPP, r * SBPP); \ >- ANY_SIMD(temp, temp + 64, param, MASK + 1); \ >- memcpy(dst_ptr + n * BPP, temp + 64, r * BPP); \ >+#define ANY11P(NAMEANY, ANY_SIMD, T, SBPP, BPP, MASK) \ >+ void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, T param, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[64 * 2]); \ >+ memset(temp, 0, 64); /* for msan */ \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(src_ptr, dst_ptr, param, n); \ >+ } \ >+ memcpy(temp, src_ptr + n * SBPP, r * SBPP); \ >+ ANY_SIMD(temp, temp + 64, param, MASK + 1); \ >+ memcpy(dst_ptr + n * BPP, temp + 64, r * BPP); \ > } > > #if defined(HAS_ARGBTORGB565DITHERROW_SSE2) > ANY11P(ARGBToRGB565DitherRow_Any_SSE2, > ARGBToRGB565DitherRow_SSE2, >- const uint32, >+ const uint32_t, > 4, > 2, > 3) >@@ -690,7 +717,7 @@ ANY11P(ARGBToRGB565DitherRow_Any_SSE2, > #if defined(HAS_ARGBTORGB565DITHERROW_AVX2) > ANY11P(ARGBToRGB565DitherRow_Any_AVX2, > ARGBToRGB565DitherRow_AVX2, >- const uint32, >+ const uint32_t, > 4, > 2, > 7) >@@ -698,7 +725,7 @@ ANY11P(ARGBToRGB565DitherRow_Any_AVX2, > #if defined(HAS_ARGBTORGB565DITHERROW_NEON) > ANY11P(ARGBToRGB565DitherRow_Any_NEON, > ARGBToRGB565DitherRow_NEON, >- const uint32, >+ const uint32_t, > 4, > 2, > 7) >@@ -706,67 +733,134 @@ ANY11P(ARGBToRGB565DitherRow_Any_NEON, > #if defined(HAS_ARGBTORGB565DITHERROW_MSA) > ANY11P(ARGBToRGB565DitherRow_Any_MSA, > ARGBToRGB565DitherRow_MSA, >- const uint32, >+ const uint32_t, > 4, > 2, > 7) > #endif >-#ifdef HAS_ARGBSHUFFLEROW_SSE2 >-ANY11P(ARGBShuffleRow_Any_SSE2, ARGBShuffleRow_SSE2, const uint8*, 4, 4, 3) >-#endif > #ifdef HAS_ARGBSHUFFLEROW_SSSE3 >-ANY11P(ARGBShuffleRow_Any_SSSE3, ARGBShuffleRow_SSSE3, const uint8*, 4, 4, 7) >+ANY11P(ARGBShuffleRow_Any_SSSE3, ARGBShuffleRow_SSSE3, const uint8_t*, 4, 4, 7) > #endif > #ifdef HAS_ARGBSHUFFLEROW_AVX2 >-ANY11P(ARGBShuffleRow_Any_AVX2, ARGBShuffleRow_AVX2, const uint8*, 4, 4, 15) >+ANY11P(ARGBShuffleRow_Any_AVX2, ARGBShuffleRow_AVX2, const uint8_t*, 4, 4, 15) > #endif > #ifdef HAS_ARGBSHUFFLEROW_NEON >-ANY11P(ARGBShuffleRow_Any_NEON, ARGBShuffleRow_NEON, const uint8*, 4, 4, 3) >+ANY11P(ARGBShuffleRow_Any_NEON, ARGBShuffleRow_NEON, const uint8_t*, 4, 4, 3) > #endif > #ifdef HAS_ARGBSHUFFLEROW_MSA >-ANY11P(ARGBShuffleRow_Any_MSA, ARGBShuffleRow_MSA, const uint8*, 4, 4, 7) >+ANY11P(ARGBShuffleRow_Any_MSA, ARGBShuffleRow_MSA, const uint8_t*, 4, 4, 7) > #endif > #undef ANY11P > > // Any 1 to 1 with parameter and shorts. BPP measures in shorts. >-#define ANY11P16(NAMEANY, ANY_SIMD, T, SBPP, BPP, MASK) \ >- void NAMEANY(const uint16* src_ptr, uint16* dst_ptr, T param, int width) { \ >- SIMD_ALIGNED(uint16 temp[16 * 2]); \ >- memset(temp, 0, 32); /* for msan */ \ >+#define ANY11C(NAMEANY, ANY_SIMD, SBPP, BPP, STYPE, DTYPE, MASK) \ >+ void NAMEANY(const STYPE* src_ptr, DTYPE* dst_ptr, int scale, int width) { \ >+ SIMD_ALIGNED(STYPE temp[32]); \ >+ SIMD_ALIGNED(DTYPE out[32]); \ >+ memset(temp, 0, 32 * SBPP); /* for msan */ \ > int r = width & MASK; \ > int n = width & ~MASK; \ > if (n > 0) { \ >- ANY_SIMD(src_ptr, dst_ptr, param, n); \ >+ ANY_SIMD(src_ptr, dst_ptr, scale, n); \ > } \ > memcpy(temp, src_ptr + n, r * SBPP); \ >- ANY_SIMD(temp, temp + 16, param, MASK + 1); \ >- memcpy(dst_ptr + n, temp + 16, r * BPP); \ >+ ANY_SIMD(temp, out, scale, MASK + 1); \ >+ memcpy(dst_ptr + n, out, r * BPP); \ >+ } >+ >+#ifdef HAS_CONVERT16TO8ROW_SSSE3 >+ANY11C(Convert16To8Row_Any_SSSE3, >+ Convert16To8Row_SSSE3, >+ 2, >+ 1, >+ uint16_t, >+ uint8_t, >+ 15) >+#endif >+#ifdef HAS_CONVERT16TO8ROW_AVX2 >+ANY11C(Convert16To8Row_Any_AVX2, >+ Convert16To8Row_AVX2, >+ 2, >+ 1, >+ uint16_t, >+ uint8_t, >+ 31) >+#endif >+#ifdef HAS_CONVERT8TO16ROW_SSE2 >+ANY11C(Convert8To16Row_Any_SSE2, >+ Convert8To16Row_SSE2, >+ 1, >+ 2, >+ uint8_t, >+ uint16_t, >+ 15) >+#endif >+#ifdef HAS_CONVERT8TO16ROW_AVX2 >+ANY11C(Convert8To16Row_Any_AVX2, >+ Convert8To16Row_AVX2, >+ 1, >+ 2, >+ uint8_t, >+ uint16_t, >+ 31) >+#endif >+#undef ANY11C >+ >+// Any 1 to 1 with parameter and shorts to byte. BPP measures in shorts. >+#define ANY11P16(NAMEANY, ANY_SIMD, ST, T, SBPP, BPP, MASK) \ >+ void NAMEANY(const ST* src_ptr, T* dst_ptr, float param, int width) { \ >+ SIMD_ALIGNED(ST temp[32]); \ >+ SIMD_ALIGNED(T out[32]); \ >+ memset(temp, 0, SBPP * 32); /* for msan */ \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(src_ptr, dst_ptr, param, n); \ >+ } \ >+ memcpy(temp, src_ptr + n, r * SBPP); \ >+ ANY_SIMD(temp, out, param, MASK + 1); \ >+ memcpy(dst_ptr + n, out, r * BPP); \ > } > > #ifdef HAS_HALFFLOATROW_SSE2 >-ANY11P16(HalfFloatRow_Any_SSE2, HalfFloatRow_SSE2, float, 2, 2, 7) >+ANY11P16(HalfFloatRow_Any_SSE2, HalfFloatRow_SSE2, uint16_t, uint16_t, 2, 2, 7) > #endif > #ifdef HAS_HALFFLOATROW_AVX2 >-ANY11P16(HalfFloatRow_Any_AVX2, HalfFloatRow_AVX2, float, 2, 2, 15) >+ANY11P16(HalfFloatRow_Any_AVX2, HalfFloatRow_AVX2, uint16_t, uint16_t, 2, 2, 15) > #endif > #ifdef HAS_HALFFLOATROW_F16C >-ANY11P16(HalfFloatRow_Any_F16C, HalfFloatRow_F16C, float, 2, 2, 15) >-ANY11P16(HalfFloat1Row_Any_F16C, HalfFloat1Row_F16C, float, 2, 2, 15) >+ANY11P16(HalfFloatRow_Any_F16C, HalfFloatRow_F16C, uint16_t, uint16_t, 2, 2, 15) >+ANY11P16(HalfFloat1Row_Any_F16C, >+ HalfFloat1Row_F16C, >+ uint16_t, >+ uint16_t, >+ 2, >+ 2, >+ 15) > #endif > #ifdef HAS_HALFFLOATROW_NEON >-ANY11P16(HalfFloatRow_Any_NEON, HalfFloatRow_NEON, float, 2, 2, 7) >-ANY11P16(HalfFloat1Row_Any_NEON, HalfFloat1Row_NEON, float, 2, 2, 7) >+ANY11P16(HalfFloatRow_Any_NEON, HalfFloatRow_NEON, uint16_t, uint16_t, 2, 2, 7) >+ANY11P16(HalfFloat1Row_Any_NEON, >+ HalfFloat1Row_NEON, >+ uint16_t, >+ uint16_t, >+ 2, >+ 2, >+ 7) > #endif > #ifdef HAS_HALFFLOATROW_MSA >-ANY11P16(HalfFloatRow_Any_MSA, HalfFloatRow_MSA, float, 2, 2, 31) >+ANY11P16(HalfFloatRow_Any_MSA, HalfFloatRow_MSA, uint16_t, uint16_t, 2, 2, 31) >+#endif >+#ifdef HAS_BYTETOFLOATROW_NEON >+ANY11P16(ByteToFloatRow_Any_NEON, ByteToFloatRow_NEON, uint8_t, float, 1, 3, 7) > #endif > #undef ANY11P16 > > // Any 1 to 1 with yuvconstants > #define ANY11C(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \ >- void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, \ >+ void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, \ > const struct YuvConstants* yuvconstants, int width) { \ >- SIMD_ALIGNED(uint8 temp[128 * 2]); \ >+ SIMD_ALIGNED(uint8_t temp[128 * 2]); \ > memset(temp, 0, 128); /* for YUY2 and msan */ \ > int r = width & MASK; \ > int n = width & ~MASK; \ >@@ -796,20 +890,20 @@ ANY11C(UYVYToARGBRow_Any_MSA, UYVYToARGBRow_MSA, 1, 4, 4, 7) > #undef ANY11C > > // Any 1 to 1 interpolate. Takes 2 rows of source via stride. >-#define ANY11T(NAMEANY, ANY_SIMD, SBPP, BPP, MASK) \ >- void NAMEANY(uint8* dst_ptr, const uint8* src_ptr, ptrdiff_t src_stride_ptr, \ >- int width, int source_y_fraction) { \ >- SIMD_ALIGNED(uint8 temp[64 * 3]); \ >- memset(temp, 0, 64 * 2); /* for msan */ \ >- int r = width & MASK; \ >- int n = width & ~MASK; \ >- if (n > 0) { \ >- ANY_SIMD(dst_ptr, src_ptr, src_stride_ptr, n, source_y_fraction); \ >- } \ >- memcpy(temp, src_ptr + n * SBPP, r * SBPP); \ >- memcpy(temp + 64, src_ptr + src_stride_ptr + n * SBPP, r * SBPP); \ >- ANY_SIMD(temp + 128, temp, 64, MASK + 1, source_y_fraction); \ >- memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \ >+#define ANY11T(NAMEANY, ANY_SIMD, SBPP, BPP, MASK) \ >+ void NAMEANY(uint8_t* dst_ptr, const uint8_t* src_ptr, \ >+ ptrdiff_t src_stride_ptr, int width, int source_y_fraction) { \ >+ SIMD_ALIGNED(uint8_t temp[64 * 3]); \ >+ memset(temp, 0, 64 * 2); /* for msan */ \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(dst_ptr, src_ptr, src_stride_ptr, n, source_y_fraction); \ >+ } \ >+ memcpy(temp, src_ptr + n * SBPP, r * SBPP); \ >+ memcpy(temp + 64, src_ptr + src_stride_ptr + n * SBPP, r * SBPP); \ >+ ANY_SIMD(temp + 128, temp, 64, MASK + 1, source_y_fraction); \ >+ memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \ > } > > #ifdef HAS_INTERPOLATEROW_AVX2 >@@ -821,9 +915,6 @@ ANY11T(InterpolateRow_Any_SSSE3, InterpolateRow_SSSE3, 1, 1, 15) > #ifdef HAS_INTERPOLATEROW_NEON > ANY11T(InterpolateRow_Any_NEON, InterpolateRow_NEON, 1, 1, 15) > #endif >-#ifdef HAS_INTERPOLATEROW_DSPR2 >-ANY11T(InterpolateRow_Any_DSPR2, InterpolateRow_DSPR2, 1, 1, 3) >-#endif > #ifdef HAS_INTERPOLATEROW_MSA > ANY11T(InterpolateRow_Any_MSA, InterpolateRow_MSA, 1, 1, 31) > #endif >@@ -831,8 +922,8 @@ ANY11T(InterpolateRow_Any_MSA, InterpolateRow_MSA, 1, 1, 31) > > // Any 1 to 1 mirror. > #define ANY11M(NAMEANY, ANY_SIMD, BPP, MASK) \ >- void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, int width) { \ >- SIMD_ALIGNED(uint8 temp[64 * 2]); \ >+ void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[64 * 2]); \ > memset(temp, 0, 64); /* for msan */ \ > int r = width & MASK; \ > int n = width & ~MASK; \ >@@ -871,46 +962,47 @@ ANY11M(ARGBMirrorRow_Any_MSA, ARGBMirrorRow_MSA, 4, 15) > #undef ANY11M > > // Any 1 plane. (memset) >-#define ANY1(NAMEANY, ANY_SIMD, T, BPP, MASK) \ >- void NAMEANY(uint8* dst_ptr, T v32, int width) { \ >- SIMD_ALIGNED(uint8 temp[64]); \ >- int r = width & MASK; \ >- int n = width & ~MASK; \ >- if (n > 0) { \ >- ANY_SIMD(dst_ptr, v32, n); \ >- } \ >- ANY_SIMD(temp, v32, MASK + 1); \ >- memcpy(dst_ptr + n * BPP, temp, r * BPP); \ >+#define ANY1(NAMEANY, ANY_SIMD, T, BPP, MASK) \ >+ void NAMEANY(uint8_t* dst_ptr, T v32, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[64]); \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(dst_ptr, v32, n); \ >+ } \ >+ ANY_SIMD(temp, v32, MASK + 1); \ >+ memcpy(dst_ptr + n * BPP, temp, r * BPP); \ > } > > #ifdef HAS_SETROW_X86 >-ANY1(SetRow_Any_X86, SetRow_X86, uint8, 1, 3) >+ANY1(SetRow_Any_X86, SetRow_X86, uint8_t, 1, 3) > #endif > #ifdef HAS_SETROW_NEON >-ANY1(SetRow_Any_NEON, SetRow_NEON, uint8, 1, 15) >+ANY1(SetRow_Any_NEON, SetRow_NEON, uint8_t, 1, 15) > #endif > #ifdef HAS_ARGBSETROW_NEON >-ANY1(ARGBSetRow_Any_NEON, ARGBSetRow_NEON, uint32, 4, 3) >+ANY1(ARGBSetRow_Any_NEON, ARGBSetRow_NEON, uint32_t, 4, 3) > #endif > #ifdef HAS_ARGBSETROW_MSA >-ANY1(ARGBSetRow_Any_MSA, ARGBSetRow_MSA, uint32, 4, 3) >+ANY1(ARGBSetRow_Any_MSA, ARGBSetRow_MSA, uint32_t, 4, 3) > #endif > #undef ANY1 > > // Any 1 to 2. Outputs UV planes. >-#define ANY12(NAMEANY, ANY_SIMD, UVSHIFT, BPP, DUVSHIFT, MASK) \ >- void NAMEANY(const uint8* src_ptr, uint8* dst_u, uint8* dst_v, int width) { \ >- SIMD_ALIGNED(uint8 temp[128 * 3]); \ >- memset(temp, 0, 128); /* for msan */ \ >- int r = width & MASK; \ >- int n = width & ~MASK; \ >- if (n > 0) { \ >- ANY_SIMD(src_ptr, dst_u, dst_v, n); \ >- } \ >- memcpy(temp, src_ptr + (n >> UVSHIFT) * BPP, SS(r, UVSHIFT) * BPP); \ >- ANY_SIMD(temp, temp + 128, temp + 256, MASK + 1); \ >- memcpy(dst_u + (n >> DUVSHIFT), temp + 128, SS(r, DUVSHIFT)); \ >- memcpy(dst_v + (n >> DUVSHIFT), temp + 256, SS(r, DUVSHIFT)); \ >+#define ANY12(NAMEANY, ANY_SIMD, UVSHIFT, BPP, DUVSHIFT, MASK) \ >+ void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_u, uint8_t* dst_v, \ >+ int width) { \ >+ SIMD_ALIGNED(uint8_t temp[128 * 3]); \ >+ memset(temp, 0, 128); /* for msan */ \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(src_ptr, dst_u, dst_v, n); \ >+ } \ >+ memcpy(temp, src_ptr + (n >> UVSHIFT) * BPP, SS(r, UVSHIFT) * BPP); \ >+ ANY_SIMD(temp, temp + 128, temp + 256, MASK + 1); \ >+ memcpy(dst_u + (n >> DUVSHIFT), temp + 128, SS(r, DUVSHIFT)); \ >+ memcpy(dst_v + (n >> DUVSHIFT), temp + 256, SS(r, DUVSHIFT)); \ > } > > #ifdef HAS_SPLITUVROW_SSE2 >@@ -922,9 +1014,6 @@ ANY12(SplitUVRow_Any_AVX2, SplitUVRow_AVX2, 0, 2, 0, 31) > #ifdef HAS_SPLITUVROW_NEON > ANY12(SplitUVRow_Any_NEON, SplitUVRow_NEON, 0, 2, 0, 15) > #endif >-#ifdef HAS_SPLITUVROW_DSPR2 >-ANY12(SplitUVRow_Any_DSPR2, SplitUVRow_DSPR2, 0, 2, 0, 15) >-#endif > #ifdef HAS_SPLITUVROW_MSA > ANY12(SplitUVRow_Any_MSA, SplitUVRow_MSA, 0, 2, 0, 31) > #endif >@@ -952,21 +1041,21 @@ ANY12(UYVYToUV422Row_Any_MSA, UYVYToUV422Row_MSA, 1, 4, 1, 31) > #undef ANY12 > > // Any 1 to 3. Outputs RGB planes. >-#define ANY13(NAMEANY, ANY_SIMD, BPP, MASK) \ >- void NAMEANY(const uint8* src_ptr, uint8* dst_r, uint8* dst_g, uint8* dst_b, \ >- int width) { \ >- SIMD_ALIGNED(uint8 temp[16 * 6]); \ >- memset(temp, 0, 16 * 3); /* for msan */ \ >- int r = width & MASK; \ >- int n = width & ~MASK; \ >- if (n > 0) { \ >- ANY_SIMD(src_ptr, dst_r, dst_g, dst_b, n); \ >- } \ >- memcpy(temp, src_ptr + n * BPP, r * BPP); \ >- ANY_SIMD(temp, temp + 16 * 3, temp + 16 * 4, temp + 16 * 5, MASK + 1); \ >- memcpy(dst_r + n, temp + 16 * 3, r); \ >- memcpy(dst_g + n, temp + 16 * 4, r); \ >- memcpy(dst_b + n, temp + 16 * 5, r); \ >+#define ANY13(NAMEANY, ANY_SIMD, BPP, MASK) \ >+ void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_r, uint8_t* dst_g, \ >+ uint8_t* dst_b, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[16 * 6]); \ >+ memset(temp, 0, 16 * 3); /* for msan */ \ >+ int r = width & MASK; \ >+ int n = width & ~MASK; \ >+ if (n > 0) { \ >+ ANY_SIMD(src_ptr, dst_r, dst_g, dst_b, n); \ >+ } \ >+ memcpy(temp, src_ptr + n * BPP, r * BPP); \ >+ ANY_SIMD(temp, temp + 16 * 3, temp + 16 * 4, temp + 16 * 5, MASK + 1); \ >+ memcpy(dst_r + n, temp + 16 * 3, r); \ >+ memcpy(dst_g + n, temp + 16 * 4, r); \ >+ memcpy(dst_b + n, temp + 16 * 5, r); \ > } > > #ifdef HAS_SPLITRGBROW_SSSE3 >@@ -979,9 +1068,9 @@ ANY13(SplitRGBRow_Any_NEON, SplitRGBRow_NEON, 3, 15) > // Any 1 to 2 with source stride (2 rows of source). Outputs UV planes. > // 128 byte row allows for 32 avx ARGB pixels. > #define ANY12S(NAMEANY, ANY_SIMD, UVSHIFT, BPP, MASK) \ >- void NAMEANY(const uint8* src_ptr, int src_stride_ptr, uint8* dst_u, \ >- uint8* dst_v, int width) { \ >- SIMD_ALIGNED(uint8 temp[128 * 4]); \ >+ void NAMEANY(const uint8_t* src_ptr, int src_stride_ptr, uint8_t* dst_u, \ >+ uint8_t* dst_v, int width) { \ >+ SIMD_ALIGNED(uint8_t temp[128 * 4]); \ > memset(temp, 0, 128 * 2); /* for msan */ \ > int r = width & MASK; \ > int n = width & ~MASK; \ >@@ -1086,18 +1175,6 @@ ANY12S(YUY2ToUVRow_Any_NEON, YUY2ToUVRow_NEON, 1, 4, 15) > #ifdef HAS_UYVYTOUVROW_NEON > ANY12S(UYVYToUVRow_Any_NEON, UYVYToUVRow_NEON, 1, 4, 15) > #endif >-#ifdef HAS_BGRATOUVROW_DSPR2 >-ANY12S(BGRAToUVRow_Any_DSPR2, BGRAToUVRow_DSPR2, 0, 4, 15) >-#endif >-#ifdef HAS_ABGRTOUVROW_DSPR2 >-ANY12S(ABGRToUVRow_Any_DSPR2, ABGRToUVRow_DSPR2, 0, 4, 15) >-#endif >-#ifdef HAS_RGBATOUVROW_DSPR2 >-ANY12S(RGBAToUVRow_Any_DSPR2, RGBAToUVRow_DSPR2, 0, 4, 15) >-#endif >-#ifdef HAS_ARGBTOUVROW_DSPR2 >-ANY12S(ARGBToUVRow_Any_DSPR2, ARGBToUVRow_DSPR2, 0, 4, 15) >-#endif > #ifdef HAS_YUY2TOUVROW_MSA > ANY12S(YUY2ToUVRow_Any_MSA, YUY2ToUVRow_MSA, 1, 4, 31) > #endif >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_common.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_common.cc >index 6ffc4febbf6537b86ba46a0b8f8e1ebbff691508..da97821f796440dd12beb6e05f4ff626842d2bd6 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_common.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_common.cc >@@ -10,6 +10,7 @@ > > #include "libyuv/row.h" > >+#include <stdio.h> > #include <string.h> // For memcpy and memset. > > #include "libyuv/basic_types.h" >@@ -23,59 +24,69 @@ extern "C" { > > #define USE_BRANCHLESS 1 > #if USE_BRANCHLESS >-static __inline int32 clamp0(int32 v) { >+static __inline int32_t clamp0(int32_t v) { > return ((-(v) >> 31) & (v)); > } > >-static __inline int32 clamp255(int32 v) { >+static __inline int32_t clamp255(int32_t v) { > return (((255 - (v)) >> 31) | (v)) & 255; > } > >-static __inline uint32 Clamp(int32 val) { >- int v = clamp0(val); >- return (uint32)(clamp255(v)); >+static __inline int32_t clamp1023(int32_t v) { >+ return (((1023 - (v)) >> 31) | (v)) & 1023; > } > >-static __inline uint32 Abs(int32 v) { >+static __inline uint32_t Abs(int32_t v) { > int m = v >> 31; > return (v + m) ^ m; > } > #else // USE_BRANCHLESS >-static __inline int32 clamp0(int32 v) { >+static __inline int32_t clamp0(int32_t v) { > return (v < 0) ? 0 : v; > } > >-static __inline int32 clamp255(int32 v) { >+static __inline int32_t clamp255(int32_t v) { > return (v > 255) ? 255 : v; > } > >-static __inline uint32 Clamp(int32 val) { >- int v = clamp0(val); >- return (uint32)(clamp255(v)); >+static __inline int32_t clamp1023(int32_t v) { >+ return (v > 1023) ? 1023 : v; > } > >-static __inline uint32 Abs(int32 v) { >+static __inline uint32_t Abs(int32_t v) { > return (v < 0) ? -v : v; > } > #endif // USE_BRANCHLESS >+static __inline uint32_t Clamp(int32_t val) { >+ int v = clamp0(val); >+ return (uint32_t)(clamp255(v)); >+} >+ >+static __inline uint32_t Clamp10(int32_t val) { >+ int v = clamp0(val); >+ return (uint32_t)(clamp1023(v)); >+} > >-#ifdef LIBYUV_LITTLE_ENDIAN >-#define WRITEWORD(p, v) *(uint32*)(p) = v >+// Little Endian >+#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ >+ defined(_M_IX86) || defined(__arm__) || defined(_M_ARM) || \ >+ (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) >+#define WRITEWORD(p, v) *(uint32_t*)(p) = v > #else >-static inline void WRITEWORD(uint8* p, uint32 v) { >- p[0] = (uint8)(v & 255); >- p[1] = (uint8)((v >> 8) & 255); >- p[2] = (uint8)((v >> 16) & 255); >- p[3] = (uint8)((v >> 24) & 255); >+static inline void WRITEWORD(uint8_t* p, uint32_t v) { >+ p[0] = (uint8_t)(v & 255); >+ p[1] = (uint8_t)((v >> 8) & 255); >+ p[2] = (uint8_t)((v >> 16) & 255); >+ p[3] = (uint8_t)((v >> 24) & 255); > } > #endif > >-void RGB24ToARGBRow_C(const uint8* src_rgb24, uint8* dst_argb, int width) { >+void RGB24ToARGBRow_C(const uint8_t* src_rgb24, uint8_t* dst_argb, int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 b = src_rgb24[0]; >- uint8 g = src_rgb24[1]; >- uint8 r = src_rgb24[2]; >+ uint8_t b = src_rgb24[0]; >+ uint8_t g = src_rgb24[1]; >+ uint8_t r = src_rgb24[2]; > dst_argb[0] = b; > dst_argb[1] = g; > dst_argb[2] = r; >@@ -85,12 +96,12 @@ void RGB24ToARGBRow_C(const uint8* src_rgb24, uint8* dst_argb, int width) { > } > } > >-void RAWToARGBRow_C(const uint8* src_raw, uint8* dst_argb, int width) { >+void RAWToARGBRow_C(const uint8_t* src_raw, uint8_t* dst_argb, int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 r = src_raw[0]; >- uint8 g = src_raw[1]; >- uint8 b = src_raw[2]; >+ uint8_t r = src_raw[0]; >+ uint8_t g = src_raw[1]; >+ uint8_t b = src_raw[2]; > dst_argb[0] = b; > dst_argb[1] = g; > dst_argb[2] = r; >@@ -100,12 +111,12 @@ void RAWToARGBRow_C(const uint8* src_raw, uint8* dst_argb, int width) { > } > } > >-void RAWToRGB24Row_C(const uint8* src_raw, uint8* dst_rgb24, int width) { >+void RAWToRGB24Row_C(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 r = src_raw[0]; >- uint8 g = src_raw[1]; >- uint8 b = src_raw[2]; >+ uint8_t r = src_raw[0]; >+ uint8_t g = src_raw[1]; >+ uint8_t b = src_raw[2]; > dst_rgb24[0] = b; > dst_rgb24[1] = g; > dst_rgb24[2] = r; >@@ -114,12 +125,14 @@ void RAWToRGB24Row_C(const uint8* src_raw, uint8* dst_rgb24, int width) { > } > } > >-void RGB565ToARGBRow_C(const uint8* src_rgb565, uint8* dst_argb, int width) { >+void RGB565ToARGBRow_C(const uint8_t* src_rgb565, >+ uint8_t* dst_argb, >+ int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 b = src_rgb565[0] & 0x1f; >- uint8 g = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); >- uint8 r = src_rgb565[1] >> 3; >+ uint8_t b = src_rgb565[0] & 0x1f; >+ uint8_t g = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); >+ uint8_t r = src_rgb565[1] >> 3; > dst_argb[0] = (b << 3) | (b >> 2); > dst_argb[1] = (g << 2) | (g >> 4); > dst_argb[2] = (r << 3) | (r >> 2); >@@ -129,15 +142,15 @@ void RGB565ToARGBRow_C(const uint8* src_rgb565, uint8* dst_argb, int width) { > } > } > >-void ARGB1555ToARGBRow_C(const uint8* src_argb1555, >- uint8* dst_argb, >+void ARGB1555ToARGBRow_C(const uint8_t* src_argb1555, >+ uint8_t* dst_argb, > int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 b = src_argb1555[0] & 0x1f; >- uint8 g = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); >- uint8 r = (src_argb1555[1] & 0x7c) >> 2; >- uint8 a = src_argb1555[1] >> 7; >+ uint8_t b = src_argb1555[0] & 0x1f; >+ uint8_t g = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); >+ uint8_t r = (src_argb1555[1] & 0x7c) >> 2; >+ uint8_t a = src_argb1555[1] >> 7; > dst_argb[0] = (b << 3) | (b >> 2); > dst_argb[1] = (g << 3) | (g >> 2); > dst_argb[2] = (r << 3) | (r >> 2); >@@ -147,15 +160,15 @@ void ARGB1555ToARGBRow_C(const uint8* src_argb1555, > } > } > >-void ARGB4444ToARGBRow_C(const uint8* src_argb4444, >- uint8* dst_argb, >+void ARGB4444ToARGBRow_C(const uint8_t* src_argb4444, >+ uint8_t* dst_argb, > int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 b = src_argb4444[0] & 0x0f; >- uint8 g = src_argb4444[0] >> 4; >- uint8 r = src_argb4444[1] & 0x0f; >- uint8 a = src_argb4444[1] >> 4; >+ uint8_t b = src_argb4444[0] & 0x0f; >+ uint8_t g = src_argb4444[0] >> 4; >+ uint8_t r = src_argb4444[1] & 0x0f; >+ uint8_t a = src_argb4444[1] >> 4; > dst_argb[0] = (b << 4) | b; > dst_argb[1] = (g << 4) | g; > dst_argb[2] = (r << 4) | r; >@@ -165,12 +178,53 @@ void ARGB4444ToARGBRow_C(const uint8* src_argb4444, > } > } > >-void ARGBToRGB24Row_C(const uint8* src_argb, uint8* dst_rgb, int width) { >+void AR30ToARGBRow_C(const uint8_t* src_ar30, uint8_t* dst_argb, int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 b = src_argb[0]; >- uint8 g = src_argb[1]; >- uint8 r = src_argb[2]; >+ uint32_t ar30 = *(uint32_t*)src_ar30; >+ uint32_t b = (ar30 >> 2) & 0xff; >+ uint32_t g = (ar30 >> 12) & 0xff; >+ uint32_t r = (ar30 >> 22) & 0xff; >+ uint32_t a = (ar30 >> 30) * 0x55; // Replicate 2 bits to 8 bits. >+ *(uint32_t*)(dst_argb) = b | (g << 8) | (r << 16) | (a << 24); >+ dst_argb += 4; >+ src_ar30 += 4; >+ } >+} >+ >+void AR30ToABGRRow_C(const uint8_t* src_ar30, uint8_t* dst_abgr, int width) { >+ int x; >+ for (x = 0; x < width; ++x) { >+ uint32_t ar30 = *(uint32_t*)src_ar30; >+ uint32_t b = (ar30 >> 2) & 0xff; >+ uint32_t g = (ar30 >> 12) & 0xff; >+ uint32_t r = (ar30 >> 22) & 0xff; >+ uint32_t a = (ar30 >> 30) * 0x55; // Replicate 2 bits to 8 bits. >+ *(uint32_t*)(dst_abgr) = r | (g << 8) | (b << 16) | (a << 24); >+ dst_abgr += 4; >+ src_ar30 += 4; >+ } >+} >+ >+void AR30ToAB30Row_C(const uint8_t* src_ar30, uint8_t* dst_ab30, int width) { >+ int x; >+ for (x = 0; x < width; ++x) { >+ uint32_t ar30 = *(uint32_t*)src_ar30; >+ uint32_t b = ar30 & 0x3ff; >+ uint32_t ga = ar30 & 0xc00ffc00; >+ uint32_t r = (ar30 >> 20) & 0x3ff; >+ *(uint32_t*)(dst_ab30) = r | ga | (b << 20); >+ dst_ab30 += 4; >+ src_ar30 += 4; >+ } >+} >+ >+void ARGBToRGB24Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { >+ int x; >+ for (x = 0; x < width; ++x) { >+ uint8_t b = src_argb[0]; >+ uint8_t g = src_argb[1]; >+ uint8_t r = src_argb[2]; > dst_rgb[0] = b; > dst_rgb[1] = g; > dst_rgb[2] = r; >@@ -179,12 +233,12 @@ void ARGBToRGB24Row_C(const uint8* src_argb, uint8* dst_rgb, int width) { > } > } > >-void ARGBToRAWRow_C(const uint8* src_argb, uint8* dst_rgb, int width) { >+void ARGBToRAWRow_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 b = src_argb[0]; >- uint8 g = src_argb[1]; >- uint8 r = src_argb[2]; >+ uint8_t b = src_argb[0]; >+ uint8_t g = src_argb[1]; >+ uint8_t r = src_argb[2]; > dst_rgb[0] = r; > dst_rgb[1] = g; > dst_rgb[2] = b; >@@ -193,25 +247,25 @@ void ARGBToRAWRow_C(const uint8* src_argb, uint8* dst_rgb, int width) { > } > } > >-void ARGBToRGB565Row_C(const uint8* src_argb, uint8* dst_rgb, int width) { >+void ARGBToRGB565Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { > int x; > for (x = 0; x < width - 1; x += 2) { >- uint8 b0 = src_argb[0] >> 3; >- uint8 g0 = src_argb[1] >> 2; >- uint8 r0 = src_argb[2] >> 3; >- uint8 b1 = src_argb[4] >> 3; >- uint8 g1 = src_argb[5] >> 2; >- uint8 r1 = src_argb[6] >> 3; >+ uint8_t b0 = src_argb[0] >> 3; >+ uint8_t g0 = src_argb[1] >> 2; >+ uint8_t r0 = src_argb[2] >> 3; >+ uint8_t b1 = src_argb[4] >> 3; >+ uint8_t g1 = src_argb[5] >> 2; >+ uint8_t r1 = src_argb[6] >> 3; > WRITEWORD(dst_rgb, b0 | (g0 << 5) | (r0 << 11) | (b1 << 16) | (g1 << 21) | > (r1 << 27)); > dst_rgb += 4; > src_argb += 8; > } > if (width & 1) { >- uint8 b0 = src_argb[0] >> 3; >- uint8 g0 = src_argb[1] >> 2; >- uint8 r0 = src_argb[2] >> 3; >- *(uint16*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11); >+ uint8_t b0 = src_argb[0] >> 3; >+ uint8_t g0 = src_argb[1] >> 2; >+ uint8_t r0 = src_argb[2] >> 3; >+ *(uint16_t*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11); > } > } > >@@ -223,20 +277,20 @@ void ARGBToRGB565Row_C(const uint8* src_argb, uint8* dst_rgb, int width) { > // endian will not affect order of the original matrix. But the dither4 > // will containing the first pixel in the lower byte for little endian > // or the upper byte for big endian. >-void ARGBToRGB565DitherRow_C(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_C(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ const uint32_t dither4, > int width) { > int x; > for (x = 0; x < width - 1; x += 2) { > int dither0 = ((const unsigned char*)(&dither4))[x & 3]; > int dither1 = ((const unsigned char*)(&dither4))[(x + 1) & 3]; >- uint8 b0 = clamp255(src_argb[0] + dither0) >> 3; >- uint8 g0 = clamp255(src_argb[1] + dither0) >> 2; >- uint8 r0 = clamp255(src_argb[2] + dither0) >> 3; >- uint8 b1 = clamp255(src_argb[4] + dither1) >> 3; >- uint8 g1 = clamp255(src_argb[5] + dither1) >> 2; >- uint8 r1 = clamp255(src_argb[6] + dither1) >> 3; >+ uint8_t b0 = clamp255(src_argb[0] + dither0) >> 3; >+ uint8_t g0 = clamp255(src_argb[1] + dither0) >> 2; >+ uint8_t r0 = clamp255(src_argb[2] + dither0) >> 3; >+ uint8_t b1 = clamp255(src_argb[4] + dither1) >> 3; >+ uint8_t g1 = clamp255(src_argb[5] + dither1) >> 2; >+ uint8_t r1 = clamp255(src_argb[6] + dither1) >> 3; > WRITEWORD(dst_rgb, b0 | (g0 << 5) | (r0 << 11) | (b1 << 16) | (g1 << 21) | > (r1 << 27)); > dst_rgb += 4; >@@ -244,112 +298,138 @@ void ARGBToRGB565DitherRow_C(const uint8* src_argb, > } > if (width & 1) { > int dither0 = ((const unsigned char*)(&dither4))[(width - 1) & 3]; >- uint8 b0 = clamp255(src_argb[0] + dither0) >> 3; >- uint8 g0 = clamp255(src_argb[1] + dither0) >> 2; >- uint8 r0 = clamp255(src_argb[2] + dither0) >> 3; >- *(uint16*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11); >+ uint8_t b0 = clamp255(src_argb[0] + dither0) >> 3; >+ uint8_t g0 = clamp255(src_argb[1] + dither0) >> 2; >+ uint8_t r0 = clamp255(src_argb[2] + dither0) >> 3; >+ *(uint16_t*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11); > } > } > >-void ARGBToARGB1555Row_C(const uint8* src_argb, uint8* dst_rgb, int width) { >+void ARGBToARGB1555Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { > int x; > for (x = 0; x < width - 1; x += 2) { >- uint8 b0 = src_argb[0] >> 3; >- uint8 g0 = src_argb[1] >> 3; >- uint8 r0 = src_argb[2] >> 3; >- uint8 a0 = src_argb[3] >> 7; >- uint8 b1 = src_argb[4] >> 3; >- uint8 g1 = src_argb[5] >> 3; >- uint8 r1 = src_argb[6] >> 3; >- uint8 a1 = src_argb[7] >> 7; >- *(uint32*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 10) | (a0 << 15) | >- (b1 << 16) | (g1 << 21) | (r1 << 26) | (a1 << 31); >+ uint8_t b0 = src_argb[0] >> 3; >+ uint8_t g0 = src_argb[1] >> 3; >+ uint8_t r0 = src_argb[2] >> 3; >+ uint8_t a0 = src_argb[3] >> 7; >+ uint8_t b1 = src_argb[4] >> 3; >+ uint8_t g1 = src_argb[5] >> 3; >+ uint8_t r1 = src_argb[6] >> 3; >+ uint8_t a1 = src_argb[7] >> 7; >+ *(uint32_t*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 10) | (a0 << 15) | >+ (b1 << 16) | (g1 << 21) | (r1 << 26) | (a1 << 31); > dst_rgb += 4; > src_argb += 8; > } > if (width & 1) { >- uint8 b0 = src_argb[0] >> 3; >- uint8 g0 = src_argb[1] >> 3; >- uint8 r0 = src_argb[2] >> 3; >- uint8 a0 = src_argb[3] >> 7; >- *(uint16*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 10) | (a0 << 15); >+ uint8_t b0 = src_argb[0] >> 3; >+ uint8_t g0 = src_argb[1] >> 3; >+ uint8_t r0 = src_argb[2] >> 3; >+ uint8_t a0 = src_argb[3] >> 7; >+ *(uint16_t*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 10) | (a0 << 15); > } > } > >-void ARGBToARGB4444Row_C(const uint8* src_argb, uint8* dst_rgb, int width) { >+void ARGBToARGB4444Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { > int x; > for (x = 0; x < width - 1; x += 2) { >- uint8 b0 = src_argb[0] >> 4; >- uint8 g0 = src_argb[1] >> 4; >- uint8 r0 = src_argb[2] >> 4; >- uint8 a0 = src_argb[3] >> 4; >- uint8 b1 = src_argb[4] >> 4; >- uint8 g1 = src_argb[5] >> 4; >- uint8 r1 = src_argb[6] >> 4; >- uint8 a1 = src_argb[7] >> 4; >- *(uint32*)(dst_rgb) = b0 | (g0 << 4) | (r0 << 8) | (a0 << 12) | (b1 << 16) | >- (g1 << 20) | (r1 << 24) | (a1 << 28); >+ uint8_t b0 = src_argb[0] >> 4; >+ uint8_t g0 = src_argb[1] >> 4; >+ uint8_t r0 = src_argb[2] >> 4; >+ uint8_t a0 = src_argb[3] >> 4; >+ uint8_t b1 = src_argb[4] >> 4; >+ uint8_t g1 = src_argb[5] >> 4; >+ uint8_t r1 = src_argb[6] >> 4; >+ uint8_t a1 = src_argb[7] >> 4; >+ *(uint32_t*)(dst_rgb) = b0 | (g0 << 4) | (r0 << 8) | (a0 << 12) | >+ (b1 << 16) | (g1 << 20) | (r1 << 24) | (a1 << 28); > dst_rgb += 4; > src_argb += 8; > } > if (width & 1) { >- uint8 b0 = src_argb[0] >> 4; >- uint8 g0 = src_argb[1] >> 4; >- uint8 r0 = src_argb[2] >> 4; >- uint8 a0 = src_argb[3] >> 4; >- *(uint16*)(dst_rgb) = b0 | (g0 << 4) | (r0 << 8) | (a0 << 12); >+ uint8_t b0 = src_argb[0] >> 4; >+ uint8_t g0 = src_argb[1] >> 4; >+ uint8_t r0 = src_argb[2] >> 4; >+ uint8_t a0 = src_argb[3] >> 4; >+ *(uint16_t*)(dst_rgb) = b0 | (g0 << 4) | (r0 << 8) | (a0 << 12); >+ } >+} >+ >+void ABGRToAR30Row_C(const uint8_t* src_abgr, uint8_t* dst_ar30, int width) { >+ int x; >+ for (x = 0; x < width; ++x) { >+ uint32_t b0 = (src_abgr[0] >> 6) | ((uint32_t)(src_abgr[0]) << 2); >+ uint32_t g0 = (src_abgr[1] >> 6) | ((uint32_t)(src_abgr[1]) << 2); >+ uint32_t r0 = (src_abgr[2] >> 6) | ((uint32_t)(src_abgr[2]) << 2); >+ uint32_t a0 = (src_abgr[3] >> 6); >+ *(uint32_t*)(dst_ar30) = r0 | (g0 << 10) | (b0 << 20) | (a0 << 30); >+ dst_ar30 += 4; >+ src_abgr += 4; > } > } > >-static __inline int RGBToY(uint8 r, uint8 g, uint8 b) { >+void ARGBToAR30Row_C(const uint8_t* src_argb, uint8_t* dst_ar30, int width) { >+ int x; >+ for (x = 0; x < width; ++x) { >+ uint32_t b0 = (src_argb[0] >> 6) | ((uint32_t)(src_argb[0]) << 2); >+ uint32_t g0 = (src_argb[1] >> 6) | ((uint32_t)(src_argb[1]) << 2); >+ uint32_t r0 = (src_argb[2] >> 6) | ((uint32_t)(src_argb[2]) << 2); >+ uint32_t a0 = (src_argb[3] >> 6); >+ *(uint32_t*)(dst_ar30) = b0 | (g0 << 10) | (r0 << 20) | (a0 << 30); >+ dst_ar30 += 4; >+ src_argb += 4; >+ } >+} >+ >+static __inline int RGBToY(uint8_t r, uint8_t g, uint8_t b) { > return (66 * r + 129 * g + 25 * b + 0x1080) >> 8; > } > >-static __inline int RGBToU(uint8 r, uint8 g, uint8 b) { >+static __inline int RGBToU(uint8_t r, uint8_t g, uint8_t b) { > return (112 * b - 74 * g - 38 * r + 0x8080) >> 8; > } >-static __inline int RGBToV(uint8 r, uint8 g, uint8 b) { >+static __inline int RGBToV(uint8_t r, uint8_t g, uint8_t b) { > return (112 * r - 94 * g - 18 * b + 0x8080) >> 8; > } > > // ARGBToY_C and ARGBToUV_C >-#define MAKEROWY(NAME, R, G, B, BPP) \ >- void NAME##ToYRow_C(const uint8* src_argb0, uint8* dst_y, int width) { \ >- int x; \ >- for (x = 0; x < width; ++x) { \ >- dst_y[0] = RGBToY(src_argb0[R], src_argb0[G], src_argb0[B]); \ >- src_argb0 += BPP; \ >- dst_y += 1; \ >- } \ >- } \ >- void NAME##ToUVRow_C(const uint8* src_rgb0, int src_stride_rgb, \ >- uint8* dst_u, uint8* dst_v, int width) { \ >- const uint8* src_rgb1 = src_rgb0 + src_stride_rgb; \ >- int x; \ >- for (x = 0; x < width - 1; x += 2) { \ >- uint8 ab = (src_rgb0[B] + src_rgb0[B + BPP] + src_rgb1[B] + \ >- src_rgb1[B + BPP]) >> \ >- 2; \ >- uint8 ag = (src_rgb0[G] + src_rgb0[G + BPP] + src_rgb1[G] + \ >- src_rgb1[G + BPP]) >> \ >- 2; \ >- uint8 ar = (src_rgb0[R] + src_rgb0[R + BPP] + src_rgb1[R] + \ >- src_rgb1[R + BPP]) >> \ >- 2; \ >- dst_u[0] = RGBToU(ar, ag, ab); \ >- dst_v[0] = RGBToV(ar, ag, ab); \ >- src_rgb0 += BPP * 2; \ >- src_rgb1 += BPP * 2; \ >- dst_u += 1; \ >- dst_v += 1; \ >- } \ >- if (width & 1) { \ >- uint8 ab = (src_rgb0[B] + src_rgb1[B]) >> 1; \ >- uint8 ag = (src_rgb0[G] + src_rgb1[G]) >> 1; \ >- uint8 ar = (src_rgb0[R] + src_rgb1[R]) >> 1; \ >- dst_u[0] = RGBToU(ar, ag, ab); \ >- dst_v[0] = RGBToV(ar, ag, ab); \ >- } \ >+#define MAKEROWY(NAME, R, G, B, BPP) \ >+ void NAME##ToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \ >+ int x; \ >+ for (x = 0; x < width; ++x) { \ >+ dst_y[0] = RGBToY(src_argb0[R], src_argb0[G], src_argb0[B]); \ >+ src_argb0 += BPP; \ >+ dst_y += 1; \ >+ } \ >+ } \ >+ void NAME##ToUVRow_C(const uint8_t* src_rgb0, int src_stride_rgb, \ >+ uint8_t* dst_u, uint8_t* dst_v, int width) { \ >+ const uint8_t* src_rgb1 = src_rgb0 + src_stride_rgb; \ >+ int x; \ >+ for (x = 0; x < width - 1; x += 2) { \ >+ uint8_t ab = (src_rgb0[B] + src_rgb0[B + BPP] + src_rgb1[B] + \ >+ src_rgb1[B + BPP]) >> \ >+ 2; \ >+ uint8_t ag = (src_rgb0[G] + src_rgb0[G + BPP] + src_rgb1[G] + \ >+ src_rgb1[G + BPP]) >> \ >+ 2; \ >+ uint8_t ar = (src_rgb0[R] + src_rgb0[R + BPP] + src_rgb1[R] + \ >+ src_rgb1[R + BPP]) >> \ >+ 2; \ >+ dst_u[0] = RGBToU(ar, ag, ab); \ >+ dst_v[0] = RGBToV(ar, ag, ab); \ >+ src_rgb0 += BPP * 2; \ >+ src_rgb1 += BPP * 2; \ >+ dst_u += 1; \ >+ dst_v += 1; \ >+ } \ >+ if (width & 1) { \ >+ uint8_t ab = (src_rgb0[B] + src_rgb1[B]) >> 1; \ >+ uint8_t ag = (src_rgb0[G] + src_rgb1[G]) >> 1; \ >+ uint8_t ar = (src_rgb0[R] + src_rgb1[R]) >> 1; \ >+ dst_u[0] = RGBToU(ar, ag, ab); \ >+ dst_v[0] = RGBToV(ar, ag, ab); \ >+ } \ > } > > MAKEROWY(ARGB, 2, 1, 0, 4) >@@ -385,65 +465,65 @@ MAKEROWY(RAW, 0, 1, 2, 3) > // g -0.41869 * 255 = -106.76595 = -107 > // r 0.50000 * 255 = 127.5 = 127 > >-static __inline int RGBToYJ(uint8 r, uint8 g, uint8 b) { >+static __inline int RGBToYJ(uint8_t r, uint8_t g, uint8_t b) { > return (38 * r + 75 * g + 15 * b + 64) >> 7; > } > >-static __inline int RGBToUJ(uint8 r, uint8 g, uint8 b) { >+static __inline int RGBToUJ(uint8_t r, uint8_t g, uint8_t b) { > return (127 * b - 84 * g - 43 * r + 0x8080) >> 8; > } >-static __inline int RGBToVJ(uint8 r, uint8 g, uint8 b) { >+static __inline int RGBToVJ(uint8_t r, uint8_t g, uint8_t b) { > return (127 * r - 107 * g - 20 * b + 0x8080) >> 8; > } > > #define AVGB(a, b) (((a) + (b) + 1) >> 1) > > // ARGBToYJ_C and ARGBToUVJ_C >-#define MAKEROWYJ(NAME, R, G, B, BPP) \ >- void NAME##ToYJRow_C(const uint8* src_argb0, uint8* dst_y, int width) { \ >- int x; \ >- for (x = 0; x < width; ++x) { \ >- dst_y[0] = RGBToYJ(src_argb0[R], src_argb0[G], src_argb0[B]); \ >- src_argb0 += BPP; \ >- dst_y += 1; \ >- } \ >- } \ >- void NAME##ToUVJRow_C(const uint8* src_rgb0, int src_stride_rgb, \ >- uint8* dst_u, uint8* dst_v, int width) { \ >- const uint8* src_rgb1 = src_rgb0 + src_stride_rgb; \ >- int x; \ >- for (x = 0; x < width - 1; x += 2) { \ >- uint8 ab = AVGB(AVGB(src_rgb0[B], src_rgb1[B]), \ >- AVGB(src_rgb0[B + BPP], src_rgb1[B + BPP])); \ >- uint8 ag = AVGB(AVGB(src_rgb0[G], src_rgb1[G]), \ >- AVGB(src_rgb0[G + BPP], src_rgb1[G + BPP])); \ >- uint8 ar = AVGB(AVGB(src_rgb0[R], src_rgb1[R]), \ >- AVGB(src_rgb0[R + BPP], src_rgb1[R + BPP])); \ >- dst_u[0] = RGBToUJ(ar, ag, ab); \ >- dst_v[0] = RGBToVJ(ar, ag, ab); \ >- src_rgb0 += BPP * 2; \ >- src_rgb1 += BPP * 2; \ >- dst_u += 1; \ >- dst_v += 1; \ >- } \ >- if (width & 1) { \ >- uint8 ab = AVGB(src_rgb0[B], src_rgb1[B]); \ >- uint8 ag = AVGB(src_rgb0[G], src_rgb1[G]); \ >- uint8 ar = AVGB(src_rgb0[R], src_rgb1[R]); \ >- dst_u[0] = RGBToUJ(ar, ag, ab); \ >- dst_v[0] = RGBToVJ(ar, ag, ab); \ >- } \ >+#define MAKEROWYJ(NAME, R, G, B, BPP) \ >+ void NAME##ToYJRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \ >+ int x; \ >+ for (x = 0; x < width; ++x) { \ >+ dst_y[0] = RGBToYJ(src_argb0[R], src_argb0[G], src_argb0[B]); \ >+ src_argb0 += BPP; \ >+ dst_y += 1; \ >+ } \ >+ } \ >+ void NAME##ToUVJRow_C(const uint8_t* src_rgb0, int src_stride_rgb, \ >+ uint8_t* dst_u, uint8_t* dst_v, int width) { \ >+ const uint8_t* src_rgb1 = src_rgb0 + src_stride_rgb; \ >+ int x; \ >+ for (x = 0; x < width - 1; x += 2) { \ >+ uint8_t ab = AVGB(AVGB(src_rgb0[B], src_rgb1[B]), \ >+ AVGB(src_rgb0[B + BPP], src_rgb1[B + BPP])); \ >+ uint8_t ag = AVGB(AVGB(src_rgb0[G], src_rgb1[G]), \ >+ AVGB(src_rgb0[G + BPP], src_rgb1[G + BPP])); \ >+ uint8_t ar = AVGB(AVGB(src_rgb0[R], src_rgb1[R]), \ >+ AVGB(src_rgb0[R + BPP], src_rgb1[R + BPP])); \ >+ dst_u[0] = RGBToUJ(ar, ag, ab); \ >+ dst_v[0] = RGBToVJ(ar, ag, ab); \ >+ src_rgb0 += BPP * 2; \ >+ src_rgb1 += BPP * 2; \ >+ dst_u += 1; \ >+ dst_v += 1; \ >+ } \ >+ if (width & 1) { \ >+ uint8_t ab = AVGB(src_rgb0[B], src_rgb1[B]); \ >+ uint8_t ag = AVGB(src_rgb0[G], src_rgb1[G]); \ >+ uint8_t ar = AVGB(src_rgb0[R], src_rgb1[R]); \ >+ dst_u[0] = RGBToUJ(ar, ag, ab); \ >+ dst_v[0] = RGBToVJ(ar, ag, ab); \ >+ } \ > } > > MAKEROWYJ(ARGB, 2, 1, 0, 4) > #undef MAKEROWYJ > >-void RGB565ToYRow_C(const uint8* src_rgb565, uint8* dst_y, int width) { >+void RGB565ToYRow_C(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 b = src_rgb565[0] & 0x1f; >- uint8 g = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); >- uint8 r = src_rgb565[1] >> 3; >+ uint8_t b = src_rgb565[0] & 0x1f; >+ uint8_t g = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); >+ uint8_t r = src_rgb565[1] >> 3; > b = (b << 3) | (b >> 2); > g = (g << 2) | (g >> 4); > r = (r << 3) | (r >> 2); >@@ -453,12 +533,12 @@ void RGB565ToYRow_C(const uint8* src_rgb565, uint8* dst_y, int width) { > } > } > >-void ARGB1555ToYRow_C(const uint8* src_argb1555, uint8* dst_y, int width) { >+void ARGB1555ToYRow_C(const uint8_t* src_argb1555, uint8_t* dst_y, int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 b = src_argb1555[0] & 0x1f; >- uint8 g = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); >- uint8 r = (src_argb1555[1] & 0x7c) >> 2; >+ uint8_t b = src_argb1555[0] & 0x1f; >+ uint8_t g = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); >+ uint8_t r = (src_argb1555[1] & 0x7c) >> 2; > b = (b << 3) | (b >> 2); > g = (g << 3) | (g >> 2); > r = (r << 3) | (r >> 2); >@@ -468,12 +548,12 @@ void ARGB1555ToYRow_C(const uint8* src_argb1555, uint8* dst_y, int width) { > } > } > >-void ARGB4444ToYRow_C(const uint8* src_argb4444, uint8* dst_y, int width) { >+void ARGB4444ToYRow_C(const uint8_t* src_argb4444, uint8_t* dst_y, int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 b = src_argb4444[0] & 0x0f; >- uint8 g = src_argb4444[0] >> 4; >- uint8 r = src_argb4444[1] & 0x0f; >+ uint8_t b = src_argb4444[0] & 0x0f; >+ uint8_t g = src_argb4444[0] >> 4; >+ uint8_t r = src_argb4444[1] & 0x0f; > b = (b << 4) | b; > g = (g << 4) | g; > r = (r << 4) | r; >@@ -483,29 +563,29 @@ void ARGB4444ToYRow_C(const uint8* src_argb4444, uint8* dst_y, int width) { > } > } > >-void RGB565ToUVRow_C(const uint8* src_rgb565, >+void RGB565ToUVRow_C(const uint8_t* src_rgb565, > int src_stride_rgb565, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* next_rgb565 = src_rgb565 + src_stride_rgb565; >+ const uint8_t* next_rgb565 = src_rgb565 + src_stride_rgb565; > int x; > for (x = 0; x < width - 1; x += 2) { >- uint8 b0 = src_rgb565[0] & 0x1f; >- uint8 g0 = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); >- uint8 r0 = src_rgb565[1] >> 3; >- uint8 b1 = src_rgb565[2] & 0x1f; >- uint8 g1 = (src_rgb565[2] >> 5) | ((src_rgb565[3] & 0x07) << 3); >- uint8 r1 = src_rgb565[3] >> 3; >- uint8 b2 = next_rgb565[0] & 0x1f; >- uint8 g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3); >- uint8 r2 = next_rgb565[1] >> 3; >- uint8 b3 = next_rgb565[2] & 0x1f; >- uint8 g3 = (next_rgb565[2] >> 5) | ((next_rgb565[3] & 0x07) << 3); >- uint8 r3 = next_rgb565[3] >> 3; >- uint8 b = (b0 + b1 + b2 + b3); // 565 * 4 = 787. >- uint8 g = (g0 + g1 + g2 + g3); >- uint8 r = (r0 + r1 + r2 + r3); >+ uint8_t b0 = src_rgb565[0] & 0x1f; >+ uint8_t g0 = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); >+ uint8_t r0 = src_rgb565[1] >> 3; >+ uint8_t b1 = src_rgb565[2] & 0x1f; >+ uint8_t g1 = (src_rgb565[2] >> 5) | ((src_rgb565[3] & 0x07) << 3); >+ uint8_t r1 = src_rgb565[3] >> 3; >+ uint8_t b2 = next_rgb565[0] & 0x1f; >+ uint8_t g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3); >+ uint8_t r2 = next_rgb565[1] >> 3; >+ uint8_t b3 = next_rgb565[2] & 0x1f; >+ uint8_t g3 = (next_rgb565[2] >> 5) | ((next_rgb565[3] & 0x07) << 3); >+ uint8_t r3 = next_rgb565[3] >> 3; >+ uint8_t b = (b0 + b1 + b2 + b3); // 565 * 4 = 787. >+ uint8_t g = (g0 + g1 + g2 + g3); >+ uint8_t r = (r0 + r1 + r2 + r3); > b = (b << 1) | (b >> 6); // 787 -> 888. > r = (r << 1) | (r >> 6); > dst_u[0] = RGBToU(r, g, b); >@@ -516,15 +596,15 @@ void RGB565ToUVRow_C(const uint8* src_rgb565, > dst_v += 1; > } > if (width & 1) { >- uint8 b0 = src_rgb565[0] & 0x1f; >- uint8 g0 = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); >- uint8 r0 = src_rgb565[1] >> 3; >- uint8 b2 = next_rgb565[0] & 0x1f; >- uint8 g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3); >- uint8 r2 = next_rgb565[1] >> 3; >- uint8 b = (b0 + b2); // 565 * 2 = 676. >- uint8 g = (g0 + g2); >- uint8 r = (r0 + r2); >+ uint8_t b0 = src_rgb565[0] & 0x1f; >+ uint8_t g0 = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); >+ uint8_t r0 = src_rgb565[1] >> 3; >+ uint8_t b2 = next_rgb565[0] & 0x1f; >+ uint8_t g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3); >+ uint8_t r2 = next_rgb565[1] >> 3; >+ uint8_t b = (b0 + b2); // 565 * 2 = 676. >+ uint8_t g = (g0 + g2); >+ uint8_t r = (r0 + r2); > b = (b << 2) | (b >> 4); // 676 -> 888 > g = (g << 1) | (g >> 6); > r = (r << 2) | (r >> 4); >@@ -533,29 +613,29 @@ void RGB565ToUVRow_C(const uint8* src_rgb565, > } > } > >-void ARGB1555ToUVRow_C(const uint8* src_argb1555, >+void ARGB1555ToUVRow_C(const uint8_t* src_argb1555, > int src_stride_argb1555, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* next_argb1555 = src_argb1555 + src_stride_argb1555; >+ const uint8_t* next_argb1555 = src_argb1555 + src_stride_argb1555; > int x; > for (x = 0; x < width - 1; x += 2) { >- uint8 b0 = src_argb1555[0] & 0x1f; >- uint8 g0 = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); >- uint8 r0 = (src_argb1555[1] & 0x7c) >> 2; >- uint8 b1 = src_argb1555[2] & 0x1f; >- uint8 g1 = (src_argb1555[2] >> 5) | ((src_argb1555[3] & 0x03) << 3); >- uint8 r1 = (src_argb1555[3] & 0x7c) >> 2; >- uint8 b2 = next_argb1555[0] & 0x1f; >- uint8 g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3); >- uint8 r2 = (next_argb1555[1] & 0x7c) >> 2; >- uint8 b3 = next_argb1555[2] & 0x1f; >- uint8 g3 = (next_argb1555[2] >> 5) | ((next_argb1555[3] & 0x03) << 3); >- uint8 r3 = (next_argb1555[3] & 0x7c) >> 2; >- uint8 b = (b0 + b1 + b2 + b3); // 555 * 4 = 777. >- uint8 g = (g0 + g1 + g2 + g3); >- uint8 r = (r0 + r1 + r2 + r3); >+ uint8_t b0 = src_argb1555[0] & 0x1f; >+ uint8_t g0 = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); >+ uint8_t r0 = (src_argb1555[1] & 0x7c) >> 2; >+ uint8_t b1 = src_argb1555[2] & 0x1f; >+ uint8_t g1 = (src_argb1555[2] >> 5) | ((src_argb1555[3] & 0x03) << 3); >+ uint8_t r1 = (src_argb1555[3] & 0x7c) >> 2; >+ uint8_t b2 = next_argb1555[0] & 0x1f; >+ uint8_t g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3); >+ uint8_t r2 = (next_argb1555[1] & 0x7c) >> 2; >+ uint8_t b3 = next_argb1555[2] & 0x1f; >+ uint8_t g3 = (next_argb1555[2] >> 5) | ((next_argb1555[3] & 0x03) << 3); >+ uint8_t r3 = (next_argb1555[3] & 0x7c) >> 2; >+ uint8_t b = (b0 + b1 + b2 + b3); // 555 * 4 = 777. >+ uint8_t g = (g0 + g1 + g2 + g3); >+ uint8_t r = (r0 + r1 + r2 + r3); > b = (b << 1) | (b >> 6); // 777 -> 888. > g = (g << 1) | (g >> 6); > r = (r << 1) | (r >> 6); >@@ -567,15 +647,15 @@ void ARGB1555ToUVRow_C(const uint8* src_argb1555, > dst_v += 1; > } > if (width & 1) { >- uint8 b0 = src_argb1555[0] & 0x1f; >- uint8 g0 = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); >- uint8 r0 = (src_argb1555[1] & 0x7c) >> 2; >- uint8 b2 = next_argb1555[0] & 0x1f; >- uint8 g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3); >- uint8 r2 = next_argb1555[1] >> 3; >- uint8 b = (b0 + b2); // 555 * 2 = 666. >- uint8 g = (g0 + g2); >- uint8 r = (r0 + r2); >+ uint8_t b0 = src_argb1555[0] & 0x1f; >+ uint8_t g0 = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); >+ uint8_t r0 = (src_argb1555[1] & 0x7c) >> 2; >+ uint8_t b2 = next_argb1555[0] & 0x1f; >+ uint8_t g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3); >+ uint8_t r2 = next_argb1555[1] >> 3; >+ uint8_t b = (b0 + b2); // 555 * 2 = 666. >+ uint8_t g = (g0 + g2); >+ uint8_t r = (r0 + r2); > b = (b << 2) | (b >> 4); // 666 -> 888. > g = (g << 2) | (g >> 4); > r = (r << 2) | (r >> 4); >@@ -584,29 +664,29 @@ void ARGB1555ToUVRow_C(const uint8* src_argb1555, > } > } > >-void ARGB4444ToUVRow_C(const uint8* src_argb4444, >+void ARGB4444ToUVRow_C(const uint8_t* src_argb4444, > int src_stride_argb4444, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* next_argb4444 = src_argb4444 + src_stride_argb4444; >+ const uint8_t* next_argb4444 = src_argb4444 + src_stride_argb4444; > int x; > for (x = 0; x < width - 1; x += 2) { >- uint8 b0 = src_argb4444[0] & 0x0f; >- uint8 g0 = src_argb4444[0] >> 4; >- uint8 r0 = src_argb4444[1] & 0x0f; >- uint8 b1 = src_argb4444[2] & 0x0f; >- uint8 g1 = src_argb4444[2] >> 4; >- uint8 r1 = src_argb4444[3] & 0x0f; >- uint8 b2 = next_argb4444[0] & 0x0f; >- uint8 g2 = next_argb4444[0] >> 4; >- uint8 r2 = next_argb4444[1] & 0x0f; >- uint8 b3 = next_argb4444[2] & 0x0f; >- uint8 g3 = next_argb4444[2] >> 4; >- uint8 r3 = next_argb4444[3] & 0x0f; >- uint8 b = (b0 + b1 + b2 + b3); // 444 * 4 = 666. >- uint8 g = (g0 + g1 + g2 + g3); >- uint8 r = (r0 + r1 + r2 + r3); >+ uint8_t b0 = src_argb4444[0] & 0x0f; >+ uint8_t g0 = src_argb4444[0] >> 4; >+ uint8_t r0 = src_argb4444[1] & 0x0f; >+ uint8_t b1 = src_argb4444[2] & 0x0f; >+ uint8_t g1 = src_argb4444[2] >> 4; >+ uint8_t r1 = src_argb4444[3] & 0x0f; >+ uint8_t b2 = next_argb4444[0] & 0x0f; >+ uint8_t g2 = next_argb4444[0] >> 4; >+ uint8_t r2 = next_argb4444[1] & 0x0f; >+ uint8_t b3 = next_argb4444[2] & 0x0f; >+ uint8_t g3 = next_argb4444[2] >> 4; >+ uint8_t r3 = next_argb4444[3] & 0x0f; >+ uint8_t b = (b0 + b1 + b2 + b3); // 444 * 4 = 666. >+ uint8_t g = (g0 + g1 + g2 + g3); >+ uint8_t r = (r0 + r1 + r2 + r3); > b = (b << 2) | (b >> 4); // 666 -> 888. > g = (g << 2) | (g >> 4); > r = (r << 2) | (r >> 4); >@@ -618,15 +698,15 @@ void ARGB4444ToUVRow_C(const uint8* src_argb4444, > dst_v += 1; > } > if (width & 1) { >- uint8 b0 = src_argb4444[0] & 0x0f; >- uint8 g0 = src_argb4444[0] >> 4; >- uint8 r0 = src_argb4444[1] & 0x0f; >- uint8 b2 = next_argb4444[0] & 0x0f; >- uint8 g2 = next_argb4444[0] >> 4; >- uint8 r2 = next_argb4444[1] & 0x0f; >- uint8 b = (b0 + b2); // 444 * 2 = 555. >- uint8 g = (g0 + g2); >- uint8 r = (r0 + r2); >+ uint8_t b0 = src_argb4444[0] & 0x0f; >+ uint8_t g0 = src_argb4444[0] >> 4; >+ uint8_t r0 = src_argb4444[1] & 0x0f; >+ uint8_t b2 = next_argb4444[0] & 0x0f; >+ uint8_t g2 = next_argb4444[0] >> 4; >+ uint8_t r2 = next_argb4444[1] & 0x0f; >+ uint8_t b = (b0 + b2); // 444 * 2 = 555. >+ uint8_t g = (g0 + g2); >+ uint8_t r = (r0 + r2); > b = (b << 3) | (b >> 2); // 555 -> 888. > g = (g << 3) | (g >> 2); > r = (r << 3) | (r >> 2); >@@ -635,15 +715,15 @@ void ARGB4444ToUVRow_C(const uint8* src_argb4444, > } > } > >-void ARGBToUV444Row_C(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUV444Row_C(const uint8_t* src_argb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 ab = src_argb[0]; >- uint8 ag = src_argb[1]; >- uint8 ar = src_argb[2]; >+ uint8_t ab = src_argb[0]; >+ uint8_t ag = src_argb[1]; >+ uint8_t ar = src_argb[2]; > dst_u[0] = RGBToU(ar, ag, ab); > dst_v[0] = RGBToV(ar, ag, ab); > src_argb += 4; >@@ -652,10 +732,10 @@ void ARGBToUV444Row_C(const uint8* src_argb, > } > } > >-void ARGBGrayRow_C(const uint8* src_argb, uint8* dst_argb, int width) { >+void ARGBGrayRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width) { > int x; > for (x = 0; x < width; ++x) { >- uint8 y = RGBToYJ(src_argb[2], src_argb[1], src_argb[0]); >+ uint8_t y = RGBToYJ(src_argb[2], src_argb[1], src_argb[0]); > dst_argb[2] = dst_argb[1] = dst_argb[0] = y; > dst_argb[3] = src_argb[3]; > dst_argb += 4; >@@ -664,7 +744,7 @@ void ARGBGrayRow_C(const uint8* src_argb, uint8* dst_argb, int width) { > } > > // Convert a row of image to Sepia tone. >-void ARGBSepiaRow_C(uint8* dst_argb, int width) { >+void ARGBSepiaRow_C(uint8_t* dst_argb, int width) { > int x; > for (x = 0; x < width; ++x) { > int b = dst_argb[0]; >@@ -683,9 +763,9 @@ void ARGBSepiaRow_C(uint8* dst_argb, int width) { > > // Apply color matrix to a row of image. Matrix is signed. > // TODO(fbarchard): Consider adding rounding (+32). >-void ARGBColorMatrixRow_C(const uint8* src_argb, >- uint8* dst_argb, >- const int8* matrix_argb, >+void ARGBColorMatrixRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const int8_t* matrix_argb, > int width) { > int x; > for (x = 0; x < width; ++x) { >@@ -715,7 +795,9 @@ void ARGBColorMatrixRow_C(const uint8* src_argb, > } > > // Apply color table to a row of image. >-void ARGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width) { >+void ARGBColorTableRow_C(uint8_t* dst_argb, >+ const uint8_t* table_argb, >+ int width) { > int x; > for (x = 0; x < width; ++x) { > int b = dst_argb[0]; >@@ -731,7 +813,9 @@ void ARGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width) { > } > > // Apply color table to a row of image. >-void RGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width) { >+void RGBColorTableRow_C(uint8_t* dst_argb, >+ const uint8_t* table_argb, >+ int width) { > int x; > for (x = 0; x < width; ++x) { > int b = dst_argb[0]; >@@ -744,7 +828,7 @@ void RGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width) { > } > } > >-void ARGBQuantizeRow_C(uint8* dst_argb, >+void ARGBQuantizeRow_C(uint8_t* dst_argb, > int scale, > int interval_size, > int interval_offset, >@@ -764,21 +848,21 @@ void ARGBQuantizeRow_C(uint8* dst_argb, > #define REPEAT8(v) (v) | ((v) << 8) > #define SHADE(f, v) v* f >> 24 > >-void ARGBShadeRow_C(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBShadeRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- uint32 value) { >- const uint32 b_scale = REPEAT8(value & 0xff); >- const uint32 g_scale = REPEAT8((value >> 8) & 0xff); >- const uint32 r_scale = REPEAT8((value >> 16) & 0xff); >- const uint32 a_scale = REPEAT8(value >> 24); >+ uint32_t value) { >+ const uint32_t b_scale = REPEAT8(value & 0xff); >+ const uint32_t g_scale = REPEAT8((value >> 8) & 0xff); >+ const uint32_t r_scale = REPEAT8((value >> 16) & 0xff); >+ const uint32_t a_scale = REPEAT8(value >> 24); > > int i; > for (i = 0; i < width; ++i) { >- const uint32 b = REPEAT8(src_argb[0]); >- const uint32 g = REPEAT8(src_argb[1]); >- const uint32 r = REPEAT8(src_argb[2]); >- const uint32 a = REPEAT8(src_argb[3]); >+ const uint32_t b = REPEAT8(src_argb[0]); >+ const uint32_t g = REPEAT8(src_argb[1]); >+ const uint32_t r = REPEAT8(src_argb[2]); >+ const uint32_t a = REPEAT8(src_argb[3]); > dst_argb[0] = SHADE(b, b_scale); > dst_argb[1] = SHADE(g, g_scale); > dst_argb[2] = SHADE(r, r_scale); >@@ -793,20 +877,20 @@ void ARGBShadeRow_C(const uint8* src_argb, > #define REPEAT8(v) (v) | ((v) << 8) > #define SHADE(f, v) v* f >> 16 > >-void ARGBMultiplyRow_C(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_C(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > int i; > for (i = 0; i < width; ++i) { >- const uint32 b = REPEAT8(src_argb0[0]); >- const uint32 g = REPEAT8(src_argb0[1]); >- const uint32 r = REPEAT8(src_argb0[2]); >- const uint32 a = REPEAT8(src_argb0[3]); >- const uint32 b_scale = src_argb1[0]; >- const uint32 g_scale = src_argb1[1]; >- const uint32 r_scale = src_argb1[2]; >- const uint32 a_scale = src_argb1[3]; >+ const uint32_t b = REPEAT8(src_argb0[0]); >+ const uint32_t g = REPEAT8(src_argb0[1]); >+ const uint32_t r = REPEAT8(src_argb0[2]); >+ const uint32_t a = REPEAT8(src_argb0[3]); >+ const uint32_t b_scale = src_argb1[0]; >+ const uint32_t g_scale = src_argb1[1]; >+ const uint32_t r_scale = src_argb1[2]; >+ const uint32_t a_scale = src_argb1[3]; > dst_argb[0] = SHADE(b, b_scale); > dst_argb[1] = SHADE(g, g_scale); > dst_argb[2] = SHADE(r, r_scale); >@@ -821,9 +905,9 @@ void ARGBMultiplyRow_C(const uint8* src_argb0, > > #define SHADE(f, v) clamp255(v + f) > >-void ARGBAddRow_C(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_C(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > int i; > for (i = 0; i < width; ++i) { >@@ -848,9 +932,9 @@ void ARGBAddRow_C(const uint8* src_argb0, > > #define SHADE(f, v) clamp0(f - v) > >-void ARGBSubtractRow_C(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_C(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > int i; > for (i = 0; i < width; ++i) { >@@ -874,10 +958,10 @@ void ARGBSubtractRow_C(const uint8* src_argb0, > #undef SHADE > > // Sobel functions which mimics SSSE3. >-void SobelXRow_C(const uint8* src_y0, >- const uint8* src_y1, >- const uint8* src_y2, >- uint8* dst_sobelx, >+void SobelXRow_C(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ const uint8_t* src_y2, >+ uint8_t* dst_sobelx, > int width) { > int i; > for (i = 0; i < width; ++i) { >@@ -891,13 +975,13 @@ void SobelXRow_C(const uint8* src_y0, > int b_diff = b - b_sub; > int c_diff = c - c_sub; > int sobel = Abs(a_diff + b_diff * 2 + c_diff); >- dst_sobelx[i] = (uint8)(clamp255(sobel)); >+ dst_sobelx[i] = (uint8_t)(clamp255(sobel)); > } > } > >-void SobelYRow_C(const uint8* src_y0, >- const uint8* src_y1, >- uint8* dst_sobely, >+void SobelYRow_C(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ uint8_t* dst_sobely, > int width) { > int i; > for (i = 0; i < width; ++i) { >@@ -911,62 +995,62 @@ void SobelYRow_C(const uint8* src_y0, > int b_diff = b - b_sub; > int c_diff = c - c_sub; > int sobel = Abs(a_diff + b_diff * 2 + c_diff); >- dst_sobely[i] = (uint8)(clamp255(sobel)); >+ dst_sobely[i] = (uint8_t)(clamp255(sobel)); > } > } > >-void SobelRow_C(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_C(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { > int i; > for (i = 0; i < width; ++i) { > int r = src_sobelx[i]; > int b = src_sobely[i]; > int s = clamp255(r + b); >- dst_argb[0] = (uint8)(s); >- dst_argb[1] = (uint8)(s); >- dst_argb[2] = (uint8)(s); >- dst_argb[3] = (uint8)(255u); >+ dst_argb[0] = (uint8_t)(s); >+ dst_argb[1] = (uint8_t)(s); >+ dst_argb[2] = (uint8_t)(s); >+ dst_argb[3] = (uint8_t)(255u); > dst_argb += 4; > } > } > >-void SobelToPlaneRow_C(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_C(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_y, > int width) { > int i; > for (i = 0; i < width; ++i) { > int r = src_sobelx[i]; > int b = src_sobely[i]; > int s = clamp255(r + b); >- dst_y[i] = (uint8)(s); >+ dst_y[i] = (uint8_t)(s); > } > } > >-void SobelXYRow_C(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_C(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { > int i; > for (i = 0; i < width; ++i) { > int r = src_sobelx[i]; > int b = src_sobely[i]; > int g = clamp255(r + b); >- dst_argb[0] = (uint8)(b); >- dst_argb[1] = (uint8)(g); >- dst_argb[2] = (uint8)(r); >- dst_argb[3] = (uint8)(255u); >+ dst_argb[0] = (uint8_t)(b); >+ dst_argb[1] = (uint8_t)(g); >+ dst_argb[2] = (uint8_t)(r); >+ dst_argb[3] = (uint8_t)(255u); > dst_argb += 4; > } > } > >-void J400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) { >+void J400ToARGBRow_C(const uint8_t* src_y, uint8_t* dst_argb, int width) { > // Copy a Y to RGB. > int x; > for (x = 0; x < width; ++x) { >- uint8 y = src_y[0]; >+ uint8_t y = src_y[0]; > dst_argb[2] = dst_argb[1] = dst_argb[0] = y; > dst_argb[3] = 255u; > dst_argb += 4; >@@ -1223,12 +1307,14 @@ const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { > #undef YG > > // C reference code that mimics the YUV assembly. >-static __inline void YuvPixel(uint8 y, >- uint8 u, >- uint8 v, >- uint8* b, >- uint8* g, >- uint8* r, >+// Reads 8 bit YUV and leaves result as 16 bit. >+ >+static __inline void YuvPixel(uint8_t y, >+ uint8_t u, >+ uint8_t v, >+ uint8_t* b, >+ uint8_t* g, >+ uint8_t* r, > const struct YuvConstants* yuvconstants) { > #if defined(__aarch64__) > int ub = -yuvconstants->kUVToRB[0]; >@@ -1259,10 +1345,117 @@ static __inline void YuvPixel(uint8 y, > int yg = yuvconstants->kYToRgb[0]; > #endif > >- uint32 y1 = (uint32)(y * 0x0101 * yg) >> 16; >- *b = Clamp((int32)(-(u * ub) + y1 + bb) >> 6); >- *g = Clamp((int32)(-(u * ug + v * vg) + y1 + bg) >> 6); >- *r = Clamp((int32)(-(v * vr) + y1 + br) >> 6); >+ uint32_t y1 = (uint32_t)(y * 0x0101 * yg) >> 16; >+ *b = Clamp((int32_t)(-(u * ub) + y1 + bb) >> 6); >+ *g = Clamp((int32_t)(-(u * ug + v * vg) + y1 + bg) >> 6); >+ *r = Clamp((int32_t)(-(v * vr) + y1 + br) >> 6); >+} >+ >+// Reads 8 bit YUV and leaves result as 16 bit. >+static __inline void YuvPixel8_16(uint8_t y, >+ uint8_t u, >+ uint8_t v, >+ int* b, >+ int* g, >+ int* r, >+ const struct YuvConstants* yuvconstants) { >+#if defined(__aarch64__) >+ int ub = -yuvconstants->kUVToRB[0]; >+ int ug = yuvconstants->kUVToG[0]; >+ int vg = yuvconstants->kUVToG[1]; >+ int vr = -yuvconstants->kUVToRB[1]; >+ int bb = yuvconstants->kUVBiasBGR[0]; >+ int bg = yuvconstants->kUVBiasBGR[1]; >+ int br = yuvconstants->kUVBiasBGR[2]; >+ int yg = yuvconstants->kYToRgb[0] / 0x0101; >+#elif defined(__arm__) >+ int ub = -yuvconstants->kUVToRB[0]; >+ int ug = yuvconstants->kUVToG[0]; >+ int vg = yuvconstants->kUVToG[4]; >+ int vr = -yuvconstants->kUVToRB[4]; >+ int bb = yuvconstants->kUVBiasBGR[0]; >+ int bg = yuvconstants->kUVBiasBGR[1]; >+ int br = yuvconstants->kUVBiasBGR[2]; >+ int yg = yuvconstants->kYToRgb[0] / 0x0101; >+#else >+ int ub = yuvconstants->kUVToB[0]; >+ int ug = yuvconstants->kUVToG[0]; >+ int vg = yuvconstants->kUVToG[1]; >+ int vr = yuvconstants->kUVToR[1]; >+ int bb = yuvconstants->kUVBiasB[0]; >+ int bg = yuvconstants->kUVBiasG[0]; >+ int br = yuvconstants->kUVBiasR[0]; >+ int yg = yuvconstants->kYToRgb[0]; >+#endif >+ >+ uint32_t y1 = (uint32_t)(y * 0x0101 * yg) >> 16; >+ *b = (int)(-(u * ub) + y1 + bb); >+ *g = (int)(-(u * ug + v * vg) + y1 + bg); >+ *r = (int)(-(v * vr) + y1 + br); >+} >+ >+// C reference code that mimics the YUV 16 bit assembly. >+// Reads 10 bit YUV and leaves result as 16 bit. >+static __inline void YuvPixel16(int16_t y, >+ int16_t u, >+ int16_t v, >+ int* b, >+ int* g, >+ int* r, >+ const struct YuvConstants* yuvconstants) { >+#if defined(__aarch64__) >+ int ub = -yuvconstants->kUVToRB[0]; >+ int ug = yuvconstants->kUVToG[0]; >+ int vg = yuvconstants->kUVToG[1]; >+ int vr = -yuvconstants->kUVToRB[1]; >+ int bb = yuvconstants->kUVBiasBGR[0]; >+ int bg = yuvconstants->kUVBiasBGR[1]; >+ int br = yuvconstants->kUVBiasBGR[2]; >+ int yg = yuvconstants->kYToRgb[0] / 0x0101; >+#elif defined(__arm__) >+ int ub = -yuvconstants->kUVToRB[0]; >+ int ug = yuvconstants->kUVToG[0]; >+ int vg = yuvconstants->kUVToG[4]; >+ int vr = -yuvconstants->kUVToRB[4]; >+ int bb = yuvconstants->kUVBiasBGR[0]; >+ int bg = yuvconstants->kUVBiasBGR[1]; >+ int br = yuvconstants->kUVBiasBGR[2]; >+ int yg = yuvconstants->kYToRgb[0] / 0x0101; >+#else >+ int ub = yuvconstants->kUVToB[0]; >+ int ug = yuvconstants->kUVToG[0]; >+ int vg = yuvconstants->kUVToG[1]; >+ int vr = yuvconstants->kUVToR[1]; >+ int bb = yuvconstants->kUVBiasB[0]; >+ int bg = yuvconstants->kUVBiasG[0]; >+ int br = yuvconstants->kUVBiasR[0]; >+ int yg = yuvconstants->kYToRgb[0]; >+#endif >+ >+ uint32_t y1 = (uint32_t)((y << 6) * yg) >> 16; >+ u = clamp255(u >> 2); >+ v = clamp255(v >> 2); >+ *b = (int)(-(u * ub) + y1 + bb); >+ *g = (int)(-(u * ug + v * vg) + y1 + bg); >+ *r = (int)(-(v * vr) + y1 + br); >+} >+ >+// C reference code that mimics the YUV 10 bit assembly. >+// Reads 10 bit YUV and clamps down to 8 bit RGB. >+static __inline void YuvPixel10(uint16_t y, >+ uint16_t u, >+ uint16_t v, >+ uint8_t* b, >+ uint8_t* g, >+ uint8_t* r, >+ const struct YuvConstants* yuvconstants) { >+ int b16; >+ int g16; >+ int r16; >+ YuvPixel16(y, u, v, &b16, &g16, &r16, yuvconstants); >+ *b = Clamp(b16 >> 6); >+ *g = Clamp(g16 >> 6); >+ *r = Clamp(r16 >> 6); > } > > // Y contribution to R,G,B. Scale and bias. >@@ -1270,11 +1463,11 @@ static __inline void YuvPixel(uint8 y, > #define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */ > > // C reference code that mimics the YUV assembly. >-static __inline void YPixel(uint8 y, uint8* b, uint8* g, uint8* r) { >- uint32 y1 = (uint32)(y * 0x0101 * YG) >> 16; >- *b = Clamp((int32)(y1 + YGB) >> 6); >- *g = Clamp((int32)(y1 + YGB) >> 6); >- *r = Clamp((int32)(y1 + YGB) >> 6); >+static __inline void YPixel(uint8_t y, uint8_t* b, uint8_t* g, uint8_t* r) { >+ uint32_t y1 = (uint32_t)(y * 0x0101 * YG) >> 16; >+ *b = Clamp((int32_t)(y1 + YGB) >> 6); >+ *g = Clamp((int32_t)(y1 + YGB) >> 6); >+ *r = Clamp((int32_t)(y1 + YGB) >> 6); > } > > #undef YG >@@ -1284,16 +1477,16 @@ static __inline void YPixel(uint8 y, uint8* b, uint8* g, uint8* r) { > (defined(__ARM_NEON__) || defined(__aarch64__) || defined(LIBYUV_NEON)) > // C mimic assembly. > // TODO(fbarchard): Remove subsampling from Neon. >-void I444ToARGBRow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* rgb_buf, >+void I444ToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) { > int x; > for (x = 0; x < width - 1; x += 2) { >- uint8 u = (src_u[0] + src_u[1] + 1) >> 1; >- uint8 v = (src_v[0] + src_v[1] + 1) >> 1; >+ uint8_t u = (src_u[0] + src_u[1] + 1) >> 1; >+ uint8_t v = (src_v[0] + src_v[1] + 1) >> 1; > YuvPixel(src_y[0], u, v, rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, > yuvconstants); > rgb_buf[3] = 255; >@@ -1312,10 +1505,10 @@ void I444ToARGBRow_C(const uint8* src_y, > } > } > #else >-void I444ToARGBRow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* rgb_buf, >+void I444ToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -1332,10 +1525,10 @@ void I444ToARGBRow_C(const uint8* src_y, > #endif > > // Also used for 420 >-void I422ToARGBRow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* rgb_buf, >+void I422ToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -1358,11 +1551,105 @@ void I422ToARGBRow_C(const uint8* src_y, > } > } > >-void I422AlphaToARGBRow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- const uint8* src_a, >- uint8* rgb_buf, >+// 10 bit YUV to ARGB >+void I210ToARGBRow_C(const uint16_t* src_y, >+ const uint16_t* src_u, >+ const uint16_t* src_v, >+ uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ int x; >+ for (x = 0; x < width - 1; x += 2) { >+ YuvPixel10(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, >+ rgb_buf + 2, yuvconstants); >+ rgb_buf[3] = 255; >+ YuvPixel10(src_y[1], src_u[0], src_v[0], rgb_buf + 4, rgb_buf + 5, >+ rgb_buf + 6, yuvconstants); >+ rgb_buf[7] = 255; >+ src_y += 2; >+ src_u += 1; >+ src_v += 1; >+ rgb_buf += 8; // Advance 2 pixels. >+ } >+ if (width & 1) { >+ YuvPixel10(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, >+ rgb_buf + 2, yuvconstants); >+ rgb_buf[3] = 255; >+ } >+} >+ >+static void StoreAR30(uint8_t* rgb_buf, int b, int g, int r) { >+ uint32_t ar30; >+ b = b >> 4; // convert 10.6 to 10 bit. >+ g = g >> 4; >+ r = r >> 4; >+ b = Clamp10(b); >+ g = Clamp10(g); >+ r = Clamp10(r); >+ ar30 = b | ((uint32_t)g << 10) | ((uint32_t)r << 20) | 0xc0000000; >+ (*(uint32_t*)rgb_buf) = ar30; >+} >+ >+// 10 bit YUV to 10 bit AR30 >+void I210ToAR30Row_C(const uint16_t* src_y, >+ const uint16_t* src_u, >+ const uint16_t* src_v, >+ uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ int x; >+ int b; >+ int g; >+ int r; >+ for (x = 0; x < width - 1; x += 2) { >+ YuvPixel16(src_y[0], src_u[0], src_v[0], &b, &g, &r, yuvconstants); >+ StoreAR30(rgb_buf, b, g, r); >+ YuvPixel16(src_y[1], src_u[0], src_v[0], &b, &g, &r, yuvconstants); >+ StoreAR30(rgb_buf + 4, b, g, r); >+ src_y += 2; >+ src_u += 1; >+ src_v += 1; >+ rgb_buf += 8; // Advance 2 pixels. >+ } >+ if (width & 1) { >+ YuvPixel16(src_y[0], src_u[0], src_v[0], &b, &g, &r, yuvconstants); >+ StoreAR30(rgb_buf, b, g, r); >+ } >+} >+ >+// 8 bit YUV to 10 bit AR30 >+// Uses same code as 10 bit YUV bit shifts the 8 bit values up to 10 bits. >+void I422ToAR30Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ int x; >+ int b; >+ int g; >+ int r; >+ for (x = 0; x < width - 1; x += 2) { >+ YuvPixel8_16(src_y[0], src_u[0], src_v[0], &b, &g, &r, yuvconstants); >+ StoreAR30(rgb_buf, b, g, r); >+ YuvPixel8_16(src_y[1], src_u[0], src_v[0], &b, &g, &r, yuvconstants); >+ StoreAR30(rgb_buf + 4, b, g, r); >+ src_y += 2; >+ src_u += 1; >+ src_v += 1; >+ rgb_buf += 8; // Advance 2 pixels. >+ } >+ if (width & 1) { >+ YuvPixel8_16(src_y[0], src_u[0], src_v[0], &b, &g, &r, yuvconstants); >+ StoreAR30(rgb_buf, b, g, r); >+ } >+} >+ >+void I422AlphaToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ const uint8_t* src_a, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -1386,10 +1673,10 @@ void I422AlphaToARGBRow_C(const uint8* src_y, > } > } > >-void I422ToRGB24Row_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* rgb_buf, >+void I422ToRGB24Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -1409,18 +1696,18 @@ void I422ToRGB24Row_C(const uint8* src_y, > } > } > >-void I422ToARGB4444Row_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB4444Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width) { >- uint8 b0; >- uint8 g0; >- uint8 r0; >- uint8 b1; >- uint8 g1; >- uint8 r1; >+ uint8_t b0; >+ uint8_t g0; >+ uint8_t r0; >+ uint8_t b1; >+ uint8_t g1; >+ uint8_t r1; > int x; > for (x = 0; x < width - 1; x += 2) { > YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants); >@@ -1431,8 +1718,8 @@ void I422ToARGB4444Row_C(const uint8* src_y, > b1 = b1 >> 4; > g1 = g1 >> 4; > r1 = r1 >> 4; >- *(uint32*)(dst_argb4444) = b0 | (g0 << 4) | (r0 << 8) | (b1 << 16) | >- (g1 << 20) | (r1 << 24) | 0xf000f000; >+ *(uint32_t*)(dst_argb4444) = b0 | (g0 << 4) | (r0 << 8) | (b1 << 16) | >+ (g1 << 20) | (r1 << 24) | 0xf000f000; > src_y += 2; > src_u += 1; > src_v += 1; >@@ -1443,22 +1730,22 @@ void I422ToARGB4444Row_C(const uint8* src_y, > b0 = b0 >> 4; > g0 = g0 >> 4; > r0 = r0 >> 4; >- *(uint16*)(dst_argb4444) = b0 | (g0 << 4) | (r0 << 8) | 0xf000; >+ *(uint16_t*)(dst_argb4444) = b0 | (g0 << 4) | (r0 << 8) | 0xf000; > } > } > >-void I422ToARGB1555Row_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb1555, >+void I422ToARGB1555Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width) { >- uint8 b0; >- uint8 g0; >- uint8 r0; >- uint8 b1; >- uint8 g1; >- uint8 r1; >+ uint8_t b0; >+ uint8_t g0; >+ uint8_t r0; >+ uint8_t b1; >+ uint8_t g1; >+ uint8_t r1; > int x; > for (x = 0; x < width - 1; x += 2) { > YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants); >@@ -1469,8 +1756,8 @@ void I422ToARGB1555Row_C(const uint8* src_y, > b1 = b1 >> 3; > g1 = g1 >> 3; > r1 = r1 >> 3; >- *(uint32*)(dst_argb1555) = b0 | (g0 << 5) | (r0 << 10) | (b1 << 16) | >- (g1 << 21) | (r1 << 26) | 0x80008000; >+ *(uint32_t*)(dst_argb1555) = b0 | (g0 << 5) | (r0 << 10) | (b1 << 16) | >+ (g1 << 21) | (r1 << 26) | 0x80008000; > src_y += 2; > src_u += 1; > src_v += 1; >@@ -1481,22 +1768,22 @@ void I422ToARGB1555Row_C(const uint8* src_y, > b0 = b0 >> 3; > g0 = g0 >> 3; > r0 = r0 >> 3; >- *(uint16*)(dst_argb1555) = b0 | (g0 << 5) | (r0 << 10) | 0x8000; >+ *(uint16_t*)(dst_argb1555) = b0 | (g0 << 5) | (r0 << 10) | 0x8000; > } > } > >-void I422ToRGB565Row_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb565, >+void I422ToRGB565Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { >- uint8 b0; >- uint8 g0; >- uint8 r0; >- uint8 b1; >- uint8 g1; >- uint8 r1; >+ uint8_t b0; >+ uint8_t g0; >+ uint8_t r0; >+ uint8_t b1; >+ uint8_t g1; >+ uint8_t r1; > int x; > for (x = 0; x < width - 1; x += 2) { > YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants); >@@ -1507,7 +1794,7 @@ void I422ToRGB565Row_C(const uint8* src_y, > b1 = b1 >> 3; > g1 = g1 >> 2; > r1 = r1 >> 3; >- *(uint32*)(dst_rgb565) = >+ *(uint32_t*)(dst_rgb565) = > b0 | (g0 << 5) | (r0 << 11) | (b1 << 16) | (g1 << 21) | (r1 << 27); > src_y += 2; > src_u += 1; >@@ -1519,13 +1806,13 @@ void I422ToRGB565Row_C(const uint8* src_y, > b0 = b0 >> 3; > g0 = g0 >> 2; > r0 = r0 >> 3; >- *(uint16*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11); >+ *(uint16_t*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11); > } > } > >-void NV12ToARGBRow_C(const uint8* src_y, >- const uint8* src_uv, >- uint8* rgb_buf, >+void NV12ToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -1547,9 +1834,9 @@ void NV12ToARGBRow_C(const uint8* src_y, > } > } > >-void NV21ToARGBRow_C(const uint8* src_y, >- const uint8* src_vu, >- uint8* rgb_buf, >+void NV21ToARGBRow_C(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -1571,17 +1858,59 @@ void NV21ToARGBRow_C(const uint8* src_y, > } > } > >-void NV12ToRGB565Row_C(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_rgb565, >+void NV12ToRGB24Row_C(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ int x; >+ for (x = 0; x < width - 1; x += 2) { >+ YuvPixel(src_y[0], src_uv[0], src_uv[1], rgb_buf + 0, rgb_buf + 1, >+ rgb_buf + 2, yuvconstants); >+ YuvPixel(src_y[1], src_uv[0], src_uv[1], rgb_buf + 3, rgb_buf + 4, >+ rgb_buf + 5, yuvconstants); >+ src_y += 2; >+ src_uv += 2; >+ rgb_buf += 6; // Advance 2 pixels. >+ } >+ if (width & 1) { >+ YuvPixel(src_y[0], src_uv[0], src_uv[1], rgb_buf + 0, rgb_buf + 1, >+ rgb_buf + 2, yuvconstants); >+ } >+} >+ >+void NV21ToRGB24Row_C(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* rgb_buf, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ int x; >+ for (x = 0; x < width - 1; x += 2) { >+ YuvPixel(src_y[0], src_vu[1], src_vu[0], rgb_buf + 0, rgb_buf + 1, >+ rgb_buf + 2, yuvconstants); >+ YuvPixel(src_y[1], src_vu[1], src_vu[0], rgb_buf + 3, rgb_buf + 4, >+ rgb_buf + 5, yuvconstants); >+ src_y += 2; >+ src_vu += 2; >+ rgb_buf += 6; // Advance 2 pixels. >+ } >+ if (width & 1) { >+ YuvPixel(src_y[0], src_vu[1], src_vu[0], rgb_buf + 0, rgb_buf + 1, >+ rgb_buf + 2, yuvconstants); >+ } >+} >+ >+void NV12ToRGB565Row_C(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { >- uint8 b0; >- uint8 g0; >- uint8 r0; >- uint8 b1; >- uint8 g1; >- uint8 r1; >+ uint8_t b0; >+ uint8_t g0; >+ uint8_t r0; >+ uint8_t b1; >+ uint8_t g1; >+ uint8_t r1; > int x; > for (x = 0; x < width - 1; x += 2) { > YuvPixel(src_y[0], src_uv[0], src_uv[1], &b0, &g0, &r0, yuvconstants); >@@ -1592,7 +1921,7 @@ void NV12ToRGB565Row_C(const uint8* src_y, > b1 = b1 >> 3; > g1 = g1 >> 2; > r1 = r1 >> 3; >- *(uint32*)(dst_rgb565) = >+ *(uint32_t*)(dst_rgb565) = > b0 | (g0 << 5) | (r0 << 11) | (b1 << 16) | (g1 << 21) | (r1 << 27); > src_y += 2; > src_uv += 2; >@@ -1603,12 +1932,12 @@ void NV12ToRGB565Row_C(const uint8* src_y, > b0 = b0 >> 3; > g0 = g0 >> 2; > r0 = r0 >> 3; >- *(uint16*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11); >+ *(uint16_t*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11); > } > } > >-void YUY2ToARGBRow_C(const uint8* src_yuy2, >- uint8* rgb_buf, >+void YUY2ToARGBRow_C(const uint8_t* src_yuy2, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -1629,8 +1958,8 @@ void YUY2ToARGBRow_C(const uint8* src_yuy2, > } > } > >-void UYVYToARGBRow_C(const uint8* src_uyvy, >- uint8* rgb_buf, >+void UYVYToARGBRow_C(const uint8_t* src_uyvy, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -1651,10 +1980,10 @@ void UYVYToARGBRow_C(const uint8* src_uyvy, > } > } > >-void I422ToRGBARow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* rgb_buf, >+void I422ToRGBARow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* rgb_buf, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -1677,7 +2006,7 @@ void I422ToRGBARow_C(const uint8* src_y, > } > } > >-void I400ToARGBRow_C(const uint8* src_y, uint8* rgb_buf, int width) { >+void I400ToARGBRow_C(const uint8_t* src_y, uint8_t* rgb_buf, int width) { > int x; > for (x = 0; x < width - 1; x += 2) { > YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); >@@ -1693,7 +2022,7 @@ void I400ToARGBRow_C(const uint8* src_y, uint8* rgb_buf, int width) { > } > } > >-void MirrorRow_C(const uint8* src, uint8* dst, int width) { >+void MirrorRow_C(const uint8_t* src, uint8_t* dst, int width) { > int x; > src += width - 1; > for (x = 0; x < width - 1; x += 2) { >@@ -1706,7 +2035,10 @@ void MirrorRow_C(const uint8* src, uint8* dst, int width) { > } > } > >-void MirrorUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width) { >+void MirrorUVRow_C(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width) { > int x; > src_uv += (width - 1) << 1; > for (x = 0; x < width - 1; x += 2) { >@@ -1722,10 +2054,10 @@ void MirrorUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width) { > } > } > >-void ARGBMirrorRow_C(const uint8* src, uint8* dst, int width) { >+void ARGBMirrorRow_C(const uint8_t* src, uint8_t* dst, int width) { > int x; >- const uint32* src32 = (const uint32*)(src); >- uint32* dst32 = (uint32*)(dst); >+ const uint32_t* src32 = (const uint32_t*)(src); >+ uint32_t* dst32 = (uint32_t*)(dst); > src32 += width - 1; > for (x = 0; x < width - 1; x += 2) { > dst32[x] = src32[0]; >@@ -1737,7 +2069,10 @@ void ARGBMirrorRow_C(const uint8* src, uint8* dst, int width) { > } > } > >-void SplitUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width) { >+void SplitUVRow_C(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int width) { > int x; > for (x = 0; x < width - 1; x += 2) { > dst_u[x] = src_uv[0]; >@@ -1752,9 +2087,9 @@ void SplitUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width) { > } > } > >-void MergeUVRow_C(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_C(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width) { > int x; > for (x = 0; x < width - 1; x += 2) { >@@ -1770,10 +2105,10 @@ void MergeUVRow_C(const uint8* src_u, > } > } > >-void SplitRGBRow_C(const uint8* src_rgb, >- uint8* dst_r, >- uint8* dst_g, >- uint8* dst_b, >+void SplitRGBRow_C(const uint8_t* src_rgb, >+ uint8_t* dst_r, >+ uint8_t* dst_g, >+ uint8_t* dst_b, > int width) { > int x; > for (x = 0; x < width; ++x) { >@@ -1784,10 +2119,10 @@ void SplitRGBRow_C(const uint8* src_rgb, > } > } > >-void MergeRGBRow_C(const uint8* src_r, >- const uint8* src_g, >- const uint8* src_b, >- uint8* dst_rgb, >+void MergeRGBRow_C(const uint8_t* src_r, >+ const uint8_t* src_g, >+ const uint8_t* src_b, >+ uint8_t* dst_rgb, > int width) { > int x; > for (x = 0; x < width; ++x) { >@@ -1798,9 +2133,14 @@ void MergeRGBRow_C(const uint8* src_r, > } > } > >-void MergeUVRow_16_C(const uint16* src_u, >- const uint16* src_v, >- uint16* dst_uv, >+// Use scale to convert lsb formats to msb, depending how many bits there are: >+// 128 = 9 bits >+// 64 = 10 bits >+// 16 = 12 bits >+// 1 = 16 bits >+void MergeUVRow_16_C(const uint16_t* src_u, >+ const uint16_t* src_v, >+ uint16_t* dst_uv, > int scale, > int width) { > int x; >@@ -1817,8 +2157,8 @@ void MergeUVRow_16_C(const uint16* src_u, > } > } > >-void MultiplyRow_16_C(const uint16* src_y, >- uint16* dst_y, >+void MultiplyRow_16_C(const uint16_t* src_y, >+ uint16_t* dst_y, > int scale, > int width) { > int x; >@@ -1827,20 +2167,48 @@ void MultiplyRow_16_C(const uint16* src_y, > } > } > >-void CopyRow_C(const uint8* src, uint8* dst, int count) { >+// Use scale to convert lsb formats to msb, depending how many bits there are: >+// 32768 = 9 bits >+// 16384 = 10 bits >+// 4096 = 12 bits >+// 256 = 16 bits >+void Convert16To8Row_C(const uint16_t* src_y, >+ uint8_t* dst_y, >+ int scale, >+ int width) { >+ int x; >+ for (x = 0; x < width; ++x) { >+ dst_y[x] = clamp255((src_y[x] * scale) >> 16); >+ } >+} >+ >+// Use scale to convert lsb formats to msb, depending how many bits there are: >+// 1024 = 10 bits >+void Convert8To16Row_C(const uint8_t* src_y, >+ uint16_t* dst_y, >+ int scale, >+ int width) { >+ int x; >+ scale *= 0x0101; // replicates the byte. >+ for (x = 0; x < width; ++x) { >+ dst_y[x] = (src_y[x] * scale) >> 16; >+ } >+} >+ >+void CopyRow_C(const uint8_t* src, uint8_t* dst, int count) { > memcpy(dst, src, count); > } > >-void CopyRow_16_C(const uint16* src, uint16* dst, int count) { >+void CopyRow_16_C(const uint16_t* src, uint16_t* dst, int count) { > memcpy(dst, src, count * 2); > } > >-void SetRow_C(uint8* dst, uint8 v8, int width) { >+void SetRow_C(uint8_t* dst, uint8_t v8, int width) { > memset(dst, v8, width); > } > >-void ARGBSetRow_C(uint8* dst_argb, uint32 v32, int width) { >- uint32* d = (uint32*)(dst_argb); >+void ARGBSetRow_C(uint8_t* dst_argb, uint32_t v32, int width) { >+ uint32_t* d = (uint32_t*)(dst_argb); > int x; > for (x = 0; x < width; ++x) { > d[x] = v32; >@@ -1848,10 +2216,10 @@ void ARGBSetRow_C(uint8* dst_argb, uint32 v32, int width) { > } > > // Filter 2 rows of YUY2 UV's (422) into U and V (420). >-void YUY2ToUVRow_C(const uint8* src_yuy2, >+void YUY2ToUVRow_C(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > // Output a row of UV values, filtering 2 rows of YUY2. > int x; >@@ -1865,9 +2233,9 @@ void YUY2ToUVRow_C(const uint8* src_yuy2, > } > > // Copy row of YUY2 UV's (422) into U and V (422). >-void YUY2ToUV422Row_C(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_C(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > // Output a row of UV values. > int x; >@@ -1881,7 +2249,7 @@ void YUY2ToUV422Row_C(const uint8* src_yuy2, > } > > // Copy row of YUY2 Y's (422) into Y (420/422). >-void YUY2ToYRow_C(const uint8* src_yuy2, uint8* dst_y, int width) { >+void YUY2ToYRow_C(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { > // Output a row of Y values. > int x; > for (x = 0; x < width - 1; x += 2) { >@@ -1895,10 +2263,10 @@ void YUY2ToYRow_C(const uint8* src_yuy2, uint8* dst_y, int width) { > } > > // Filter 2 rows of UYVY UV's (422) into U and V (420). >-void UYVYToUVRow_C(const uint8* src_uyvy, >+void UYVYToUVRow_C(const uint8_t* src_uyvy, > int src_stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > // Output a row of UV values. > int x; >@@ -1912,9 +2280,9 @@ void UYVYToUVRow_C(const uint8* src_uyvy, > } > > // Copy row of UYVY UV's (422) into U and V (422). >-void UYVYToUV422Row_C(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_C(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > // Output a row of UV values. > int x; >@@ -1928,7 +2296,7 @@ void UYVYToUV422Row_C(const uint8* src_uyvy, > } > > // Copy row of UYVY Y's (422) into Y (420/422). >-void UYVYToYRow_C(const uint8* src_uyvy, uint8* dst_y, int width) { >+void UYVYToYRow_C(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { > // Output a row of Y values. > int x; > for (x = 0; x < width - 1; x += 2) { >@@ -1946,19 +2314,19 @@ void UYVYToYRow_C(const uint8* src_uyvy, uint8* dst_y, int width) { > // Blend src_argb0 over src_argb1 and store to dst_argb. > // dst_argb may be src_argb0 or src_argb1. > // This code mimics the SSSE3 version for better testability. >-void ARGBBlendRow_C(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBBlendRow_C(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > int x; > for (x = 0; x < width - 1; x += 2) { >- uint32 fb = src_argb0[0]; >- uint32 fg = src_argb0[1]; >- uint32 fr = src_argb0[2]; >- uint32 a = src_argb0[3]; >- uint32 bb = src_argb1[0]; >- uint32 bg = src_argb1[1]; >- uint32 br = src_argb1[2]; >+ uint32_t fb = src_argb0[0]; >+ uint32_t fg = src_argb0[1]; >+ uint32_t fr = src_argb0[2]; >+ uint32_t a = src_argb0[3]; >+ uint32_t bb = src_argb1[0]; >+ uint32_t bg = src_argb1[1]; >+ uint32_t br = src_argb1[2]; > dst_argb[0] = BLEND(fb, bb, a); > dst_argb[1] = BLEND(fg, bg, a); > dst_argb[2] = BLEND(fr, br, a); >@@ -1981,13 +2349,13 @@ void ARGBBlendRow_C(const uint8* src_argb0, > } > > if (width & 1) { >- uint32 fb = src_argb0[0]; >- uint32 fg = src_argb0[1]; >- uint32 fr = src_argb0[2]; >- uint32 a = src_argb0[3]; >- uint32 bb = src_argb1[0]; >- uint32 bg = src_argb1[1]; >- uint32 br = src_argb1[2]; >+ uint32_t fb = src_argb0[0]; >+ uint32_t fg = src_argb0[1]; >+ uint32_t fr = src_argb0[2]; >+ uint32_t a = src_argb0[3]; >+ uint32_t bb = src_argb1[0]; >+ uint32_t bg = src_argb1[1]; >+ uint32_t br = src_argb1[2]; > dst_argb[0] = BLEND(fb, bb, a); > dst_argb[1] = BLEND(fg, bg, a); > dst_argb[2] = BLEND(fr, br, a); >@@ -1997,10 +2365,10 @@ void ARGBBlendRow_C(const uint8* src_argb0, > #undef BLEND > > #define UBLEND(f, b, a) (((a)*f) + ((255 - a) * b) + 255) >> 8 >-void BlendPlaneRow_C(const uint8* src0, >- const uint8* src1, >- const uint8* alpha, >- uint8* dst, >+void BlendPlaneRow_C(const uint8_t* src0, >+ const uint8_t* src1, >+ const uint8_t* alpha, >+ uint8_t* dst, > int width) { > int x; > for (x = 0; x < width - 1; x += 2) { >@@ -2021,13 +2389,13 @@ void BlendPlaneRow_C(const uint8* src0, > > // Multiply source RGB by alpha and store to destination. > // This code mimics the SSSE3 version for better testability. >-void ARGBAttenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) { >+void ARGBAttenuateRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width) { > int i; > for (i = 0; i < width - 1; i += 2) { >- uint32 b = src_argb[0]; >- uint32 g = src_argb[1]; >- uint32 r = src_argb[2]; >- uint32 a = src_argb[3]; >+ uint32_t b = src_argb[0]; >+ uint32_t g = src_argb[1]; >+ uint32_t r = src_argb[2]; >+ uint32_t a = src_argb[3]; > dst_argb[0] = ATTENUATE(b, a); > dst_argb[1] = ATTENUATE(g, a); > dst_argb[2] = ATTENUATE(r, a); >@@ -2045,10 +2413,10 @@ void ARGBAttenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) { > } > > if (width & 1) { >- const uint32 b = src_argb[0]; >- const uint32 g = src_argb[1]; >- const uint32 r = src_argb[2]; >- const uint32 a = src_argb[3]; >+ const uint32_t b = src_argb[0]; >+ const uint32_t g = src_argb[1]; >+ const uint32_t r = src_argb[2]; >+ const uint32_t a = src_argb[3]; > dst_argb[0] = ATTENUATE(b, a); > dst_argb[1] = ATTENUATE(g, a); > dst_argb[2] = ATTENUATE(r, a); >@@ -2064,7 +2432,7 @@ void ARGBAttenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) { > // Reciprocal method is off by 1 on some values. ie 125 > // 8.8 fixed point inverse table with 1.0 in upper short and 1 / a in lower. > #define T(a) 0x01000000 + (0x10000 / a) >-const uint32 fixed_invtbl8[256] = { >+const uint32_t fixed_invtbl8[256] = { > 0x01000000, 0x0100ffff, T(0x02), T(0x03), T(0x04), T(0x05), T(0x06), > T(0x07), T(0x08), T(0x09), T(0x0a), T(0x0b), T(0x0c), T(0x0d), > T(0x0e), T(0x0f), T(0x10), T(0x11), T(0x12), T(0x13), T(0x14), >@@ -2104,14 +2472,16 @@ const uint32 fixed_invtbl8[256] = { > T(0xfc), T(0xfd), T(0xfe), 0x01000100}; > #undef T > >-void ARGBUnattenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) { >+void ARGBUnattenuateRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width) { > int i; > for (i = 0; i < width; ++i) { >- uint32 b = src_argb[0]; >- uint32 g = src_argb[1]; >- uint32 r = src_argb[2]; >- const uint32 a = src_argb[3]; >- const uint32 ia = fixed_invtbl8[a] & 0xffff; // 8.8 fixed point >+ uint32_t b = src_argb[0]; >+ uint32_t g = src_argb[1]; >+ uint32_t r = src_argb[2]; >+ const uint32_t a = src_argb[3]; >+ const uint32_t ia = fixed_invtbl8[a] & 0xffff; // 8.8 fixed point > b = (b * ia) >> 8; > g = (g * ia) >> 8; > r = (r * ia) >> 8; >@@ -2125,11 +2495,11 @@ void ARGBUnattenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) { > } > } > >-void ComputeCumulativeSumRow_C(const uint8* row, >- int32* cumsum, >- const int32* previous_cumsum, >+void ComputeCumulativeSumRow_C(const uint8_t* row, >+ int32_t* cumsum, >+ const int32_t* previous_cumsum, > int width) { >- int32 row_sum[4] = {0, 0, 0, 0}; >+ int32_t row_sum[4] = {0, 0, 0, 0}; > int x; > for (x = 0; x < width; ++x) { > row_sum[0] += row[x * 4 + 0]; >@@ -2143,19 +2513,19 @@ void ComputeCumulativeSumRow_C(const uint8* row, > } > } > >-void CumulativeSumToAverageRow_C(const int32* tl, >- const int32* bl, >+void CumulativeSumToAverageRow_C(const int32_t* tl, >+ const int32_t* bl, > int w, > int area, >- uint8* dst, >+ uint8_t* dst, > int count) { > float ooa = 1.0f / area; > int i; > for (i = 0; i < count; ++i) { >- dst[0] = (uint8)((bl[w + 0] + tl[0] - bl[0] - tl[w + 0]) * ooa); >- dst[1] = (uint8)((bl[w + 1] + tl[1] - bl[1] - tl[w + 1]) * ooa); >- dst[2] = (uint8)((bl[w + 2] + tl[2] - bl[2] - tl[w + 2]) * ooa); >- dst[3] = (uint8)((bl[w + 3] + tl[3] - bl[3] - tl[w + 3]) * ooa); >+ dst[0] = (uint8_t)((bl[w + 0] + tl[0] - bl[0] - tl[w + 0]) * ooa); >+ dst[1] = (uint8_t)((bl[w + 1] + tl[1] - bl[1] - tl[w + 1]) * ooa); >+ dst[2] = (uint8_t)((bl[w + 2] + tl[2] - bl[2] - tl[w + 2]) * ooa); >+ dst[3] = (uint8_t)((bl[w + 3] + tl[3] - bl[3] - tl[w + 3]) * ooa); > dst += 4; > tl += 4; > bl += 4; >@@ -2164,9 +2534,9 @@ void CumulativeSumToAverageRow_C(const int32* tl, > > // Copy pixels from rotated source to destination row with a slope. > LIBYUV_API >-void ARGBAffineRow_C(const uint8* src_argb, >+void ARGBAffineRow_C(const uint8_t* src_argb, > int src_argb_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > const float* uv_dudv, > int width) { > int i; >@@ -2177,8 +2547,8 @@ void ARGBAffineRow_C(const uint8* src_argb, > for (i = 0; i < width; ++i) { > int x = (int)(uv[0]); > int y = (int)(uv[1]); >- *(uint32*)(dst_argb) = >- *(const uint32*)(src_argb + y * src_argb_stride + x * 4); >+ *(uint32_t*)(dst_argb) = >+ *(const uint32_t*)(src_argb + y * src_argb_stride + x * 4); > dst_argb += 4; > uv[0] += uv_dudv[2]; > uv[1] += uv_dudv[3]; >@@ -2186,9 +2556,9 @@ void ARGBAffineRow_C(const uint8* src_argb, > } > > // Blend 2 rows into 1. >-static void HalfRow_C(const uint8* src_uv, >+static void HalfRow_C(const uint8_t* src_uv, > ptrdiff_t src_uv_stride, >- uint8* dst_uv, >+ uint8_t* dst_uv, > int width) { > int x; > for (x = 0; x < width; ++x) { >@@ -2196,9 +2566,9 @@ static void HalfRow_C(const uint8* src_uv, > } > } > >-static void HalfRow_16_C(const uint16* src_uv, >+static void HalfRow_16_C(const uint16_t* src_uv, > ptrdiff_t src_uv_stride, >- uint16* dst_uv, >+ uint16_t* dst_uv, > int width) { > int x; > for (x = 0; x < width; ++x) { >@@ -2207,14 +2577,14 @@ static void HalfRow_16_C(const uint16* src_uv, > } > > // C version 2x2 -> 2x1. >-void InterpolateRow_C(uint8* dst_ptr, >- const uint8* src_ptr, >+void InterpolateRow_C(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride, > int width, > int source_y_fraction) { > int y1_fraction = source_y_fraction; > int y0_fraction = 256 - y1_fraction; >- const uint8* src_ptr1 = src_ptr + src_stride; >+ const uint8_t* src_ptr1 = src_ptr + src_stride; > int x; > if (y1_fraction == 0) { > memcpy(dst_ptr, src_ptr, width); >@@ -2239,14 +2609,14 @@ void InterpolateRow_C(uint8* dst_ptr, > } > } > >-void InterpolateRow_16_C(uint16* dst_ptr, >- const uint16* src_ptr, >+void InterpolateRow_16_C(uint16_t* dst_ptr, >+ const uint16_t* src_ptr, > ptrdiff_t src_stride, > int width, > int source_y_fraction) { > int y1_fraction = source_y_fraction; > int y0_fraction = 256 - y1_fraction; >- const uint16* src_ptr1 = src_ptr + src_stride; >+ const uint16_t* src_ptr1 = src_ptr + src_stride; > int x; > if (source_y_fraction == 0) { > memcpy(dst_ptr, src_ptr, width * 2); >@@ -2269,9 +2639,9 @@ void InterpolateRow_16_C(uint16* dst_ptr, > } > > // Use first 4 shuffler values to reorder ARGB channels. >-void ARGBShuffleRow_C(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width) { > int index0 = shuffler[0]; > int index1 = shuffler[1]; >@@ -2281,10 +2651,10 @@ void ARGBShuffleRow_C(const uint8* src_argb, > int x; > for (x = 0; x < width; ++x) { > // To support in-place conversion. >- uint8 b = src_argb[index0]; >- uint8 g = src_argb[index1]; >- uint8 r = src_argb[index2]; >- uint8 a = src_argb[index3]; >+ uint8_t b = src_argb[index0]; >+ uint8_t g = src_argb[index1]; >+ uint8_t r = src_argb[index2]; >+ uint8_t a = src_argb[index3]; > dst_argb[0] = b; > dst_argb[1] = g; > dst_argb[2] = r; >@@ -2294,10 +2664,10 @@ void ARGBShuffleRow_C(const uint8* src_argb, > } > } > >-void I422ToYUY2Row_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_frame, >+void I422ToYUY2Row_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_frame, > int width) { > int x; > for (x = 0; x < width - 1; x += 2) { >@@ -2318,10 +2688,10 @@ void I422ToYUY2Row_C(const uint8* src_y, > } > } > >-void I422ToUYVYRow_C(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_frame, >+void I422ToUYVYRow_C(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_frame, > int width) { > int x; > for (x = 0; x < width - 1; x += 2) { >@@ -2342,8 +2712,8 @@ void I422ToUYVYRow_C(const uint8* src_y, > } > } > >-void ARGBPolynomialRow_C(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBPolynomialRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, > const float* poly, > int width) { > int i; >@@ -2373,10 +2743,10 @@ void ARGBPolynomialRow_C(const uint8* src_argb, > dr += poly[14] * r3; > da += poly[15] * a3; > >- dst_argb[0] = Clamp((int32)(db)); >- dst_argb[1] = Clamp((int32)(dg)); >- dst_argb[2] = Clamp((int32)(dr)); >- dst_argb[3] = Clamp((int32)(da)); >+ dst_argb[0] = Clamp((int32_t)(db)); >+ dst_argb[1] = Clamp((int32_t)(dg)); >+ dst_argb[2] = Clamp((int32_t)(dr)); >+ dst_argb[3] = Clamp((int32_t)(da)); > src_argb += 4; > dst_argb += 4; > } >@@ -2392,31 +2762,42 @@ void ARGBPolynomialRow_C(const uint8* src_argb, > // simply extract the low bits of the exponent and the high > // bits of the mantissa from our float and we're done. > >-void HalfFloatRow_C(const uint16* src, uint16* dst, float scale, int width) { >+void HalfFloatRow_C(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width) { > int i; > float mult = 1.9259299444e-34f * scale; > for (i = 0; i < width; ++i) { > float value = src[i] * mult; >- dst[i] = (uint16)((*(uint32_t*)&value) >> 13); >+ dst[i] = (uint16_t)((*(uint32_t*)&value) >> 13); >+ } >+} >+ >+void ByteToFloatRow_C(const uint8_t* src, float* dst, float scale, int width) { >+ int i; >+ for (i = 0; i < width; ++i) { >+ float value = src[i] * scale; >+ dst[i] = value; > } > } > >-void ARGBLumaColorTableRow_C(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBLumaColorTableRow_C(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- const uint8* luma, >- uint32 lumacoeff) { >- uint32 bc = lumacoeff & 0xff; >- uint32 gc = (lumacoeff >> 8) & 0xff; >- uint32 rc = (lumacoeff >> 16) & 0xff; >+ const uint8_t* luma, >+ uint32_t lumacoeff) { >+ uint32_t bc = lumacoeff & 0xff; >+ uint32_t gc = (lumacoeff >> 8) & 0xff; >+ uint32_t rc = (lumacoeff >> 16) & 0xff; > > int i; > for (i = 0; i < width - 1; i += 2) { > // Luminance in rows, color values in columns. >- const uint8* luma0 = >+ const uint8_t* luma0 = > ((src_argb[0] * bc + src_argb[1] * gc + src_argb[2] * rc) & 0x7F00u) + > luma; >- const uint8* luma1; >+ const uint8_t* luma1; > dst_argb[0] = luma0[src_argb[0]]; > dst_argb[1] = luma0[src_argb[1]]; > dst_argb[2] = luma0[src_argb[2]]; >@@ -2433,7 +2814,7 @@ void ARGBLumaColorTableRow_C(const uint8* src_argb, > } > if (width & 1) { > // Luminance in rows, color values in columns. >- const uint8* luma0 = >+ const uint8_t* luma0 = > ((src_argb[0] * bc + src_argb[1] * gc + src_argb[2] * rc) & 0x7F00u) + > luma; > dst_argb[0] = luma0[src_argb[0]]; >@@ -2443,7 +2824,7 @@ void ARGBLumaColorTableRow_C(const uint8* src_argb, > } > } > >-void ARGBCopyAlphaRow_C(const uint8* src, uint8* dst, int width) { >+void ARGBCopyAlphaRow_C(const uint8_t* src, uint8_t* dst, int width) { > int i; > for (i = 0; i < width - 1; i += 2) { > dst[3] = src[3]; >@@ -2456,7 +2837,7 @@ void ARGBCopyAlphaRow_C(const uint8* src, uint8* dst, int width) { > } > } > >-void ARGBExtractAlphaRow_C(const uint8* src_argb, uint8* dst_a, int width) { >+void ARGBExtractAlphaRow_C(const uint8_t* src_argb, uint8_t* dst_a, int width) { > int i; > for (i = 0; i < width - 1; i += 2) { > dst_a[0] = src_argb[3]; >@@ -2469,7 +2850,7 @@ void ARGBExtractAlphaRow_C(const uint8* src_argb, uint8* dst_a, int width) { > } > } > >-void ARGBCopyYToAlphaRow_C(const uint8* src, uint8* dst, int width) { >+void ARGBCopyYToAlphaRow_C(const uint8_t* src, uint8_t* dst, int width) { > int i; > for (i = 0; i < width - 1; i += 2) { > dst[3] = src[0]; >@@ -2488,13 +2869,13 @@ void ARGBCopyYToAlphaRow_C(const uint8* src, uint8* dst, int width) { > #if !(defined(_MSC_VER) && defined(_M_IX86)) && \ > defined(HAS_I422TORGB565ROW_SSSE3) > // row_win.cc has asm version, but GCC uses 2 step wrapper. >-void I422ToRGB565Row_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb565, >+void I422ToRGB565Row_SSSE3(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { >- SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); >+ SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); > while (width > 0) { > int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; > I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth); >@@ -2509,14 +2890,14 @@ void I422ToRGB565Row_SSSE3(const uint8* src_y, > #endif > > #if defined(HAS_I422TOARGB1555ROW_SSSE3) >-void I422ToARGB1555Row_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb1555, >+void I422ToARGB1555Row_SSSE3(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width) { > // Row buffer for intermediate ARGB pixels. >- SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); >+ SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); > while (width > 0) { > int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; > I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth); >@@ -2531,14 +2912,14 @@ void I422ToARGB1555Row_SSSE3(const uint8* src_y, > #endif > > #if defined(HAS_I422TOARGB4444ROW_SSSE3) >-void I422ToARGB4444Row_SSSE3(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB4444Row_SSSE3(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width) { > // Row buffer for intermediate ARGB pixels. >- SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); >+ SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); > while (width > 0) { > int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; > I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth); >@@ -2553,13 +2934,13 @@ void I422ToARGB4444Row_SSSE3(const uint8* src_y, > #endif > > #if defined(HAS_NV12TORGB565ROW_SSSE3) >-void NV12ToRGB565Row_SSSE3(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_rgb565, >+void NV12ToRGB565Row_SSSE3(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { > // Row buffer for intermediate ARGB pixels. >- SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); >+ SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); > while (width > 0) { > int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; > NV12ToARGBRow_SSSE3(src_y, src_uv, row, yuvconstants, twidth); >@@ -2573,13 +2954,13 @@ void NV12ToRGB565Row_SSSE3(const uint8* src_y, > #endif > > #if defined(HAS_I422TORGB565ROW_AVX2) >-void I422ToRGB565Row_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb565, >+void I422ToRGB565Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { >- SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); >+ SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); > while (width > 0) { > int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; > I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth); >@@ -2598,14 +2979,14 @@ void I422ToRGB565Row_AVX2(const uint8* src_y, > #endif > > #if defined(HAS_I422TOARGB1555ROW_AVX2) >-void I422ToARGB1555Row_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb1555, >+void I422ToARGB1555Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width) { > // Row buffer for intermediate ARGB pixels. >- SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); >+ SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); > while (width > 0) { > int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; > I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth); >@@ -2624,14 +3005,14 @@ void I422ToARGB1555Row_AVX2(const uint8* src_y, > #endif > > #if defined(HAS_I422TOARGB4444ROW_AVX2) >-void I422ToARGB4444Row_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB4444Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width) { > // Row buffer for intermediate ARGB pixels. >- SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); >+ SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); > while (width > 0) { > int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; > I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth); >@@ -2650,14 +3031,14 @@ void I422ToARGB4444Row_AVX2(const uint8* src_y, > #endif > > #if defined(HAS_I422TORGB24ROW_AVX2) >-void I422ToRGB24Row_AVX2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb24, >+void I422ToRGB24Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb24, > const struct YuvConstants* yuvconstants, > int width) { > // Row buffer for intermediate ARGB pixels. >- SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); >+ SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); > while (width > 0) { > int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; > I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth); >@@ -2673,13 +3054,13 @@ void I422ToRGB24Row_AVX2(const uint8* src_y, > #endif > > #if defined(HAS_NV12TORGB565ROW_AVX2) >-void NV12ToRGB565Row_AVX2(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_rgb565, >+void NV12ToRGB565Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { > // Row buffer for intermediate ARGB pixels. >- SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); >+ SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); > while (width > 0) { > int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; > NV12ToARGBRow_AVX2(src_y, src_uv, row, yuvconstants, twidth); >@@ -2729,7 +3110,7 @@ void ScaleSamples_C(const float* src, float* dst, float scale, int width) { > } > } > >-void GaussRow_C(const uint32* src, uint16* dst, int width) { >+void GaussRow_C(const uint32_t* src, uint16_t* dst, int width) { > int i; > for (i = 0; i < width; ++i) { > *dst++ = >@@ -2739,12 +3120,12 @@ void GaussRow_C(const uint32* src, uint16* dst, int width) { > } > > // filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. >-void GaussCol_C(const uint16* src0, >- const uint16* src1, >- const uint16* src2, >- const uint16* src3, >- const uint16* src4, >- uint32* dst, >+void GaussCol_C(const uint16_t* src0, >+ const uint16_t* src1, >+ const uint16_t* src2, >+ const uint16_t* src3, >+ const uint16_t* src4, >+ uint32_t* dst, > int width) { > int i; > for (i = 0; i < width; ++i) { >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_gcc.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_gcc.cc >index b5c2e65c9381bec1ae2f1428d7a02cca6534b232..95845c2592f7c84307c37b00bf18274ea83b8cc9 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_gcc.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_gcc.cc >@@ -22,80 +22,80 @@ extern "C" { > #if defined(HAS_ARGBTOYROW_SSSE3) || defined(HAS_ARGBGRAYROW_SSSE3) > > // Constants for ARGB >-static vec8 kARGBToY = {13, 65, 33, 0, 13, 65, 33, 0, >- 13, 65, 33, 0, 13, 65, 33, 0}; >+static const vec8 kARGBToY = {13, 65, 33, 0, 13, 65, 33, 0, >+ 13, 65, 33, 0, 13, 65, 33, 0}; > > // JPeg full range. >-static vec8 kARGBToYJ = {15, 75, 38, 0, 15, 75, 38, 0, >- 15, 75, 38, 0, 15, 75, 38, 0}; >+static const vec8 kARGBToYJ = {15, 75, 38, 0, 15, 75, 38, 0, >+ 15, 75, 38, 0, 15, 75, 38, 0}; > #endif // defined(HAS_ARGBTOYROW_SSSE3) || defined(HAS_ARGBGRAYROW_SSSE3) > > #if defined(HAS_ARGBTOYROW_SSSE3) || defined(HAS_I422TOARGBROW_SSSE3) > >-static vec8 kARGBToU = {112, -74, -38, 0, 112, -74, -38, 0, >- 112, -74, -38, 0, 112, -74, -38, 0}; >+static const vec8 kARGBToU = {112, -74, -38, 0, 112, -74, -38, 0, >+ 112, -74, -38, 0, 112, -74, -38, 0}; > >-static vec8 kARGBToUJ = {127, -84, -43, 0, 127, -84, -43, 0, >- 127, -84, -43, 0, 127, -84, -43, 0}; >+static const vec8 kARGBToUJ = {127, -84, -43, 0, 127, -84, -43, 0, >+ 127, -84, -43, 0, 127, -84, -43, 0}; > >-static vec8 kARGBToV = {-18, -94, 112, 0, -18, -94, 112, 0, >- -18, -94, 112, 0, -18, -94, 112, 0}; >+static const vec8 kARGBToV = {-18, -94, 112, 0, -18, -94, 112, 0, >+ -18, -94, 112, 0, -18, -94, 112, 0}; > >-static vec8 kARGBToVJ = {-20, -107, 127, 0, -20, -107, 127, 0, >- -20, -107, 127, 0, -20, -107, 127, 0}; >+static const vec8 kARGBToVJ = {-20, -107, 127, 0, -20, -107, 127, 0, >+ -20, -107, 127, 0, -20, -107, 127, 0}; > > // Constants for BGRA >-static vec8 kBGRAToY = {0, 33, 65, 13, 0, 33, 65, 13, >- 0, 33, 65, 13, 0, 33, 65, 13}; >+static const vec8 kBGRAToY = {0, 33, 65, 13, 0, 33, 65, 13, >+ 0, 33, 65, 13, 0, 33, 65, 13}; > >-static vec8 kBGRAToU = {0, -38, -74, 112, 0, -38, -74, 112, >- 0, -38, -74, 112, 0, -38, -74, 112}; >+static const vec8 kBGRAToU = {0, -38, -74, 112, 0, -38, -74, 112, >+ 0, -38, -74, 112, 0, -38, -74, 112}; > >-static vec8 kBGRAToV = {0, 112, -94, -18, 0, 112, -94, -18, >- 0, 112, -94, -18, 0, 112, -94, -18}; >+static const vec8 kBGRAToV = {0, 112, -94, -18, 0, 112, -94, -18, >+ 0, 112, -94, -18, 0, 112, -94, -18}; > > // Constants for ABGR >-static vec8 kABGRToY = {33, 65, 13, 0, 33, 65, 13, 0, >- 33, 65, 13, 0, 33, 65, 13, 0}; >+static const vec8 kABGRToY = {33, 65, 13, 0, 33, 65, 13, 0, >+ 33, 65, 13, 0, 33, 65, 13, 0}; > >-static vec8 kABGRToU = {-38, -74, 112, 0, -38, -74, 112, 0, >- -38, -74, 112, 0, -38, -74, 112, 0}; >+static const vec8 kABGRToU = {-38, -74, 112, 0, -38, -74, 112, 0, >+ -38, -74, 112, 0, -38, -74, 112, 0}; > >-static vec8 kABGRToV = {112, -94, -18, 0, 112, -94, -18, 0, >- 112, -94, -18, 0, 112, -94, -18, 0}; >+static const vec8 kABGRToV = {112, -94, -18, 0, 112, -94, -18, 0, >+ 112, -94, -18, 0, 112, -94, -18, 0}; > > // Constants for RGBA. >-static vec8 kRGBAToY = {0, 13, 65, 33, 0, 13, 65, 33, >- 0, 13, 65, 33, 0, 13, 65, 33}; >+static const vec8 kRGBAToY = {0, 13, 65, 33, 0, 13, 65, 33, >+ 0, 13, 65, 33, 0, 13, 65, 33}; > >-static vec8 kRGBAToU = {0, 112, -74, -38, 0, 112, -74, -38, >- 0, 112, -74, -38, 0, 112, -74, -38}; >+static const vec8 kRGBAToU = {0, 112, -74, -38, 0, 112, -74, -38, >+ 0, 112, -74, -38, 0, 112, -74, -38}; > >-static vec8 kRGBAToV = {0, -18, -94, 112, 0, -18, -94, 112, >- 0, -18, -94, 112, 0, -18, -94, 112}; >+static const vec8 kRGBAToV = {0, -18, -94, 112, 0, -18, -94, 112, >+ 0, -18, -94, 112, 0, -18, -94, 112}; > >-static uvec8 kAddY16 = {16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, >- 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u}; >+static const uvec8 kAddY16 = {16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, >+ 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u}; > > // 7 bit fixed point 0.5. >-static vec16 kAddYJ64 = {64, 64, 64, 64, 64, 64, 64, 64}; >+static const vec16 kAddYJ64 = {64, 64, 64, 64, 64, 64, 64, 64}; > >-static uvec8 kAddUV128 = {128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u, >- 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; >+static const uvec8 kAddUV128 = {128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u, >+ 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; > >-static uvec16 kAddUVJ128 = {0x8080u, 0x8080u, 0x8080u, 0x8080u, >- 0x8080u, 0x8080u, 0x8080u, 0x8080u}; >+static const uvec16 kAddUVJ128 = {0x8080u, 0x8080u, 0x8080u, 0x8080u, >+ 0x8080u, 0x8080u, 0x8080u, 0x8080u}; > #endif // defined(HAS_ARGBTOYROW_SSSE3) || defined(HAS_I422TOARGBROW_SSSE3) > > #ifdef HAS_RGB24TOARGBROW_SSSE3 > > // Shuffle table for converting RGB24 to ARGB. >-static uvec8 kShuffleMaskRGB24ToARGB = {0u, 1u, 2u, 12u, 3u, 4u, 5u, 13u, >- 6u, 7u, 8u, 14u, 9u, 10u, 11u, 15u}; >+static const uvec8 kShuffleMaskRGB24ToARGB = { >+ 0u, 1u, 2u, 12u, 3u, 4u, 5u, 13u, 6u, 7u, 8u, 14u, 9u, 10u, 11u, 15u}; > > // Shuffle table for converting RAW to ARGB. >-static uvec8 kShuffleMaskRAWToARGB = {2u, 1u, 0u, 12u, 5u, 4u, 3u, 13u, >- 8u, 7u, 6u, 14u, 11u, 10u, 9u, 15u}; >+static const uvec8 kShuffleMaskRAWToARGB = {2u, 1u, 0u, 12u, 5u, 4u, 3u, 13u, >+ 8u, 7u, 6u, 14u, 11u, 10u, 9u, 15u}; > > // Shuffle table for converting RAW to RGB24. First 8. > static const uvec8 kShuffleMaskRAWToRGB24_0 = { >@@ -113,15 +113,15 @@ static const uvec8 kShuffleMaskRAWToRGB24_2 = { > 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; > > // Shuffle table for converting ARGB to RGB24. >-static uvec8 kShuffleMaskARGBToRGB24 = { >+static const uvec8 kShuffleMaskARGBToRGB24 = { > 0u, 1u, 2u, 4u, 5u, 6u, 8u, 9u, 10u, 12u, 13u, 14u, 128u, 128u, 128u, 128u}; > > // Shuffle table for converting ARGB to RAW. >-static uvec8 kShuffleMaskARGBToRAW = { >+static const uvec8 kShuffleMaskARGBToRAW = { > 2u, 1u, 0u, 6u, 5u, 4u, 10u, 9u, 8u, 14u, 13u, 12u, 128u, 128u, 128u, 128u}; > > // Shuffle table for converting ARGBToRGB24 for I422ToRGB24. First 8 + next 4 >-static uvec8 kShuffleMaskARGBToRGB24_0 = { >+static const uvec8 kShuffleMaskARGBToRGB24_0 = { > 0u, 1u, 2u, 4u, 5u, 6u, 8u, 9u, 128u, 128u, 128u, 128u, 10u, 12u, 13u, 14u}; > > // YUY2 shuf 16 Y to 32 Y. >@@ -152,392 +152,399 @@ static const lvec8 kShuffleNV21 = { > #endif // HAS_RGB24TOARGBROW_SSSE3 > > #ifdef HAS_J400TOARGBROW_SSE2 >-void J400ToARGBRow_SSE2(const uint8* src_y, uint8* dst_argb, int width) { >- asm volatile ( >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "pslld $0x18,%%xmm5 \n" >- LABELALIGN >- "1: \n" >- "movq " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x8,0) ",%0 \n" >- "punpcklbw %%xmm0,%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklwd %%xmm0,%%xmm0 \n" >- "punpckhwd %%xmm1,%%xmm1 \n" >- "por %%xmm5,%%xmm0 \n" >- "por %%xmm5,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src_y), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- :: "memory", "cc", "xmm0", "xmm1", "xmm5" >- ); >+void J400ToARGBRow_SSE2(const uint8_t* src_y, uint8_t* dst_argb, int width) { >+ asm volatile( >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "pslld $0x18,%%xmm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movq (%0),%%xmm0 \n" >+ "lea 0x8(%0),%0 \n" >+ "punpcklbw %%xmm0,%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpcklwd %%xmm0,%%xmm0 \n" >+ "punpckhwd %%xmm1,%%xmm1 \n" >+ "por %%xmm5,%%xmm0 \n" >+ "por %%xmm5,%%xmm1 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_y), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm5"); > } > #endif // HAS_J400TOARGBROW_SSE2 > > #ifdef HAS_RGB24TOARGBROW_SSSE3 >-void RGB24ToARGBRow_SSSE3(const uint8* src_rgb24, uint8* dst_argb, int width) { >- asm volatile ( >- "pcmpeqb %%xmm5,%%xmm5 \n" // generate mask 0xff000000 >- "pslld $0x18,%%xmm5 \n" >- "movdqa %3,%%xmm4 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm3 \n" >- "lea " MEMLEA(0x30,0) ",%0 \n" >- "movdqa %%xmm3,%%xmm2 \n" >- "palignr $0x8,%%xmm1,%%xmm2 \n" >- "pshufb %%xmm4,%%xmm2 \n" >- "por %%xmm5,%%xmm2 \n" >- "palignr $0xc,%%xmm0,%%xmm1 \n" >- "pshufb %%xmm4,%%xmm0 \n" >- "movdqu %%xmm2," MEMACCESS2(0x20,1) " \n" >- "por %%xmm5,%%xmm0 \n" >- "pshufb %%xmm4,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "por %%xmm5,%%xmm1 \n" >- "palignr $0x4,%%xmm3,%%xmm3 \n" >- "pshufb %%xmm4,%%xmm3 \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,1) " \n" >- "por %%xmm5,%%xmm3 \n" >- "movdqu %%xmm3," MEMACCESS2(0x30,1) " \n" >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_rgb24), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "m"(kShuffleMaskRGB24ToARGB) // %3 >- : "memory", "cc" , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+void RGB24ToARGBRow_SSSE3(const uint8_t* src_rgb24, >+ uint8_t* dst_argb, >+ int width) { >+ asm volatile( >+ "pcmpeqb %%xmm5,%%xmm5 \n" // 0xff000000 >+ "pslld $0x18,%%xmm5 \n" >+ "movdqa %3,%%xmm4 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm3 \n" >+ "lea 0x30(%0),%0 \n" >+ "movdqa %%xmm3,%%xmm2 \n" >+ "palignr $0x8,%%xmm1,%%xmm2 \n" >+ "pshufb %%xmm4,%%xmm2 \n" >+ "por %%xmm5,%%xmm2 \n" >+ "palignr $0xc,%%xmm0,%%xmm1 \n" >+ "pshufb %%xmm4,%%xmm0 \n" >+ "movdqu %%xmm2,0x20(%1) \n" >+ "por %%xmm5,%%xmm0 \n" >+ "pshufb %%xmm4,%%xmm1 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "por %%xmm5,%%xmm1 \n" >+ "palignr $0x4,%%xmm3,%%xmm3 \n" >+ "pshufb %%xmm4,%%xmm3 \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "por %%xmm5,%%xmm3 \n" >+ "movdqu %%xmm3,0x30(%1) \n" >+ "lea 0x40(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_rgb24), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleMaskRGB24ToARGB) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > >-void RAWToARGBRow_SSSE3(const uint8* src_raw, uint8* dst_argb, int width) { >- asm volatile ( >- "pcmpeqb %%xmm5,%%xmm5 \n" // generate mask 0xff000000 >- "pslld $0x18,%%xmm5 \n" >- "movdqa %3,%%xmm4 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm3 \n" >- "lea " MEMLEA(0x30,0) ",%0 \n" >- "movdqa %%xmm3,%%xmm2 \n" >- "palignr $0x8,%%xmm1,%%xmm2 \n" >- "pshufb %%xmm4,%%xmm2 \n" >- "por %%xmm5,%%xmm2 \n" >- "palignr $0xc,%%xmm0,%%xmm1 \n" >- "pshufb %%xmm4,%%xmm0 \n" >- "movdqu %%xmm2," MEMACCESS2(0x20,1) " \n" >- "por %%xmm5,%%xmm0 \n" >- "pshufb %%xmm4,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "por %%xmm5,%%xmm1 \n" >- "palignr $0x4,%%xmm3,%%xmm3 \n" >- "pshufb %%xmm4,%%xmm3 \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,1) " \n" >- "por %%xmm5,%%xmm3 \n" >- "movdqu %%xmm3," MEMACCESS2(0x30,1) " \n" >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_raw), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "m"(kShuffleMaskRAWToARGB) // %3 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+void RAWToARGBRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_argb, int width) { >+ asm volatile( >+ "pcmpeqb %%xmm5,%%xmm5 \n" // 0xff000000 >+ "pslld $0x18,%%xmm5 \n" >+ "movdqa %3,%%xmm4 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm3 \n" >+ "lea 0x30(%0),%0 \n" >+ "movdqa %%xmm3,%%xmm2 \n" >+ "palignr $0x8,%%xmm1,%%xmm2 \n" >+ "pshufb %%xmm4,%%xmm2 \n" >+ "por %%xmm5,%%xmm2 \n" >+ "palignr $0xc,%%xmm0,%%xmm1 \n" >+ "pshufb %%xmm4,%%xmm0 \n" >+ "movdqu %%xmm2,0x20(%1) \n" >+ "por %%xmm5,%%xmm0 \n" >+ "pshufb %%xmm4,%%xmm1 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "por %%xmm5,%%xmm1 \n" >+ "palignr $0x4,%%xmm3,%%xmm3 \n" >+ "pshufb %%xmm4,%%xmm3 \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "por %%xmm5,%%xmm3 \n" >+ "movdqu %%xmm3,0x30(%1) \n" >+ "lea 0x40(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_raw), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleMaskRAWToARGB) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > >-void RAWToRGB24Row_SSSE3(const uint8* src_raw, uint8* dst_rgb24, int width) { >- asm volatile ( >- "movdqa %3,%%xmm3 \n" >- "movdqa %4,%%xmm4 \n" >- "movdqa %5,%%xmm5 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x4,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x8,0) ",%%xmm2 \n" >- "lea " MEMLEA(0x18,0) ",%0 \n" >- "pshufb %%xmm3,%%xmm0 \n" >- "pshufb %%xmm4,%%xmm1 \n" >- "pshufb %%xmm5,%%xmm2 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- "movq %%xmm1," MEMACCESS2(0x8,1) " \n" >- "movq %%xmm2," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x18,1) ",%1 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src_raw), // %0 >- "+r"(dst_rgb24), // %1 >- "+r"(width) // %2 >- : "m"(kShuffleMaskRAWToRGB24_0), // %3 >- "m"(kShuffleMaskRAWToRGB24_1), // %4 >- "m"(kShuffleMaskRAWToRGB24_2) // %5 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+void RAWToRGB24Row_SSSE3(const uint8_t* src_raw, >+ uint8_t* dst_rgb24, >+ int width) { >+ asm volatile( >+ "movdqa %3,%%xmm3 \n" >+ "movdqa %4,%%xmm4 \n" >+ "movdqa %5,%%xmm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x4(%0),%%xmm1 \n" >+ "movdqu 0x8(%0),%%xmm2 \n" >+ "lea 0x18(%0),%0 \n" >+ "pshufb %%xmm3,%%xmm0 \n" >+ "pshufb %%xmm4,%%xmm1 \n" >+ "pshufb %%xmm5,%%xmm2 \n" >+ "movq %%xmm0,(%1) \n" >+ "movq %%xmm1,0x8(%1) \n" >+ "movq %%xmm2,0x10(%1) \n" >+ "lea 0x18(%1),%1 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_raw), // %0 >+ "+r"(dst_rgb24), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleMaskRAWToRGB24_0), // %3 >+ "m"(kShuffleMaskRAWToRGB24_1), // %4 >+ "m"(kShuffleMaskRAWToRGB24_2) // %5 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > >-void RGB565ToARGBRow_SSE2(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "mov $0x1080108,%%eax \n" >- "movd %%eax,%%xmm5 \n" >- "pshufd $0x0,%%xmm5,%%xmm5 \n" >- "mov $0x20802080,%%eax \n" >- "movd %%eax,%%xmm6 \n" >- "pshufd $0x0,%%xmm6,%%xmm6 \n" >- "pcmpeqb %%xmm3,%%xmm3 \n" >- "psllw $0xb,%%xmm3 \n" >- "pcmpeqb %%xmm4,%%xmm4 \n" >- "psllw $0xa,%%xmm4 \n" >- "psrlw $0x5,%%xmm4 \n" >- "pcmpeqb %%xmm7,%%xmm7 \n" >- "psllw $0x8,%%xmm7 \n" >- "sub %0,%1 \n" >- "sub %0,%1 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "pand %%xmm3,%%xmm1 \n" >- "psllw $0xb,%%xmm2 \n" >- "pmulhuw %%xmm5,%%xmm1 \n" >- "pmulhuw %%xmm5,%%xmm2 \n" >- "psllw $0x8,%%xmm1 \n" >- "por %%xmm2,%%xmm1 \n" >- "pand %%xmm4,%%xmm0 \n" >- "pmulhuw %%xmm6,%%xmm0 \n" >- "por %%xmm7,%%xmm0 \n" >- "movdqa %%xmm1,%%xmm2 \n" >- "punpcklbw %%xmm0,%%xmm1 \n" >- "punpckhbw %%xmm0,%%xmm2 \n" >- MEMOPMEM(movdqu,xmm1,0x00,1,0,2) // movdqu %%xmm1,(%1,%0,2) >- MEMOPMEM(movdqu,xmm2,0x10,1,0,2) // movdqu %%xmm2,0x10(%1,%0,2) >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc", "eax", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+void RGB565ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "mov $0x1080108,%%eax \n" >+ "movd %%eax,%%xmm5 \n" >+ "pshufd $0x0,%%xmm5,%%xmm5 \n" >+ "mov $0x20802080,%%eax \n" >+ "movd %%eax,%%xmm6 \n" >+ "pshufd $0x0,%%xmm6,%%xmm6 \n" >+ "pcmpeqb %%xmm3,%%xmm3 \n" >+ "psllw $0xb,%%xmm3 \n" >+ "pcmpeqb %%xmm4,%%xmm4 \n" >+ "psllw $0xa,%%xmm4 \n" >+ "psrlw $0x5,%%xmm4 \n" >+ "pcmpeqb %%xmm7,%%xmm7 \n" >+ "psllw $0x8,%%xmm7 \n" >+ "sub %0,%1 \n" >+ "sub %0,%1 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "pand %%xmm3,%%xmm1 \n" >+ "psllw $0xb,%%xmm2 \n" >+ "pmulhuw %%xmm5,%%xmm1 \n" >+ "pmulhuw %%xmm5,%%xmm2 \n" >+ "psllw $0x8,%%xmm1 \n" >+ "por %%xmm2,%%xmm1 \n" >+ "pand %%xmm4,%%xmm0 \n" >+ "pmulhuw %%xmm6,%%xmm0 \n" >+ "por %%xmm7,%%xmm0 \n" >+ "movdqa %%xmm1,%%xmm2 \n" >+ "punpcklbw %%xmm0,%%xmm1 \n" >+ "punpckhbw %%xmm0,%%xmm2 \n" >+ "movdqu %%xmm1,0x00(%1,%0,2) \n" >+ "movdqu %%xmm2,0x10(%1,%0,2) \n" >+ "lea 0x10(%0),%0 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", >+ "xmm6", "xmm7"); > } > >-void ARGB1555ToARGBRow_SSE2(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "mov $0x1080108,%%eax \n" >- "movd %%eax,%%xmm5 \n" >- "pshufd $0x0,%%xmm5,%%xmm5 \n" >- "mov $0x42004200,%%eax \n" >- "movd %%eax,%%xmm6 \n" >- "pshufd $0x0,%%xmm6,%%xmm6 \n" >- "pcmpeqb %%xmm3,%%xmm3 \n" >- "psllw $0xb,%%xmm3 \n" >- "movdqa %%xmm3,%%xmm4 \n" >- "psrlw $0x6,%%xmm4 \n" >- "pcmpeqb %%xmm7,%%xmm7 \n" >- "psllw $0x8,%%xmm7 \n" >- "sub %0,%1 \n" >- "sub %0,%1 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "psllw $0x1,%%xmm1 \n" >- "psllw $0xb,%%xmm2 \n" >- "pand %%xmm3,%%xmm1 \n" >- "pmulhuw %%xmm5,%%xmm2 \n" >- "pmulhuw %%xmm5,%%xmm1 \n" >- "psllw $0x8,%%xmm1 \n" >- "por %%xmm2,%%xmm1 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "pand %%xmm4,%%xmm0 \n" >- "psraw $0x8,%%xmm2 \n" >- "pmulhuw %%xmm6,%%xmm0 \n" >- "pand %%xmm7,%%xmm2 \n" >- "por %%xmm2,%%xmm0 \n" >- "movdqa %%xmm1,%%xmm2 \n" >- "punpcklbw %%xmm0,%%xmm1 \n" >- "punpckhbw %%xmm0,%%xmm2 \n" >- MEMOPMEM(movdqu,xmm1,0x00,1,0,2) // movdqu %%xmm1,(%1,%0,2) >- MEMOPMEM(movdqu,xmm2,0x10,1,0,2) // movdqu %%xmm2,0x10(%1,%0,2) >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc", "eax", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+void ARGB1555ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "mov $0x1080108,%%eax \n" >+ "movd %%eax,%%xmm5 \n" >+ "pshufd $0x0,%%xmm5,%%xmm5 \n" >+ "mov $0x42004200,%%eax \n" >+ "movd %%eax,%%xmm6 \n" >+ "pshufd $0x0,%%xmm6,%%xmm6 \n" >+ "pcmpeqb %%xmm3,%%xmm3 \n" >+ "psllw $0xb,%%xmm3 \n" >+ "movdqa %%xmm3,%%xmm4 \n" >+ "psrlw $0x6,%%xmm4 \n" >+ "pcmpeqb %%xmm7,%%xmm7 \n" >+ "psllw $0x8,%%xmm7 \n" >+ "sub %0,%1 \n" >+ "sub %0,%1 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "psllw $0x1,%%xmm1 \n" >+ "psllw $0xb,%%xmm2 \n" >+ "pand %%xmm3,%%xmm1 \n" >+ "pmulhuw %%xmm5,%%xmm2 \n" >+ "pmulhuw %%xmm5,%%xmm1 \n" >+ "psllw $0x8,%%xmm1 \n" >+ "por %%xmm2,%%xmm1 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "pand %%xmm4,%%xmm0 \n" >+ "psraw $0x8,%%xmm2 \n" >+ "pmulhuw %%xmm6,%%xmm0 \n" >+ "pand %%xmm7,%%xmm2 \n" >+ "por %%xmm2,%%xmm0 \n" >+ "movdqa %%xmm1,%%xmm2 \n" >+ "punpcklbw %%xmm0,%%xmm1 \n" >+ "punpckhbw %%xmm0,%%xmm2 \n" >+ "movdqu %%xmm1,0x00(%1,%0,2) \n" >+ "movdqu %%xmm2,0x10(%1,%0,2) \n" >+ "lea 0x10(%0),%0 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", >+ "xmm6", "xmm7"); > } > >-void ARGB4444ToARGBRow_SSE2(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "mov $0xf0f0f0f,%%eax \n" >- "movd %%eax,%%xmm4 \n" >- "pshufd $0x0,%%xmm4,%%xmm4 \n" >- "movdqa %%xmm4,%%xmm5 \n" >- "pslld $0x4,%%xmm5 \n" >- "sub %0,%1 \n" >- "sub %0,%1 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "pand %%xmm4,%%xmm0 \n" >- "pand %%xmm5,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm2,%%xmm3 \n" >- "psllw $0x4,%%xmm1 \n" >- "psrlw $0x4,%%xmm3 \n" >- "por %%xmm1,%%xmm0 \n" >- "por %%xmm3,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklbw %%xmm2,%%xmm0 \n" >- "punpckhbw %%xmm2,%%xmm1 \n" >- MEMOPMEM(movdqu,xmm0,0x00,1,0,2) // movdqu %%xmm0,(%1,%0,2) >- MEMOPMEM(movdqu,xmm1,0x10,1,0,2) // movdqu %%xmm1,0x10(%1,%0,2) >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc", "eax", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+void ARGB4444ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "mov $0xf0f0f0f,%%eax \n" >+ "movd %%eax,%%xmm4 \n" >+ "pshufd $0x0,%%xmm4,%%xmm4 \n" >+ "movdqa %%xmm4,%%xmm5 \n" >+ "pslld $0x4,%%xmm5 \n" >+ "sub %0,%1 \n" >+ "sub %0,%1 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "pand %%xmm4,%%xmm0 \n" >+ "pand %%xmm5,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm2,%%xmm3 \n" >+ "psllw $0x4,%%xmm1 \n" >+ "psrlw $0x4,%%xmm3 \n" >+ "por %%xmm1,%%xmm0 \n" >+ "por %%xmm3,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpcklbw %%xmm2,%%xmm0 \n" >+ "punpckhbw %%xmm2,%%xmm1 \n" >+ "movdqu %%xmm0,0x00(%1,%0,2) \n" >+ "movdqu %%xmm1,0x10(%1,%0,2) \n" >+ "lea 0x10(%0),%0 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > >-void ARGBToRGB24Row_SSSE3(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "movdqa %3,%%xmm6 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm3 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "pshufb %%xmm6,%%xmm0 \n" >- "pshufb %%xmm6,%%xmm1 \n" >- "pshufb %%xmm6,%%xmm2 \n" >- "pshufb %%xmm6,%%xmm3 \n" >- "movdqa %%xmm1,%%xmm4 \n" >- "psrldq $0x4,%%xmm1 \n" >- "pslldq $0xc,%%xmm4 \n" >- "movdqa %%xmm2,%%xmm5 \n" >- "por %%xmm4,%%xmm0 \n" >- "pslldq $0x8,%%xmm5 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "por %%xmm5,%%xmm1 \n" >- "psrldq $0x8,%%xmm2 \n" >- "pslldq $0x4,%%xmm3 \n" >- "por %%xmm3,%%xmm2 \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,1) " \n" >- "movdqu %%xmm2," MEMACCESS2(0x20,1) " \n" >- "lea " MEMLEA(0x30,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- : "m"(kShuffleMaskARGBToRGB24) // %3 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" >- ); >+void ARGBToRGB24Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ >+ "movdqa %3,%%xmm6 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "pshufb %%xmm6,%%xmm0 \n" >+ "pshufb %%xmm6,%%xmm1 \n" >+ "pshufb %%xmm6,%%xmm2 \n" >+ "pshufb %%xmm6,%%xmm3 \n" >+ "movdqa %%xmm1,%%xmm4 \n" >+ "psrldq $0x4,%%xmm1 \n" >+ "pslldq $0xc,%%xmm4 \n" >+ "movdqa %%xmm2,%%xmm5 \n" >+ "por %%xmm4,%%xmm0 \n" >+ "pslldq $0x8,%%xmm5 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "por %%xmm5,%%xmm1 \n" >+ "psrldq $0x8,%%xmm2 \n" >+ "pslldq $0x4,%%xmm3 \n" >+ "por %%xmm3,%%xmm2 \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "movdqu %%xmm2,0x20(%1) \n" >+ "lea 0x30(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleMaskARGBToRGB24) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); > } > >-void ARGBToRAWRow_SSSE3(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "movdqa %3,%%xmm6 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm3 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "pshufb %%xmm6,%%xmm0 \n" >- "pshufb %%xmm6,%%xmm1 \n" >- "pshufb %%xmm6,%%xmm2 \n" >- "pshufb %%xmm6,%%xmm3 \n" >- "movdqa %%xmm1,%%xmm4 \n" >- "psrldq $0x4,%%xmm1 \n" >- "pslldq $0xc,%%xmm4 \n" >- "movdqa %%xmm2,%%xmm5 \n" >- "por %%xmm4,%%xmm0 \n" >- "pslldq $0x8,%%xmm5 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "por %%xmm5,%%xmm1 \n" >- "psrldq $0x8,%%xmm2 \n" >- "pslldq $0x4,%%xmm3 \n" >- "por %%xmm3,%%xmm2 \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,1) " \n" >- "movdqu %%xmm2," MEMACCESS2(0x20,1) " \n" >- "lea " MEMLEA(0x30,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- : "m"(kShuffleMaskARGBToRAW) // %3 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" >- ); >+void ARGBToRAWRow_SSSE3(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ >+ "movdqa %3,%%xmm6 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "pshufb %%xmm6,%%xmm0 \n" >+ "pshufb %%xmm6,%%xmm1 \n" >+ "pshufb %%xmm6,%%xmm2 \n" >+ "pshufb %%xmm6,%%xmm3 \n" >+ "movdqa %%xmm1,%%xmm4 \n" >+ "psrldq $0x4,%%xmm1 \n" >+ "pslldq $0xc,%%xmm4 \n" >+ "movdqa %%xmm2,%%xmm5 \n" >+ "por %%xmm4,%%xmm0 \n" >+ "pslldq $0x8,%%xmm5 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "por %%xmm5,%%xmm1 \n" >+ "psrldq $0x8,%%xmm2 \n" >+ "pslldq $0x4,%%xmm3 \n" >+ "por %%xmm3,%%xmm2 \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "movdqu %%xmm2,0x20(%1) \n" >+ "lea 0x30(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleMaskARGBToRAW) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); > } > >-void ARGBToRGB565Row_SSE2(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "pcmpeqb %%xmm3,%%xmm3 \n" >- "psrld $0x1b,%%xmm3 \n" >- "pcmpeqb %%xmm4,%%xmm4 \n" >- "psrld $0x1a,%%xmm4 \n" >- "pslld $0x5,%%xmm4 \n" >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "pslld $0xb,%%xmm5 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "pslld $0x8,%%xmm0 \n" >- "psrld $0x3,%%xmm1 \n" >- "psrld $0x5,%%xmm2 \n" >- "psrad $0x10,%%xmm0 \n" >- "pand %%xmm3,%%xmm1 \n" >- "pand %%xmm4,%%xmm2 \n" >- "pand %%xmm5,%%xmm0 \n" >- "por %%xmm2,%%xmm1 \n" >- "por %%xmm1,%%xmm0 \n" >- "packssdw %%xmm0,%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x4,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- :: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+void ARGBToRGB565Row_SSE2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "pcmpeqb %%xmm3,%%xmm3 \n" >+ "psrld $0x1b,%%xmm3 \n" >+ "pcmpeqb %%xmm4,%%xmm4 \n" >+ "psrld $0x1a,%%xmm4 \n" >+ "pslld $0x5,%%xmm4 \n" >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "pslld $0xb,%%xmm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "pslld $0x8,%%xmm0 \n" >+ "psrld $0x3,%%xmm1 \n" >+ "psrld $0x5,%%xmm2 \n" >+ "psrad $0x10,%%xmm0 \n" >+ "pand %%xmm3,%%xmm1 \n" >+ "pand %%xmm4,%%xmm2 \n" >+ "pand %%xmm5,%%xmm0 \n" >+ "por %%xmm2,%%xmm1 \n" >+ "por %%xmm1,%%xmm0 \n" >+ "packssdw %%xmm0,%%xmm0 \n" >+ "lea 0x10(%0),%0 \n" >+ "movq %%xmm0,(%1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > >-void ARGBToRGB565DitherRow_SSE2(const uint8* src, >- uint8* dst, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_SSE2(const uint8_t* src, >+ uint8_t* dst, >+ const uint32_t dither4, > int width) { > asm volatile( > "movd %3,%%xmm6 \n" >@@ -583,9 +590,9 @@ void ARGBToRGB565DitherRow_SSE2(const uint8* src, > } > > #ifdef HAS_ARGBTORGB565DITHERROW_AVX2 >-void ARGBToRGB565DitherRow_AVX2(const uint8* src, >- uint8* dst, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_AVX2(const uint8_t* src, >+ uint8_t* dst, >+ const uint32_t dither4, > int width) { > asm volatile( > "vbroadcastss %3,%%xmm6 \n" >@@ -628,153 +635,335 @@ void ARGBToRGB565DitherRow_AVX2(const uint8* src, > } > #endif // HAS_ARGBTORGB565DITHERROW_AVX2 > >-void ARGBToARGB1555Row_SSE2(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "pcmpeqb %%xmm4,%%xmm4 \n" >- "psrld $0x1b,%%xmm4 \n" >- "movdqa %%xmm4,%%xmm5 \n" >- "pslld $0x5,%%xmm5 \n" >- "movdqa %%xmm4,%%xmm6 \n" >- "pslld $0xa,%%xmm6 \n" >- "pcmpeqb %%xmm7,%%xmm7 \n" >- "pslld $0xf,%%xmm7 \n" >+void ARGBToARGB1555Row_SSE2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "pcmpeqb %%xmm4,%%xmm4 \n" >+ "psrld $0x1b,%%xmm4 \n" >+ "movdqa %%xmm4,%%xmm5 \n" >+ "pslld $0x5,%%xmm5 \n" >+ "movdqa %%xmm4,%%xmm6 \n" >+ "pslld $0xa,%%xmm6 \n" >+ "pcmpeqb %%xmm7,%%xmm7 \n" >+ "pslld $0xf,%%xmm7 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm3 \n" >- "psrad $0x10,%%xmm0 \n" >- "psrld $0x3,%%xmm1 \n" >- "psrld $0x6,%%xmm2 \n" >- "psrld $0x9,%%xmm3 \n" >- "pand %%xmm7,%%xmm0 \n" >- "pand %%xmm4,%%xmm1 \n" >- "pand %%xmm5,%%xmm2 \n" >- "pand %%xmm6,%%xmm3 \n" >- "por %%xmm1,%%xmm0 \n" >- "por %%xmm3,%%xmm2 \n" >- "por %%xmm2,%%xmm0 \n" >- "packssdw %%xmm0,%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x4,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- :: "memory", "cc", >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm3 \n" >+ "psrad $0x10,%%xmm0 \n" >+ "psrld $0x3,%%xmm1 \n" >+ "psrld $0x6,%%xmm2 \n" >+ "psrld $0x9,%%xmm3 \n" >+ "pand %%xmm7,%%xmm0 \n" >+ "pand %%xmm4,%%xmm1 \n" >+ "pand %%xmm5,%%xmm2 \n" >+ "pand %%xmm6,%%xmm3 \n" >+ "por %%xmm1,%%xmm0 \n" >+ "por %%xmm3,%%xmm2 \n" >+ "por %%xmm2,%%xmm0 \n" >+ "packssdw %%xmm0,%%xmm0 \n" >+ "lea 0x10(%0),%0 \n" >+ "movq %%xmm0,(%1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"); > } > >-void ARGBToARGB4444Row_SSE2(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "pcmpeqb %%xmm4,%%xmm4 \n" >- "psllw $0xc,%%xmm4 \n" >- "movdqa %%xmm4,%%xmm3 \n" >- "psrlw $0x8,%%xmm3 \n" >+void ARGBToARGB4444Row_SSE2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "pcmpeqb %%xmm4,%%xmm4 \n" >+ "psllw $0xc,%%xmm4 \n" >+ "movdqa %%xmm4,%%xmm3 \n" >+ "psrlw $0x8,%%xmm3 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "pand %%xmm3,%%xmm0 \n" >- "pand %%xmm4,%%xmm1 \n" >- "psrlq $0x4,%%xmm0 \n" >- "psrlq $0x8,%%xmm1 \n" >- "por %%xmm1,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x4,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- :: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "pand %%xmm3,%%xmm0 \n" >+ "pand %%xmm4,%%xmm1 \n" >+ "psrlq $0x4,%%xmm0 \n" >+ "psrlq $0x8,%%xmm1 \n" >+ "por %%xmm1,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "lea 0x10(%0),%0 \n" >+ "movq %%xmm0,(%1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); > } > #endif // HAS_RGB24TOARGBROW_SSSE3 > >+/* >+ >+ARGBToAR30Row: >+ >+Red Blue >+With the 8 bit value in the upper bits of a short, vpmulhuw by (1024+4) will >+produce a 10 bit value in the low 10 bits of each 16 bit value. This is whats >+wanted for the blue channel. The red needs to be shifted 4 left, so multiply by >+(1024+4)*16 for red. >+ >+Alpha Green >+Alpha and Green are already in the high bits so vpand can zero out the other >+bits, keeping just 2 upper bits of alpha and 8 bit green. The same multiplier >+could be used for Green - (1024+4) putting the 10 bit green in the lsb. Alpha >+would be a simple multiplier to shift it into position. It wants a gap of 10 >+above the green. Green is 10 bits, so there are 6 bits in the low short. 4 >+more are needed, so a multiplier of 4 gets the 2 bits into the upper 16 bits, >+and then a shift of 4 is a multiply of 16, so (4*16) = 64. Then shift the >+result left 10 to position the A and G channels. >+*/ >+ >+// Shuffle table for converting RAW to RGB24. Last 8. >+static const uvec8 kShuffleRB30 = {128u, 0u, 128u, 2u, 128u, 4u, 128u, 6u, >+ 128u, 8u, 128u, 10u, 128u, 12u, 128u, 14u}; >+ >+static const uvec8 kShuffleBR30 = {128u, 2u, 128u, 0u, 128u, 6u, 128u, 4u, >+ 128u, 10u, 128u, 8u, 128u, 14u, 128u, 12u}; >+ >+static const uint32_t kMulRB10 = 1028 * 16 * 65536 + 1028; >+static const uint32_t kMaskRB10 = 0x3ff003ff; >+static const uint32_t kMaskAG10 = 0xc000ff00; >+static const uint32_t kMulAG10 = 64 * 65536 + 1028; >+ >+void ARGBToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "movdqa %3,%%xmm2 \n" // shuffler for RB >+ "movd %4,%%xmm3 \n" // multipler for RB >+ "movd %5,%%xmm4 \n" // mask for R10 B10 >+ "movd %6,%%xmm5 \n" // mask for AG >+ "movd %7,%%xmm6 \n" // multipler for AG >+ "pshufd $0x0,%%xmm3,%%xmm3 \n" >+ "pshufd $0x0,%%xmm4,%%xmm4 \n" >+ "pshufd $0x0,%%xmm5,%%xmm5 \n" >+ "pshufd $0x0,%%xmm6,%%xmm6 \n" >+ "sub %0,%1 \n" >+ >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" // fetch 4 ARGB pixels >+ "movdqa %%xmm0,%%xmm1 \n" >+ "pshufb %%xmm2,%%xmm1 \n" // R0B0 >+ "pand %%xmm5,%%xmm0 \n" // A0G0 >+ "pmulhuw %%xmm3,%%xmm1 \n" // X2 R16 X4 B10 >+ "pmulhuw %%xmm6,%%xmm0 \n" // X10 A2 X10 G10 >+ "pand %%xmm4,%%xmm1 \n" // X2 R10 X10 B10 >+ "pslld $10,%%xmm0 \n" // A2 x10 G10 x10 >+ "por %%xmm1,%%xmm0 \n" // A2 R10 G10 B10 >+ "movdqu %%xmm0,(%1,%0) \n" // store 4 AR30 pixels >+ "add $0x10,%0 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleRB30), // %3 >+ "m"(kMulRB10), // %4 >+ "m"(kMaskRB10), // %5 >+ "m"(kMaskAG10), // %6 >+ "m"(kMulAG10) // %7 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); >+} >+ >+void ABGRToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "movdqa %3,%%xmm2 \n" // shuffler for RB >+ "movd %4,%%xmm3 \n" // multipler for RB >+ "movd %5,%%xmm4 \n" // mask for R10 B10 >+ "movd %6,%%xmm5 \n" // mask for AG >+ "movd %7,%%xmm6 \n" // multipler for AG >+ "pshufd $0x0,%%xmm3,%%xmm3 \n" >+ "pshufd $0x0,%%xmm4,%%xmm4 \n" >+ "pshufd $0x0,%%xmm5,%%xmm5 \n" >+ "pshufd $0x0,%%xmm6,%%xmm6 \n" >+ "sub %0,%1 \n" >+ >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" // fetch 4 ABGR pixels >+ "movdqa %%xmm0,%%xmm1 \n" >+ "pshufb %%xmm2,%%xmm1 \n" // R0B0 >+ "pand %%xmm5,%%xmm0 \n" // A0G0 >+ "pmulhuw %%xmm3,%%xmm1 \n" // X2 R16 X4 B10 >+ "pmulhuw %%xmm6,%%xmm0 \n" // X10 A2 X10 G10 >+ "pand %%xmm4,%%xmm1 \n" // X2 R10 X10 B10 >+ "pslld $10,%%xmm0 \n" // A2 x10 G10 x10 >+ "por %%xmm1,%%xmm0 \n" // A2 R10 G10 B10 >+ "movdqu %%xmm0,(%1,%0) \n" // store 4 AR30 pixels >+ "add $0x10,%0 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleBR30), // %3 reversed shuffler >+ "m"(kMulRB10), // %4 >+ "m"(kMaskRB10), // %5 >+ "m"(kMaskAG10), // %6 >+ "m"(kMulAG10) // %7 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); >+} >+ >+#ifdef HAS_ARGBTOAR30ROW_AVX2 >+void ARGBToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "vbroadcastf128 %3,%%ymm2 \n" // shuffler for RB >+ "vbroadcastss %4,%%ymm3 \n" // multipler for RB >+ "vbroadcastss %5,%%ymm4 \n" // mask for R10 B10 >+ "vbroadcastss %6,%%ymm5 \n" // mask for AG >+ "vbroadcastss %7,%%ymm6 \n" // multipler for AG >+ "sub %0,%1 \n" >+ >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" // fetch 8 ARGB pixels >+ "vpshufb %%ymm2,%%ymm0,%%ymm1 \n" // R0B0 >+ "vpand %%ymm5,%%ymm0,%%ymm0 \n" // A0G0 >+ "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" // X2 R16 X4 B10 >+ "vpmulhuw %%ymm6,%%ymm0,%%ymm0 \n" // X10 A2 X10 G10 >+ "vpand %%ymm4,%%ymm1,%%ymm1 \n" // X2 R10 X10 B10 >+ "vpslld $10,%%ymm0,%%ymm0 \n" // A2 x10 G10 x10 >+ "vpor %%ymm1,%%ymm0,%%ymm0 \n" // A2 R10 G10 B10 >+ "vmovdqu %%ymm0,(%1,%0) \n" // store 8 AR30 pixels >+ "add $0x20,%0 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleRB30), // %3 >+ "m"(kMulRB10), // %4 >+ "m"(kMaskRB10), // %5 >+ "m"(kMaskAG10), // %6 >+ "m"(kMulAG10) // %7 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); >+} >+#endif >+ >+#ifdef HAS_ABGRTOAR30ROW_AVX2 >+void ABGRToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "vbroadcastf128 %3,%%ymm2 \n" // shuffler for RB >+ "vbroadcastss %4,%%ymm3 \n" // multipler for RB >+ "vbroadcastss %5,%%ymm4 \n" // mask for R10 B10 >+ "vbroadcastss %6,%%ymm5 \n" // mask for AG >+ "vbroadcastss %7,%%ymm6 \n" // multipler for AG >+ "sub %0,%1 \n" >+ >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" // fetch 8 ABGR pixels >+ "vpshufb %%ymm2,%%ymm0,%%ymm1 \n" // R0B0 >+ "vpand %%ymm5,%%ymm0,%%ymm0 \n" // A0G0 >+ "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" // X2 R16 X4 B10 >+ "vpmulhuw %%ymm6,%%ymm0,%%ymm0 \n" // X10 A2 X10 G10 >+ "vpand %%ymm4,%%ymm1,%%ymm1 \n" // X2 R10 X10 B10 >+ "vpslld $10,%%ymm0,%%ymm0 \n" // A2 x10 G10 x10 >+ "vpor %%ymm1,%%ymm0,%%ymm0 \n" // A2 R10 G10 B10 >+ "vmovdqu %%ymm0,(%1,%0) \n" // store 8 AR30 pixels >+ "add $0x20,%0 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleBR30), // %3 reversed shuffler >+ "m"(kMulRB10), // %4 >+ "m"(kMaskRB10), // %5 >+ "m"(kMaskAG10), // %6 >+ "m"(kMulAG10) // %7 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); >+} >+#endif >+ > #ifdef HAS_ARGBTOYROW_SSSE3 > // Convert 16 ARGB pixels (64 bytes) to 16 Y values. >-void ARGBToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int width) { >- asm volatile ( >- "movdqa %3,%%xmm4 \n" >- "movdqa %4,%%xmm5 \n" >+void ARGBToYRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width) { >+ asm volatile( >+ "movdqa %3,%%xmm4 \n" >+ "movdqa %4,%%xmm5 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm3 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm4,%%xmm3 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "phaddw %%xmm1,%%xmm0 \n" >- "phaddw %%xmm3,%%xmm2 \n" >- "psrlw $0x7,%%xmm0 \n" >- "psrlw $0x7,%%xmm2 \n" >- "packuswb %%xmm2,%%xmm0 \n" >- "paddb %%xmm5,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : "m"(kARGBToY), // %3 >- "m"(kAddY16) // %4 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm3 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm4,%%xmm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "phaddw %%xmm1,%%xmm0 \n" >+ "phaddw %%xmm3,%%xmm2 \n" >+ "psrlw $0x7,%%xmm0 \n" >+ "psrlw $0x7,%%xmm2 \n" >+ "packuswb %%xmm2,%%xmm0 \n" >+ "paddb %%xmm5,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "m"(kARGBToY), // %3 >+ "m"(kAddY16) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_ARGBTOYROW_SSSE3 > > #ifdef HAS_ARGBTOYJROW_SSSE3 > // Convert 16 ARGB pixels (64 bytes) to 16 YJ values. > // Same as ARGBToYRow but different coefficients, no add 16, but do rounding. >-void ARGBToYJRow_SSSE3(const uint8* src_argb, uint8* dst_y, int width) { >- asm volatile ( >- "movdqa %3,%%xmm4 \n" >- "movdqa %4,%%xmm5 \n" >+void ARGBToYJRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width) { >+ asm volatile( >+ "movdqa %3,%%xmm4 \n" >+ "movdqa %4,%%xmm5 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm3 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm4,%%xmm3 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "phaddw %%xmm1,%%xmm0 \n" >- "phaddw %%xmm3,%%xmm2 \n" >- "paddw %%xmm5,%%xmm0 \n" >- "paddw %%xmm5,%%xmm2 \n" >- "psrlw $0x7,%%xmm0 \n" >- "psrlw $0x7,%%xmm2 \n" >- "packuswb %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : "m"(kARGBToYJ), // %3 >- "m"(kAddYJ64) // %4 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm3 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm4,%%xmm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "phaddw %%xmm1,%%xmm0 \n" >+ "phaddw %%xmm3,%%xmm2 \n" >+ "paddw %%xmm5,%%xmm0 \n" >+ "paddw %%xmm5,%%xmm2 \n" >+ "psrlw $0x7,%%xmm0 \n" >+ "psrlw $0x7,%%xmm2 \n" >+ "packuswb %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "m"(kARGBToYJ), // %3 >+ "m"(kAddYJ64) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_ARGBTOYJROW_SSSE3 > >@@ -783,153 +972,149 @@ void ARGBToYJRow_SSSE3(const uint8* src_argb, uint8* dst_y, int width) { > static const lvec32 kPermdARGBToY_AVX = {0, 4, 1, 5, 2, 6, 3, 7}; > > // Convert 32 ARGB pixels (128 bytes) to 32 Y values. >-void ARGBToYRow_AVX2(const uint8* src_argb, uint8* dst_y, int width) { >- asm volatile ( >- "vbroadcastf128 %3,%%ymm4 \n" >- "vbroadcastf128 %4,%%ymm5 \n" >- "vmovdqu %5,%%ymm6 \n" >+void ARGBToYRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width) { >+ asm volatile( >+ "vbroadcastf128 %3,%%ymm4 \n" >+ "vbroadcastf128 %4,%%ymm5 \n" >+ "vmovdqu %5,%%ymm6 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "vmovdqu " MEMACCESS2(0x40,0) ",%%ymm2 \n" >- "vmovdqu " MEMACCESS2(0x60,0) ",%%ymm3 \n" >- "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" >- "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" >- "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >- "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >- "lea " MEMLEA(0x80,0) ",%0 \n" >- "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" // mutates. >- "vphaddw %%ymm3,%%ymm2,%%ymm2 \n" >- "vpsrlw $0x7,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x7,%%ymm2,%%ymm2 \n" >- "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. >- "vpermd %%ymm0,%%ymm6,%%ymm0 \n" // unmutate. >- "vpaddb %%ymm5,%%ymm0,%%ymm0 \n" // add 16 for Y >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : "m"(kARGBToY), // %3 >- "m"(kAddY16), // %4 >- "m"(kPermdARGBToY_AVX) // %5 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "vmovdqu 0x40(%0),%%ymm2 \n" >+ "vmovdqu 0x60(%0),%%ymm3 \n" >+ "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" >+ "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" >+ "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >+ "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >+ "lea 0x80(%0),%0 \n" >+ "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" // mutates. >+ "vphaddw %%ymm3,%%ymm2,%%ymm2 \n" >+ "vpsrlw $0x7,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x7,%%ymm2,%%ymm2 \n" >+ "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. >+ "vpermd %%ymm0,%%ymm6,%%ymm0 \n" // unmutate. >+ "vpaddb %%ymm5,%%ymm0,%%ymm0 \n" // add 16 for Y >+ "vmovdqu %%ymm0,(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "m"(kARGBToY), // %3 >+ "m"(kAddY16), // %4 >+ "m"(kPermdARGBToY_AVX) // %5 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); > } > #endif // HAS_ARGBTOYROW_AVX2 > > #ifdef HAS_ARGBTOYJROW_AVX2 > // Convert 32 ARGB pixels (128 bytes) to 32 Y values. >-void ARGBToYJRow_AVX2(const uint8* src_argb, uint8* dst_y, int width) { >- asm volatile ( >- "vbroadcastf128 %3,%%ymm4 \n" >- "vbroadcastf128 %4,%%ymm5 \n" >- "vmovdqu %5,%%ymm6 \n" >+void ARGBToYJRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width) { >+ asm volatile( >+ "vbroadcastf128 %3,%%ymm4 \n" >+ "vbroadcastf128 %4,%%ymm5 \n" >+ "vmovdqu %5,%%ymm6 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "vmovdqu " MEMACCESS2(0x40,0) ",%%ymm2 \n" >- "vmovdqu " MEMACCESS2(0x60,0) ",%%ymm3 \n" >- "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" >- "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" >- "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >- "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >- "lea " MEMLEA(0x80,0) ",%0 \n" >- "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" // mutates. >- "vphaddw %%ymm3,%%ymm2,%%ymm2 \n" >- "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" // Add .5 for rounding. >- "vpaddw %%ymm5,%%ymm2,%%ymm2 \n" >- "vpsrlw $0x7,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x7,%%ymm2,%%ymm2 \n" >- "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. >- "vpermd %%ymm0,%%ymm6,%%ymm0 \n" // unmutate. >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : "m"(kARGBToYJ), // %3 >- "m"(kAddYJ64), // %4 >- "m"(kPermdARGBToY_AVX) // %5 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "vmovdqu 0x40(%0),%%ymm2 \n" >+ "vmovdqu 0x60(%0),%%ymm3 \n" >+ "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" >+ "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" >+ "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >+ "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >+ "lea 0x80(%0),%0 \n" >+ "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" // mutates. >+ "vphaddw %%ymm3,%%ymm2,%%ymm2 \n" >+ "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" // Add .5 for rounding. >+ "vpaddw %%ymm5,%%ymm2,%%ymm2 \n" >+ "vpsrlw $0x7,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x7,%%ymm2,%%ymm2 \n" >+ "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. >+ "vpermd %%ymm0,%%ymm6,%%ymm0 \n" // unmutate. >+ "vmovdqu %%ymm0,(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "m"(kARGBToYJ), // %3 >+ "m"(kAddYJ64), // %4 >+ "m"(kPermdARGBToY_AVX) // %5 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); > } > #endif // HAS_ARGBTOYJROW_AVX2 > > #ifdef HAS_ARGBTOUVROW_SSSE3 >-void ARGBToUVRow_SSSE3(const uint8* src_argb0, >+void ARGBToUVRow_SSSE3(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "movdqa %5,%%xmm3 \n" >- "movdqa %6,%%xmm4 \n" >- "movdqa %7,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "movdqa %5,%%xmm3 \n" >+ "movdqa %6,%%xmm4 \n" >+ "movdqa %7,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,4,1,xmm7) // movdqu (%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- MEMOPREG(movdqu,0x10,0,4,1,xmm7) // movdqu 0x10(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- MEMOPREG(movdqu,0x20,0,4,1,xmm7) // movdqu 0x20(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x30,0,4,1,xmm7) // movdqu 0x30(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm6 \n" >- >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm7 \n" >- "shufps $0x88,%%xmm1,%%xmm0 \n" >- "shufps $0xdd,%%xmm1,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm0 \n" >- "movdqa %%xmm2,%%xmm7 \n" >- "shufps $0x88,%%xmm6,%%xmm2 \n" >- "shufps $0xdd,%%xmm6,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm2,%%xmm6 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm3,%%xmm1 \n" >- "pmaddubsw %%xmm3,%%xmm6 \n" >- "phaddw %%xmm2,%%xmm0 \n" >- "phaddw %%xmm6,%%xmm1 \n" >- "psraw $0x8,%%xmm0 \n" >- "psraw $0x8,%%xmm1 \n" >- "packsswb %%xmm1,%%xmm0 \n" >- "paddb %%xmm5,%%xmm0 \n" >- "movlps %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movhps,xmm0,0x00,1,2,1) // movhps %%xmm0,(%1,%2,1) >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_argb0), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+rm"(width) // %3 >- : "r"((intptr_t)(src_stride_argb)), // %4 >- "m"(kARGBToV), // %5 >- "m"(kARGBToU), // %6 >- "m"(kAddUV128) // %7 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm6", "xmm7" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x10(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x20(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm6 \n" >+ "movdqu 0x30(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ >+ "lea 0x40(%0),%0 \n" >+ "movdqa %%xmm0,%%xmm7 \n" >+ "shufps $0x88,%%xmm1,%%xmm0 \n" >+ "shufps $0xdd,%%xmm1,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm0 \n" >+ "movdqa %%xmm2,%%xmm7 \n" >+ "shufps $0x88,%%xmm6,%%xmm2 \n" >+ "shufps $0xdd,%%xmm6,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm2,%%xmm6 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm3,%%xmm1 \n" >+ "pmaddubsw %%xmm3,%%xmm6 \n" >+ "phaddw %%xmm2,%%xmm0 \n" >+ "phaddw %%xmm6,%%xmm1 \n" >+ "psraw $0x8,%%xmm0 \n" >+ "psraw $0x8,%%xmm1 \n" >+ "packsswb %%xmm1,%%xmm0 \n" >+ "paddb %%xmm5,%%xmm0 \n" >+ "movlps %%xmm0,(%1) \n" >+ "movhps %%xmm0,0x00(%1,%2,1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+rm"(width) // %3 >+ : "r"((intptr_t)(src_stride_argb)), // %4 >+ "m"(kARGBToV), // %5 >+ "m"(kARGBToU), // %6 >+ "m"(kAddUV128) // %7 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6", "xmm7"); > } > #endif // HAS_ARGBTOUVROW_SSSE3 > >@@ -938,643 +1123,644 @@ void ARGBToUVRow_SSSE3(const uint8* src_argb0, > static const lvec8 kShufARGBToUV_AVX = { > 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15, > 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15}; >-void ARGBToUVRow_AVX2(const uint8* src_argb0, >+void ARGBToUVRow_AVX2(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "vbroadcastf128 %5,%%ymm5 \n" >- "vbroadcastf128 %6,%%ymm6 \n" >- "vbroadcastf128 %7,%%ymm7 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "vbroadcastf128 %5,%%ymm5 \n" >+ "vbroadcastf128 %6,%%ymm6 \n" >+ "vbroadcastf128 %7,%%ymm7 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "vmovdqu " MEMACCESS2(0x40,0) ",%%ymm2 \n" >- "vmovdqu " MEMACCESS2(0x60,0) ",%%ymm3 \n" >- VMEMOPREG(vpavgb,0x00,0,4,1,ymm0,ymm0) // vpavgb (%0,%4,1),%%ymm0,%%ymm0 >- VMEMOPREG(vpavgb,0x20,0,4,1,ymm1,ymm1) >- VMEMOPREG(vpavgb,0x40,0,4,1,ymm2,ymm2) >- VMEMOPREG(vpavgb,0x60,0,4,1,ymm3,ymm3) >- "lea " MEMLEA(0x80,0) ",%0 \n" >- "vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n" >- "vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n" >- "vpavgb %%ymm4,%%ymm0,%%ymm0 \n" >- "vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n" >- "vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n" >- "vpavgb %%ymm4,%%ymm2,%%ymm2 \n" >- >- "vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n" >- "vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n" >- "vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n" >- "vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n" >- "vphaddw %%ymm3,%%ymm1,%%ymm1 \n" >- "vphaddw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpsraw $0x8,%%ymm1,%%ymm1 \n" >- "vpsraw $0x8,%%ymm0,%%ymm0 \n" >- "vpacksswb %%ymm0,%%ymm1,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpshufb %8,%%ymm0,%%ymm0 \n" >- "vpaddb %%ymm5,%%ymm0,%%ymm0 \n" >- >- "vextractf128 $0x0,%%ymm0," MEMACCESS(1) " \n" >- VEXTOPMEM(vextractf128,1,ymm0,0x0,1,2,1) // vextractf128 $1,%%ymm0,(%1,%2,1) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x20,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb0), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+rm"(width) // %3 >- : "r"((intptr_t)(src_stride_argb)), // %4 >- "m"(kAddUV128), // %5 >- "m"(kARGBToV), // %6 >- "m"(kARGBToU), // %7 >- "m"(kShufARGBToUV_AVX) // %8 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >-} >-#endif // HAS_ARGBTOUVROW_AVX2 >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "vmovdqu 0x40(%0),%%ymm2 \n" >+ "vmovdqu 0x60(%0),%%ymm3 \n" >+ "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" >+ "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" >+ "vpavgb 0x40(%0,%4,1),%%ymm2,%%ymm2 \n" >+ "vpavgb 0x60(%0,%4,1),%%ymm3,%%ymm3 \n" >+ "lea 0x80(%0),%0 \n" >+ "vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n" >+ "vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n" >+ "vpavgb %%ymm4,%%ymm0,%%ymm0 \n" >+ "vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n" >+ "vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n" >+ "vpavgb %%ymm4,%%ymm2,%%ymm2 \n" >+ >+ "vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n" >+ "vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n" >+ "vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n" >+ "vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n" >+ "vphaddw %%ymm3,%%ymm1,%%ymm1 \n" >+ "vphaddw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpsraw $0x8,%%ymm1,%%ymm1 \n" >+ "vpsraw $0x8,%%ymm0,%%ymm0 \n" >+ "vpacksswb %%ymm0,%%ymm1,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpshufb %8,%%ymm0,%%ymm0 \n" >+ "vpaddb %%ymm5,%%ymm0,%%ymm0 \n" > >-#ifdef HAS_ARGBTOUVJROW_AVX2 >-void ARGBToUVJRow_AVX2(const uint8* src_argb0, >- int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ "vextractf128 $0x0,%%ymm0,(%1) \n" >+ "vextractf128 $0x1,%%ymm0,0x0(%1,%2,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x20,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+rm"(width) // %3 >+ : "r"((intptr_t)(src_stride_argb)), // %4 >+ "m"(kAddUV128), // %5 >+ "m"(kARGBToV), // %6 >+ "m"(kARGBToU), // %7 >+ "m"(kShufARGBToUV_AVX) // %8 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); >+} >+#endif // HAS_ARGBTOUVROW_AVX2 >+ >+#ifdef HAS_ARGBTOUVJROW_AVX2 >+void ARGBToUVJRow_AVX2(const uint8_t* src_argb0, >+ int src_stride_argb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "vbroadcastf128 %5,%%ymm5 \n" >- "vbroadcastf128 %6,%%ymm6 \n" >- "vbroadcastf128 %7,%%ymm7 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "vbroadcastf128 %5,%%ymm5 \n" >+ "vbroadcastf128 %6,%%ymm6 \n" >+ "vbroadcastf128 %7,%%ymm7 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "vmovdqu " MEMACCESS2(0x40,0) ",%%ymm2 \n" >- "vmovdqu " MEMACCESS2(0x60,0) ",%%ymm3 \n" >- VMEMOPREG(vpavgb,0x00,0,4,1,ymm0,ymm0) // vpavgb (%0,%4,1),%%ymm0,%%ymm0 >- VMEMOPREG(vpavgb,0x20,0,4,1,ymm1,ymm1) >- VMEMOPREG(vpavgb,0x40,0,4,1,ymm2,ymm2) >- VMEMOPREG(vpavgb,0x60,0,4,1,ymm3,ymm3) >- "lea " MEMLEA(0x80,0) ",%0 \n" >- "vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n" >- "vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n" >- "vpavgb %%ymm4,%%ymm0,%%ymm0 \n" >- "vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n" >- "vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n" >- "vpavgb %%ymm4,%%ymm2,%%ymm2 \n" >- >- "vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n" >- "vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n" >- "vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n" >- "vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n" >- "vphaddw %%ymm3,%%ymm1,%%ymm1 \n" >- "vphaddw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" >- "vpaddw %%ymm5,%%ymm1,%%ymm1 \n" >- "vpsraw $0x8,%%ymm1,%%ymm1 \n" >- "vpsraw $0x8,%%ymm0,%%ymm0 \n" >- "vpacksswb %%ymm0,%%ymm1,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpshufb %8,%%ymm0,%%ymm0 \n" >- >- "vextractf128 $0x0,%%ymm0," MEMACCESS(1) " \n" >- VEXTOPMEM(vextractf128,1,ymm0,0x0,1,2,1) // vextractf128 $1,%%ymm0,(%1,%2,1) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x20,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb0), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+rm"(width) // %3 >- : "r"((intptr_t)(src_stride_argb)), // %4 >- "m"(kAddUVJ128), // %5 >- "m"(kARGBToVJ), // %6 >- "m"(kARGBToUJ), // %7 >- "m"(kShufARGBToUV_AVX) // %8 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "vmovdqu 0x40(%0),%%ymm2 \n" >+ "vmovdqu 0x60(%0),%%ymm3 \n" >+ "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" >+ "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" >+ "vpavgb 0x40(%0,%4,1),%%ymm2,%%ymm2 \n" >+ "vpavgb 0x60(%0,%4,1),%%ymm3,%%ymm3 \n" >+ "lea 0x80(%0),%0 \n" >+ "vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n" >+ "vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n" >+ "vpavgb %%ymm4,%%ymm0,%%ymm0 \n" >+ "vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n" >+ "vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n" >+ "vpavgb %%ymm4,%%ymm2,%%ymm2 \n" >+ >+ "vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n" >+ "vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n" >+ "vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n" >+ "vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n" >+ "vphaddw %%ymm3,%%ymm1,%%ymm1 \n" >+ "vphaddw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpaddw %%ymm5,%%ymm1,%%ymm1 \n" >+ "vpsraw $0x8,%%ymm1,%%ymm1 \n" >+ "vpsraw $0x8,%%ymm0,%%ymm0 \n" >+ "vpacksswb %%ymm0,%%ymm1,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpshufb %8,%%ymm0,%%ymm0 \n" >+ >+ "vextractf128 $0x0,%%ymm0,(%1) \n" >+ "vextractf128 $0x1,%%ymm0,0x0(%1,%2,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x20,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+rm"(width) // %3 >+ : "r"((intptr_t)(src_stride_argb)), // %4 >+ "m"(kAddUVJ128), // %5 >+ "m"(kARGBToVJ), // %6 >+ "m"(kARGBToUJ), // %7 >+ "m"(kShufARGBToUV_AVX) // %8 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > #endif // HAS_ARGBTOUVJROW_AVX2 > > #ifdef HAS_ARGBTOUVJROW_SSSE3 >-void ARGBToUVJRow_SSSE3(const uint8* src_argb0, >+void ARGBToUVJRow_SSSE3(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "movdqa %5,%%xmm3 \n" >- "movdqa %6,%%xmm4 \n" >- "movdqa %7,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "movdqa %5,%%xmm3 \n" >+ "movdqa %6,%%xmm4 \n" >+ "movdqa %7,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,4,1,xmm7) // movdqu (%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- MEMOPREG(movdqu,0x10,0,4,1,xmm7) // movdqu 0x10(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- MEMOPREG(movdqu,0x20,0,4,1,xmm7) // movdqu 0x20(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x30,0,4,1,xmm7) // movdqu 0x30(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm6 \n" >- >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm7 \n" >- "shufps $0x88,%%xmm1,%%xmm0 \n" >- "shufps $0xdd,%%xmm1,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm0 \n" >- "movdqa %%xmm2,%%xmm7 \n" >- "shufps $0x88,%%xmm6,%%xmm2 \n" >- "shufps $0xdd,%%xmm6,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm2,%%xmm6 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm3,%%xmm1 \n" >- "pmaddubsw %%xmm3,%%xmm6 \n" >- "phaddw %%xmm2,%%xmm0 \n" >- "phaddw %%xmm6,%%xmm1 \n" >- "paddw %%xmm5,%%xmm0 \n" >- "paddw %%xmm5,%%xmm1 \n" >- "psraw $0x8,%%xmm0 \n" >- "psraw $0x8,%%xmm1 \n" >- "packsswb %%xmm1,%%xmm0 \n" >- "movlps %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movhps,xmm0,0x00,1,2,1) // movhps %%xmm0,(%1,%2,1) >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_argb0), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+rm"(width) // %3 >- : "r"((intptr_t)(src_stride_argb)), // %4 >- "m"(kARGBToVJ), // %5 >- "m"(kARGBToUJ), // %6 >- "m"(kAddUVJ128) // %7 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm6", "xmm7" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x10(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x20(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm6 \n" >+ "movdqu 0x30(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ >+ "lea 0x40(%0),%0 \n" >+ "movdqa %%xmm0,%%xmm7 \n" >+ "shufps $0x88,%%xmm1,%%xmm0 \n" >+ "shufps $0xdd,%%xmm1,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm0 \n" >+ "movdqa %%xmm2,%%xmm7 \n" >+ "shufps $0x88,%%xmm6,%%xmm2 \n" >+ "shufps $0xdd,%%xmm6,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm2,%%xmm6 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm3,%%xmm1 \n" >+ "pmaddubsw %%xmm3,%%xmm6 \n" >+ "phaddw %%xmm2,%%xmm0 \n" >+ "phaddw %%xmm6,%%xmm1 \n" >+ "paddw %%xmm5,%%xmm0 \n" >+ "paddw %%xmm5,%%xmm1 \n" >+ "psraw $0x8,%%xmm0 \n" >+ "psraw $0x8,%%xmm1 \n" >+ "packsswb %%xmm1,%%xmm0 \n" >+ "movlps %%xmm0,(%1) \n" >+ "movhps %%xmm0,0x00(%1,%2,1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+rm"(width) // %3 >+ : "r"((intptr_t)(src_stride_argb)), // %4 >+ "m"(kARGBToVJ), // %5 >+ "m"(kARGBToUJ), // %6 >+ "m"(kAddUVJ128) // %7 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6", "xmm7"); > } > #endif // HAS_ARGBTOUVJROW_SSSE3 > > #ifdef HAS_ARGBTOUV444ROW_SSSE3 >-void ARGBToUV444Row_SSSE3(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUV444Row_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "movdqa %4,%%xmm3 \n" >- "movdqa %5,%%xmm4 \n" >- "movdqa %6,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "movdqa %4,%%xmm3 \n" >+ "movdqa %5,%%xmm4 \n" >+ "movdqa %6,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm6 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm4,%%xmm6 \n" >- "phaddw %%xmm1,%%xmm0 \n" >- "phaddw %%xmm6,%%xmm2 \n" >- "psraw $0x8,%%xmm0 \n" >- "psraw $0x8,%%xmm2 \n" >- "packsswb %%xmm2,%%xmm0 \n" >- "paddb %%xmm5,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm6 \n" >- "pmaddubsw %%xmm3,%%xmm0 \n" >- "pmaddubsw %%xmm3,%%xmm1 \n" >- "pmaddubsw %%xmm3,%%xmm2 \n" >- "pmaddubsw %%xmm3,%%xmm6 \n" >- "phaddw %%xmm1,%%xmm0 \n" >- "phaddw %%xmm6,%%xmm2 \n" >- "psraw $0x8,%%xmm0 \n" >- "psraw $0x8,%%xmm2 \n" >- "packsswb %%xmm2,%%xmm0 \n" >- "paddb %%xmm5,%%xmm0 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- MEMOPMEM(movdqu,xmm0,0x00,1,2,1) // movdqu %%xmm0,(%1,%2,1) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+rm"(width) // %3 >- : "m"(kARGBToV), // %4 >- "m"(kARGBToU), // %5 >- "m"(kAddUV128) // %6 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm6" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm6 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm4,%%xmm6 \n" >+ "phaddw %%xmm1,%%xmm0 \n" >+ "phaddw %%xmm6,%%xmm2 \n" >+ "psraw $0x8,%%xmm0 \n" >+ "psraw $0x8,%%xmm2 \n" >+ "packsswb %%xmm2,%%xmm0 \n" >+ "paddb %%xmm5,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm6 \n" >+ "pmaddubsw %%xmm3,%%xmm0 \n" >+ "pmaddubsw %%xmm3,%%xmm1 \n" >+ "pmaddubsw %%xmm3,%%xmm2 \n" >+ "pmaddubsw %%xmm3,%%xmm6 \n" >+ "phaddw %%xmm1,%%xmm0 \n" >+ "phaddw %%xmm6,%%xmm2 \n" >+ "psraw $0x8,%%xmm0 \n" >+ "psraw $0x8,%%xmm2 \n" >+ "packsswb %%xmm2,%%xmm0 \n" >+ "paddb %%xmm5,%%xmm0 \n" >+ "lea 0x40(%0),%0 \n" >+ "movdqu %%xmm0,0x00(%1,%2,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+rm"(width) // %3 >+ : "m"(kARGBToV), // %4 >+ "m"(kARGBToU), // %5 >+ "m"(kAddUV128) // %6 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6"); > } > #endif // HAS_ARGBTOUV444ROW_SSSE3 > >-void BGRAToYRow_SSSE3(const uint8* src_bgra, uint8* dst_y, int width) { >- asm volatile ( >- "movdqa %4,%%xmm5 \n" >- "movdqa %3,%%xmm4 \n" >+void BGRAToYRow_SSSE3(const uint8_t* src_bgra, uint8_t* dst_y, int width) { >+ asm volatile( >+ "movdqa %4,%%xmm5 \n" >+ "movdqa %3,%%xmm4 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm3 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm4,%%xmm3 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "phaddw %%xmm1,%%xmm0 \n" >- "phaddw %%xmm3,%%xmm2 \n" >- "psrlw $0x7,%%xmm0 \n" >- "psrlw $0x7,%%xmm2 \n" >- "packuswb %%xmm2,%%xmm0 \n" >- "paddb %%xmm5,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_bgra), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : "m"(kBGRAToY), // %3 >- "m"(kAddY16) // %4 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm3 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm4,%%xmm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "phaddw %%xmm1,%%xmm0 \n" >+ "phaddw %%xmm3,%%xmm2 \n" >+ "psrlw $0x7,%%xmm0 \n" >+ "psrlw $0x7,%%xmm2 \n" >+ "packuswb %%xmm2,%%xmm0 \n" >+ "paddb %%xmm5,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_bgra), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "m"(kBGRAToY), // %3 >+ "m"(kAddY16) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > >-void BGRAToUVRow_SSSE3(const uint8* src_bgra0, >+void BGRAToUVRow_SSSE3(const uint8_t* src_bgra0, > int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "movdqa %5,%%xmm3 \n" >- "movdqa %6,%%xmm4 \n" >- "movdqa %7,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "movdqa %5,%%xmm3 \n" >+ "movdqa %6,%%xmm4 \n" >+ "movdqa %7,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,4,1,xmm7) // movdqu (%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- MEMOPREG(movdqu,0x10,0,4,1,xmm7) // movdqu 0x10(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- MEMOPREG(movdqu,0x20,0,4,1,xmm7) // movdqu 0x20(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x30,0,4,1,xmm7) // movdqu 0x30(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm6 \n" >- >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm7 \n" >- "shufps $0x88,%%xmm1,%%xmm0 \n" >- "shufps $0xdd,%%xmm1,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm0 \n" >- "movdqa %%xmm2,%%xmm7 \n" >- "shufps $0x88,%%xmm6,%%xmm2 \n" >- "shufps $0xdd,%%xmm6,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm2,%%xmm6 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm3,%%xmm1 \n" >- "pmaddubsw %%xmm3,%%xmm6 \n" >- "phaddw %%xmm2,%%xmm0 \n" >- "phaddw %%xmm6,%%xmm1 \n" >- "psraw $0x8,%%xmm0 \n" >- "psraw $0x8,%%xmm1 \n" >- "packsswb %%xmm1,%%xmm0 \n" >- "paddb %%xmm5,%%xmm0 \n" >- "movlps %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movhps,xmm0,0x00,1,2,1) // movhps %%xmm0,(%1,%2,1) >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_bgra0), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+rm"(width) // %3 >- : "r"((intptr_t)(src_stride_bgra)), // %4 >- "m"(kBGRAToV), // %5 >- "m"(kBGRAToU), // %6 >- "m"(kAddUV128) // %7 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm6", "xmm7" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x10(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x20(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm6 \n" >+ "movdqu 0x30(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ >+ "lea 0x40(%0),%0 \n" >+ "movdqa %%xmm0,%%xmm7 \n" >+ "shufps $0x88,%%xmm1,%%xmm0 \n" >+ "shufps $0xdd,%%xmm1,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm0 \n" >+ "movdqa %%xmm2,%%xmm7 \n" >+ "shufps $0x88,%%xmm6,%%xmm2 \n" >+ "shufps $0xdd,%%xmm6,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm2,%%xmm6 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm3,%%xmm1 \n" >+ "pmaddubsw %%xmm3,%%xmm6 \n" >+ "phaddw %%xmm2,%%xmm0 \n" >+ "phaddw %%xmm6,%%xmm1 \n" >+ "psraw $0x8,%%xmm0 \n" >+ "psraw $0x8,%%xmm1 \n" >+ "packsswb %%xmm1,%%xmm0 \n" >+ "paddb %%xmm5,%%xmm0 \n" >+ "movlps %%xmm0,(%1) \n" >+ "movhps %%xmm0,0x00(%1,%2,1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_bgra0), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+rm"(width) // %3 >+ : "r"((intptr_t)(src_stride_bgra)), // %4 >+ "m"(kBGRAToV), // %5 >+ "m"(kBGRAToU), // %6 >+ "m"(kAddUV128) // %7 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6", "xmm7"); > } > >-void ABGRToYRow_SSSE3(const uint8* src_abgr, uint8* dst_y, int width) { >- asm volatile ( >- "movdqa %4,%%xmm5 \n" >- "movdqa %3,%%xmm4 \n" >+void ABGRToYRow_SSSE3(const uint8_t* src_abgr, uint8_t* dst_y, int width) { >+ asm volatile( >+ "movdqa %4,%%xmm5 \n" >+ "movdqa %3,%%xmm4 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm3 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm4,%%xmm3 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "phaddw %%xmm1,%%xmm0 \n" >- "phaddw %%xmm3,%%xmm2 \n" >- "psrlw $0x7,%%xmm0 \n" >- "psrlw $0x7,%%xmm2 \n" >- "packuswb %%xmm2,%%xmm0 \n" >- "paddb %%xmm5,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_abgr), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : "m"(kABGRToY), // %3 >- "m"(kAddY16) // %4 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm3 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm4,%%xmm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "phaddw %%xmm1,%%xmm0 \n" >+ "phaddw %%xmm3,%%xmm2 \n" >+ "psrlw $0x7,%%xmm0 \n" >+ "psrlw $0x7,%%xmm2 \n" >+ "packuswb %%xmm2,%%xmm0 \n" >+ "paddb %%xmm5,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_abgr), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "m"(kABGRToY), // %3 >+ "m"(kAddY16) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > >-void RGBAToYRow_SSSE3(const uint8* src_rgba, uint8* dst_y, int width) { >- asm volatile ( >- "movdqa %4,%%xmm5 \n" >- "movdqa %3,%%xmm4 \n" >+void RGBAToYRow_SSSE3(const uint8_t* src_rgba, uint8_t* dst_y, int width) { >+ asm volatile( >+ "movdqa %4,%%xmm5 \n" >+ "movdqa %3,%%xmm4 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm3 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm4,%%xmm3 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "phaddw %%xmm1,%%xmm0 \n" >- "phaddw %%xmm3,%%xmm2 \n" >- "psrlw $0x7,%%xmm0 \n" >- "psrlw $0x7,%%xmm2 \n" >- "packuswb %%xmm2,%%xmm0 \n" >- "paddb %%xmm5,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_rgba), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : "m"(kRGBAToY), // %3 >- "m"(kAddY16) // %4 >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm3 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm4,%%xmm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "phaddw %%xmm1,%%xmm0 \n" >+ "phaddw %%xmm3,%%xmm2 \n" >+ "psrlw $0x7,%%xmm0 \n" >+ "psrlw $0x7,%%xmm2 \n" >+ "packuswb %%xmm2,%%xmm0 \n" >+ "paddb %%xmm5,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_rgba), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "m"(kRGBAToY), // %3 >+ "m"(kAddY16) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > >-void ABGRToUVRow_SSSE3(const uint8* src_abgr0, >+void ABGRToUVRow_SSSE3(const uint8_t* src_abgr0, > int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "movdqa %5,%%xmm3 \n" >- "movdqa %6,%%xmm4 \n" >- "movdqa %7,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "movdqa %5,%%xmm3 \n" >+ "movdqa %6,%%xmm4 \n" >+ "movdqa %7,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,4,1,xmm7) // movdqu (%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- MEMOPREG(movdqu,0x10,0,4,1,xmm7) // movdqu 0x10(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- MEMOPREG(movdqu,0x20,0,4,1,xmm7) // movdqu 0x20(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x30,0,4,1,xmm7) // movdqu 0x30(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm6 \n" >- >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm7 \n" >- "shufps $0x88,%%xmm1,%%xmm0 \n" >- "shufps $0xdd,%%xmm1,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm0 \n" >- "movdqa %%xmm2,%%xmm7 \n" >- "shufps $0x88,%%xmm6,%%xmm2 \n" >- "shufps $0xdd,%%xmm6,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm2,%%xmm6 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm3,%%xmm1 \n" >- "pmaddubsw %%xmm3,%%xmm6 \n" >- "phaddw %%xmm2,%%xmm0 \n" >- "phaddw %%xmm6,%%xmm1 \n" >- "psraw $0x8,%%xmm0 \n" >- "psraw $0x8,%%xmm1 \n" >- "packsswb %%xmm1,%%xmm0 \n" >- "paddb %%xmm5,%%xmm0 \n" >- "movlps %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movhps,xmm0,0x00,1,2,1) // movhps %%xmm0,(%1,%2,1) >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_abgr0), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+rm"(width) // %3 >- : "r"((intptr_t)(src_stride_abgr)), // %4 >- "m"(kABGRToV), // %5 >- "m"(kABGRToU), // %6 >- "m"(kAddUV128) // %7 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm6", "xmm7" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x10(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x20(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm6 \n" >+ "movdqu 0x30(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ >+ "lea 0x40(%0),%0 \n" >+ "movdqa %%xmm0,%%xmm7 \n" >+ "shufps $0x88,%%xmm1,%%xmm0 \n" >+ "shufps $0xdd,%%xmm1,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm0 \n" >+ "movdqa %%xmm2,%%xmm7 \n" >+ "shufps $0x88,%%xmm6,%%xmm2 \n" >+ "shufps $0xdd,%%xmm6,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm2,%%xmm6 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm3,%%xmm1 \n" >+ "pmaddubsw %%xmm3,%%xmm6 \n" >+ "phaddw %%xmm2,%%xmm0 \n" >+ "phaddw %%xmm6,%%xmm1 \n" >+ "psraw $0x8,%%xmm0 \n" >+ "psraw $0x8,%%xmm1 \n" >+ "packsswb %%xmm1,%%xmm0 \n" >+ "paddb %%xmm5,%%xmm0 \n" >+ "movlps %%xmm0,(%1) \n" >+ "movhps %%xmm0,0x00(%1,%2,1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_abgr0), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+rm"(width) // %3 >+ : "r"((intptr_t)(src_stride_abgr)), // %4 >+ "m"(kABGRToV), // %5 >+ "m"(kABGRToU), // %6 >+ "m"(kAddUV128) // %7 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6", "xmm7"); > } > >-void RGBAToUVRow_SSSE3(const uint8* src_rgba0, >+void RGBAToUVRow_SSSE3(const uint8_t* src_rgba0, > int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "movdqa %5,%%xmm3 \n" >- "movdqa %6,%%xmm4 \n" >- "movdqa %7,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "movdqa %5,%%xmm3 \n" >+ "movdqa %6,%%xmm4 \n" >+ "movdqa %7,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,4,1,xmm7) // movdqu (%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- MEMOPREG(movdqu,0x10,0,4,1,xmm7) // movdqu 0x10(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- MEMOPREG(movdqu,0x20,0,4,1,xmm7) // movdqu 0x20(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x30,0,4,1,xmm7) // movdqu 0x30(%0,%4,1),%%xmm7 >- "pavgb %%xmm7,%%xmm6 \n" >- >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm7 \n" >- "shufps $0x88,%%xmm1,%%xmm0 \n" >- "shufps $0xdd,%%xmm1,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm0 \n" >- "movdqa %%xmm2,%%xmm7 \n" >- "shufps $0x88,%%xmm6,%%xmm2 \n" >- "shufps $0xdd,%%xmm6,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm2,%%xmm6 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm3,%%xmm1 \n" >- "pmaddubsw %%xmm3,%%xmm6 \n" >- "phaddw %%xmm2,%%xmm0 \n" >- "phaddw %%xmm6,%%xmm1 \n" >- "psraw $0x8,%%xmm0 \n" >- "psraw $0x8,%%xmm1 \n" >- "packsswb %%xmm1,%%xmm0 \n" >- "paddb %%xmm5,%%xmm0 \n" >- "movlps %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movhps,xmm0,0x00,1,2,1) // movhps %%xmm0,(%1,%2,1) >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_rgba0), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+rm"(width) // %3 >- : "r"((intptr_t)(src_stride_rgba)), // %4 >- "m"(kRGBAToV), // %5 >- "m"(kRGBAToU), // %6 >- "m"(kAddUV128) // %7 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm6", "xmm7" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x10(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x20(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm6 \n" >+ "movdqu 0x30(%0,%4,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ >+ "lea 0x40(%0),%0 \n" >+ "movdqa %%xmm0,%%xmm7 \n" >+ "shufps $0x88,%%xmm1,%%xmm0 \n" >+ "shufps $0xdd,%%xmm1,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm0 \n" >+ "movdqa %%xmm2,%%xmm7 \n" >+ "shufps $0x88,%%xmm6,%%xmm2 \n" >+ "shufps $0xdd,%%xmm6,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm2,%%xmm6 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm3,%%xmm1 \n" >+ "pmaddubsw %%xmm3,%%xmm6 \n" >+ "phaddw %%xmm2,%%xmm0 \n" >+ "phaddw %%xmm6,%%xmm1 \n" >+ "psraw $0x8,%%xmm0 \n" >+ "psraw $0x8,%%xmm1 \n" >+ "packsswb %%xmm1,%%xmm0 \n" >+ "paddb %%xmm5,%%xmm0 \n" >+ "movlps %%xmm0,(%1) \n" >+ "movhps %%xmm0,0x00(%1,%2,1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_rgba0), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+rm"(width) // %3 >+ : "r"((intptr_t)(src_stride_rgba)), // %4 >+ "m"(kRGBAToV), // %5 >+ "m"(kRGBAToU), // %6 >+ "m"(kAddUV128) // %7 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6", "xmm7"); > } > > #if defined(HAS_I422TOARGBROW_SSSE3) || defined(HAS_I422TOARGBROW_AVX2) > > // Read 8 UV from 444 >-#define READYUV444 \ >- "movq " MEMACCESS([u_buf]) ",%%xmm0 \n" \ >- MEMOPREG(movq, 0x00, [u_buf], [v_buf], 1, xmm1) \ >- "lea " MEMLEA(0x8, [u_buf]) ",%[u_buf] \n" \ >- "punpcklbw %%xmm1,%%xmm0 \n" \ >- "movq " MEMACCESS([y_buf]) ",%%xmm4 \n" \ >- "punpcklbw %%xmm4,%%xmm4 \n" \ >- "lea " MEMLEA(0x8, [y_buf]) ",%[y_buf] \n" >+#define READYUV444 \ >+ "movq (%[u_buf]),%%xmm0 \n" \ >+ "movq 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ >+ "lea 0x8(%[u_buf]),%[u_buf] \n" \ >+ "punpcklbw %%xmm1,%%xmm0 \n" \ >+ "movq (%[y_buf]),%%xmm4 \n" \ >+ "punpcklbw %%xmm4,%%xmm4 \n" \ >+ "lea 0x8(%[y_buf]),%[y_buf] \n" > > // Read 4 UV from 422, upsample to 8 UV >-#define READYUV422 \ >- "movd " MEMACCESS([u_buf]) ",%%xmm0 \n" \ >- MEMOPREG(movd, 0x00, [u_buf], [v_buf], 1, xmm1) \ >- "lea " MEMLEA(0x4, [u_buf]) ",%[u_buf] \n" \ >- "punpcklbw %%xmm1,%%xmm0 \n" \ >- "punpcklwd %%xmm0,%%xmm0 \n" \ >- "movq " MEMACCESS([y_buf]) ",%%xmm4 \n" \ >- "punpcklbw %%xmm4,%%xmm4 \n" \ >- "lea " MEMLEA(0x8, [y_buf]) ",%[y_buf] \n" >+#define READYUV422 \ >+ "movd (%[u_buf]),%%xmm0 \n" \ >+ "movd 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ >+ "lea 0x4(%[u_buf]),%[u_buf] \n" \ >+ "punpcklbw %%xmm1,%%xmm0 \n" \ >+ "punpcklwd %%xmm0,%%xmm0 \n" \ >+ "movq (%[y_buf]),%%xmm4 \n" \ >+ "punpcklbw %%xmm4,%%xmm4 \n" \ >+ "lea 0x8(%[y_buf]),%[y_buf] \n" >+ >+// Read 4 UV from 422 10 bit, upsample to 8 UV >+// TODO(fbarchard): Consider shufb to replace pack/unpack >+// TODO(fbarchard): Consider pmulhuw to replace psraw >+// TODO(fbarchard): Consider pmullw to replace psllw and allow different bits. >+#define READYUV210 \ >+ "movq (%[u_buf]),%%xmm0 \n" \ >+ "movq 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ >+ "lea 0x8(%[u_buf]),%[u_buf] \n" \ >+ "punpcklwd %%xmm1,%%xmm0 \n" \ >+ "psraw $0x2,%%xmm0 \n" \ >+ "packuswb %%xmm0,%%xmm0 \n" \ >+ "punpcklwd %%xmm0,%%xmm0 \n" \ >+ "movdqu (%[y_buf]),%%xmm4 \n" \ >+ "psllw $0x6,%%xmm4 \n" \ >+ "lea 0x10(%[y_buf]),%[y_buf] \n" > > // Read 4 UV from 422, upsample to 8 UV. With 8 Alpha. >-#define READYUVA422 \ >- "movd " MEMACCESS([u_buf]) ",%%xmm0 \n" \ >- MEMOPREG(movd, 0x00, [u_buf], [v_buf], 1, xmm1) \ >- "lea " MEMLEA(0x4, [u_buf]) ",%[u_buf] \n" \ >- "punpcklbw %%xmm1,%%xmm0 \n" \ >- "punpcklwd %%xmm0,%%xmm0 \n" \ >- "movq " MEMACCESS([y_buf]) ",%%xmm4 \n" \ >- "punpcklbw %%xmm4,%%xmm4 \n" \ >- "lea " MEMLEA(0x8, [y_buf]) ",%[y_buf] \n" \ >- "movq " MEMACCESS([a_buf]) ",%%xmm5 \n" \ >- "lea " MEMLEA(0x8, [a_buf]) ",%[a_buf] \n" >+#define READYUVA422 \ >+ "movd (%[u_buf]),%%xmm0 \n" \ >+ "movd 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ >+ "lea 0x4(%[u_buf]),%[u_buf] \n" \ >+ "punpcklbw %%xmm1,%%xmm0 \n" \ >+ "punpcklwd %%xmm0,%%xmm0 \n" \ >+ "movq (%[y_buf]),%%xmm4 \n" \ >+ "punpcklbw %%xmm4,%%xmm4 \n" \ >+ "lea 0x8(%[y_buf]),%[y_buf] \n" \ >+ "movq (%[a_buf]),%%xmm5 \n" \ >+ "lea 0x8(%[a_buf]),%[a_buf] \n" > > // Read 4 UV from NV12, upsample to 8 UV >-#define READNV12 \ >- "movq " MEMACCESS([uv_buf]) ",%%xmm0 \n" \ >- "lea " MEMLEA(0x8, [uv_buf]) ",%[uv_buf] \n" \ >- "punpcklwd %%xmm0,%%xmm0 \n" \ >- "movq " MEMACCESS([y_buf]) ",%%xmm4 \n" \ >- "punpcklbw %%xmm4,%%xmm4 \n" \ >- "lea " MEMLEA(0x8, [y_buf]) ",%[y_buf] \n" >+#define READNV12 \ >+ "movq (%[uv_buf]),%%xmm0 \n" \ >+ "lea 0x8(%[uv_buf]),%[uv_buf] \n" \ >+ "punpcklwd %%xmm0,%%xmm0 \n" \ >+ "movq (%[y_buf]),%%xmm4 \n" \ >+ "punpcklbw %%xmm4,%%xmm4 \n" \ >+ "lea 0x8(%[y_buf]),%[y_buf] \n" > > // Read 4 VU from NV21, upsample to 8 UV >-#define READNV21 \ >- "movq " MEMACCESS([vu_buf]) ",%%xmm0 \n" \ >- "lea " MEMLEA(0x8, [vu_buf]) ",%[vu_buf] \n" \ >- "pshufb %[kShuffleNV21], %%xmm0 \n" \ >- "movq " MEMACCESS([y_buf]) ",%%xmm4 \n" \ >- "punpcklbw %%xmm4,%%xmm4 \n" \ >- "lea " MEMLEA(0x8, [y_buf]) ",%[y_buf] \n" >+#define READNV21 \ >+ "movq (%[vu_buf]),%%xmm0 \n" \ >+ "lea 0x8(%[vu_buf]),%[vu_buf] \n" \ >+ "pshufb %[kShuffleNV21], %%xmm0 \n" \ >+ "movq (%[y_buf]),%%xmm4 \n" \ >+ "punpcklbw %%xmm4,%%xmm4 \n" \ >+ "lea 0x8(%[y_buf]),%[y_buf] \n" > > // Read 4 YUY2 with 8 Y and update 4 UV to 8 UV. >-#define READYUY2 \ >- "movdqu " MEMACCESS([yuy2_buf]) ",%%xmm4 \n" \ >- "pshufb %[kShuffleYUY2Y], %%xmm4 \n" \ >- "movdqu " MEMACCESS([yuy2_buf]) ",%%xmm0 \n" \ >- "pshufb %[kShuffleYUY2UV], %%xmm0 \n" \ >- "lea " MEMLEA(0x10, [yuy2_buf]) ",%[yuy2_buf] \n" >+#define READYUY2 \ >+ "movdqu (%[yuy2_buf]),%%xmm4 \n" \ >+ "pshufb %[kShuffleYUY2Y], %%xmm4 \n" \ >+ "movdqu (%[yuy2_buf]),%%xmm0 \n" \ >+ "pshufb %[kShuffleYUY2UV], %%xmm0 \n" \ >+ "lea 0x10(%[yuy2_buf]),%[yuy2_buf] \n" > > // Read 4 UYVY with 8 Y and update 4 UV to 8 UV. >-#define READUYVY \ >- "movdqu " MEMACCESS([uyvy_buf]) ",%%xmm4 \n" \ >- "pshufb %[kShuffleUYVYY], %%xmm4 \n" \ >- "movdqu " MEMACCESS([uyvy_buf]) ",%%xmm0 \n" \ >- "pshufb %[kShuffleUYVYUV], %%xmm0 \n" \ >- "lea " MEMLEA(0x10, [uyvy_buf]) ",%[uyvy_buf] \n" >+#define READUYVY \ >+ "movdqu (%[uyvy_buf]),%%xmm4 \n" \ >+ "pshufb %[kShuffleUYVYY], %%xmm4 \n" \ >+ "movdqu (%[uyvy_buf]),%%xmm0 \n" \ >+ "pshufb %[kShuffleUYVYUV], %%xmm0 \n" \ >+ "lea 0x10(%[uyvy_buf]),%[uyvy_buf] \n" > > #if defined(__x86_64__) >-#define YUVTORGB_SETUP(yuvconstants) \ >- "movdqa " MEMACCESS([yuvconstants]) ",%%xmm8 \n" \ >- "movdqa " MEMACCESS2(32, [yuvconstants]) ",%%xmm9 \n" \ >- "movdqa " MEMACCESS2(64, [yuvconstants]) ",%%xmm10 \n" \ >- "movdqa " MEMACCESS2(96, [yuvconstants]) ",%%xmm11 \n" \ >- "movdqa " MEMACCESS2(128, [yuvconstants]) ",%%xmm12 \n" \ >- "movdqa " MEMACCESS2(160, [yuvconstants]) ",%%xmm13 \n" \ >- "movdqa " MEMACCESS2(192, [yuvconstants]) ",%%xmm14 \n" >+#define YUVTORGB_SETUP(yuvconstants) \ >+ "movdqa (%[yuvconstants]),%%xmm8 \n" \ >+ "movdqa 32(%[yuvconstants]),%%xmm9 \n" \ >+ "movdqa 64(%[yuvconstants]),%%xmm10 \n" \ >+ "movdqa 96(%[yuvconstants]),%%xmm11 \n" \ >+ "movdqa 128(%[yuvconstants]),%%xmm12 \n" \ >+ "movdqa 160(%[yuvconstants]),%%xmm13 \n" \ >+ "movdqa 192(%[yuvconstants]),%%xmm14 \n" > // Convert 8 pixels: 8 UV and 8 Y >-#define YUVTORGB(yuvconstants) \ >+#define YUVTORGB16(yuvconstants) \ > "movdqa %%xmm0,%%xmm1 \n" \ > "movdqa %%xmm0,%%xmm2 \n" \ > "movdqa %%xmm0,%%xmm3 \n" \ >@@ -1590,72 +1776,95 @@ void RGBAToUVRow_SSSE3(const uint8* src_rgba0, > "pmulhuw %%xmm14,%%xmm4 \n" \ > "paddsw %%xmm4,%%xmm0 \n" \ > "paddsw %%xmm4,%%xmm1 \n" \ >- "paddsw %%xmm4,%%xmm2 \n" \ >- "psraw $0x6,%%xmm0 \n" \ >- "psraw $0x6,%%xmm1 \n" \ >- "psraw $0x6,%%xmm2 \n" \ >- "packuswb %%xmm0,%%xmm0 \n" \ >- "packuswb %%xmm1,%%xmm1 \n" \ >- "packuswb %%xmm2,%%xmm2 \n" >+ "paddsw %%xmm4,%%xmm2 \n" > #define YUVTORGB_REGS \ > "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", > > #else > #define YUVTORGB_SETUP(yuvconstants) > // Convert 8 pixels: 8 UV and 8 Y >-#define YUVTORGB(yuvconstants) \ >- "movdqa %%xmm0,%%xmm1 \n" \ >- "movdqa %%xmm0,%%xmm2 \n" \ >- "movdqa %%xmm0,%%xmm3 \n" \ >- "movdqa " MEMACCESS2(96, [yuvconstants]) ",%%xmm0 \n" \ >- "pmaddubsw " MEMACCESS([yuvconstants]) ",%%xmm1 \n" \ >- "psubw %%xmm1,%%xmm0 \n" \ >- "movdqa " MEMACCESS2(128, [yuvconstants]) ",%%xmm1 \n" \ >- "pmaddubsw " MEMACCESS2(32, [yuvconstants]) ",%%xmm2 \n" \ >- "psubw %%xmm2,%%xmm1 \n" \ >- "movdqa " MEMACCESS2(160, [yuvconstants]) ",%%xmm2 \n" \ >- "pmaddubsw " MEMACCESS2(64, [yuvconstants]) ",%%xmm3 \n" \ >- "psubw %%xmm3,%%xmm2 \n" \ >- "pmulhuw " MEMACCESS2(192, [yuvconstants]) ",%%xmm4 \n" \ >- "paddsw %%xmm4,%%xmm0 \n" \ >- "paddsw %%xmm4,%%xmm1 \n" \ >- "paddsw %%xmm4,%%xmm2 \n" \ >- "psraw $0x6,%%xmm0 \n" \ >- "psraw $0x6,%%xmm1 \n" \ >- "psraw $0x6,%%xmm2 \n" \ >- "packuswb %%xmm0,%%xmm0 \n" \ >- "packuswb %%xmm1,%%xmm1 \n" \ >- "packuswb %%xmm2,%%xmm2 \n" >+#define YUVTORGB16(yuvconstants) \ >+ "movdqa %%xmm0,%%xmm1 \n" \ >+ "movdqa %%xmm0,%%xmm2 \n" \ >+ "movdqa %%xmm0,%%xmm3 \n" \ >+ "movdqa 96(%[yuvconstants]),%%xmm0 \n" \ >+ "pmaddubsw (%[yuvconstants]),%%xmm1 \n" \ >+ "psubw %%xmm1,%%xmm0 \n" \ >+ "movdqa 128(%[yuvconstants]),%%xmm1 \n" \ >+ "pmaddubsw 32(%[yuvconstants]),%%xmm2 \n" \ >+ "psubw %%xmm2,%%xmm1 \n" \ >+ "movdqa 160(%[yuvconstants]),%%xmm2 \n" \ >+ "pmaddubsw 64(%[yuvconstants]),%%xmm3 \n" \ >+ "psubw %%xmm3,%%xmm2 \n" \ >+ "pmulhuw 192(%[yuvconstants]),%%xmm4 \n" \ >+ "paddsw %%xmm4,%%xmm0 \n" \ >+ "paddsw %%xmm4,%%xmm1 \n" \ >+ "paddsw %%xmm4,%%xmm2 \n" > #define YUVTORGB_REGS > #endif > >+#define YUVTORGB(yuvconstants) \ >+ YUVTORGB16(yuvconstants) \ >+ "psraw $0x6,%%xmm0 \n" \ >+ "psraw $0x6,%%xmm1 \n" \ >+ "psraw $0x6,%%xmm2 \n" \ >+ "packuswb %%xmm0,%%xmm0 \n" \ >+ "packuswb %%xmm1,%%xmm1 \n" \ >+ "packuswb %%xmm2,%%xmm2 \n" >+ > // Store 8 ARGB values. >-#define STOREARGB \ >- "punpcklbw %%xmm1,%%xmm0 \n" \ >- "punpcklbw %%xmm5,%%xmm2 \n" \ >- "movdqa %%xmm0,%%xmm1 \n" \ >- "punpcklwd %%xmm2,%%xmm0 \n" \ >- "punpckhwd %%xmm2,%%xmm1 \n" \ >- "movdqu %%xmm0," MEMACCESS([dst_argb]) " \n" \ >- "movdqu %%xmm1," MEMACCESS2(0x10, [dst_argb]) " \n" \ >- "lea " MEMLEA(0x20, [dst_argb]) ", %[dst_argb] \n" >+#define STOREARGB \ >+ "punpcklbw %%xmm1,%%xmm0 \n" \ >+ "punpcklbw %%xmm5,%%xmm2 \n" \ >+ "movdqa %%xmm0,%%xmm1 \n" \ >+ "punpcklwd %%xmm2,%%xmm0 \n" \ >+ "punpckhwd %%xmm2,%%xmm1 \n" \ >+ "movdqu %%xmm0,(%[dst_argb]) \n" \ >+ "movdqu %%xmm1,0x10(%[dst_argb]) \n" \ >+ "lea 0x20(%[dst_argb]), %[dst_argb] \n" > > // Store 8 RGBA values. >-#define STORERGBA \ >- "pcmpeqb %%xmm5,%%xmm5 \n" \ >- "punpcklbw %%xmm2,%%xmm1 \n" \ >- "punpcklbw %%xmm0,%%xmm5 \n" \ >- "movdqa %%xmm5,%%xmm0 \n" \ >- "punpcklwd %%xmm1,%%xmm5 \n" \ >- "punpckhwd %%xmm1,%%xmm0 \n" \ >- "movdqu %%xmm5," MEMACCESS([dst_rgba]) " \n" \ >- "movdqu %%xmm0," MEMACCESS2(0x10, [dst_rgba]) " \n" \ >- "lea " MEMLEA(0x20, [dst_rgba]) ",%[dst_rgba] \n" >- >-void OMITFP I444ToARGBRow_SSSE3(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+#define STORERGBA \ >+ "pcmpeqb %%xmm5,%%xmm5 \n" \ >+ "punpcklbw %%xmm2,%%xmm1 \n" \ >+ "punpcklbw %%xmm0,%%xmm5 \n" \ >+ "movdqa %%xmm5,%%xmm0 \n" \ >+ "punpcklwd %%xmm1,%%xmm5 \n" \ >+ "punpckhwd %%xmm1,%%xmm0 \n" \ >+ "movdqu %%xmm5,(%[dst_rgba]) \n" \ >+ "movdqu %%xmm0,0x10(%[dst_rgba]) \n" \ >+ "lea 0x20(%[dst_rgba]),%[dst_rgba] \n" >+ >+// Store 8 AR30 values. >+#define STOREAR30 \ >+ "psraw $0x4,%%xmm0 \n" \ >+ "psraw $0x4,%%xmm1 \n" \ >+ "psraw $0x4,%%xmm2 \n" \ >+ "pminsw %%xmm7,%%xmm0 \n" \ >+ "pminsw %%xmm7,%%xmm1 \n" \ >+ "pminsw %%xmm7,%%xmm2 \n" \ >+ "pmaxsw %%xmm6,%%xmm0 \n" \ >+ "pmaxsw %%xmm6,%%xmm1 \n" \ >+ "pmaxsw %%xmm6,%%xmm2 \n" \ >+ "psllw $0x4,%%xmm2 \n" \ >+ "movdqa %%xmm0,%%xmm3 \n" \ >+ "punpcklwd %%xmm2,%%xmm0 \n" \ >+ "punpckhwd %%xmm2,%%xmm3 \n" \ >+ "movdqa %%xmm1,%%xmm2 \n" \ >+ "punpcklwd %%xmm5,%%xmm1 \n" \ >+ "punpckhwd %%xmm5,%%xmm2 \n" \ >+ "pslld $0xa,%%xmm1 \n" \ >+ "pslld $0xa,%%xmm2 \n" \ >+ "por %%xmm1,%%xmm0 \n" \ >+ "por %%xmm2,%%xmm3 \n" \ >+ "movdqu %%xmm0,(%[dst_ar30]) \n" \ >+ "movdqu %%xmm3,0x10(%[dst_ar30]) \n" \ >+ "lea 0x20(%[dst_ar30]), %[dst_ar30] \n" >+ >+void OMITFP I444ToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -1676,15 +1885,15 @@ void OMITFP I444ToARGBRow_SSSE3(const uint8* y_buf, > [dst_argb]"+r"(dst_argb), // %[dst_argb] > [width]"+rm"(width) // %[width] > : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >- : "memory", "cc", NACL_R14 YUVTORGB_REGS >+ : "memory", "cc", YUVTORGB_REGS > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > } > >-void OMITFP I422ToRGB24Row_SSSE3(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_rgb24, >+void OMITFP I422ToRGB24Row_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_rgb24, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -1705,9 +1914,9 @@ void OMITFP I422ToRGB24Row_SSSE3(const uint8* y_buf, > "pshufb %%xmm5,%%xmm0 \n" > "pshufb %%xmm6,%%xmm1 \n" > "palignr $0xc,%%xmm0,%%xmm1 \n" >- "movq %%xmm0," MEMACCESS([dst_rgb24]) "\n" >- "movdqu %%xmm1," MEMACCESS2(0x8,[dst_rgb24]) "\n" >- "lea " MEMLEA(0x18,[dst_rgb24]) ",%[dst_rgb24] \n" >+ "movq %%xmm0,(%[dst_rgb24]) \n" >+ "movdqu %%xmm1,0x8(%[dst_rgb24]) \n" >+ "lea 0x18(%[dst_rgb24]),%[dst_rgb24] \n" > "subl $0x8,%[width] \n" > "jg 1b \n" > : [y_buf]"+r"(y_buf), // %[y_buf] >@@ -1722,15 +1931,15 @@ void OMITFP I422ToRGB24Row_SSSE3(const uint8* y_buf, > : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] > [kShuffleMaskARGBToRGB24_0]"m"(kShuffleMaskARGBToRGB24_0), > [kShuffleMaskARGBToRGB24]"m"(kShuffleMaskARGBToRGB24) >- : "memory", "cc", NACL_R14 YUVTORGB_REGS >+ : "memory", "cc", YUVTORGB_REGS > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" > ); > } > >-void OMITFP I422ToARGBRow_SSSE3(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+void OMITFP I422ToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -1751,17 +1960,116 @@ void OMITFP I422ToARGBRow_SSSE3(const uint8* y_buf, > [dst_argb]"+r"(dst_argb), // %[dst_argb] > [width]"+rm"(width) // %[width] > : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >- : "memory", "cc", NACL_R14 YUVTORGB_REGS >+ : "memory", "cc", YUVTORGB_REGS >+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >+ ); >+} >+ >+void OMITFP I422ToAR30Row_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ar30, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ asm volatile ( >+ YUVTORGB_SETUP(yuvconstants) >+ "sub %[u_buf],%[v_buf] \n" >+ "pcmpeqb %%xmm5,%%xmm5 \n" // AR30 constants >+ "psrlw $14,%%xmm5 \n" >+ "psllw $4,%%xmm5 \n" // 2 alpha bits >+ "pxor %%xmm6,%%xmm6 \n" >+ "pcmpeqb %%xmm7,%%xmm7 \n" // 0 for min >+ "psrlw $6,%%xmm7 \n" // 1023 for max >+ >+ LABELALIGN >+ "1: \n" >+ READYUV422 >+ YUVTORGB16(yuvconstants) >+ STOREAR30 >+ "sub $0x8,%[width] \n" >+ "jg 1b \n" >+ : [y_buf]"+r"(y_buf), // %[y_buf] >+ [u_buf]"+r"(u_buf), // %[u_buf] >+ [v_buf]"+r"(v_buf), // %[v_buf] >+ [dst_ar30]"+r"(dst_ar30), // %[dst_ar30] >+ [width]"+rm"(width) // %[width] >+ : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >+ : "memory", "cc", YUVTORGB_REGS >+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >+ ); >+} >+ >+// 10 bit YUV to ARGB >+void OMITFP I210ToARGBRow_SSSE3(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_argb, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ asm volatile ( >+ YUVTORGB_SETUP(yuvconstants) >+ "sub %[u_buf],%[v_buf] \n" >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ READYUV210 >+ YUVTORGB(yuvconstants) >+ STOREARGB >+ "sub $0x8,%[width] \n" >+ "jg 1b \n" >+ : [y_buf]"+r"(y_buf), // %[y_buf] >+ [u_buf]"+r"(u_buf), // %[u_buf] >+ [v_buf]"+r"(v_buf), // %[v_buf] >+ [dst_argb]"+r"(dst_argb), // %[dst_argb] >+ [width]"+rm"(width) // %[width] >+ : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >+ : "memory", "cc", YUVTORGB_REGS > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > } > >+// 10 bit YUV to AR30 >+void OMITFP I210ToAR30Row_SSSE3(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_ar30, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ asm volatile ( >+ YUVTORGB_SETUP(yuvconstants) >+ "sub %[u_buf],%[v_buf] \n" >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "psrlw $14,%%xmm5 \n" >+ "psllw $4,%%xmm5 \n" // 2 alpha bits >+ "pxor %%xmm6,%%xmm6 \n" >+ "pcmpeqb %%xmm7,%%xmm7 \n" // 0 for min >+ "psrlw $6,%%xmm7 \n" // 1023 for max >+ >+ LABELALIGN >+ "1: \n" >+ READYUV210 >+ YUVTORGB16(yuvconstants) >+ STOREAR30 >+ "sub $0x8,%[width] \n" >+ "jg 1b \n" >+ : [y_buf]"+r"(y_buf), // %[y_buf] >+ [u_buf]"+r"(u_buf), // %[u_buf] >+ [v_buf]"+r"(v_buf), // %[v_buf] >+ [dst_ar30]"+r"(dst_ar30), // %[dst_ar30] >+ [width]"+rm"(width) // %[width] >+ : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >+ : "memory", "cc", YUVTORGB_REGS >+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >+ ); >+} >+ > #ifdef HAS_I422ALPHATOARGBROW_SSSE3 >-void OMITFP I422AlphaToARGBRow_SSSE3(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+void OMITFP I422AlphaToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > // clang-format off >@@ -1787,16 +2095,16 @@ void OMITFP I422AlphaToARGBRow_SSSE3(const uint8* y_buf, > [width]"+rm"(width) // %[width] > #endif > : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >- : "memory", "cc", NACL_R14 YUVTORGB_REGS >+ : "memory", "cc", YUVTORGB_REGS > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > // clang-format on > } > #endif // HAS_I422ALPHATOARGBROW_SSSE3 > >-void OMITFP NV12ToARGBRow_SSSE3(const uint8* y_buf, >- const uint8* uv_buf, >- uint8* dst_argb, >+void OMITFP NV12ToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > // clang-format off >@@ -1816,15 +2124,15 @@ void OMITFP NV12ToARGBRow_SSSE3(const uint8* y_buf, > [dst_argb]"+r"(dst_argb), // %[dst_argb] > [width]"+rm"(width) // %[width] > : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >- : "memory", "cc", YUVTORGB_REGS // Does not use r14. >+ : "memory", "cc", YUVTORGB_REGS > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > // clang-format on > } > >-void OMITFP NV21ToARGBRow_SSSE3(const uint8* y_buf, >- const uint8* vu_buf, >- uint8* dst_argb, >+void OMITFP NV21ToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* vu_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > // clang-format off >@@ -1845,14 +2153,14 @@ void OMITFP NV21ToARGBRow_SSSE3(const uint8* y_buf, > [width]"+rm"(width) // %[width] > : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] > [kShuffleNV21]"m"(kShuffleNV21) >- : "memory", "cc", YUVTORGB_REGS // Does not use r14. >+ : "memory", "cc", YUVTORGB_REGS > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > // clang-format on > } > >-void OMITFP YUY2ToARGBRow_SSSE3(const uint8* yuy2_buf, >- uint8* dst_argb, >+void OMITFP YUY2ToARGBRow_SSSE3(const uint8_t* yuy2_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > // clang-format off >@@ -1873,14 +2181,14 @@ void OMITFP YUY2ToARGBRow_SSSE3(const uint8* yuy2_buf, > : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] > [kShuffleYUY2Y]"m"(kShuffleYUY2Y), > [kShuffleYUY2UV]"m"(kShuffleYUY2UV) >- : "memory", "cc", YUVTORGB_REGS // Does not use r14. >+ : "memory", "cc", YUVTORGB_REGS > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > // clang-format on > } > >-void OMITFP UYVYToARGBRow_SSSE3(const uint8* uyvy_buf, >- uint8* dst_argb, >+void OMITFP UYVYToARGBRow_SSSE3(const uint8_t* uyvy_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > // clang-format off >@@ -1901,16 +2209,16 @@ void OMITFP UYVYToARGBRow_SSSE3(const uint8* uyvy_buf, > : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] > [kShuffleUYVYY]"m"(kShuffleUYVYY), > [kShuffleUYVYUV]"m"(kShuffleUYVYUV) >- : "memory", "cc", YUVTORGB_REGS // Does not use r14. >+ : "memory", "cc", YUVTORGB_REGS > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > // clang-format on > } > >-void OMITFP I422ToRGBARow_SSSE3(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_rgba, >+void OMITFP I422ToRGBARow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_rgba, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -1931,7 +2239,7 @@ void OMITFP I422ToRGBARow_SSSE3(const uint8* y_buf, > [dst_rgba]"+r"(dst_rgba), // %[dst_rgba] > [width]"+rm"(width) // %[width] > : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >- : "memory", "cc", NACL_R14 YUVTORGB_REGS >+ : "memory", "cc", YUVTORGB_REGS > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > } >@@ -1939,96 +2247,113 @@ void OMITFP I422ToRGBARow_SSSE3(const uint8* y_buf, > #endif // HAS_I422TOARGBROW_SSSE3 > > // Read 16 UV from 444 >-#define READYUV444_AVX2 \ >- "vmovdqu " MEMACCESS([u_buf]) ",%%xmm0 \n" \ >- MEMOPREG(vmovdqu, 0x00, [u_buf], [v_buf], 1, xmm1) \ >- "lea " MEMLEA(0x10, [u_buf]) ",%[u_buf] \n" \ >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >- "vpermq $0xd8,%%ymm1,%%ymm1 \n" \ >- "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ >- "vmovdqu " MEMACCESS([y_buf]) ",%%xmm4 \n" \ >- "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ >- "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ >- "lea " MEMLEA(0x10, [y_buf]) ",%[y_buf] \n" >+#define READYUV444_AVX2 \ >+ "vmovdqu (%[u_buf]),%%xmm0 \n" \ >+ "vmovdqu 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ >+ "lea 0x10(%[u_buf]),%[u_buf] \n" \ >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >+ "vpermq $0xd8,%%ymm1,%%ymm1 \n" \ >+ "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ >+ "vmovdqu (%[y_buf]),%%xmm4 \n" \ >+ "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ >+ "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ >+ "lea 0x10(%[y_buf]),%[y_buf] \n" > > // Read 8 UV from 422, upsample to 16 UV. >-#define READYUV422_AVX2 \ >- "vmovq " MEMACCESS([u_buf]) ",%%xmm0 \n" \ >- MEMOPREG(vmovq, 0x00, [u_buf], [v_buf], 1, xmm1) \ >- "lea " MEMLEA(0x8, [u_buf]) ",%[u_buf] \n" \ >- "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >- "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ >- "vmovdqu " MEMACCESS([y_buf]) ",%%xmm4 \n" \ >- "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ >- "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ >- "lea " MEMLEA(0x10, [y_buf]) ",%[y_buf] \n" >+#define READYUV422_AVX2 \ >+ "vmovq (%[u_buf]),%%xmm0 \n" \ >+ "vmovq 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ >+ "lea 0x8(%[u_buf]),%[u_buf] \n" \ >+ "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >+ "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ >+ "vmovdqu (%[y_buf]),%%xmm4 \n" \ >+ "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ >+ "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ >+ "lea 0x10(%[y_buf]),%[y_buf] \n" >+ >+// Read 8 UV from 210 10 bit, upsample to 16 UV >+// TODO(fbarchard): Consider vshufb to replace pack/unpack >+// TODO(fbarchard): Consider vunpcklpd to combine the 2 registers into 1. >+#define READYUV210_AVX2 \ >+ "vmovdqu (%[u_buf]),%%xmm0 \n" \ >+ "vmovdqu 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ >+ "lea 0x10(%[u_buf]),%[u_buf] \n" \ >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >+ "vpermq $0xd8,%%ymm1,%%ymm1 \n" \ >+ "vpunpcklwd %%ymm1,%%ymm0,%%ymm0 \n" \ >+ "vpsraw $0x2,%%ymm0,%%ymm0 \n" \ >+ "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" \ >+ "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ >+ "vmovdqu (%[y_buf]),%%ymm4 \n" \ >+ "vpsllw $0x6,%%ymm4,%%ymm4 \n" \ >+ "lea 0x20(%[y_buf]),%[y_buf] \n" > > // Read 8 UV from 422, upsample to 16 UV. With 16 Alpha. >-#define READYUVA422_AVX2 \ >- "vmovq " MEMACCESS([u_buf]) ",%%xmm0 \n" \ >- MEMOPREG(vmovq, 0x00, [u_buf], [v_buf], 1, xmm1) \ >- "lea " MEMLEA(0x8, [u_buf]) ",%[u_buf] \n" \ >- "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >- "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ >- "vmovdqu " MEMACCESS([y_buf]) ",%%xmm4 \n" \ >- "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ >- "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ >- "lea " MEMLEA(0x10, [y_buf]) ",%[y_buf] \n" \ >- "vmovdqu " MEMACCESS([a_buf]) ",%%xmm5 \n" \ >- "vpermq $0xd8,%%ymm5,%%ymm5 \n" \ >- "lea " MEMLEA(0x10, [a_buf]) ",%[a_buf] \n" >+#define READYUVA422_AVX2 \ >+ "vmovq (%[u_buf]),%%xmm0 \n" \ >+ "vmovq 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ >+ "lea 0x8(%[u_buf]),%[u_buf] \n" \ >+ "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >+ "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ >+ "vmovdqu (%[y_buf]),%%xmm4 \n" \ >+ "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ >+ "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ >+ "lea 0x10(%[y_buf]),%[y_buf] \n" \ >+ "vmovdqu (%[a_buf]),%%xmm5 \n" \ >+ "vpermq $0xd8,%%ymm5,%%ymm5 \n" \ >+ "lea 0x10(%[a_buf]),%[a_buf] \n" > > // Read 8 UV from NV12, upsample to 16 UV. >-#define READNV12_AVX2 \ >- "vmovdqu " MEMACCESS([uv_buf]) ",%%xmm0 \n" \ >- "lea " MEMLEA(0x10, [uv_buf]) ",%[uv_buf] \n" \ >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >- "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ >- "vmovdqu " MEMACCESS([y_buf]) ",%%xmm4 \n" \ >- "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ >- "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ >- "lea " MEMLEA(0x10, [y_buf]) ",%[y_buf] \n" >+#define READNV12_AVX2 \ >+ "vmovdqu (%[uv_buf]),%%xmm0 \n" \ >+ "lea 0x10(%[uv_buf]),%[uv_buf] \n" \ >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >+ "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ >+ "vmovdqu (%[y_buf]),%%xmm4 \n" \ >+ "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ >+ "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ >+ "lea 0x10(%[y_buf]),%[y_buf] \n" > > // Read 8 VU from NV21, upsample to 16 UV. >-#define READNV21_AVX2 \ >- "vmovdqu " MEMACCESS([vu_buf]) ",%%xmm0 \n" \ >- "lea " MEMLEA(0x10, [vu_buf]) ",%[vu_buf] \n" \ >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >- "vpshufb %[kShuffleNV21], %%ymm0, %%ymm0 \n" \ >- "vmovdqu " MEMACCESS([y_buf]) ",%%xmm4 \n" \ >- "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ >- "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ >- "lea " MEMLEA(0x10, [y_buf]) ",%[y_buf] \n" >+#define READNV21_AVX2 \ >+ "vmovdqu (%[vu_buf]),%%xmm0 \n" \ >+ "lea 0x10(%[vu_buf]),%[vu_buf] \n" \ >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >+ "vpshufb %[kShuffleNV21], %%ymm0, %%ymm0 \n" \ >+ "vmovdqu (%[y_buf]),%%xmm4 \n" \ >+ "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ >+ "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ >+ "lea 0x10(%[y_buf]),%[y_buf] \n" > > // Read 8 YUY2 with 16 Y and upsample 8 UV to 16 UV. >-#define READYUY2_AVX2 \ >- "vmovdqu " MEMACCESS([yuy2_buf]) ",%%ymm4 \n" \ >- "vpshufb %[kShuffleYUY2Y], %%ymm4, %%ymm4 \n" \ >- "vmovdqu " MEMACCESS([yuy2_buf]) ",%%ymm0 \n" \ >- "vpshufb %[kShuffleYUY2UV], %%ymm0, %%ymm0 \n" \ >- "lea " MEMLEA(0x20, [yuy2_buf]) ",%[yuy2_buf] \n" >+#define READYUY2_AVX2 \ >+ "vmovdqu (%[yuy2_buf]),%%ymm4 \n" \ >+ "vpshufb %[kShuffleYUY2Y], %%ymm4, %%ymm4 \n" \ >+ "vmovdqu (%[yuy2_buf]),%%ymm0 \n" \ >+ "vpshufb %[kShuffleYUY2UV], %%ymm0, %%ymm0 \n" \ >+ "lea 0x20(%[yuy2_buf]),%[yuy2_buf] \n" > > // Read 8 UYVY with 16 Y and upsample 8 UV to 16 UV. >-#define READUYVY_AVX2 \ >- "vmovdqu " MEMACCESS([uyvy_buf]) ",%%ymm4 \n" \ >- "vpshufb %[kShuffleUYVYY], %%ymm4, %%ymm4 \n" \ >- "vmovdqu " MEMACCESS([uyvy_buf]) ",%%ymm0 \n" \ >- "vpshufb %[kShuffleUYVYUV], %%ymm0, %%ymm0 \n" \ >- "lea " MEMLEA(0x20, [uyvy_buf]) ",%[uyvy_buf] \n" >+#define READUYVY_AVX2 \ >+ "vmovdqu (%[uyvy_buf]),%%ymm4 \n" \ >+ "vpshufb %[kShuffleUYVYY], %%ymm4, %%ymm4 \n" \ >+ "vmovdqu (%[uyvy_buf]),%%ymm0 \n" \ >+ "vpshufb %[kShuffleUYVYUV], %%ymm0, %%ymm0 \n" \ >+ "lea 0x20(%[uyvy_buf]),%[uyvy_buf] \n" > > #if defined(__x86_64__) >-#define YUVTORGB_SETUP_AVX2(yuvconstants) \ >- "vmovdqa " MEMACCESS([yuvconstants]) ",%%ymm8 \n" \ >- "vmovdqa " MEMACCESS2(32, [yuvconstants]) ",%%ymm9 \n" \ >- "vmovdqa " MEMACCESS2(64, [yuvconstants]) ",%%ymm10 \n" \ >- "vmovdqa " MEMACCESS2(96, [yuvconstants]) ",%%ymm11 \n" \ >- "vmovdqa " MEMACCESS2(128, [yuvconstants]) ",%%ymm12 \n" \ >- "vmovdqa " MEMACCESS2(160, [yuvconstants]) ",%%ymm13 \n" \ >- "vmovdqa " MEMACCESS2(192, [yuvconstants]) ",%%ymm14 \n" >- >-#define YUVTORGB_AVX2(yuvconstants) \ >+#define YUVTORGB_SETUP_AVX2(yuvconstants) \ >+ "vmovdqa (%[yuvconstants]),%%ymm8 \n" \ >+ "vmovdqa 32(%[yuvconstants]),%%ymm9 \n" \ >+ "vmovdqa 64(%[yuvconstants]),%%ymm10 \n" \ >+ "vmovdqa 96(%[yuvconstants]),%%ymm11 \n" \ >+ "vmovdqa 128(%[yuvconstants]),%%ymm12 \n" \ >+ "vmovdqa 160(%[yuvconstants]),%%ymm13 \n" \ >+ "vmovdqa 192(%[yuvconstants]),%%ymm14 \n" >+ >+#define YUVTORGB16_AVX2(yuvconstants) \ > "vpmaddubsw %%ymm10,%%ymm0,%%ymm2 \n" \ > "vpmaddubsw %%ymm9,%%ymm0,%%ymm1 \n" \ > "vpmaddubsw %%ymm8,%%ymm0,%%ymm0 \n" \ >@@ -2038,13 +2363,7 @@ void OMITFP I422ToRGBARow_SSSE3(const uint8* y_buf, > "vpmulhuw %%ymm14,%%ymm4,%%ymm4 \n" \ > "vpaddsw %%ymm4,%%ymm0,%%ymm0 \n" \ > "vpaddsw %%ymm4,%%ymm1,%%ymm1 \n" \ >- "vpaddsw %%ymm4,%%ymm2,%%ymm2 \n" \ >- "vpsraw $0x6,%%ymm0,%%ymm0 \n" \ >- "vpsraw $0x6,%%ymm1,%%ymm1 \n" \ >- "vpsraw $0x6,%%ymm2,%%ymm2 \n" \ >- "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" \ >- "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" \ >- "vpackuswb %%ymm2,%%ymm2,%%ymm2 \n" >+ "vpaddsw %%ymm4,%%ymm2,%%ymm2 \n" > > #define YUVTORGB_REGS_AVX2 \ > "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", >@@ -2052,48 +2371,78 @@ void OMITFP I422ToRGBARow_SSSE3(const uint8* y_buf, > #else // Convert 16 pixels: 16 UV and 16 Y. > > #define YUVTORGB_SETUP_AVX2(yuvconstants) >-#define YUVTORGB_AVX2(yuvconstants) \ >- "vpmaddubsw " MEMACCESS2(64, [yuvconstants]) ",%%ymm0,%%ymm2 \n" \ >- "vpmaddubsw " MEMACCESS2(32, [yuvconstants]) ",%%ymm0,%%ymm1 \n" \ >- "vpmaddubsw " MEMACCESS([yuvconstants]) ",%%ymm0,%%ymm0 \n" \ >- "vmovdqu " MEMACCESS2(160, [yuvconstants]) ",%%ymm3 \n" \ >- "vpsubw %%ymm2,%%ymm3,%%ymm2 \n" \ >- "vmovdqu " MEMACCESS2(128, [yuvconstants]) ",%%ymm3 \n" \ >- "vpsubw %%ymm1,%%ymm3,%%ymm1 \n" \ >- "vmovdqu " MEMACCESS2(96, [yuvconstants]) ",%%ymm3 \n" \ >- "vpsubw %%ymm0,%%ymm3,%%ymm0 \n" \ >- "vpmulhuw " MEMACCESS2(192, [yuvconstants]) ",%%ymm4,%%ymm4 \n" \ >- "vpaddsw %%ymm4,%%ymm0,%%ymm0 \n" \ >- "vpaddsw %%ymm4,%%ymm1,%%ymm1 \n" \ >- "vpaddsw %%ymm4,%%ymm2,%%ymm2 \n" \ >- "vpsraw $0x6,%%ymm0,%%ymm0 \n" \ >- "vpsraw $0x6,%%ymm1,%%ymm1 \n" \ >- "vpsraw $0x6,%%ymm2,%%ymm2 \n" \ >- "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" \ >- "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" \ >- "vpackuswb %%ymm2,%%ymm2,%%ymm2 \n" >+#define YUVTORGB16_AVX2(yuvconstants) \ >+ "vpmaddubsw 64(%[yuvconstants]),%%ymm0,%%ymm2 \n" \ >+ "vpmaddubsw 32(%[yuvconstants]),%%ymm0,%%ymm1 \n" \ >+ "vpmaddubsw (%[yuvconstants]),%%ymm0,%%ymm0 \n" \ >+ "vmovdqu 160(%[yuvconstants]),%%ymm3 \n" \ >+ "vpsubw %%ymm2,%%ymm3,%%ymm2 \n" \ >+ "vmovdqu 128(%[yuvconstants]),%%ymm3 \n" \ >+ "vpsubw %%ymm1,%%ymm3,%%ymm1 \n" \ >+ "vmovdqu 96(%[yuvconstants]),%%ymm3 \n" \ >+ "vpsubw %%ymm0,%%ymm3,%%ymm0 \n" \ >+ "vpmulhuw 192(%[yuvconstants]),%%ymm4,%%ymm4 \n" \ >+ "vpaddsw %%ymm4,%%ymm0,%%ymm0 \n" \ >+ "vpaddsw %%ymm4,%%ymm1,%%ymm1 \n" \ >+ "vpaddsw %%ymm4,%%ymm2,%%ymm2 \n" > #define YUVTORGB_REGS_AVX2 > #endif > >+#define YUVTORGB_AVX2(yuvconstants) \ >+ YUVTORGB16_AVX2(yuvconstants) \ >+ "vpsraw $0x6,%%ymm0,%%ymm0 \n" \ >+ "vpsraw $0x6,%%ymm1,%%ymm1 \n" \ >+ "vpsraw $0x6,%%ymm2,%%ymm2 \n" \ >+ "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" \ >+ "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" \ >+ "vpackuswb %%ymm2,%%ymm2,%%ymm2 \n" >+ > // Store 16 ARGB values. >-#define STOREARGB_AVX2 \ >- "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >- "vpunpcklbw %%ymm5,%%ymm2,%%ymm2 \n" \ >- "vpermq $0xd8,%%ymm2,%%ymm2 \n" \ >- "vpunpcklwd %%ymm2,%%ymm0,%%ymm1 \n" \ >- "vpunpckhwd %%ymm2,%%ymm0,%%ymm0 \n" \ >- "vmovdqu %%ymm1," MEMACCESS([dst_argb]) " \n" \ >- "vmovdqu %%ymm0," MEMACCESS2(0x20, [dst_argb]) " \n" \ >- "lea " MEMLEA(0x40, [dst_argb]) ", %[dst_argb] \n" >+#define STOREARGB_AVX2 \ >+ "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >+ "vpunpcklbw %%ymm5,%%ymm2,%%ymm2 \n" \ >+ "vpermq $0xd8,%%ymm2,%%ymm2 \n" \ >+ "vpunpcklwd %%ymm2,%%ymm0,%%ymm1 \n" \ >+ "vpunpckhwd %%ymm2,%%ymm0,%%ymm0 \n" \ >+ "vmovdqu %%ymm1,(%[dst_argb]) \n" \ >+ "vmovdqu %%ymm0,0x20(%[dst_argb]) \n" \ >+ "lea 0x40(%[dst_argb]), %[dst_argb] \n" >+ >+// Store 16 AR30 values. >+#define STOREAR30_AVX2 \ >+ "vpsraw $0x4,%%ymm0,%%ymm0 \n" \ >+ "vpsraw $0x4,%%ymm1,%%ymm1 \n" \ >+ "vpsraw $0x4,%%ymm2,%%ymm2 \n" \ >+ "vpminsw %%ymm7,%%ymm0,%%ymm0 \n" \ >+ "vpminsw %%ymm7,%%ymm1,%%ymm1 \n" \ >+ "vpminsw %%ymm7,%%ymm2,%%ymm2 \n" \ >+ "vpmaxsw %%ymm6,%%ymm0,%%ymm0 \n" \ >+ "vpmaxsw %%ymm6,%%ymm1,%%ymm1 \n" \ >+ "vpmaxsw %%ymm6,%%ymm2,%%ymm2 \n" \ >+ "vpsllw $0x4,%%ymm2,%%ymm2 \n" \ >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ >+ "vpermq $0xd8,%%ymm1,%%ymm1 \n" \ >+ "vpermq $0xd8,%%ymm2,%%ymm2 \n" \ >+ "vpunpckhwd %%ymm2,%%ymm0,%%ymm3 \n" \ >+ "vpunpcklwd %%ymm2,%%ymm0,%%ymm0 \n" \ >+ "vpunpckhwd %%ymm5,%%ymm1,%%ymm2 \n" \ >+ "vpunpcklwd %%ymm5,%%ymm1,%%ymm1 \n" \ >+ "vpslld $0xa,%%ymm1,%%ymm1 \n" \ >+ "vpslld $0xa,%%ymm2,%%ymm2 \n" \ >+ "vpor %%ymm1,%%ymm0,%%ymm0 \n" \ >+ "vpor %%ymm2,%%ymm3,%%ymm3 \n" \ >+ "vmovdqu %%ymm0,(%[dst_ar30]) \n" \ >+ "vmovdqu %%ymm3,0x20(%[dst_ar30]) \n" \ >+ "lea 0x40(%[dst_ar30]), %[dst_ar30] \n" > > #ifdef HAS_I444TOARGBROW_AVX2 > // 16 pixels > // 16 UV values with 16 Y producing 16 ARGB (64 bytes). >-void OMITFP I444ToARGBRow_AVX2(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+void OMITFP I444ToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -2115,7 +2464,7 @@ void OMITFP I444ToARGBRow_AVX2(const uint8* y_buf, > [dst_argb]"+r"(dst_argb), // %[dst_argb] > [width]"+rm"(width) // %[width] > : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >- : "memory", "cc", NACL_R14 YUVTORGB_REGS_AVX2 >+ : "memory", "cc", YUVTORGB_REGS_AVX2 > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > } >@@ -2124,10 +2473,10 @@ void OMITFP I444ToARGBRow_AVX2(const uint8* y_buf, > #if defined(HAS_I422TOARGBROW_AVX2) > // 16 pixels > // 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). >-void OMITFP I422ToARGBRow_AVX2(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+void OMITFP I422ToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -2150,84 +2499,74 @@ void OMITFP I422ToARGBRow_AVX2(const uint8* y_buf, > [dst_argb]"+r"(dst_argb), // %[dst_argb] > [width]"+rm"(width) // %[width] > : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >- : "memory", "cc", NACL_R14 YUVTORGB_REGS_AVX2 >+ : "memory", "cc", YUVTORGB_REGS_AVX2 > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > } > #endif // HAS_I422TOARGBROW_AVX2 > >-#if defined(HAS_I422ALPHATOARGBROW_AVX2) >+#if defined(HAS_I422TOAR30ROW_AVX2) > // 16 pixels >-// 8 UV values upsampled to 16 UV, mixed with 16 Y and 16 A producing 16 ARGB. >-void OMITFP I422AlphaToARGBRow_AVX2(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >- const struct YuvConstants* yuvconstants, >- int width) { >- // clang-format off >+// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 AR30 (64 bytes). >+void OMITFP I422ToAR30Row_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_ar30, >+ const struct YuvConstants* yuvconstants, >+ int width) { > asm volatile ( > YUVTORGB_SETUP_AVX2(yuvconstants) > "sub %[u_buf],%[v_buf] \n" >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" // AR30 constants >+ "vpsrlw $14,%%ymm5,%%ymm5 \n" >+ "vpsllw $4,%%ymm5,%%ymm5 \n" // 2 alpha bits >+ "vpxor %%ymm6,%%ymm6,%%ymm6 \n" // 0 for min >+ "vpcmpeqb %%ymm7,%%ymm7,%%ymm7 \n" // 1023 for max >+ "vpsrlw $6,%%ymm7,%%ymm7 \n" > > LABELALIGN > "1: \n" >- READYUVA422_AVX2 >- YUVTORGB_AVX2(yuvconstants) >- STOREARGB_AVX2 >- "subl $0x10,%[width] \n" >+ READYUV422_AVX2 >+ YUVTORGB16_AVX2(yuvconstants) >+ STOREAR30_AVX2 >+ "sub $0x10,%[width] \n" > "jg 1b \n" >+ > "vzeroupper \n" > : [y_buf]"+r"(y_buf), // %[y_buf] > [u_buf]"+r"(u_buf), // %[u_buf] > [v_buf]"+r"(v_buf), // %[v_buf] >- [a_buf]"+r"(a_buf), // %[a_buf] >- [dst_argb]"+r"(dst_argb), // %[dst_argb] >-#if defined(__i386__) >- [width]"+m"(width) // %[width] >-#else >+ [dst_ar30]"+r"(dst_ar30), // %[dst_ar30] > [width]"+rm"(width) // %[width] >-#endif > : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >- : "memory", "cc", NACL_R14 YUVTORGB_REGS_AVX2 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >+ : "memory", "cc", YUVTORGB_REGS_AVX2 >+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" > ); >- // clang-format on > } >-#endif // HAS_I422ALPHATOARGBROW_AVX2 >+#endif // HAS_I422TOAR30ROW_AVX2 > >-#if defined(HAS_I422TORGBAROW_AVX2) >+#if defined(HAS_I210TOARGBROW_AVX2) > // 16 pixels >-// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 RGBA (64 bytes). >-void OMITFP I422ToRGBARow_AVX2(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). >+void OMITFP I210ToARGBRow_AVX2(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( > YUVTORGB_SETUP_AVX2(yuvconstants) > "sub %[u_buf],%[v_buf] \n" >- "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" > > LABELALIGN > "1: \n" >- READYUV422_AVX2 >+ READYUV210_AVX2 > YUVTORGB_AVX2(yuvconstants) >- >- // Step 3: Weave into RGBA >- "vpunpcklbw %%ymm2,%%ymm1,%%ymm1 \n" >- "vpermq $0xd8,%%ymm1,%%ymm1 \n" >- "vpunpcklbw %%ymm0,%%ymm5,%%ymm2 \n" >- "vpermq $0xd8,%%ymm2,%%ymm2 \n" >- "vpunpcklwd %%ymm1,%%ymm2,%%ymm0 \n" >- "vpunpckhwd %%ymm1,%%ymm2,%%ymm1 \n" >- "vmovdqu %%ymm0," MEMACCESS([dst_argb]) "\n" >- "vmovdqu %%ymm1," MEMACCESS2(0x20,[dst_argb]) "\n" >- "lea " MEMLEA(0x40,[dst_argb]) ",%[dst_argb] \n" >+ STOREARGB_AVX2 > "sub $0x10,%[width] \n" > "jg 1b \n" >+ > "vzeroupper \n" > : [y_buf]"+r"(y_buf), // %[y_buf] > [u_buf]"+r"(u_buf), // %[u_buf] >@@ -2235,18 +2574,143 @@ void OMITFP I422ToRGBARow_AVX2(const uint8* y_buf, > [dst_argb]"+r"(dst_argb), // %[dst_argb] > [width]"+rm"(width) // %[width] > : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >- : "memory", "cc", NACL_R14 YUVTORGB_REGS_AVX2 >+ : "memory", "cc", YUVTORGB_REGS_AVX2 > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > } >-#endif // HAS_I422TORGBAROW_AVX2 >+#endif // HAS_I210TOARGBROW_AVX2 > >-#if defined(HAS_NV12TOARGBROW_AVX2) >-// 16 pixels. >+#if defined(HAS_I210TOAR30ROW_AVX2) >+// 16 pixels >+// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 AR30 (64 bytes). >+void OMITFP I210ToAR30Row_AVX2(const uint16_t* y_buf, >+ const uint16_t* u_buf, >+ const uint16_t* v_buf, >+ uint8_t* dst_ar30, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ asm volatile ( >+ YUVTORGB_SETUP_AVX2(yuvconstants) >+ "sub %[u_buf],%[v_buf] \n" >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" // AR30 constants >+ "vpsrlw $14,%%ymm5,%%ymm5 \n" >+ "vpsllw $4,%%ymm5,%%ymm5 \n" // 2 alpha bits >+ "vpxor %%ymm6,%%ymm6,%%ymm6 \n" // 0 for min >+ "vpcmpeqb %%ymm7,%%ymm7,%%ymm7 \n" // 1023 for max >+ "vpsrlw $6,%%ymm7,%%ymm7 \n" >+ >+ LABELALIGN >+ "1: \n" >+ READYUV210_AVX2 >+ YUVTORGB16_AVX2(yuvconstants) >+ STOREAR30_AVX2 >+ "sub $0x10,%[width] \n" >+ "jg 1b \n" >+ >+ "vzeroupper \n" >+ : [y_buf]"+r"(y_buf), // %[y_buf] >+ [u_buf]"+r"(u_buf), // %[u_buf] >+ [v_buf]"+r"(v_buf), // %[v_buf] >+ [dst_ar30]"+r"(dst_ar30), // %[dst_ar30] >+ [width]"+rm"(width) // %[width] >+ : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >+ : "memory", "cc", YUVTORGB_REGS_AVX2 >+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >+ ); >+} >+#endif // HAS_I210TOAR30ROW_AVX2 >+ >+#if defined(HAS_I422ALPHATOARGBROW_AVX2) >+// 16 pixels >+// 8 UV values upsampled to 16 UV, mixed with 16 Y and 16 A producing 16 ARGB. >+void OMITFP I422AlphaToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_argb, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ // clang-format off >+ asm volatile ( >+ YUVTORGB_SETUP_AVX2(yuvconstants) >+ "sub %[u_buf],%[v_buf] \n" >+ >+ LABELALIGN >+ "1: \n" >+ READYUVA422_AVX2 >+ YUVTORGB_AVX2(yuvconstants) >+ STOREARGB_AVX2 >+ "subl $0x10,%[width] \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : [y_buf]"+r"(y_buf), // %[y_buf] >+ [u_buf]"+r"(u_buf), // %[u_buf] >+ [v_buf]"+r"(v_buf), // %[v_buf] >+ [a_buf]"+r"(a_buf), // %[a_buf] >+ [dst_argb]"+r"(dst_argb), // %[dst_argb] >+#if defined(__i386__) >+ [width]"+m"(width) // %[width] >+#else >+ [width]"+rm"(width) // %[width] >+#endif >+ : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >+ : "memory", "cc", YUVTORGB_REGS_AVX2 >+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >+ ); >+ // clang-format on >+} >+#endif // HAS_I422ALPHATOARGBROW_AVX2 >+ >+#if defined(HAS_I422TORGBAROW_AVX2) >+// 16 pixels >+// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 RGBA (64 bytes). >+void OMITFP I422ToRGBARow_AVX2(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ asm volatile ( >+ YUVTORGB_SETUP_AVX2(yuvconstants) >+ "sub %[u_buf],%[v_buf] \n" >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ READYUV422_AVX2 >+ YUVTORGB_AVX2(yuvconstants) >+ >+ // Step 3: Weave into RGBA >+ "vpunpcklbw %%ymm2,%%ymm1,%%ymm1 \n" >+ "vpermq $0xd8,%%ymm1,%%ymm1 \n" >+ "vpunpcklbw %%ymm0,%%ymm5,%%ymm2 \n" >+ "vpermq $0xd8,%%ymm2,%%ymm2 \n" >+ "vpunpcklwd %%ymm1,%%ymm2,%%ymm0 \n" >+ "vpunpckhwd %%ymm1,%%ymm2,%%ymm1 \n" >+ "vmovdqu %%ymm0,(%[dst_argb]) \n" >+ "vmovdqu %%ymm1,0x20(%[dst_argb]) \n" >+ "lea 0x40(%[dst_argb]),%[dst_argb] \n" >+ "sub $0x10,%[width] \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : [y_buf]"+r"(y_buf), // %[y_buf] >+ [u_buf]"+r"(u_buf), // %[u_buf] >+ [v_buf]"+r"(v_buf), // %[v_buf] >+ [dst_argb]"+r"(dst_argb), // %[dst_argb] >+ [width]"+rm"(width) // %[width] >+ : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >+ : "memory", "cc", YUVTORGB_REGS_AVX2 >+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >+ ); >+} >+#endif // HAS_I422TORGBAROW_AVX2 >+ >+#if defined(HAS_NV12TOARGBROW_AVX2) >+// 16 pixels. > // 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). >-void OMITFP NV12ToARGBRow_AVX2(const uint8* y_buf, >- const uint8* uv_buf, >- uint8* dst_argb, >+void OMITFP NV12ToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > // clang-format off >@@ -2267,7 +2731,7 @@ void OMITFP NV12ToARGBRow_AVX2(const uint8* y_buf, > [dst_argb]"+r"(dst_argb), // %[dst_argb] > [width]"+rm"(width) // %[width] > : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] >- : "memory", "cc", YUVTORGB_REGS_AVX2 // Does not use r14. >+ : "memory", "cc", YUVTORGB_REGS_AVX2 > "xmm0", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > // clang-format on >@@ -2277,9 +2741,9 @@ void OMITFP NV12ToARGBRow_AVX2(const uint8* y_buf, > #if defined(HAS_NV21TOARGBROW_AVX2) > // 16 pixels. > // 8 VU values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). >-void OMITFP NV21ToARGBRow_AVX2(const uint8* y_buf, >- const uint8* vu_buf, >- uint8* dst_argb, >+void OMITFP NV21ToARGBRow_AVX2(const uint8_t* y_buf, >+ const uint8_t* vu_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > // clang-format off >@@ -2301,7 +2765,7 @@ void OMITFP NV21ToARGBRow_AVX2(const uint8* y_buf, > [width]"+rm"(width) // %[width] > : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] > [kShuffleNV21]"m"(kShuffleNV21) >- : "memory", "cc", YUVTORGB_REGS_AVX2 // Does not use r14. >+ : "memory", "cc", YUVTORGB_REGS_AVX2 > "xmm0", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > // clang-format on >@@ -2311,8 +2775,8 @@ void OMITFP NV21ToARGBRow_AVX2(const uint8* y_buf, > #if defined(HAS_YUY2TOARGBROW_AVX2) > // 16 pixels. > // 8 YUY2 values with 16 Y and 8 UV producing 16 ARGB (64 bytes). >-void OMITFP YUY2ToARGBRow_AVX2(const uint8* yuy2_buf, >- uint8* dst_argb, >+void OMITFP YUY2ToARGBRow_AVX2(const uint8_t* yuy2_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > // clang-format off >@@ -2334,7 +2798,7 @@ void OMITFP YUY2ToARGBRow_AVX2(const uint8* yuy2_buf, > : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] > [kShuffleYUY2Y]"m"(kShuffleYUY2Y), > [kShuffleYUY2UV]"m"(kShuffleYUY2UV) >- : "memory", "cc", YUVTORGB_REGS_AVX2 // Does not use r14. >+ : "memory", "cc", YUVTORGB_REGS_AVX2 > "xmm0", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > // clang-format on >@@ -2344,8 +2808,8 @@ void OMITFP YUY2ToARGBRow_AVX2(const uint8* yuy2_buf, > #if defined(HAS_UYVYTOARGBROW_AVX2) > // 16 pixels. > // 8 UYVY values with 16 Y and 8 UV producing 16 ARGB (64 bytes). >-void OMITFP UYVYToARGBRow_AVX2(const uint8* uyvy_buf, >- uint8* dst_argb, >+void OMITFP UYVYToARGBRow_AVX2(const uint8_t* uyvy_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > // clang-format off >@@ -2367,7 +2831,7 @@ void OMITFP UYVYToARGBRow_AVX2(const uint8* uyvy_buf, > : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] > [kShuffleUYVYY]"m"(kShuffleUYVYY), > [kShuffleUYVYUV]"m"(kShuffleUYVYUV) >- : "memory", "cc", YUVTORGB_REGS_AVX2 // Does not use r14. >+ : "memory", "cc", YUVTORGB_REGS_AVX2 > "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" > ); > // clang-format on >@@ -2375,381 +2839,367 @@ void OMITFP UYVYToARGBRow_AVX2(const uint8* uyvy_buf, > #endif // HAS_UYVYTOARGBROW_AVX2 > > #ifdef HAS_I400TOARGBROW_SSE2 >-void I400ToARGBRow_SSE2(const uint8* y_buf, uint8* dst_argb, int width) { >- asm volatile ( >- "mov $0x4a354a35,%%eax \n" // 4a35 = 18997 = 1.164 >- "movd %%eax,%%xmm2 \n" >- "pshufd $0x0,%%xmm2,%%xmm2 \n" >- "mov $0x04880488,%%eax \n" // 0488 = 1160 = 1.164 * 16 >- "movd %%eax,%%xmm3 \n" >- "pshufd $0x0,%%xmm3,%%xmm3 \n" >- "pcmpeqb %%xmm4,%%xmm4 \n" >- "pslld $0x18,%%xmm4 \n" >+void I400ToARGBRow_SSE2(const uint8_t* y_buf, uint8_t* dst_argb, int width) { >+ asm volatile( >+ "mov $0x4a354a35,%%eax \n" // 4a35 = 18997 = 1.164 >+ "movd %%eax,%%xmm2 \n" >+ "pshufd $0x0,%%xmm2,%%xmm2 \n" >+ "mov $0x04880488,%%eax \n" // 0488 = 1160 = 1.164 * >+ // 16 >+ "movd %%eax,%%xmm3 \n" >+ "pshufd $0x0,%%xmm3,%%xmm3 \n" >+ "pcmpeqb %%xmm4,%%xmm4 \n" >+ "pslld $0x18,%%xmm4 \n" > >- LABELALIGN >- "1: \n" >- // Step 1: Scale Y contribution to 8 G values. G = (y - 16) * 1.164 >- "movq " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x8,0) ",%0 \n" >- "punpcklbw %%xmm0,%%xmm0 \n" >- "pmulhuw %%xmm2,%%xmm0 \n" >- "psubusw %%xmm3,%%xmm0 \n" >- "psrlw $6, %%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- >- // Step 2: Weave into ARGB >- "punpcklbw %%xmm0,%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklwd %%xmm0,%%xmm0 \n" >- "punpckhwd %%xmm1,%%xmm1 \n" >- "por %%xmm4,%%xmm0 \n" >- "por %%xmm4,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(y_buf), // %0 >- "+r"(dst_argb), // %1 >- "+rm"(width) // %2 >- : >- : "memory", "cc", "eax" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4" >- ); >+ LABELALIGN >+ "1: \n" >+ // Step 1: Scale Y contribution to 8 G values. G = (y - 16) * 1.164 >+ "movq (%0),%%xmm0 \n" >+ "lea 0x8(%0),%0 \n" >+ "punpcklbw %%xmm0,%%xmm0 \n" >+ "pmulhuw %%xmm2,%%xmm0 \n" >+ "psubusw %%xmm3,%%xmm0 \n" >+ "psrlw $6, %%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ >+ // Step 2: Weave into ARGB >+ "punpcklbw %%xmm0,%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpcklwd %%xmm0,%%xmm0 \n" >+ "punpckhwd %%xmm1,%%xmm1 \n" >+ "por %%xmm4,%%xmm0 \n" >+ "por %%xmm4,%%xmm1 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(y_buf), // %0 >+ "+r"(dst_argb), // %1 >+ "+rm"(width) // %2 >+ : >+ : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); > } > #endif // HAS_I400TOARGBROW_SSE2 > > #ifdef HAS_I400TOARGBROW_AVX2 > // 16 pixels of Y converted to 16 pixels of ARGB (64 bytes). > // note: vpunpcklbw mutates and vpackuswb unmutates. >-void I400ToARGBRow_AVX2(const uint8* y_buf, uint8* dst_argb, int width) { >- asm volatile ( >- "mov $0x4a354a35,%%eax \n" // 0488 = 1160 = 1.164 * 16 >- "vmovd %%eax,%%xmm2 \n" >- "vbroadcastss %%xmm2,%%ymm2 \n" >- "mov $0x4880488,%%eax \n" // 4a35 = 18997 = 1.164 >- "vmovd %%eax,%%xmm3 \n" >- "vbroadcastss %%xmm3,%%ymm3 \n" >- "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" >- "vpslld $0x18,%%ymm4,%%ymm4 \n" >+void I400ToARGBRow_AVX2(const uint8_t* y_buf, uint8_t* dst_argb, int width) { >+ asm volatile( >+ "mov $0x4a354a35,%%eax \n" // 0488 = 1160 = 1.164 * >+ // 16 >+ "vmovd %%eax,%%xmm2 \n" >+ "vbroadcastss %%xmm2,%%ymm2 \n" >+ "mov $0x4880488,%%eax \n" // 4a35 = 18997 = 1.164 >+ "vmovd %%eax,%%xmm3 \n" >+ "vbroadcastss %%xmm3,%%ymm3 \n" >+ "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" >+ "vpslld $0x18,%%ymm4,%%ymm4 \n" > >- LABELALIGN >- "1: \n" >- // Step 1: Scale Y contribution to 16 G values. G = (y - 16) * 1.164 >- "vmovdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" >- "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpsubusw %%ymm3,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x6,%%ymm0,%%ymm0 \n" >- "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >- "vpunpcklbw %%ymm0,%%ymm0,%%ymm1 \n" >- "vpermq $0xd8,%%ymm1,%%ymm1 \n" >- "vpunpcklwd %%ymm1,%%ymm1,%%ymm0 \n" >- "vpunpckhwd %%ymm1,%%ymm1,%%ymm1 \n" >- "vpor %%ymm4,%%ymm0,%%ymm0 \n" >- "vpor %%ymm4,%%ymm1,%%ymm1 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "vmovdqu %%ymm1," MEMACCESS2(0x20,1) " \n" >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(y_buf), // %0 >- "+r"(dst_argb), // %1 >- "+rm"(width) // %2 >- : >- : "memory", "cc", "eax" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4" >- ); >+ LABELALIGN >+ "1: \n" >+ // Step 1: Scale Y contribution to 16 G values. G = (y - 16) * 1.164 >+ "vmovdqu (%0),%%xmm0 \n" >+ "lea 0x10(%0),%0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpsubusw %%ymm3,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x6,%%ymm0,%%ymm0 \n" >+ "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpunpcklbw %%ymm0,%%ymm0,%%ymm1 \n" >+ "vpermq $0xd8,%%ymm1,%%ymm1 \n" >+ "vpunpcklwd %%ymm1,%%ymm1,%%ymm0 \n" >+ "vpunpckhwd %%ymm1,%%ymm1,%%ymm1 \n" >+ "vpor %%ymm4,%%ymm0,%%ymm0 \n" >+ "vpor %%ymm4,%%ymm1,%%ymm1 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "vmovdqu %%ymm1,0x20(%1) \n" >+ "lea 0x40(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(y_buf), // %0 >+ "+r"(dst_argb), // %1 >+ "+rm"(width) // %2 >+ : >+ : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); > } > #endif // HAS_I400TOARGBROW_AVX2 > > #ifdef HAS_MIRRORROW_SSSE3 > // Shuffle table for reversing the bytes. >-static uvec8 kShuffleMirror = {15u, 14u, 13u, 12u, 11u, 10u, 9u, 8u, >- 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u}; >+static const uvec8 kShuffleMirror = {15u, 14u, 13u, 12u, 11u, 10u, 9u, 8u, >+ 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u}; > >-void MirrorRow_SSSE3(const uint8* src, uint8* dst, int width) { >+void MirrorRow_SSSE3(const uint8_t* src, uint8_t* dst, int width) { > intptr_t temp_width = (intptr_t)(width); >- asm volatile ( >- "movdqa %3,%%xmm5 \n" >+ asm volatile( > >- LABELALIGN >- "1: \n" >- MEMOPREG(movdqu,-0x10,0,2,1,xmm0) // movdqu -0x10(%0,%2),%%xmm0 >- "pshufb %%xmm5,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(temp_width) // %2 >- : "m"(kShuffleMirror) // %3 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm5" >- ); >+ "movdqa %3,%%xmm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu -0x10(%0,%2,1),%%xmm0 \n" >+ "pshufb %%xmm5,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(temp_width) // %2 >+ : "m"(kShuffleMirror) // %3 >+ : "memory", "cc", "xmm0", "xmm5"); > } > #endif // HAS_MIRRORROW_SSSE3 > > #ifdef HAS_MIRRORROW_AVX2 >-void MirrorRow_AVX2(const uint8* src, uint8* dst, int width) { >+void MirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { > intptr_t temp_width = (intptr_t)(width); >- asm volatile ( >- "vbroadcastf128 %3,%%ymm5 \n" >+ asm volatile( > >- LABELALIGN >- "1: \n" >- MEMOPREG(vmovdqu,-0x20,0,2,1,ymm0) // vmovdqu -0x20(%0,%2),%%ymm0 >- "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" >- "vpermq $0x4e,%%ymm0,%%ymm0 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(temp_width) // %2 >- : "m"(kShuffleMirror) // %3 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm5" >- ); >+ "vbroadcastf128 %3,%%ymm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu -0x20(%0,%2,1),%%ymm0 \n" >+ "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpermq $0x4e,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(temp_width) // %2 >+ : "m"(kShuffleMirror) // %3 >+ : "memory", "cc", "xmm0", "xmm5"); > } > #endif // HAS_MIRRORROW_AVX2 > > #ifdef HAS_MIRRORUVROW_SSSE3 > // Shuffle table for reversing the bytes of UV channels. >-static uvec8 kShuffleMirrorUV = {14u, 12u, 10u, 8u, 6u, 4u, 2u, 0u, >- 15u, 13u, 11u, 9u, 7u, 5u, 3u, 1u}; >-void MirrorUVRow_SSSE3(const uint8* src, >- uint8* dst_u, >- uint8* dst_v, >+static const uvec8 kShuffleMirrorUV = {14u, 12u, 10u, 8u, 6u, 4u, 2u, 0u, >+ 15u, 13u, 11u, 9u, 7u, 5u, 3u, 1u}; >+void MirrorUVRow_SSSE3(const uint8_t* src, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > intptr_t temp_width = (intptr_t)(width); >- asm volatile ( >- "movdqa %4,%%xmm1 \n" >- "lea " MEMLEA4(-0x10,0,3,2) ",%0 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "movdqa %4,%%xmm1 \n" >+ "lea -0x10(%0,%3,2),%0 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(-0x10,0) ",%0 \n" >- "pshufb %%xmm1,%%xmm0 \n" >- "movlpd %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movhpd,xmm0,0x00,1,2,1) // movhpd %%xmm0,(%1,%2) >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $8,%3 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(temp_width) // %3 >- : "m"(kShuffleMirrorUV) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "lea -0x10(%0),%0 \n" >+ "pshufb %%xmm1,%%xmm0 \n" >+ "movlpd %%xmm0,(%1) \n" >+ "movhpd %%xmm0,0x00(%1,%2,1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $8,%3 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(temp_width) // %3 >+ : "m"(kShuffleMirrorUV) // %4 >+ : "memory", "cc", "xmm0", "xmm1"); > } > #endif // HAS_MIRRORUVROW_SSSE3 > > #ifdef HAS_ARGBMIRRORROW_SSE2 > >-void ARGBMirrorRow_SSE2(const uint8* src, uint8* dst, int width) { >+void ARGBMirrorRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { > intptr_t temp_width = (intptr_t)(width); >- asm volatile ( >- "lea " MEMLEA4(-0x10,0,2,4) ",%0 \n" >+ asm volatile( > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "pshufd $0x1b,%%xmm0,%%xmm0 \n" >- "lea " MEMLEA(-0x10,0) ",%0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(temp_width) // %2 >- : >- : "memory", "cc" >- , "xmm0" >- ); >+ "lea -0x10(%0,%2,4),%0 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "pshufd $0x1b,%%xmm0,%%xmm0 \n" >+ "lea -0x10(%0),%0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(temp_width) // %2 >+ : >+ : "memory", "cc", "xmm0"); > } > #endif // HAS_ARGBMIRRORROW_SSE2 > > #ifdef HAS_ARGBMIRRORROW_AVX2 > // Shuffle table for reversing the bytes. > static const ulvec32 kARGBShuffleMirror_AVX2 = {7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u}; >-void ARGBMirrorRow_AVX2(const uint8* src, uint8* dst, int width) { >+void ARGBMirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { > intptr_t temp_width = (intptr_t)(width); >- asm volatile ( >- "vmovdqu %3,%%ymm5 \n" >+ asm volatile( > >- LABELALIGN >- "1: \n" >- VMEMOPREG(vpermd,-0x20,0,2,4,ymm5,ymm0) // vpermd -0x20(%0,%2,4),ymm5,ymm0 >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(temp_width) // %2 >- : "m"(kARGBShuffleMirror_AVX2) // %3 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm5" >- ); >+ "vmovdqu %3,%%ymm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vpermd -0x20(%0,%2,4),%%ymm5,%%ymm0 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(temp_width) // %2 >+ : "m"(kARGBShuffleMirror_AVX2) // %3 >+ : "memory", "cc", "xmm0", "xmm5"); > } > #endif // HAS_ARGBMIRRORROW_AVX2 > > #ifdef HAS_SPLITUVROW_AVX2 >-void SplitUVRow_AVX2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void SplitUVRow_AVX2(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >- "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >+ "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm2 \n" >- "vpsrlw $0x8,%%ymm1,%%ymm3 \n" >- "vpand %%ymm5,%%ymm0,%%ymm0 \n" >- "vpand %%ymm5,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpackuswb %%ymm3,%%ymm2,%%ymm2 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm2,%%ymm2 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- MEMOPMEM(vmovdqu,ymm2,0x00,1,2,1) // vmovdqu %%ymm2,(%1,%2) >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_uv), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm2 \n" >+ "vpsrlw $0x8,%%ymm1,%%ymm3 \n" >+ "vpand %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpand %%ymm5,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpackuswb %%ymm3,%%ymm2,%%ymm2 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm2,%%ymm2 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "vmovdqu %%ymm2,0x00(%1,%2,1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_uv), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > #endif // HAS_SPLITUVROW_AVX2 > > #ifdef HAS_SPLITUVROW_SSE2 >-void SplitUVRow_SSE2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void SplitUVRow_SSE2(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "psrlw $0x8,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "psrlw $0x8,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "movdqa %%xmm1,%%xmm3 \n" >- "pand %%xmm5,%%xmm0 \n" >- "pand %%xmm5,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "psrlw $0x8,%%xmm2 \n" >- "psrlw $0x8,%%xmm3 \n" >- "packuswb %%xmm3,%%xmm2 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movdqu,xmm2,0x00,1,2,1) // movdqu %%xmm2,(%1,%2) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_uv), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "movdqa %%xmm1,%%xmm3 \n" >+ "pand %%xmm5,%%xmm0 \n" >+ "pand %%xmm5,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "psrlw $0x8,%%xmm2 \n" >+ "psrlw $0x8,%%xmm3 \n" >+ "packuswb %%xmm3,%%xmm2 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "movdqu %%xmm2,0x00(%1,%2,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_uv), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > #endif // HAS_SPLITUVROW_SSE2 > > #ifdef HAS_MERGEUVROW_AVX2 >-void MergeUVRow_AVX2(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_AVX2(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width) { >- asm volatile ( >- "sub %0,%1 \n" >+ asm volatile( > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- MEMOPREG(vmovdqu,0x00,0,1,1,ymm1) // vmovdqu (%0,%1,1),%%ymm1 >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "vpunpcklbw %%ymm1,%%ymm0,%%ymm2 \n" >- "vpunpckhbw %%ymm1,%%ymm0,%%ymm0 \n" >- "vextractf128 $0x0,%%ymm2," MEMACCESS(2) " \n" >- "vextractf128 $0x0,%%ymm0," MEMACCESS2(0x10,2) "\n" >- "vextractf128 $0x1,%%ymm2," MEMACCESS2(0x20,2) "\n" >- "vextractf128 $0x1,%%ymm0," MEMACCESS2(0x30,2) "\n" >- "lea " MEMLEA(0x40,2) ",%2 \n" >- "sub $0x20,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_u), // %0 >- "+r"(src_v), // %1 >- "+r"(dst_uv), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2" >- ); >+ "sub %0,%1 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x00(%0,%1,1),%%ymm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "vpunpcklbw %%ymm1,%%ymm0,%%ymm2 \n" >+ "vpunpckhbw %%ymm1,%%ymm0,%%ymm0 \n" >+ "vextractf128 $0x0,%%ymm2,(%2) \n" >+ "vextractf128 $0x0,%%ymm0,0x10(%2) \n" >+ "vextractf128 $0x1,%%ymm2,0x20(%2) \n" >+ "vextractf128 $0x1,%%ymm0,0x30(%2) \n" >+ "lea 0x40(%2),%2 \n" >+ "sub $0x20,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_u), // %0 >+ "+r"(src_v), // %1 >+ "+r"(dst_uv), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); > } > #endif // HAS_MERGEUVROW_AVX2 > > #ifdef HAS_MERGEUVROW_SSE2 >-void MergeUVRow_SSE2(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_SSE2(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width) { >- asm volatile ( >- "sub %0,%1 \n" >+ asm volatile( > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,1,1,xmm1) // movdqu (%0,%1,1),%%xmm1 >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "punpcklbw %%xmm1,%%xmm0 \n" >- "punpckhbw %%xmm1,%%xmm2 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "movdqu %%xmm2," MEMACCESS2(0x10,2) " \n" >- "lea " MEMLEA(0x20,2) ",%2 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_u), // %0 >- "+r"(src_v), // %1 >- "+r"(dst_uv), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2" >- ); >+ "sub %0,%1 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%1,1),%%xmm1 \n" >+ "lea 0x10(%0),%0 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "punpcklbw %%xmm1,%%xmm0 \n" >+ "punpckhbw %%xmm1,%%xmm2 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "movdqu %%xmm2,0x10(%2) \n" >+ "lea 0x20(%2),%2 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_u), // %0 >+ "+r"(src_v), // %1 >+ "+r"(dst_uv), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); > } > #endif // HAS_MERGEUVROW_SSE2 > >@@ -2759,9 +3209,9 @@ void MergeUVRow_SSE2(const uint8* src_u, > // 16 = 12 bits > // 1 = 16 bits > #ifdef HAS_MERGEUVROW_16_AVX2 >-void MergeUVRow_16_AVX2(const uint16* src_u, >- const uint16* src_v, >- uint16* dst_uv, >+void MergeUVRow_16_AVX2(const uint16_t* src_u, >+ const uint16_t* src_v, >+ uint16_t* dst_uv, > int scale, > int width) { > // clang-format off >@@ -2800,9 +3250,14 @@ void MergeUVRow_16_AVX2(const uint16* src_u, > } > #endif // HAS_MERGEUVROW_AVX2 > >+// Use scale to convert lsb formats to msb, depending how many bits there are: >+// 128 = 9 bits >+// 64 = 10 bits >+// 16 = 12 bits >+// 1 = 16 bits > #ifdef HAS_MULTIPLYROW_16_AVX2 >-void MultiplyRow_16_AVX2(const uint16* src_y, >- uint16* dst_y, >+void MultiplyRow_16_AVX2(const uint16_t* src_y, >+ uint16_t* dst_y, > int scale, > int width) { > // clang-format off >@@ -2834,367 +3289,507 @@ void MultiplyRow_16_AVX2(const uint16* src_y, > } > #endif // HAS_MULTIPLYROW_16_AVX2 > >-#ifdef HAS_SPLITRGBROW_SSSE3 >- >-// Shuffle table for converting RGB to Planar. >-static uvec8 kShuffleMaskRGBToR0 = {0u, 3u, 6u, 9u, 12u, 15u, >- 128u, 128u, 128u, 128u, 128u, 128u, >- 128u, 128u, 128u, 128u}; >-static uvec8 kShuffleMaskRGBToR1 = {128u, 128u, 128u, 128u, 128u, 128u, >- 2u, 5u, 8u, 11u, 14u, 128u, >- 128u, 128u, 128u, 128u}; >-static uvec8 kShuffleMaskRGBToR2 = {128u, 128u, 128u, 128u, 128u, 128u, >- 128u, 128u, 128u, 128u, 128u, 1u, >- 4u, 7u, 10u, 13u}; >- >-static uvec8 kShuffleMaskRGBToG0 = {1u, 4u, 7u, 10u, 13u, 128u, >- 128u, 128u, 128u, 128u, 128u, 128u, >- 128u, 128u, 128u, 128u}; >-static uvec8 kShuffleMaskRGBToG1 = {128u, 128u, 128u, 128u, 128u, 0u, >- 3u, 6u, 9u, 12u, 15u, 128u, >- 128u, 128u, 128u, 128u}; >-static uvec8 kShuffleMaskRGBToG2 = {128u, 128u, 128u, 128u, 128u, 128u, >- 128u, 128u, 128u, 128u, 128u, 2u, >- 5u, 8u, 11u, 14u}; >- >-static uvec8 kShuffleMaskRGBToB0 = {2u, 5u, 8u, 11u, 14u, 128u, >- 128u, 128u, 128u, 128u, 128u, 128u, >- 128u, 128u, 128u, 128u}; >-static uvec8 kShuffleMaskRGBToB1 = {128u, 128u, 128u, 128u, 128u, 1u, >- 4u, 7u, 10u, 13u, 128u, 128u, >- 128u, 128u, 128u, 128u}; >-static uvec8 kShuffleMaskRGBToB2 = {128u, 128u, 128u, 128u, 128u, 128u, >- 128u, 128u, 128u, 128u, 0u, 3u, >- 6u, 9u, 12u, 15u}; >- >-void SplitRGBRow_SSSE3(const uint8* src_rgb, >- uint8* dst_r, >- uint8* dst_g, >- uint8* dst_b, >- int width) { >+// Use scale to convert lsb formats to msb, depending how many bits there are: >+// 32768 = 9 bits >+// 16384 = 10 bits >+// 4096 = 12 bits >+// 256 = 16 bits >+void Convert16To8Row_SSSE3(const uint16_t* src_y, >+ uint8_t* dst_y, >+ int scale, >+ int width) { >+ // clang-format off > asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "pshufb %5, %%xmm0 \n" >- "pshufb %6, %%xmm1 \n" >- "pshufb %7, %%xmm2 \n" >- "por %%xmm1,%%xmm0 \n" >- "por %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "pshufb %8, %%xmm0 \n" >- "pshufb %9, %%xmm1 \n" >- "pshufb %10, %%xmm2 \n" >- "por %%xmm1,%%xmm0 \n" >- "por %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "pshufb %11, %%xmm0 \n" >- "pshufb %12, %%xmm1 \n" >- "pshufb %13, %%xmm2 \n" >- "por %%xmm1,%%xmm0 \n" >- "por %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(3) " \n" >- "lea " MEMLEA(0x10,3) ",%3 \n" >- "lea " MEMLEA(0x30,0) ",%0 \n" >- "sub $0x10,%4 \n" >- "jg 1b \n" >- : "+r"(src_rgb), // %0 >- "+r"(dst_r), // %1 >- "+r"(dst_g), // %2 >- "+r"(dst_b), // %3 >- "+r"(width) // %4 >- : "m"(kShuffleMaskRGBToR0), // %5 >- "m"(kShuffleMaskRGBToR1), // %6 >- "m"(kShuffleMaskRGBToR2), // %7 >- "m"(kShuffleMaskRGBToG0), // %8 >- "m"(kShuffleMaskRGBToG1), // %9 >- "m"(kShuffleMaskRGBToG2), // %10 >- "m"(kShuffleMaskRGBToB0), // %11 >- "m"(kShuffleMaskRGBToB1), // %12 >- "m"(kShuffleMaskRGBToB2) // %13 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2" >- ); >-} >-#endif // HAS_SPLITRGBROW_SSSE3 >- >-#ifdef HAS_MERGERGBROW_SSSE3 >+ "movd %3,%%xmm2 \n" >+ "punpcklwd %%xmm2,%%xmm2 \n" >+ "pshufd $0x0,%%xmm2,%%xmm2 \n" >+ >+ // 32 pixels per loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "add $0x20,%0 \n" >+ "pmulhuw %%xmm2,%%xmm0 \n" >+ "pmulhuw %%xmm2,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "add $0x10,%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_y), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "r"(scale) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); >+ // clang-format on >+} > >-// Shuffle table for converting RGB to Planar. >-static uvec8 kShuffleMaskRToRGB0 = {0u, 128u, 128u, 1u, 128u, 128u, >- 2u, 128u, 128u, 3u, 128u, 128u, >- 4u, 128u, 128u, 5u}; >-static uvec8 kShuffleMaskGToRGB0 = {128u, 0u, 128u, 128u, 1u, 128u, >- 128u, 2u, 128u, 128u, 3u, 128u, >- 128u, 4u, 128u, 128u}; >-static uvec8 kShuffleMaskBToRGB0 = {128u, 128u, 0u, 128u, 128u, 1u, >- 128u, 128u, 2u, 128u, 128u, 3u, >- 128u, 128u, 4u, 128u}; >- >-static uvec8 kShuffleMaskGToRGB1 = {5u, 128u, 128u, 6u, 128u, 128u, >- 7u, 128u, 128u, 8u, 128u, 128u, >- 9u, 128u, 128u, 10u}; >-static uvec8 kShuffleMaskBToRGB1 = {128u, 5u, 128u, 128u, 6u, 128u, >- 128u, 7u, 128u, 128u, 8u, 128u, >- 128u, 9u, 128u, 128u}; >-static uvec8 kShuffleMaskRToRGB1 = {128u, 128u, 6u, 128u, 128u, 7u, >- 128u, 128u, 8u, 128u, 128u, 9u, >- 128u, 128u, 10u, 128u}; >- >-static uvec8 kShuffleMaskBToRGB2 = {10u, 128u, 128u, 11u, 128u, 128u, >- 12u, 128u, 128u, 13u, 128u, 128u, >- 14u, 128u, 128u, 15u}; >-static uvec8 kShuffleMaskRToRGB2 = {128u, 11u, 128u, 128u, 12u, 128u, >- 128u, 13u, 128u, 128u, 14u, 128u, >- 128u, 15u, 128u, 128u}; >-static uvec8 kShuffleMaskGToRGB2 = {128u, 128u, 11u, 128u, 128u, 12u, >- 128u, 128u, 13u, 128u, 128u, 14u, >- 128u, 128u, 15u, 128u}; >- >-void MergeRGBRow_SSSE3(const uint8* src_r, >- const uint8* src_g, >- const uint8* src_b, >- uint8* dst_rgb, >- int width) { >+#ifdef HAS_CONVERT16TO8ROW_AVX2 >+void Convert16To8Row_AVX2(const uint16_t* src_y, >+ uint8_t* dst_y, >+ int scale, >+ int width) { >+ // clang-format off > asm volatile ( >+ "vmovd %3,%%xmm2 \n" >+ "vpunpcklwd %%xmm2,%%xmm2,%%xmm2 \n" >+ "vbroadcastss %%xmm2,%%ymm2 \n" >+ >+ // 32 pixels per loop. > LABELALIGN > "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS(1) ",%%xmm1 \n" >- "movdqu " MEMACCESS(2) ",%%xmm2 \n" >- "pshufb %5, %%xmm0 \n" >- "pshufb %6, %%xmm1 \n" >- "pshufb %7, %%xmm2 \n" >- "por %%xmm1,%%xmm0 \n" >- "por %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(3) " \n" >- >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS(1) ",%%xmm1 \n" >- "movdqu " MEMACCESS(2) ",%%xmm2 \n" >- "pshufb %8, %%xmm0 \n" >- "pshufb %9, %%xmm1 \n" >- "pshufb %10, %%xmm2 \n" >- "por %%xmm1,%%xmm0 \n" >- "por %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS2(16, 3) " \n" >- >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS(1) ",%%xmm1 \n" >- "movdqu " MEMACCESS(2) ",%%xmm2 \n" >- "pshufb %11, %%xmm0 \n" >- "pshufb %12, %%xmm1 \n" >- "pshufb %13, %%xmm2 \n" >- "por %%xmm1,%%xmm0 \n" >- "por %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS2(32, 3) " \n" >- >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "lea " MEMLEA(0x30,3) ",%3 \n" >- "sub $0x10,%4 \n" >- "jg 1b \n" >- : "+r"(src_r), // %0 >- "+r"(src_g), // %1 >- "+r"(src_b), // %2 >- "+r"(dst_rgb), // %3 >- "+r"(width) // %4 >- : "m"(kShuffleMaskRToRGB0), // %5 >- "m"(kShuffleMaskGToRGB0), // %6 >- "m"(kShuffleMaskBToRGB0), // %7 >- "m"(kShuffleMaskRToRGB1), // %8 >- "m"(kShuffleMaskGToRGB1), // %9 >- "m"(kShuffleMaskBToRGB1), // %10 >- "m"(kShuffleMaskRToRGB2), // %11 >- "m"(kShuffleMaskGToRGB2), // %12 >- "m"(kShuffleMaskBToRGB2) // %13 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2" >- ); >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "add $0x40,%0 \n" >+ "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpmulhuw %%ymm2,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" // mutates >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "add $0x20,%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_y), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "r"(scale) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); >+ // clang-format on >+} >+#endif // HAS_CONVERT16TO8ROW_AVX2 >+ >+// Use scale to convert to lsb formats depending how many bits there are: >+// 512 = 9 bits >+// 1024 = 10 bits >+// 4096 = 12 bits >+// TODO(fbarchard): reduce to SSE2 >+void Convert8To16Row_SSE2(const uint8_t* src_y, >+ uint16_t* dst_y, >+ int scale, >+ int width) { >+ // clang-format off >+ asm volatile ( >+ "movd %3,%%xmm2 \n" >+ "punpcklwd %%xmm2,%%xmm2 \n" >+ "pshufd $0x0,%%xmm2,%%xmm2 \n" >+ >+ // 32 pixels per loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpcklbw %%xmm0,%%xmm0 \n" >+ "punpckhbw %%xmm1,%%xmm1 \n" >+ "add $0x10,%0 \n" >+ "pmulhuw %%xmm2,%%xmm0 \n" >+ "pmulhuw %%xmm2,%%xmm1 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "add $0x20,%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_y), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "r"(scale) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); >+ // clang-format on > } >-#endif // HAS_MERGERGBROW_SSSE3 > >-#ifdef HAS_COPYROW_SSE2 >-void CopyRow_SSE2(const uint8* src, uint8* dst, int count) { >+#ifdef HAS_CONVERT8TO16ROW_AVX2 >+void Convert8To16Row_AVX2(const uint8_t* src_y, >+ uint16_t* dst_y, >+ int scale, >+ int width) { >+ // clang-format off > asm volatile ( >- "test $0xf,%0 \n" >- "jne 2f \n" >- "test $0xf,%1 \n" >- "jne 2f \n" >+ "vmovd %3,%%xmm2 \n" >+ "vpunpcklwd %%xmm2,%%xmm2,%%xmm2 \n" >+ "vbroadcastss %%xmm2,%%ymm2 \n" > >+ // 32 pixels per loop. > LABELALIGN > "1: \n" >- "movdqa " MEMACCESS(0) ",%%xmm0 \n" >- "movdqa " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "movdqa %%xmm0," MEMACCESS(1) " \n" >- "movdqa %%xmm1," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "add $0x20,%0 \n" >+ "vpunpckhbw %%ymm0,%%ymm0,%%ymm1 \n" >+ "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpmulhuw %%ymm2,%%ymm1,%%ymm1 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "vmovdqu %%ymm1,0x20(%1) \n" >+ "add $0x40,%1 \n" > "sub $0x20,%2 \n" > "jg 1b \n" >- "jmp 9f \n" >+ "vzeroupper \n" >+ : "+r"(src_y), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : "r"(scale) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); >+ // clang-format on >+} >+#endif // HAS_CONVERT8TO16ROW_AVX2 > >- LABELALIGN >- "2: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 2b \n" >- "9: \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(count) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1" >- ); >+#ifdef HAS_SPLITRGBROW_SSSE3 >+ >+// Shuffle table for converting RGB to Planar. >+static const uvec8 kShuffleMaskRGBToR0 = {0u, 3u, 6u, 9u, 12u, 15u, >+ 128u, 128u, 128u, 128u, 128u, 128u, >+ 128u, 128u, 128u, 128u}; >+static const uvec8 kShuffleMaskRGBToR1 = {128u, 128u, 128u, 128u, 128u, 128u, >+ 2u, 5u, 8u, 11u, 14u, 128u, >+ 128u, 128u, 128u, 128u}; >+static const uvec8 kShuffleMaskRGBToR2 = {128u, 128u, 128u, 128u, 128u, 128u, >+ 128u, 128u, 128u, 128u, 128u, 1u, >+ 4u, 7u, 10u, 13u}; >+ >+static const uvec8 kShuffleMaskRGBToG0 = {1u, 4u, 7u, 10u, 13u, 128u, >+ 128u, 128u, 128u, 128u, 128u, 128u, >+ 128u, 128u, 128u, 128u}; >+static const uvec8 kShuffleMaskRGBToG1 = {128u, 128u, 128u, 128u, 128u, 0u, >+ 3u, 6u, 9u, 12u, 15u, 128u, >+ 128u, 128u, 128u, 128u}; >+static const uvec8 kShuffleMaskRGBToG2 = {128u, 128u, 128u, 128u, 128u, 128u, >+ 128u, 128u, 128u, 128u, 128u, 2u, >+ 5u, 8u, 11u, 14u}; >+ >+static const uvec8 kShuffleMaskRGBToB0 = {2u, 5u, 8u, 11u, 14u, 128u, >+ 128u, 128u, 128u, 128u, 128u, 128u, >+ 128u, 128u, 128u, 128u}; >+static const uvec8 kShuffleMaskRGBToB1 = {128u, 128u, 128u, 128u, 128u, 1u, >+ 4u, 7u, 10u, 13u, 128u, 128u, >+ 128u, 128u, 128u, 128u}; >+static const uvec8 kShuffleMaskRGBToB2 = {128u, 128u, 128u, 128u, 128u, 128u, >+ 128u, 128u, 128u, 128u, 0u, 3u, >+ 6u, 9u, 12u, 15u}; >+ >+void SplitRGBRow_SSSE3(const uint8_t* src_rgb, >+ uint8_t* dst_r, >+ uint8_t* dst_g, >+ uint8_t* dst_b, >+ int width) { >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "pshufb %5, %%xmm0 \n" >+ "pshufb %6, %%xmm1 \n" >+ "pshufb %7, %%xmm2 \n" >+ "por %%xmm1,%%xmm0 \n" >+ "por %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "pshufb %8, %%xmm0 \n" >+ "pshufb %9, %%xmm1 \n" >+ "pshufb %10, %%xmm2 \n" >+ "por %%xmm1,%%xmm0 \n" >+ "por %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "pshufb %11, %%xmm0 \n" >+ "pshufb %12, %%xmm1 \n" >+ "pshufb %13, %%xmm2 \n" >+ "por %%xmm1,%%xmm0 \n" >+ "por %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%3) \n" >+ "lea 0x10(%3),%3 \n" >+ "lea 0x30(%0),%0 \n" >+ "sub $0x10,%4 \n" >+ "jg 1b \n" >+ : "+r"(src_rgb), // %0 >+ "+r"(dst_r), // %1 >+ "+r"(dst_g), // %2 >+ "+r"(dst_b), // %3 >+ "+r"(width) // %4 >+ : "m"(kShuffleMaskRGBToR0), // %5 >+ "m"(kShuffleMaskRGBToR1), // %6 >+ "m"(kShuffleMaskRGBToR2), // %7 >+ "m"(kShuffleMaskRGBToG0), // %8 >+ "m"(kShuffleMaskRGBToG1), // %9 >+ "m"(kShuffleMaskRGBToG2), // %10 >+ "m"(kShuffleMaskRGBToB0), // %11 >+ "m"(kShuffleMaskRGBToB1), // %12 >+ "m"(kShuffleMaskRGBToB2) // %13 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); >+} >+#endif // HAS_SPLITRGBROW_SSSE3 >+ >+#ifdef HAS_MERGERGBROW_SSSE3 >+ >+// Shuffle table for converting RGB to Planar. >+static const uvec8 kShuffleMaskRToRGB0 = {0u, 128u, 128u, 1u, 128u, 128u, >+ 2u, 128u, 128u, 3u, 128u, 128u, >+ 4u, 128u, 128u, 5u}; >+static const uvec8 kShuffleMaskGToRGB0 = {128u, 0u, 128u, 128u, 1u, 128u, >+ 128u, 2u, 128u, 128u, 3u, 128u, >+ 128u, 4u, 128u, 128u}; >+static const uvec8 kShuffleMaskBToRGB0 = {128u, 128u, 0u, 128u, 128u, 1u, >+ 128u, 128u, 2u, 128u, 128u, 3u, >+ 128u, 128u, 4u, 128u}; >+ >+static const uvec8 kShuffleMaskGToRGB1 = {5u, 128u, 128u, 6u, 128u, 128u, >+ 7u, 128u, 128u, 8u, 128u, 128u, >+ 9u, 128u, 128u, 10u}; >+static const uvec8 kShuffleMaskBToRGB1 = {128u, 5u, 128u, 128u, 6u, 128u, >+ 128u, 7u, 128u, 128u, 8u, 128u, >+ 128u, 9u, 128u, 128u}; >+static const uvec8 kShuffleMaskRToRGB1 = {128u, 128u, 6u, 128u, 128u, 7u, >+ 128u, 128u, 8u, 128u, 128u, 9u, >+ 128u, 128u, 10u, 128u}; >+ >+static const uvec8 kShuffleMaskBToRGB2 = {10u, 128u, 128u, 11u, 128u, 128u, >+ 12u, 128u, 128u, 13u, 128u, 128u, >+ 14u, 128u, 128u, 15u}; >+static const uvec8 kShuffleMaskRToRGB2 = {128u, 11u, 128u, 128u, 12u, 128u, >+ 128u, 13u, 128u, 128u, 14u, 128u, >+ 128u, 15u, 128u, 128u}; >+static const uvec8 kShuffleMaskGToRGB2 = {128u, 128u, 11u, 128u, 128u, 12u, >+ 128u, 128u, 13u, 128u, 128u, 14u, >+ 128u, 128u, 15u, 128u}; >+ >+void MergeRGBRow_SSSE3(const uint8_t* src_r, >+ const uint8_t* src_g, >+ const uint8_t* src_b, >+ uint8_t* dst_rgb, >+ int width) { >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu (%1),%%xmm1 \n" >+ "movdqu (%2),%%xmm2 \n" >+ "pshufb %5, %%xmm0 \n" >+ "pshufb %6, %%xmm1 \n" >+ "pshufb %7, %%xmm2 \n" >+ "por %%xmm1,%%xmm0 \n" >+ "por %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%3) \n" >+ >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu (%1),%%xmm1 \n" >+ "movdqu (%2),%%xmm2 \n" >+ "pshufb %8, %%xmm0 \n" >+ "pshufb %9, %%xmm1 \n" >+ "pshufb %10, %%xmm2 \n" >+ "por %%xmm1,%%xmm0 \n" >+ "por %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,16(%3) \n" >+ >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu (%1),%%xmm1 \n" >+ "movdqu (%2),%%xmm2 \n" >+ "pshufb %11, %%xmm0 \n" >+ "pshufb %12, %%xmm1 \n" >+ "pshufb %13, %%xmm2 \n" >+ "por %%xmm1,%%xmm0 \n" >+ "por %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,32(%3) \n" >+ >+ "lea 0x10(%0),%0 \n" >+ "lea 0x10(%1),%1 \n" >+ "lea 0x10(%2),%2 \n" >+ "lea 0x30(%3),%3 \n" >+ "sub $0x10,%4 \n" >+ "jg 1b \n" >+ : "+r"(src_r), // %0 >+ "+r"(src_g), // %1 >+ "+r"(src_b), // %2 >+ "+r"(dst_rgb), // %3 >+ "+r"(width) // %4 >+ : "m"(kShuffleMaskRToRGB0), // %5 >+ "m"(kShuffleMaskGToRGB0), // %6 >+ "m"(kShuffleMaskBToRGB0), // %7 >+ "m"(kShuffleMaskRToRGB1), // %8 >+ "m"(kShuffleMaskGToRGB1), // %9 >+ "m"(kShuffleMaskBToRGB1), // %10 >+ "m"(kShuffleMaskRToRGB2), // %11 >+ "m"(kShuffleMaskGToRGB2), // %12 >+ "m"(kShuffleMaskBToRGB2) // %13 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); >+} >+#endif // HAS_MERGERGBROW_SSSE3 >+ >+#ifdef HAS_COPYROW_SSE2 >+void CopyRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "test $0xf,%0 \n" >+ "jne 2f \n" >+ "test $0xf,%1 \n" >+ "jne 2f \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqa (%0),%%xmm0 \n" >+ "movdqa 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "movdqa %%xmm0,(%1) \n" >+ "movdqa %%xmm1,0x10(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "jmp 9f \n" >+ >+ LABELALIGN >+ "2: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 2b \n" >+ >+ LABELALIGN "9: \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1"); > } > #endif // HAS_COPYROW_SSE2 > > #ifdef HAS_COPYROW_AVX >-void CopyRow_AVX(const uint8* src, uint8* dst, int count) { >- asm volatile ( >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "vmovdqu %%ymm1," MEMACCESS2(0x20,1) " \n" >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "sub $0x40,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(count) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1" >- ); >+void CopyRow_AVX(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "vmovdqu %%ymm1,0x20(%1) \n" >+ "lea 0x40(%1),%1 \n" >+ "sub $0x40,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1"); > } > #endif // HAS_COPYROW_AVX > > #ifdef HAS_COPYROW_ERMS > // Multiple of 1. >-void CopyRow_ERMS(const uint8* src, uint8* dst, int width) { >+void CopyRow_ERMS(const uint8_t* src, uint8_t* dst, int width) { > size_t width_tmp = (size_t)(width); >- asm volatile("rep movsb " MEMMOVESTRING(0, 1) " \n" >- : "+S"(src), // %0 >- "+D"(dst), // %1 >- "+c"(width_tmp) // %2 >- : >- : "memory", "cc"); >+ asm volatile( >+ >+ "rep movsb \n" >+ : "+S"(src), // %0 >+ "+D"(dst), // %1 >+ "+c"(width_tmp) // %2 >+ : >+ : "memory", "cc"); > } > #endif // HAS_COPYROW_ERMS > > #ifdef HAS_ARGBCOPYALPHAROW_SSE2 > // width in pixels >-void ARGBCopyAlphaRow_SSE2(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "pcmpeqb %%xmm0,%%xmm0 \n" >- "pslld $0x18,%%xmm0 \n" >- "pcmpeqb %%xmm1,%%xmm1 \n" >- "psrld $0x8,%%xmm1 \n" >+void ARGBCopyAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "pcmpeqb %%xmm0,%%xmm0 \n" >+ "pslld $0x18,%%xmm0 \n" >+ "pcmpeqb %%xmm1,%%xmm1 \n" >+ "psrld $0x8,%%xmm1 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm3 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "movdqu " MEMACCESS(1) ",%%xmm4 \n" >- "movdqu " MEMACCESS2(0x10,1) ",%%xmm5 \n" >- "pand %%xmm0,%%xmm2 \n" >- "pand %%xmm0,%%xmm3 \n" >- "pand %%xmm1,%%xmm4 \n" >- "pand %%xmm1,%%xmm5 \n" >- "por %%xmm4,%%xmm2 \n" >- "por %%xmm5,%%xmm3 \n" >- "movdqu %%xmm2," MEMACCESS(1) " \n" >- "movdqu %%xmm3," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm2 \n" >+ "movdqu 0x10(%0),%%xmm3 \n" >+ "lea 0x20(%0),%0 \n" >+ "movdqu (%1),%%xmm4 \n" >+ "movdqu 0x10(%1),%%xmm5 \n" >+ "pand %%xmm0,%%xmm2 \n" >+ "pand %%xmm0,%%xmm3 \n" >+ "pand %%xmm1,%%xmm4 \n" >+ "pand %%xmm1,%%xmm5 \n" >+ "por %%xmm4,%%xmm2 \n" >+ "por %%xmm5,%%xmm3 \n" >+ "movdqu %%xmm2,(%1) \n" >+ "movdqu %%xmm3,0x10(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_ARGBCOPYALPHAROW_SSE2 > > #ifdef HAS_ARGBCOPYALPHAROW_AVX2 > // width in pixels >-void ARGBCopyAlphaRow_AVX2(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "vpcmpeqb %%ymm0,%%ymm0,%%ymm0 \n" >- "vpsrld $0x8,%%ymm0,%%ymm0 \n" >+void ARGBCopyAlphaRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "vpcmpeqb %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpsrld $0x8,%%ymm0,%%ymm0 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm1 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm2 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpblendvb %%ymm0," MEMACCESS(1) ",%%ymm1,%%ymm1 \n" >- "vpblendvb %%ymm0," MEMACCESS2(0x20,1) ",%%ymm2,%%ymm2 \n" >- "vmovdqu %%ymm1," MEMACCESS(1) " \n" >- "vmovdqu %%ymm2," MEMACCESS2(0x20,1) " \n" >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm1 \n" >+ "vmovdqu 0x20(%0),%%ymm2 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpblendvb %%ymm0,(%1),%%ymm1,%%ymm1 \n" >+ "vpblendvb %%ymm0,0x20(%1),%%ymm2,%%ymm2 \n" >+ "vmovdqu %%ymm1,(%1) \n" >+ "vmovdqu %%ymm2,0x20(%1) \n" >+ "lea 0x40(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); > } > #endif // HAS_ARGBCOPYALPHAROW_AVX2 > > #ifdef HAS_ARGBEXTRACTALPHAROW_SSE2 > // width in pixels >-void ARGBExtractAlphaRow_SSE2(const uint8* src_argb, uint8* dst_a, int width) { >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ", %%xmm0 \n" >- "movdqu " MEMACCESS2(0x10, 0) ", %%xmm1 \n" >- "lea " MEMLEA(0x20, 0) ", %0 \n" >- "psrld $0x18, %%xmm0 \n" >- "psrld $0x18, %%xmm1 \n" >- "packssdw %%xmm1, %%xmm0 \n" >- "packuswb %%xmm0, %%xmm0 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x8, 1) ", %1 \n" >- "sub $0x8, %2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_a), // %1 >- "+rm"(width) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1" >- ); >+void ARGBExtractAlphaRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_a, >+ int width) { >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0), %%xmm0 \n" >+ "movdqu 0x10(%0), %%xmm1 \n" >+ "lea 0x20(%0), %0 \n" >+ "psrld $0x18, %%xmm0 \n" >+ "psrld $0x18, %%xmm1 \n" >+ "packssdw %%xmm1, %%xmm0 \n" >+ "packuswb %%xmm0, %%xmm0 \n" >+ "movq %%xmm0,(%1) \n" >+ "lea 0x8(%1), %1 \n" >+ "sub $0x8, %2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_a), // %1 >+ "+rm"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1"); > } > #endif // HAS_ARGBEXTRACTALPHAROW_SSE2 > >@@ -3203,657 +3798,636 @@ static const uvec8 kShuffleAlphaShort_AVX2 = { > 3u, 128u, 128u, 128u, 7u, 128u, 128u, 128u, > 11u, 128u, 128u, 128u, 15u, 128u, 128u, 128u}; > >-void ARGBExtractAlphaRow_AVX2(const uint8* src_argb, uint8* dst_a, int width) { >- asm volatile ( >- "vmovdqa %3,%%ymm4 \n" >- "vbroadcastf128 %4,%%ymm5 \n" >+void ARGBExtractAlphaRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_a, >+ int width) { >+ asm volatile( >+ "vmovdqa %3,%%ymm4 \n" >+ "vbroadcastf128 %4,%%ymm5 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ", %%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20, 0) ", %%ymm1 \n" >- "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" // vpsrld $0x18, %%ymm0 >- "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" >- "vmovdqu " MEMACCESS2(0x40, 0) ", %%ymm2 \n" >- "vmovdqu " MEMACCESS2(0x60, 0) ", %%ymm3 \n" >- "lea " MEMLEA(0x80, 0) ", %0 \n" >- "vpackssdw %%ymm1, %%ymm0, %%ymm0 \n" // mutates >- "vpshufb %%ymm5,%%ymm2,%%ymm2 \n" >- "vpshufb %%ymm5,%%ymm3,%%ymm3 \n" >- "vpackssdw %%ymm3, %%ymm2, %%ymm2 \n" // mutates >- "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. >- "vpermd %%ymm0,%%ymm4,%%ymm0 \n" // unmutate. >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20, %2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_a), // %1 >- "+rm"(width) // %2 >- : "m"(kPermdARGBToY_AVX), // %3 >- "m"(kShuffleAlphaShort_AVX2) // %4 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0), %%ymm0 \n" >+ "vmovdqu 0x20(%0), %%ymm1 \n" >+ "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" // vpsrld $0x18, %%ymm0 >+ "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" >+ "vmovdqu 0x40(%0), %%ymm2 \n" >+ "vmovdqu 0x60(%0), %%ymm3 \n" >+ "lea 0x80(%0), %0 \n" >+ "vpackssdw %%ymm1, %%ymm0, %%ymm0 \n" // mutates >+ "vpshufb %%ymm5,%%ymm2,%%ymm2 \n" >+ "vpshufb %%ymm5,%%ymm3,%%ymm3 \n" >+ "vpackssdw %%ymm3, %%ymm2, %%ymm2 \n" // mutates >+ "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. >+ "vpermd %%ymm0,%%ymm4,%%ymm0 \n" // unmutate. >+ "vmovdqu %%ymm0,(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20, %2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_a), // %1 >+ "+rm"(width) // %2 >+ : "m"(kPermdARGBToY_AVX), // %3 >+ "m"(kShuffleAlphaShort_AVX2) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_ARGBEXTRACTALPHAROW_AVX2 > > #ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2 > // width in pixels >-void ARGBCopyYToAlphaRow_SSE2(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "pcmpeqb %%xmm0,%%xmm0 \n" >- "pslld $0x18,%%xmm0 \n" >- "pcmpeqb %%xmm1,%%xmm1 \n" >- "psrld $0x8,%%xmm1 \n" >+void ARGBCopyYToAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "pcmpeqb %%xmm0,%%xmm0 \n" >+ "pslld $0x18,%%xmm0 \n" >+ "pcmpeqb %%xmm1,%%xmm1 \n" >+ "psrld $0x8,%%xmm1 \n" > >- LABELALIGN >- "1: \n" >- "movq " MEMACCESS(0) ",%%xmm2 \n" >- "lea " MEMLEA(0x8,0) ",%0 \n" >- "punpcklbw %%xmm2,%%xmm2 \n" >- "punpckhwd %%xmm2,%%xmm3 \n" >- "punpcklwd %%xmm2,%%xmm2 \n" >- "movdqu " MEMACCESS(1) ",%%xmm4 \n" >- "movdqu " MEMACCESS2(0x10,1) ",%%xmm5 \n" >- "pand %%xmm0,%%xmm2 \n" >- "pand %%xmm0,%%xmm3 \n" >- "pand %%xmm1,%%xmm4 \n" >- "pand %%xmm1,%%xmm5 \n" >- "por %%xmm4,%%xmm2 \n" >- "por %%xmm5,%%xmm3 \n" >- "movdqu %%xmm2," MEMACCESS(1) " \n" >- "movdqu %%xmm3," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movq (%0),%%xmm2 \n" >+ "lea 0x8(%0),%0 \n" >+ "punpcklbw %%xmm2,%%xmm2 \n" >+ "punpckhwd %%xmm2,%%xmm3 \n" >+ "punpcklwd %%xmm2,%%xmm2 \n" >+ "movdqu (%1),%%xmm4 \n" >+ "movdqu 0x10(%1),%%xmm5 \n" >+ "pand %%xmm0,%%xmm2 \n" >+ "pand %%xmm0,%%xmm3 \n" >+ "pand %%xmm1,%%xmm4 \n" >+ "pand %%xmm1,%%xmm5 \n" >+ "por %%xmm4,%%xmm2 \n" >+ "por %%xmm5,%%xmm3 \n" >+ "movdqu %%xmm2,(%1) \n" >+ "movdqu %%xmm3,0x10(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_ARGBCOPYYTOALPHAROW_SSE2 > > #ifdef HAS_ARGBCOPYYTOALPHAROW_AVX2 > // width in pixels >-void ARGBCopyYToAlphaRow_AVX2(const uint8* src, uint8* dst, int width) { >- asm volatile ( >- "vpcmpeqb %%ymm0,%%ymm0,%%ymm0 \n" >- "vpsrld $0x8,%%ymm0,%%ymm0 \n" >+void ARGBCopyYToAlphaRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { >+ asm volatile( >+ "vpcmpeqb %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpsrld $0x8,%%ymm0,%%ymm0 \n" > >- LABELALIGN >- "1: \n" >- "vpmovzxbd " MEMACCESS(0) ",%%ymm1 \n" >- "vpmovzxbd " MEMACCESS2(0x8,0) ",%%ymm2 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "vpslld $0x18,%%ymm1,%%ymm1 \n" >- "vpslld $0x18,%%ymm2,%%ymm2 \n" >- "vpblendvb %%ymm0," MEMACCESS(1) ",%%ymm1,%%ymm1 \n" >- "vpblendvb %%ymm0," MEMACCESS2(0x20,1) ",%%ymm2,%%ymm2 \n" >- "vmovdqu %%ymm1," MEMACCESS(1) " \n" >- "vmovdqu %%ymm2," MEMACCESS2(0x20,1) " \n" >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2" >- ); >+ LABELALIGN >+ "1: \n" >+ "vpmovzxbd (%0),%%ymm1 \n" >+ "vpmovzxbd 0x8(%0),%%ymm2 \n" >+ "lea 0x10(%0),%0 \n" >+ "vpslld $0x18,%%ymm1,%%ymm1 \n" >+ "vpslld $0x18,%%ymm2,%%ymm2 \n" >+ "vpblendvb %%ymm0,(%1),%%ymm1,%%ymm1 \n" >+ "vpblendvb %%ymm0,0x20(%1),%%ymm2,%%ymm2 \n" >+ "vmovdqu %%ymm1,(%1) \n" >+ "vmovdqu %%ymm2,0x20(%1) \n" >+ "lea 0x40(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); > } > #endif // HAS_ARGBCOPYYTOALPHAROW_AVX2 > > #ifdef HAS_SETROW_X86 >-void SetRow_X86(uint8* dst, uint8 v8, int width) { >+void SetRow_X86(uint8_t* dst, uint8_t v8, int width) { > size_t width_tmp = (size_t)(width >> 2); >- const uint32 v32 = v8 * 0x01010101u; // Duplicate byte to all bytes. >- asm volatile("rep stosl " MEMSTORESTRING(eax, 0) " \n" >- : "+D"(dst), // %0 >- "+c"(width_tmp) // %1 >- : "a"(v32) // %2 >- : "memory", "cc"); >+ const uint32_t v32 = v8 * 0x01010101u; // Duplicate byte to all bytes. >+ asm volatile( >+ >+ "rep stosl \n" >+ : "+D"(dst), // %0 >+ "+c"(width_tmp) // %1 >+ : "a"(v32) // %2 >+ : "memory", "cc"); > } > >-void SetRow_ERMS(uint8* dst, uint8 v8, int width) { >+void SetRow_ERMS(uint8_t* dst, uint8_t v8, int width) { > size_t width_tmp = (size_t)(width); >- asm volatile("rep stosb " MEMSTORESTRING(al, 0) " \n" >- : "+D"(dst), // %0 >- "+c"(width_tmp) // %1 >- : "a"(v8) // %2 >- : "memory", "cc"); >+ asm volatile( >+ >+ "rep stosb \n" >+ : "+D"(dst), // %0 >+ "+c"(width_tmp) // %1 >+ : "a"(v8) // %2 >+ : "memory", "cc"); > } > >-void ARGBSetRow_X86(uint8* dst_argb, uint32 v32, int width) { >+void ARGBSetRow_X86(uint8_t* dst_argb, uint32_t v32, int width) { > size_t width_tmp = (size_t)(width); >- asm volatile("rep stosl " MEMSTORESTRING(eax, 0) " \n" >- : "+D"(dst_argb), // %0 >- "+c"(width_tmp) // %1 >- : "a"(v32) // %2 >- : "memory", "cc"); >+ asm volatile( >+ >+ "rep stosl \n" >+ : "+D"(dst_argb), // %0 >+ "+c"(width_tmp) // %1 >+ : "a"(v32) // %2 >+ : "memory", "cc"); > } > #endif // HAS_SETROW_X86 > > #ifdef HAS_YUY2TOYROW_SSE2 >-void YUY2ToYRow_SSE2(const uint8* src_yuy2, uint8* dst_y, int width) { >- asm volatile ( >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "psrlw $0x8,%%xmm5 \n" >+void YUY2ToYRow_SSE2(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { >+ asm volatile( >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "psrlw $0x8,%%xmm5 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pand %%xmm5,%%xmm0 \n" >- "pand %%xmm5,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_yuy2), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "pand %%xmm5,%%xmm0 \n" >+ "pand %%xmm5,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_yuy2), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } > >-void YUY2ToUVRow_SSE2(const uint8* src_yuy2, >+void YUY2ToUVRow_SSE2(const uint8_t* src_yuy2, > int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "psrlw $0x8,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "psrlw $0x8,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- MEMOPREG(movdqu,0x00,0,4,1,xmm2) // movdqu (%0,%4,1),%%xmm2 >- MEMOPREG(movdqu,0x10,0,4,1,xmm3) // movdqu 0x10(%0,%4,1),%%xmm3 >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pavgb %%xmm2,%%xmm0 \n" >- "pavgb %%xmm3,%%xmm1 \n" >- "psrlw $0x8,%%xmm0 \n" >- "psrlw $0x8,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "pand %%xmm5,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "psrlw $0x8,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm1 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movq,xmm1,0x00,1,2,1) // movq %%xmm1,(%1,%2) >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_yuy2), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(width) // %3 >- : "r"((intptr_t)(stride_yuy2)) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x00(%0,%4,1),%%xmm2 \n" >+ "movdqu 0x10(%0,%4,1),%%xmm3 \n" >+ "lea 0x20(%0),%0 \n" >+ "pavgb %%xmm2,%%xmm0 \n" >+ "pavgb %%xmm3,%%xmm1 \n" >+ "psrlw $0x8,%%xmm0 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "pand %%xmm5,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm1 \n" >+ "movq %%xmm0,(%1) \n" >+ "movq %%xmm1,0x00(%1,%2,1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_yuy2), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(width) // %3 >+ : "r"((intptr_t)(stride_yuy2)) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > >-void YUY2ToUV422Row_SSE2(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_SSE2(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "psrlw $0x8,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "psrlw $0x8,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "psrlw $0x8,%%xmm0 \n" >- "psrlw $0x8,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "pand %%xmm5,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "psrlw $0x8,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm1 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movq,xmm1,0x00,1,2,1) // movq %%xmm1,(%1,%2) >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_yuy2), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "psrlw $0x8,%%xmm0 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "pand %%xmm5,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm1 \n" >+ "movq %%xmm0,(%1) \n" >+ "movq %%xmm1,0x00(%1,%2,1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_yuy2), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } > >-void UYVYToYRow_SSE2(const uint8* src_uyvy, uint8* dst_y, int width) { >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "psrlw $0x8,%%xmm0 \n" >- "psrlw $0x8,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_uyvy), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1" >- ); >+void UYVYToYRow_SSE2(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "psrlw $0x8,%%xmm0 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_uyvy), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1"); > } > >-void UYVYToUVRow_SSE2(const uint8* src_uyvy, >+void UYVYToUVRow_SSE2(const uint8_t* src_uyvy, > int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "psrlw $0x8,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "psrlw $0x8,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- MEMOPREG(movdqu,0x00,0,4,1,xmm2) // movdqu (%0,%4,1),%%xmm2 >- MEMOPREG(movdqu,0x10,0,4,1,xmm3) // movdqu 0x10(%0,%4,1),%%xmm3 >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pavgb %%xmm2,%%xmm0 \n" >- "pavgb %%xmm3,%%xmm1 \n" >- "pand %%xmm5,%%xmm0 \n" >- "pand %%xmm5,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "pand %%xmm5,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "psrlw $0x8,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm1 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movq,xmm1,0x00,1,2,1) // movq %%xmm1,(%1,%2) >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_uyvy), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(width) // %3 >- : "r"((intptr_t)(stride_uyvy)) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x00(%0,%4,1),%%xmm2 \n" >+ "movdqu 0x10(%0,%4,1),%%xmm3 \n" >+ "lea 0x20(%0),%0 \n" >+ "pavgb %%xmm2,%%xmm0 \n" >+ "pavgb %%xmm3,%%xmm1 \n" >+ "pand %%xmm5,%%xmm0 \n" >+ "pand %%xmm5,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "pand %%xmm5,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm1 \n" >+ "movq %%xmm0,(%1) \n" >+ "movq %%xmm1,0x00(%1,%2,1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_uyvy), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(width) // %3 >+ : "r"((intptr_t)(stride_uyvy)) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > >-void UYVYToUV422Row_SSE2(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_SSE2(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "psrlw $0x8,%%xmm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "psrlw $0x8,%%xmm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pand %%xmm5,%%xmm0 \n" >- "pand %%xmm5,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "pand %%xmm5,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "psrlw $0x8,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm1 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- MEMOPMEM(movq,xmm1,0x00,1,2,1) // movq %%xmm1,(%1,%2) >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_uyvy), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "pand %%xmm5,%%xmm0 \n" >+ "pand %%xmm5,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "pand %%xmm5,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm1 \n" >+ "movq %%xmm0,(%1) \n" >+ "movq %%xmm1,0x00(%1,%2,1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_uyvy), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } > #endif // HAS_YUY2TOYROW_SSE2 > > #ifdef HAS_YUY2TOYROW_AVX2 >-void YUY2ToYRow_AVX2(const uint8* src_yuy2, uint8* dst_y, int width) { >- asm volatile ( >- "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >- "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >+void YUY2ToYRow_AVX2(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { >+ asm volatile( >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >+ "vpsrlw $0x8,%%ymm5,%%ymm5 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpand %%ymm5,%%ymm0,%%ymm0 \n" >- "vpand %%ymm5,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_yuy2), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpand %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpand %%ymm5,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_yuy2), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } > >-void YUY2ToUVRow_AVX2(const uint8* src_yuy2, >+void YUY2ToUVRow_AVX2(const uint8_t* src_yuy2, > int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >- "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >+ "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- VMEMOPREG(vpavgb,0x00,0,4,1,ymm0,ymm0) // vpavgb (%0,%4,1),%%ymm0,%%ymm0 >- VMEMOPREG(vpavgb,0x20,0,4,1,ymm1,ymm1) >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpand %%ymm5,%%ymm0,%%ymm1 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm1,%%ymm1 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vextractf128 $0x0,%%ymm1," MEMACCESS(1) " \n" >- VEXTOPMEM(vextractf128,0,ymm0,0x00,1,2,1) // vextractf128 $0x0,%%ymm0,(%1,%2,1) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x20,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_yuy2), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(width) // %3 >- : "r"((intptr_t)(stride_yuy2)) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" >+ "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpand %%ymm5,%%ymm0,%%ymm1 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm1,%%ymm1 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vextractf128 $0x0,%%ymm1,(%1) \n" >+ "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x20,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_yuy2), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(width) // %3 >+ : "r"((intptr_t)(stride_yuy2)) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } > >-void YUY2ToUV422Row_AVX2(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_AVX2(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >- "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >+ "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpand %%ymm5,%%ymm0,%%ymm1 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm1,%%ymm1 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vextractf128 $0x0,%%ymm1," MEMACCESS(1) " \n" >- VEXTOPMEM(vextractf128,0,ymm0,0x00,1,2,1) // vextractf128 $0x0,%%ymm0,(%1,%2,1) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x20,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_yuy2), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpand %%ymm5,%%ymm0,%%ymm1 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm1,%%ymm1 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vextractf128 $0x0,%%ymm1,(%1) \n" >+ "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x20,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_yuy2), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } >- >-void UYVYToYRow_AVX2(const uint8* src_uyvy, uint8* dst_y, int width) { >- asm volatile ( >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_uyvy), // %0 >- "+r"(dst_y), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm5" >- ); >+ >+void UYVYToYRow_AVX2(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_uyvy), // %0 >+ "+r"(dst_y), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } >-void UYVYToUVRow_AVX2(const uint8* src_uyvy, >+void UYVYToUVRow_AVX2(const uint8_t* src_uyvy, > int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >- "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >+ "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- VMEMOPREG(vpavgb,0x00,0,4,1,ymm0,ymm0) // vpavgb (%0,%4,1),%%ymm0,%%ymm0 >- VMEMOPREG(vpavgb,0x20,0,4,1,ymm1,ymm1) >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpand %%ymm5,%%ymm0,%%ymm0 \n" >- "vpand %%ymm5,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpand %%ymm5,%%ymm0,%%ymm1 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm1,%%ymm1 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vextractf128 $0x0,%%ymm1," MEMACCESS(1) " \n" >- VEXTOPMEM(vextractf128,0,ymm0,0x00,1,2,1) // vextractf128 $0x0,%%ymm0,(%1,%2,1) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x20,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_uyvy), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(width) // %3 >- : "r"((intptr_t)(stride_uyvy)) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" >+ "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpand %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpand %%ymm5,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpand %%ymm5,%%ymm0,%%ymm1 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm1,%%ymm1 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vextractf128 $0x0,%%ymm1,(%1) \n" >+ "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x20,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_uyvy), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(width) // %3 >+ : "r"((intptr_t)(stride_uyvy)) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } > >-void UYVYToUV422Row_AVX2(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_AVX2(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- asm volatile ( >- "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >- "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >- "sub %1,%2 \n" >+ asm volatile( >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >+ "vpsrlw $0x8,%%ymm5,%%ymm5 \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpand %%ymm5,%%ymm0,%%ymm0 \n" >- "vpand %%ymm5,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpand %%ymm5,%%ymm0,%%ymm1 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm1,%%ymm1 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vextractf128 $0x0,%%ymm1," MEMACCESS(1) " \n" >- VEXTOPMEM(vextractf128,0,ymm0,0x00,1,2,1) // vextractf128 $0x0,%%ymm0,(%1,%2,1) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x20,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_uyvy), // %0 >- "+r"(dst_u), // %1 >- "+r"(dst_v), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpand %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpand %%ymm5,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpand %%ymm5,%%ymm0,%%ymm1 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm1,%%ymm1 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vextractf128 $0x0,%%ymm1,(%1) \n" >+ "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x20,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_uyvy), // %0 >+ "+r"(dst_u), // %1 >+ "+r"(dst_v), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } > #endif // HAS_YUY2TOYROW_AVX2 > > #ifdef HAS_ARGBBLENDROW_SSSE3 > // Shuffle table for isolating alpha. >-static uvec8 kShuffleAlpha = {3u, 0x80, 3u, 0x80, 7u, 0x80, 7u, 0x80, >- 11u, 0x80, 11u, 0x80, 15u, 0x80, 15u, 0x80}; >+static const uvec8 kShuffleAlpha = {3u, 0x80, 3u, 0x80, 7u, 0x80, 7u, 0x80, >+ 11u, 0x80, 11u, 0x80, 15u, 0x80, 15u, 0x80}; > > // Blend 8 pixels at a time >-void ARGBBlendRow_SSSE3(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBBlendRow_SSSE3(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { >- asm volatile ( >- "pcmpeqb %%xmm7,%%xmm7 \n" >- "psrlw $0xf,%%xmm7 \n" >- "pcmpeqb %%xmm6,%%xmm6 \n" >- "psrlw $0x8,%%xmm6 \n" >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "psllw $0x8,%%xmm5 \n" >- "pcmpeqb %%xmm4,%%xmm4 \n" >- "pslld $0x18,%%xmm4 \n" >- "sub $0x4,%3 \n" >- "jl 49f \n" >- >- // 4 pixel loop. >- LABELALIGN >- "40: \n" >- "movdqu " MEMACCESS(0) ",%%xmm3 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqa %%xmm3,%%xmm0 \n" >- "pxor %%xmm4,%%xmm3 \n" >- "movdqu " MEMACCESS(1) ",%%xmm2 \n" >- "pshufb %4,%%xmm3 \n" >- "pand %%xmm6,%%xmm2 \n" >- "paddw %%xmm7,%%xmm3 \n" >- "pmullw %%xmm3,%%xmm2 \n" >- "movdqu " MEMACCESS(1) ",%%xmm1 \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "psrlw $0x8,%%xmm1 \n" >- "por %%xmm4,%%xmm0 \n" >- "pmullw %%xmm3,%%xmm1 \n" >- "psrlw $0x8,%%xmm2 \n" >- "paddusb %%xmm2,%%xmm0 \n" >- "pand %%xmm5,%%xmm1 \n" >- "paddusb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x4,%3 \n" >- "jge 40b \n" >- >- "49: \n" >- "add $0x3,%3 \n" >- "jl 99f \n" >- >- // 1 pixel loop. >- "91: \n" >- "movd " MEMACCESS(0) ",%%xmm3 \n" >- "lea " MEMLEA(0x4,0) ",%0 \n" >- "movdqa %%xmm3,%%xmm0 \n" >- "pxor %%xmm4,%%xmm3 \n" >- "movd " MEMACCESS(1) ",%%xmm2 \n" >- "pshufb %4,%%xmm3 \n" >- "pand %%xmm6,%%xmm2 \n" >- "paddw %%xmm7,%%xmm3 \n" >- "pmullw %%xmm3,%%xmm2 \n" >- "movd " MEMACCESS(1) ",%%xmm1 \n" >- "lea " MEMLEA(0x4,1) ",%1 \n" >- "psrlw $0x8,%%xmm1 \n" >- "por %%xmm4,%%xmm0 \n" >- "pmullw %%xmm3,%%xmm1 \n" >- "psrlw $0x8,%%xmm2 \n" >- "paddusb %%xmm2,%%xmm0 \n" >- "pand %%xmm5,%%xmm1 \n" >- "paddusb %%xmm1,%%xmm0 \n" >- "movd %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x4,2) ",%2 \n" >- "sub $0x1,%3 \n" >- "jge 91b \n" >- "99: \n" >- : "+r"(src_argb0), // %0 >- "+r"(src_argb1), // %1 >- "+r"(dst_argb), // %2 >- "+r"(width) // %3 >- : "m"(kShuffleAlpha) // %4 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ asm volatile( >+ "pcmpeqb %%xmm7,%%xmm7 \n" >+ "psrlw $0xf,%%xmm7 \n" >+ "pcmpeqb %%xmm6,%%xmm6 \n" >+ "psrlw $0x8,%%xmm6 \n" >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "psllw $0x8,%%xmm5 \n" >+ "pcmpeqb %%xmm4,%%xmm4 \n" >+ "pslld $0x18,%%xmm4 \n" >+ "sub $0x4,%3 \n" >+ "jl 49f \n" >+ >+ // 4 pixel loop. >+ LABELALIGN >+ "40: \n" >+ "movdqu (%0),%%xmm3 \n" >+ "lea 0x10(%0),%0 \n" >+ "movdqa %%xmm3,%%xmm0 \n" >+ "pxor %%xmm4,%%xmm3 \n" >+ "movdqu (%1),%%xmm2 \n" >+ "pshufb %4,%%xmm3 \n" >+ "pand %%xmm6,%%xmm2 \n" >+ "paddw %%xmm7,%%xmm3 \n" >+ "pmullw %%xmm3,%%xmm2 \n" >+ "movdqu (%1),%%xmm1 \n" >+ "lea 0x10(%1),%1 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "por %%xmm4,%%xmm0 \n" >+ "pmullw %%xmm3,%%xmm1 \n" >+ "psrlw $0x8,%%xmm2 \n" >+ "paddusb %%xmm2,%%xmm0 \n" >+ "pand %%xmm5,%%xmm1 \n" >+ "paddusb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x4,%3 \n" >+ "jge 40b \n" >+ >+ "49: \n" >+ "add $0x3,%3 \n" >+ "jl 99f \n" >+ >+ // 1 pixel loop. >+ "91: \n" >+ "movd (%0),%%xmm3 \n" >+ "lea 0x4(%0),%0 \n" >+ "movdqa %%xmm3,%%xmm0 \n" >+ "pxor %%xmm4,%%xmm3 \n" >+ "movd (%1),%%xmm2 \n" >+ "pshufb %4,%%xmm3 \n" >+ "pand %%xmm6,%%xmm2 \n" >+ "paddw %%xmm7,%%xmm3 \n" >+ "pmullw %%xmm3,%%xmm2 \n" >+ "movd (%1),%%xmm1 \n" >+ "lea 0x4(%1),%1 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "por %%xmm4,%%xmm0 \n" >+ "pmullw %%xmm3,%%xmm1 \n" >+ "psrlw $0x8,%%xmm2 \n" >+ "paddusb %%xmm2,%%xmm0 \n" >+ "pand %%xmm5,%%xmm1 \n" >+ "paddusb %%xmm1,%%xmm0 \n" >+ "movd %%xmm0,(%2) \n" >+ "lea 0x4(%2),%2 \n" >+ "sub $0x1,%3 \n" >+ "jge 91b \n" >+ "99: \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(src_argb1), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(width) // %3 >+ : "m"(kShuffleAlpha) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > #endif // HAS_ARGBBLENDROW_SSSE3 > >@@ -3863,10 +4437,10 @@ void ARGBBlendRow_SSSE3(const uint8* src_argb0, > // =((A2*C2)+(B2*(255-C2))+255)/256 > // signed version of math > // =(((A2-128)*C2)+((B2-128)*(255-C2))+32768+127)/256 >-void BlendPlaneRow_SSSE3(const uint8* src0, >- const uint8* src1, >- const uint8* alpha, >- uint8* dst, >+void BlendPlaneRow_SSSE3(const uint8_t* src0, >+ const uint8_t* src1, >+ const uint8_t* alpha, >+ uint8_t* dst, > int width) { > asm volatile( > "pcmpeqb %%xmm5,%%xmm5 \n" >@@ -3915,10 +4489,10 @@ void BlendPlaneRow_SSSE3(const uint8* src0, > // =((A2*C2)+(B2*(255-C2))+255)/256 > // signed version of math > // =(((A2-128)*C2)+((B2-128)*(255-C2))+32768+127)/256 >-void BlendPlaneRow_AVX2(const uint8* src0, >- const uint8* src1, >- const uint8* alpha, >- uint8* dst, >+void BlendPlaneRow_AVX2(const uint8_t* src0, >+ const uint8_t* src1, >+ const uint8_t* alpha, >+ uint8_t* dst, > int width) { > asm volatile( > "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >@@ -3972,50 +4546,50 @@ void BlendPlaneRow_AVX2(const uint8* src0, > > #ifdef HAS_ARGBATTENUATEROW_SSSE3 > // Shuffle table duplicating alpha >-static uvec8 kShuffleAlpha0 = {3u, 3u, 3u, 3u, 3u, 3u, 128u, 128u, >- 7u, 7u, 7u, 7u, 7u, 7u, 128u, 128u}; >-static uvec8 kShuffleAlpha1 = {11u, 11u, 11u, 11u, 11u, 11u, 128u, 128u, >- 15u, 15u, 15u, 15u, 15u, 15u, 128u, 128u}; >+static const uvec8 kShuffleAlpha0 = {3u, 3u, 3u, 3u, 3u, 3u, 128u, 128u, >+ 7u, 7u, 7u, 7u, 7u, 7u, 128u, 128u}; >+static const uvec8 kShuffleAlpha1 = {11u, 11u, 11u, 11u, 11u, 11u, 128u, 128u, >+ 15u, 15u, 15u, 15u, 15u, 15u, 128u, 128u}; > // Attenuate 4 pixels at a time. >-void ARGBAttenuateRow_SSSE3(const uint8* src_argb, uint8* dst_argb, int width) { >- asm volatile ( >- "pcmpeqb %%xmm3,%%xmm3 \n" >- "pslld $0x18,%%xmm3 \n" >- "movdqa %3,%%xmm4 \n" >- "movdqa %4,%%xmm5 \n" >+void ARGBAttenuateRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width) { >+ asm volatile( >+ "pcmpeqb %%xmm3,%%xmm3 \n" >+ "pslld $0x18,%%xmm3 \n" >+ "movdqa %3,%%xmm4 \n" >+ "movdqa %4,%%xmm5 \n" > >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "pshufb %%xmm4,%%xmm0 \n" >- "movdqu " MEMACCESS(0) ",%%xmm1 \n" >- "punpcklbw %%xmm1,%%xmm1 \n" >- "pmulhuw %%xmm1,%%xmm0 \n" >- "movdqu " MEMACCESS(0) ",%%xmm1 \n" >- "pshufb %%xmm5,%%xmm1 \n" >- "movdqu " MEMACCESS(0) ",%%xmm2 \n" >- "punpckhbw %%xmm2,%%xmm2 \n" >- "pmulhuw %%xmm2,%%xmm1 \n" >- "movdqu " MEMACCESS(0) ",%%xmm2 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "pand %%xmm3,%%xmm2 \n" >- "psrlw $0x8,%%xmm0 \n" >- "psrlw $0x8,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "por %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "m"(kShuffleAlpha0), // %3 >- "m"(kShuffleAlpha1) // %4 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "pshufb %%xmm4,%%xmm0 \n" >+ "movdqu (%0),%%xmm1 \n" >+ "punpcklbw %%xmm1,%%xmm1 \n" >+ "pmulhuw %%xmm1,%%xmm0 \n" >+ "movdqu (%0),%%xmm1 \n" >+ "pshufb %%xmm5,%%xmm1 \n" >+ "movdqu (%0),%%xmm2 \n" >+ "punpckhbw %%xmm2,%%xmm2 \n" >+ "pmulhuw %%xmm2,%%xmm1 \n" >+ "movdqu (%0),%%xmm2 \n" >+ "lea 0x10(%0),%0 \n" >+ "pand %%xmm3,%%xmm2 \n" >+ "psrlw $0x8,%%xmm0 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "por %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleAlpha0), // %3 >+ "m"(kShuffleAlpha1) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_ARGBATTENUATEROW_SSSE3 > >@@ -4025,87 +4599,85 @@ static const uvec8 kShuffleAlpha_AVX2 = {6u, 7u, 6u, 7u, 6u, 7u, > 128u, 128u, 14u, 15u, 14u, 15u, > 14u, 15u, 128u, 128u}; > // Attenuate 8 pixels at a time. >-void ARGBAttenuateRow_AVX2(const uint8* src_argb, uint8* dst_argb, int width) { >- asm volatile ( >- "vbroadcastf128 %3,%%ymm4 \n" >- "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >- "vpslld $0x18,%%ymm5,%%ymm5 \n" >- "sub %0,%1 \n" >+void ARGBAttenuateRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width) { >+ asm volatile( >+ "vbroadcastf128 %3,%%ymm4 \n" >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >+ "vpslld $0x18,%%ymm5,%%ymm5 \n" >+ "sub %0,%1 \n" > >- // 8 pixel loop. >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm6 \n" >- "vpunpcklbw %%ymm6,%%ymm6,%%ymm0 \n" >- "vpunpckhbw %%ymm6,%%ymm6,%%ymm1 \n" >- "vpshufb %%ymm4,%%ymm0,%%ymm2 \n" >- "vpshufb %%ymm4,%%ymm1,%%ymm3 \n" >- "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" >- "vpand %%ymm5,%%ymm6,%%ymm6 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpor %%ymm6,%%ymm0,%%ymm0 \n" >- MEMOPMEM(vmovdqu,ymm0,0x00,0,1,1) // vmovdqu %%ymm0,(%0,%1) >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "m"(kShuffleAlpha_AVX2) // %3 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" >- ); >+ // 8 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm6 \n" >+ "vpunpcklbw %%ymm6,%%ymm6,%%ymm0 \n" >+ "vpunpckhbw %%ymm6,%%ymm6,%%ymm1 \n" >+ "vpshufb %%ymm4,%%ymm0,%%ymm2 \n" >+ "vpshufb %%ymm4,%%ymm1,%%ymm3 \n" >+ "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" >+ "vpand %%ymm5,%%ymm6,%%ymm6 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpor %%ymm6,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,0x00(%0,%1,1) \n" >+ "lea 0x20(%0),%0 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "m"(kShuffleAlpha_AVX2) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); > } > #endif // HAS_ARGBATTENUATEROW_AVX2 > > #ifdef HAS_ARGBUNATTENUATEROW_SSE2 > // Unattenuate 4 pixels at a time. >-void ARGBUnattenuateRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBUnattenuateRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width) { > uintptr_t alpha; >- asm volatile ( >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movzb " MEMACCESS2(0x03,0) ",%3 \n" >- "punpcklbw %%xmm0,%%xmm0 \n" >- MEMOPREG(movd,0x00,4,3,4,xmm2) // movd 0x0(%4,%3,4),%%xmm2 >- "movzb " MEMACCESS2(0x07,0) ",%3 \n" >- MEMOPREG(movd,0x00,4,3,4,xmm3) // movd 0x0(%4,%3,4),%%xmm3 >- "pshuflw $0x40,%%xmm2,%%xmm2 \n" >- "pshuflw $0x40,%%xmm3,%%xmm3 \n" >- "movlhps %%xmm3,%%xmm2 \n" >- "pmulhuw %%xmm2,%%xmm0 \n" >- "movdqu " MEMACCESS(0) ",%%xmm1 \n" >- "movzb " MEMACCESS2(0x0b,0) ",%3 \n" >- "punpckhbw %%xmm1,%%xmm1 \n" >- MEMOPREG(movd,0x00,4,3,4,xmm2) // movd 0x0(%4,%3,4),%%xmm2 >- "movzb " MEMACCESS2(0x0f,0) ",%3 \n" >- MEMOPREG(movd,0x00,4,3,4,xmm3) // movd 0x0(%4,%3,4),%%xmm3 >- "pshuflw $0x40,%%xmm2,%%xmm2 \n" >- "pshuflw $0x40,%%xmm3,%%xmm3 \n" >- "movlhps %%xmm3,%%xmm2 \n" >- "pmulhuw %%xmm2,%%xmm1 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width), // %2 >- "=&r"(alpha) // %3 >- : "r"(fixed_invtbl8) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ asm volatile( >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movzb 0x03(%0),%3 \n" >+ "punpcklbw %%xmm0,%%xmm0 \n" >+ "movd 0x00(%4,%3,4),%%xmm2 \n" >+ "movzb 0x07(%0),%3 \n" >+ "movd 0x00(%4,%3,4),%%xmm3 \n" >+ "pshuflw $0x40,%%xmm2,%%xmm2 \n" >+ "pshuflw $0x40,%%xmm3,%%xmm3 \n" >+ "movlhps %%xmm3,%%xmm2 \n" >+ "pmulhuw %%xmm2,%%xmm0 \n" >+ "movdqu (%0),%%xmm1 \n" >+ "movzb 0x0b(%0),%3 \n" >+ "punpckhbw %%xmm1,%%xmm1 \n" >+ "movd 0x00(%4,%3,4),%%xmm2 \n" >+ "movzb 0x0f(%0),%3 \n" >+ "movd 0x00(%4,%3,4),%%xmm3 \n" >+ "pshuflw $0x40,%%xmm2,%%xmm2 \n" >+ "pshuflw $0x40,%%xmm3,%%xmm3 \n" >+ "movlhps %%xmm3,%%xmm2 \n" >+ "pmulhuw %%xmm2,%%xmm1 \n" >+ "lea 0x10(%0),%0 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width), // %2 >+ "=&r"(alpha) // %3 >+ : "r"(fixed_invtbl8) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_ARGBUNATTENUATEROW_SSE2 > >@@ -4114,114 +4686,111 @@ void ARGBUnattenuateRow_SSE2(const uint8* src_argb, > static const uvec8 kUnattenShuffleAlpha_AVX2 = { > 0u, 1u, 0u, 1u, 0u, 1u, 6u, 7u, 8u, 9u, 8u, 9u, 8u, 9u, 14u, 15u}; > // Unattenuate 8 pixels at a time. >-void ARGBUnattenuateRow_AVX2(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBUnattenuateRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width) { > uintptr_t alpha; >- asm volatile ( >- "sub %0,%1 \n" >- "vbroadcastf128 %5,%%ymm5 \n" >+ asm volatile( >+ "sub %0,%1 \n" >+ "vbroadcastf128 %5,%%ymm5 \n" > >- // 8 pixel loop. >- LABELALIGN >- "1: \n" >- // replace VPGATHER >- "movzb " MEMACCESS2(0x03,0) ",%3 \n" >- MEMOPREG(vmovd,0x00,4,3,4,xmm0) // vmovd 0x0(%4,%3,4),%%xmm0 >- "movzb " MEMACCESS2(0x07,0) ",%3 \n" >- MEMOPREG(vmovd,0x00,4,3,4,xmm1) // vmovd 0x0(%4,%3,4),%%xmm1 >- "movzb " MEMACCESS2(0x0b,0) ",%3 \n" >- "vpunpckldq %%xmm1,%%xmm0,%%xmm6 \n" >- MEMOPREG(vmovd,0x00,4,3,4,xmm2) // vmovd 0x0(%4,%3,4),%%xmm2 >- "movzb " MEMACCESS2(0x0f,0) ",%3 \n" >- MEMOPREG(vmovd,0x00,4,3,4,xmm3) // vmovd 0x0(%4,%3,4),%%xmm3 >- "movzb " MEMACCESS2(0x13,0) ",%3 \n" >- "vpunpckldq %%xmm3,%%xmm2,%%xmm7 \n" >- MEMOPREG(vmovd,0x00,4,3,4,xmm0) // vmovd 0x0(%4,%3,4),%%xmm0 >- "movzb " MEMACCESS2(0x17,0) ",%3 \n" >- MEMOPREG(vmovd,0x00,4,3,4,xmm1) // vmovd 0x0(%4,%3,4),%%xmm1 >- "movzb " MEMACCESS2(0x1b,0) ",%3 \n" >- "vpunpckldq %%xmm1,%%xmm0,%%xmm0 \n" >- MEMOPREG(vmovd,0x00,4,3,4,xmm2) // vmovd 0x0(%4,%3,4),%%xmm2 >- "movzb " MEMACCESS2(0x1f,0) ",%3 \n" >- MEMOPREG(vmovd,0x00,4,3,4,xmm3) // vmovd 0x0(%4,%3,4),%%xmm3 >- "vpunpckldq %%xmm3,%%xmm2,%%xmm2 \n" >- "vpunpcklqdq %%xmm7,%%xmm6,%%xmm3 \n" >- "vpunpcklqdq %%xmm2,%%xmm0,%%xmm0 \n" >- "vinserti128 $0x1,%%xmm0,%%ymm3,%%ymm3 \n" >- // end of VPGATHER >- >- "vmovdqu " MEMACCESS(0) ",%%ymm6 \n" >- "vpunpcklbw %%ymm6,%%ymm6,%%ymm0 \n" >- "vpunpckhbw %%ymm6,%%ymm6,%%ymm1 \n" >- "vpunpcklwd %%ymm3,%%ymm3,%%ymm2 \n" >- "vpunpckhwd %%ymm3,%%ymm3,%%ymm3 \n" >- "vpshufb %%ymm5,%%ymm2,%%ymm2 \n" >- "vpshufb %%ymm5,%%ymm3,%%ymm3 \n" >- "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- MEMOPMEM(vmovdqu,ymm0,0x00,0,1,1) // vmovdqu %%ymm0,(%0,%1) >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width), // %2 >- "=&r"(alpha) // %3 >- : "r"(fixed_invtbl8), // %4 >- "m"(kUnattenShuffleAlpha_AVX2) // %5 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ // 8 pixel loop. >+ LABELALIGN >+ "1: \n" >+ // replace VPGATHER >+ "movzb 0x03(%0),%3 \n" >+ "vmovd 0x00(%4,%3,4),%%xmm0 \n" >+ "movzb 0x07(%0),%3 \n" >+ "vmovd 0x00(%4,%3,4),%%xmm1 \n" >+ "movzb 0x0b(%0),%3 \n" >+ "vpunpckldq %%xmm1,%%xmm0,%%xmm6 \n" >+ "vmovd 0x00(%4,%3,4),%%xmm2 \n" >+ "movzb 0x0f(%0),%3 \n" >+ "vmovd 0x00(%4,%3,4),%%xmm3 \n" >+ "movzb 0x13(%0),%3 \n" >+ "vpunpckldq %%xmm3,%%xmm2,%%xmm7 \n" >+ "vmovd 0x00(%4,%3,4),%%xmm0 \n" >+ "movzb 0x17(%0),%3 \n" >+ "vmovd 0x00(%4,%3,4),%%xmm1 \n" >+ "movzb 0x1b(%0),%3 \n" >+ "vpunpckldq %%xmm1,%%xmm0,%%xmm0 \n" >+ "vmovd 0x00(%4,%3,4),%%xmm2 \n" >+ "movzb 0x1f(%0),%3 \n" >+ "vmovd 0x00(%4,%3,4),%%xmm3 \n" >+ "vpunpckldq %%xmm3,%%xmm2,%%xmm2 \n" >+ "vpunpcklqdq %%xmm7,%%xmm6,%%xmm3 \n" >+ "vpunpcklqdq %%xmm2,%%xmm0,%%xmm0 \n" >+ "vinserti128 $0x1,%%xmm0,%%ymm3,%%ymm3 \n" >+ // end of VPGATHER >+ >+ "vmovdqu (%0),%%ymm6 \n" >+ "vpunpcklbw %%ymm6,%%ymm6,%%ymm0 \n" >+ "vpunpckhbw %%ymm6,%%ymm6,%%ymm1 \n" >+ "vpunpcklwd %%ymm3,%%ymm3,%%ymm2 \n" >+ "vpunpckhwd %%ymm3,%%ymm3,%%ymm3 \n" >+ "vpshufb %%ymm5,%%ymm2,%%ymm2 \n" >+ "vpshufb %%ymm5,%%ymm3,%%ymm3 \n" >+ "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,0x00(%0,%1,1) \n" >+ "lea 0x20(%0),%0 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width), // %2 >+ "=&r"(alpha) // %3 >+ : "r"(fixed_invtbl8), // %4 >+ "m"(kUnattenShuffleAlpha_AVX2) // %5 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > #endif // HAS_ARGBUNATTENUATEROW_AVX2 > > #ifdef HAS_ARGBGRAYROW_SSSE3 > // Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels >-void ARGBGrayRow_SSSE3(const uint8* src_argb, uint8* dst_argb, int width) { >- asm volatile ( >- "movdqa %3,%%xmm4 \n" >- "movdqa %4,%%xmm5 \n" >+void ARGBGrayRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_argb, int width) { >+ asm volatile( >+ "movdqa %3,%%xmm4 \n" >+ "movdqa %4,%%xmm5 \n" > >- // 8 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "phaddw %%xmm1,%%xmm0 \n" >- "paddw %%xmm5,%%xmm0 \n" >- "psrlw $0x7,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "movdqu " MEMACCESS(0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm3 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "psrld $0x18,%%xmm2 \n" >- "psrld $0x18,%%xmm3 \n" >- "packuswb %%xmm3,%%xmm2 \n" >- "packuswb %%xmm2,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm3 \n" >- "punpcklbw %%xmm0,%%xmm0 \n" >- "punpcklbw %%xmm2,%%xmm3 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklwd %%xmm3,%%xmm0 \n" >- "punpckhwd %%xmm3,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "m"(kARGBToYJ), // %3 >- "m"(kAddYJ64) // %4 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ // 8 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "phaddw %%xmm1,%%xmm0 \n" >+ "paddw %%xmm5,%%xmm0 \n" >+ "psrlw $0x7,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "movdqu (%0),%%xmm2 \n" >+ "movdqu 0x10(%0),%%xmm3 \n" >+ "lea 0x20(%0),%0 \n" >+ "psrld $0x18,%%xmm2 \n" >+ "psrld $0x18,%%xmm3 \n" >+ "packuswb %%xmm3,%%xmm2 \n" >+ "packuswb %%xmm2,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm3 \n" >+ "punpcklbw %%xmm0,%%xmm0 \n" >+ "punpcklbw %%xmm2,%%xmm3 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpcklwd %%xmm3,%%xmm0 \n" >+ "punpckhwd %%xmm3,%%xmm1 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "m"(kARGBToYJ), // %3 >+ "m"(kAddYJ64) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_ARGBGRAYROW_SSSE3 > >@@ -4230,428 +4799,415 @@ void ARGBGrayRow_SSSE3(const uint8* src_argb, uint8* dst_argb, int width) { > // g = (r * 45 + g * 88 + b * 22) >> 7 > // r = (r * 50 + g * 98 + b * 24) >> 7 > // Constant for ARGB color to sepia tone >-static vec8 kARGBToSepiaB = {17, 68, 35, 0, 17, 68, 35, 0, >- 17, 68, 35, 0, 17, 68, 35, 0}; >+static const vec8 kARGBToSepiaB = {17, 68, 35, 0, 17, 68, 35, 0, >+ 17, 68, 35, 0, 17, 68, 35, 0}; > >-static vec8 kARGBToSepiaG = {22, 88, 45, 0, 22, 88, 45, 0, >- 22, 88, 45, 0, 22, 88, 45, 0}; >+static const vec8 kARGBToSepiaG = {22, 88, 45, 0, 22, 88, 45, 0, >+ 22, 88, 45, 0, 22, 88, 45, 0}; > >-static vec8 kARGBToSepiaR = {24, 98, 50, 0, 24, 98, 50, 0, >- 24, 98, 50, 0, 24, 98, 50, 0}; >+static const vec8 kARGBToSepiaR = {24, 98, 50, 0, 24, 98, 50, 0, >+ 24, 98, 50, 0, 24, 98, 50, 0}; > > // Convert 8 ARGB pixels (32 bytes) to 8 Sepia ARGB pixels. >-void ARGBSepiaRow_SSSE3(uint8* dst_argb, int width) { >- asm volatile ( >- "movdqa %2,%%xmm2 \n" >- "movdqa %3,%%xmm3 \n" >- "movdqa %4,%%xmm4 \n" >+void ARGBSepiaRow_SSSE3(uint8_t* dst_argb, int width) { >+ asm volatile( >+ "movdqa %2,%%xmm2 \n" >+ "movdqa %3,%%xmm3 \n" >+ "movdqa %4,%%xmm4 \n" > >- // 8 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm6 \n" >- "pmaddubsw %%xmm2,%%xmm0 \n" >- "pmaddubsw %%xmm2,%%xmm6 \n" >- "phaddw %%xmm6,%%xmm0 \n" >- "psrlw $0x7,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "movdqu " MEMACCESS(0) ",%%xmm5 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "pmaddubsw %%xmm3,%%xmm5 \n" >- "pmaddubsw %%xmm3,%%xmm1 \n" >- "phaddw %%xmm1,%%xmm5 \n" >- "psrlw $0x7,%%xmm5 \n" >- "packuswb %%xmm5,%%xmm5 \n" >- "punpcklbw %%xmm5,%%xmm0 \n" >- "movdqu " MEMACCESS(0) ",%%xmm5 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm5 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "phaddw %%xmm1,%%xmm5 \n" >- "psrlw $0x7,%%xmm5 \n" >- "packuswb %%xmm5,%%xmm5 \n" >- "movdqu " MEMACCESS(0) ",%%xmm6 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "psrld $0x18,%%xmm6 \n" >- "psrld $0x18,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm6 \n" >- "packuswb %%xmm6,%%xmm6 \n" >- "punpcklbw %%xmm6,%%xmm5 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklwd %%xmm5,%%xmm0 \n" >- "punpckhwd %%xmm5,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(0) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,0) " \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "sub $0x8,%1 \n" >- "jg 1b \n" >- : "+r"(dst_argb), // %0 >- "+r"(width) // %1 >- : "m"(kARGBToSepiaB), // %2 >- "m"(kARGBToSepiaG), // %3 >- "m"(kARGBToSepiaR) // %4 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" >- ); >+ // 8 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm6 \n" >+ "pmaddubsw %%xmm2,%%xmm0 \n" >+ "pmaddubsw %%xmm2,%%xmm6 \n" >+ "phaddw %%xmm6,%%xmm0 \n" >+ "psrlw $0x7,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "movdqu (%0),%%xmm5 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "pmaddubsw %%xmm3,%%xmm5 \n" >+ "pmaddubsw %%xmm3,%%xmm1 \n" >+ "phaddw %%xmm1,%%xmm5 \n" >+ "psrlw $0x7,%%xmm5 \n" >+ "packuswb %%xmm5,%%xmm5 \n" >+ "punpcklbw %%xmm5,%%xmm0 \n" >+ "movdqu (%0),%%xmm5 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm5 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "phaddw %%xmm1,%%xmm5 \n" >+ "psrlw $0x7,%%xmm5 \n" >+ "packuswb %%xmm5,%%xmm5 \n" >+ "movdqu (%0),%%xmm6 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "psrld $0x18,%%xmm6 \n" >+ "psrld $0x18,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm6 \n" >+ "packuswb %%xmm6,%%xmm6 \n" >+ "punpcklbw %%xmm6,%%xmm5 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpcklwd %%xmm5,%%xmm0 \n" >+ "punpckhwd %%xmm5,%%xmm1 \n" >+ "movdqu %%xmm0,(%0) \n" >+ "movdqu %%xmm1,0x10(%0) \n" >+ "lea 0x20(%0),%0 \n" >+ "sub $0x8,%1 \n" >+ "jg 1b \n" >+ : "+r"(dst_argb), // %0 >+ "+r"(width) // %1 >+ : "m"(kARGBToSepiaB), // %2 >+ "m"(kARGBToSepiaG), // %3 >+ "m"(kARGBToSepiaR) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); > } > #endif // HAS_ARGBSEPIAROW_SSSE3 > > #ifdef HAS_ARGBCOLORMATRIXROW_SSSE3 > // Tranform 8 ARGB pixels (32 bytes) with color matrix. > // Same as Sepia except matrix is provided. >-void ARGBColorMatrixRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >- const int8* matrix_argb, >+void ARGBColorMatrixRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const int8_t* matrix_argb, > int width) { >- asm volatile ( >- "movdqu " MEMACCESS(3) ",%%xmm5 \n" >- "pshufd $0x00,%%xmm5,%%xmm2 \n" >- "pshufd $0x55,%%xmm5,%%xmm3 \n" >- "pshufd $0xaa,%%xmm5,%%xmm4 \n" >- "pshufd $0xff,%%xmm5,%%xmm5 \n" >+ asm volatile( >+ "movdqu (%3),%%xmm5 \n" >+ "pshufd $0x00,%%xmm5,%%xmm2 \n" >+ "pshufd $0x55,%%xmm5,%%xmm3 \n" >+ "pshufd $0xaa,%%xmm5,%%xmm4 \n" >+ "pshufd $0xff,%%xmm5,%%xmm5 \n" > >- // 8 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm7 \n" >- "pmaddubsw %%xmm2,%%xmm0 \n" >- "pmaddubsw %%xmm2,%%xmm7 \n" >- "movdqu " MEMACCESS(0) ",%%xmm6 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "pmaddubsw %%xmm3,%%xmm6 \n" >- "pmaddubsw %%xmm3,%%xmm1 \n" >- "phaddsw %%xmm7,%%xmm0 \n" >- "phaddsw %%xmm1,%%xmm6 \n" >- "psraw $0x6,%%xmm0 \n" >- "psraw $0x6,%%xmm6 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "packuswb %%xmm6,%%xmm6 \n" >- "punpcklbw %%xmm6,%%xmm0 \n" >- "movdqu " MEMACCESS(0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm7 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm7 \n" >- "phaddsw %%xmm7,%%xmm1 \n" >- "movdqu " MEMACCESS(0) ",%%xmm6 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm7 \n" >- "pmaddubsw %%xmm5,%%xmm6 \n" >- "pmaddubsw %%xmm5,%%xmm7 \n" >- "phaddsw %%xmm7,%%xmm6 \n" >- "psraw $0x6,%%xmm1 \n" >- "psraw $0x6,%%xmm6 \n" >- "packuswb %%xmm1,%%xmm1 \n" >- "packuswb %%xmm6,%%xmm6 \n" >- "punpcklbw %%xmm6,%%xmm1 \n" >- "movdqa %%xmm0,%%xmm6 \n" >- "punpcklwd %%xmm1,%%xmm0 \n" >- "punpckhwd %%xmm1,%%xmm6 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "movdqu %%xmm6," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "r"(matrix_argb) // %3 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ // 8 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm7 \n" >+ "pmaddubsw %%xmm2,%%xmm0 \n" >+ "pmaddubsw %%xmm2,%%xmm7 \n" >+ "movdqu (%0),%%xmm6 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "pmaddubsw %%xmm3,%%xmm6 \n" >+ "pmaddubsw %%xmm3,%%xmm1 \n" >+ "phaddsw %%xmm7,%%xmm0 \n" >+ "phaddsw %%xmm1,%%xmm6 \n" >+ "psraw $0x6,%%xmm0 \n" >+ "psraw $0x6,%%xmm6 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "packuswb %%xmm6,%%xmm6 \n" >+ "punpcklbw %%xmm6,%%xmm0 \n" >+ "movdqu (%0),%%xmm1 \n" >+ "movdqu 0x10(%0),%%xmm7 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm7 \n" >+ "phaddsw %%xmm7,%%xmm1 \n" >+ "movdqu (%0),%%xmm6 \n" >+ "movdqu 0x10(%0),%%xmm7 \n" >+ "pmaddubsw %%xmm5,%%xmm6 \n" >+ "pmaddubsw %%xmm5,%%xmm7 \n" >+ "phaddsw %%xmm7,%%xmm6 \n" >+ "psraw $0x6,%%xmm1 \n" >+ "psraw $0x6,%%xmm6 \n" >+ "packuswb %%xmm1,%%xmm1 \n" >+ "packuswb %%xmm6,%%xmm6 \n" >+ "punpcklbw %%xmm6,%%xmm1 \n" >+ "movdqa %%xmm0,%%xmm6 \n" >+ "punpcklwd %%xmm1,%%xmm0 \n" >+ "punpckhwd %%xmm1,%%xmm6 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "movdqu %%xmm6,0x10(%1) \n" >+ "lea 0x20(%0),%0 \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "r"(matrix_argb) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > #endif // HAS_ARGBCOLORMATRIXROW_SSSE3 > > #ifdef HAS_ARGBQUANTIZEROW_SSE2 > // Quantize 4 ARGB pixels (16 bytes). >-void ARGBQuantizeRow_SSE2(uint8* dst_argb, >+void ARGBQuantizeRow_SSE2(uint8_t* dst_argb, > int scale, > int interval_size, > int interval_offset, > int width) { >- asm volatile ( >- "movd %2,%%xmm2 \n" >- "movd %3,%%xmm3 \n" >- "movd %4,%%xmm4 \n" >- "pshuflw $0x40,%%xmm2,%%xmm2 \n" >- "pshufd $0x44,%%xmm2,%%xmm2 \n" >- "pshuflw $0x40,%%xmm3,%%xmm3 \n" >- "pshufd $0x44,%%xmm3,%%xmm3 \n" >- "pshuflw $0x40,%%xmm4,%%xmm4 \n" >- "pshufd $0x44,%%xmm4,%%xmm4 \n" >- "pxor %%xmm5,%%xmm5 \n" >- "pcmpeqb %%xmm6,%%xmm6 \n" >- "pslld $0x18,%%xmm6 \n" >- >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "punpcklbw %%xmm5,%%xmm0 \n" >- "pmulhuw %%xmm2,%%xmm0 \n" >- "movdqu " MEMACCESS(0) ",%%xmm1 \n" >- "punpckhbw %%xmm5,%%xmm1 \n" >- "pmulhuw %%xmm2,%%xmm1 \n" >- "pmullw %%xmm3,%%xmm0 \n" >- "movdqu " MEMACCESS(0) ",%%xmm7 \n" >- "pmullw %%xmm3,%%xmm1 \n" >- "pand %%xmm6,%%xmm7 \n" >- "paddw %%xmm4,%%xmm0 \n" >- "paddw %%xmm4,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "por %%xmm7,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(0) " \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "sub $0x4,%1 \n" >- "jg 1b \n" >- : "+r"(dst_argb), // %0 >- "+r"(width) // %1 >- : "r"(scale), // %2 >- "r"(interval_size), // %3 >- "r"(interval_offset) // %4 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ asm volatile( >+ "movd %2,%%xmm2 \n" >+ "movd %3,%%xmm3 \n" >+ "movd %4,%%xmm4 \n" >+ "pshuflw $0x40,%%xmm2,%%xmm2 \n" >+ "pshufd $0x44,%%xmm2,%%xmm2 \n" >+ "pshuflw $0x40,%%xmm3,%%xmm3 \n" >+ "pshufd $0x44,%%xmm3,%%xmm3 \n" >+ "pshuflw $0x40,%%xmm4,%%xmm4 \n" >+ "pshufd $0x44,%%xmm4,%%xmm4 \n" >+ "pxor %%xmm5,%%xmm5 \n" >+ "pcmpeqb %%xmm6,%%xmm6 \n" >+ "pslld $0x18,%%xmm6 \n" >+ >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "punpcklbw %%xmm5,%%xmm0 \n" >+ "pmulhuw %%xmm2,%%xmm0 \n" >+ "movdqu (%0),%%xmm1 \n" >+ "punpckhbw %%xmm5,%%xmm1 \n" >+ "pmulhuw %%xmm2,%%xmm1 \n" >+ "pmullw %%xmm3,%%xmm0 \n" >+ "movdqu (%0),%%xmm7 \n" >+ "pmullw %%xmm3,%%xmm1 \n" >+ "pand %%xmm6,%%xmm7 \n" >+ "paddw %%xmm4,%%xmm0 \n" >+ "paddw %%xmm4,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "por %%xmm7,%%xmm0 \n" >+ "movdqu %%xmm0,(%0) \n" >+ "lea 0x10(%0),%0 \n" >+ "sub $0x4,%1 \n" >+ "jg 1b \n" >+ : "+r"(dst_argb), // %0 >+ "+r"(width) // %1 >+ : "r"(scale), // %2 >+ "r"(interval_size), // %3 >+ "r"(interval_offset) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > #endif // HAS_ARGBQUANTIZEROW_SSE2 > > #ifdef HAS_ARGBSHADEROW_SSE2 > // Shade 4 pixels at a time by specified value. >-void ARGBShadeRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBShadeRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- uint32 value) { >- asm volatile ( >- "movd %3,%%xmm2 \n" >- "punpcklbw %%xmm2,%%xmm2 \n" >- "punpcklqdq %%xmm2,%%xmm2 \n" >+ uint32_t value) { >+ asm volatile( >+ "movd %3,%%xmm2 \n" >+ "punpcklbw %%xmm2,%%xmm2 \n" >+ "punpcklqdq %%xmm2,%%xmm2 \n" > >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklbw %%xmm0,%%xmm0 \n" >- "punpckhbw %%xmm1,%%xmm1 \n" >- "pmulhuw %%xmm2,%%xmm0 \n" >- "pmulhuw %%xmm2,%%xmm1 \n" >- "psrlw $0x8,%%xmm0 \n" >- "psrlw $0x8,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "r"(value) // %3 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2" >- ); >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "lea 0x10(%0),%0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpcklbw %%xmm0,%%xmm0 \n" >+ "punpckhbw %%xmm1,%%xmm1 \n" >+ "pmulhuw %%xmm2,%%xmm0 \n" >+ "pmulhuw %%xmm2,%%xmm1 \n" >+ "psrlw $0x8,%%xmm0 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "r"(value) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); > } > #endif // HAS_ARGBSHADEROW_SSE2 > > #ifdef HAS_ARGBMULTIPLYROW_SSE2 > // Multiply 2 rows of ARGB pixels together, 4 pixels at a time. >-void ARGBMultiplyRow_SSE2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_SSE2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { >- asm volatile ( >- "pxor %%xmm5,%%xmm5 \n" >+ asm volatile( > >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqu " MEMACCESS(1) ",%%xmm2 \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "movdqu %%xmm0,%%xmm1 \n" >- "movdqu %%xmm2,%%xmm3 \n" >- "punpcklbw %%xmm0,%%xmm0 \n" >- "punpckhbw %%xmm1,%%xmm1 \n" >- "punpcklbw %%xmm5,%%xmm2 \n" >- "punpckhbw %%xmm5,%%xmm3 \n" >- "pmulhuw %%xmm2,%%xmm0 \n" >- "pmulhuw %%xmm3,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x4,%3 \n" >- "jg 1b \n" >- : "+r"(src_argb0), // %0 >- "+r"(src_argb1), // %1 >- "+r"(dst_argb), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ "pxor %%xmm5,%%xmm5 \n" >+ >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "lea 0x10(%0),%0 \n" >+ "movdqu (%1),%%xmm2 \n" >+ "lea 0x10(%1),%1 \n" >+ "movdqu %%xmm0,%%xmm1 \n" >+ "movdqu %%xmm2,%%xmm3 \n" >+ "punpcklbw %%xmm0,%%xmm0 \n" >+ "punpckhbw %%xmm1,%%xmm1 \n" >+ "punpcklbw %%xmm5,%%xmm2 \n" >+ "punpckhbw %%xmm5,%%xmm3 \n" >+ "pmulhuw %%xmm2,%%xmm0 \n" >+ "pmulhuw %%xmm3,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x4,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(src_argb1), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > #endif // HAS_ARGBMULTIPLYROW_SSE2 > > #ifdef HAS_ARGBMULTIPLYROW_AVX2 > // Multiply 2 rows of ARGB pixels together, 8 pixels at a time. >-void ARGBMultiplyRow_AVX2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_AVX2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { >- asm volatile ( >- "vpxor %%ymm5,%%ymm5,%%ymm5 \n" >+ asm volatile( > >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "vmovdqu " MEMACCESS(1) ",%%ymm3 \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "vpunpcklbw %%ymm1,%%ymm1,%%ymm0 \n" >- "vpunpckhbw %%ymm1,%%ymm1,%%ymm1 \n" >- "vpunpcklbw %%ymm5,%%ymm3,%%ymm2 \n" >- "vpunpckhbw %%ymm5,%%ymm3,%%ymm3 \n" >- "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vmovdqu %%ymm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x20,2) ",%2 \n" >- "sub $0x8,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb0), // %0 >- "+r"(src_argb1), // %1 >- "+r"(dst_argb), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc" >+ "vpxor %%ymm5,%%ymm5,%%ymm5 \n" >+ >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "vmovdqu (%1),%%ymm3 \n" >+ "lea 0x20(%1),%1 \n" >+ "vpunpcklbw %%ymm1,%%ymm1,%%ymm0 \n" >+ "vpunpckhbw %%ymm1,%%ymm1,%%ymm1 \n" >+ "vpunpcklbw %%ymm5,%%ymm3,%%ymm2 \n" >+ "vpunpckhbw %%ymm5,%%ymm3,%%ymm3 \n" >+ "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,(%2) \n" >+ "lea 0x20(%2),%2 \n" >+ "sub $0x8,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(src_argb1), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc" > #if defined(__AVX2__) >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >+ , >+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" > #endif >- ); >+ ); > } > #endif // HAS_ARGBMULTIPLYROW_AVX2 > > #ifdef HAS_ARGBADDROW_SSE2 > // Add 2 rows of ARGB pixels together, 4 pixels at a time. >-void ARGBAddRow_SSE2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_SSE2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { >- asm volatile ( >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqu " MEMACCESS(1) ",%%xmm1 \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "paddusb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x4,%3 \n" >- "jg 1b \n" >- : "+r"(src_argb0), // %0 >- "+r"(src_argb1), // %1 >- "+r"(dst_argb), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc" >- , "xmm0", "xmm1" >- ); >+ asm volatile( >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "lea 0x10(%0),%0 \n" >+ "movdqu (%1),%%xmm1 \n" >+ "lea 0x10(%1),%1 \n" >+ "paddusb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x4,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(src_argb1), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1"); > } > #endif // HAS_ARGBADDROW_SSE2 > > #ifdef HAS_ARGBADDROW_AVX2 > // Add 2 rows of ARGB pixels together, 4 pixels at a time. >-void ARGBAddRow_AVX2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_AVX2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { >- asm volatile ( >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "vpaddusb " MEMACCESS(1) ",%%ymm0,%%ymm0 \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "vmovdqu %%ymm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x20,2) ",%2 \n" >- "sub $0x8,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb0), // %0 >- "+r"(src_argb1), // %1 >- "+r"(dst_argb), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc" >- , "xmm0" >- ); >+ asm volatile( >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "lea 0x20(%0),%0 \n" >+ "vpaddusb (%1),%%ymm0,%%ymm0 \n" >+ "lea 0x20(%1),%1 \n" >+ "vmovdqu %%ymm0,(%2) \n" >+ "lea 0x20(%2),%2 \n" >+ "sub $0x8,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(src_argb1), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0"); > } > #endif // HAS_ARGBADDROW_AVX2 > > #ifdef HAS_ARGBSUBTRACTROW_SSE2 > // Subtract 2 rows of ARGB pixels, 4 pixels at a time. >-void ARGBSubtractRow_SSE2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_SSE2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { >- asm volatile ( >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqu " MEMACCESS(1) ",%%xmm1 \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "psubusb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x4,%3 \n" >- "jg 1b \n" >- : "+r"(src_argb0), // %0 >- "+r"(src_argb1), // %1 >- "+r"(dst_argb), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc" >- , "xmm0", "xmm1" >- ); >+ asm volatile( >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "lea 0x10(%0),%0 \n" >+ "movdqu (%1),%%xmm1 \n" >+ "lea 0x10(%1),%1 \n" >+ "psubusb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x4,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(src_argb1), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1"); > } > #endif // HAS_ARGBSUBTRACTROW_SSE2 > > #ifdef HAS_ARGBSUBTRACTROW_AVX2 > // Subtract 2 rows of ARGB pixels, 8 pixels at a time. >-void ARGBSubtractRow_AVX2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_AVX2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { >- asm volatile ( >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "vpsubusb " MEMACCESS(1) ",%%ymm0,%%ymm0 \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "vmovdqu %%ymm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x20,2) ",%2 \n" >- "sub $0x8,%3 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb0), // %0 >- "+r"(src_argb1), // %1 >- "+r"(dst_argb), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc" >- , "xmm0" >- ); >+ asm volatile( >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "lea 0x20(%0),%0 \n" >+ "vpsubusb (%1),%%ymm0,%%ymm0 \n" >+ "lea 0x20(%1),%1 \n" >+ "vmovdqu %%ymm0,(%2) \n" >+ "lea 0x20(%2),%2 \n" >+ "sub $0x8,%3 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb0), // %0 >+ "+r"(src_argb1), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0"); > } > #endif // HAS_ARGBSUBTRACTROW_AVX2 > >@@ -4660,55 +5216,53 @@ void ARGBSubtractRow_AVX2(const uint8* src_argb0, > // -1 0 1 > // -2 0 2 > // -1 0 1 >-void SobelXRow_SSE2(const uint8* src_y0, >- const uint8* src_y1, >- const uint8* src_y2, >- uint8* dst_sobelx, >+void SobelXRow_SSE2(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ const uint8_t* src_y2, >+ uint8_t* dst_sobelx, > int width) { >- asm volatile ( >- "sub %0,%1 \n" >- "sub %0,%2 \n" >- "sub %0,%3 \n" >- "pxor %%xmm5,%%xmm5 \n" >+ asm volatile( >+ "sub %0,%1 \n" >+ "sub %0,%2 \n" >+ "sub %0,%3 \n" >+ "pxor %%xmm5,%%xmm5 \n" > >- // 8 pixel loop. >- LABELALIGN >- "1: \n" >- "movq " MEMACCESS(0) ",%%xmm0 \n" >- "movq " MEMACCESS2(0x2,0) ",%%xmm1 \n" >- "punpcklbw %%xmm5,%%xmm0 \n" >- "punpcklbw %%xmm5,%%xmm1 \n" >- "psubw %%xmm1,%%xmm0 \n" >- MEMOPREG(movq,0x00,0,1,1,xmm1) // movq (%0,%1,1),%%xmm1 >- MEMOPREG(movq,0x02,0,1,1,xmm2) // movq 0x2(%0,%1,1),%%xmm2 >- "punpcklbw %%xmm5,%%xmm1 \n" >- "punpcklbw %%xmm5,%%xmm2 \n" >- "psubw %%xmm2,%%xmm1 \n" >- MEMOPREG(movq,0x00,0,2,1,xmm2) // movq (%0,%2,1),%%xmm2 >- MEMOPREG(movq,0x02,0,2,1,xmm3) // movq 0x2(%0,%2,1),%%xmm3 >- "punpcklbw %%xmm5,%%xmm2 \n" >- "punpcklbw %%xmm5,%%xmm3 \n" >- "psubw %%xmm3,%%xmm2 \n" >- "paddw %%xmm2,%%xmm0 \n" >- "paddw %%xmm1,%%xmm0 \n" >- "paddw %%xmm1,%%xmm0 \n" >- "pxor %%xmm1,%%xmm1 \n" >- "psubw %%xmm0,%%xmm1 \n" >- "pmaxsw %%xmm1,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- MEMOPMEM(movq,xmm0,0x00,0,3,1) // movq %%xmm0,(%0,%3,1) >- "lea " MEMLEA(0x8,0) ",%0 \n" >- "sub $0x8,%4 \n" >- "jg 1b \n" >- : "+r"(src_y0), // %0 >- "+r"(src_y1), // %1 >- "+r"(src_y2), // %2 >- "+r"(dst_sobelx), // %3 >- "+r"(width) // %4 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ // 8 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movq (%0),%%xmm0 \n" >+ "movq 0x2(%0),%%xmm1 \n" >+ "punpcklbw %%xmm5,%%xmm0 \n" >+ "punpcklbw %%xmm5,%%xmm1 \n" >+ "psubw %%xmm1,%%xmm0 \n" >+ "movq 0x00(%0,%1,1),%%xmm1 \n" >+ "movq 0x02(%0,%1,1),%%xmm2 \n" >+ "punpcklbw %%xmm5,%%xmm1 \n" >+ "punpcklbw %%xmm5,%%xmm2 \n" >+ "psubw %%xmm2,%%xmm1 \n" >+ "movq 0x00(%0,%2,1),%%xmm2 \n" >+ "movq 0x02(%0,%2,1),%%xmm3 \n" >+ "punpcklbw %%xmm5,%%xmm2 \n" >+ "punpcklbw %%xmm5,%%xmm3 \n" >+ "psubw %%xmm3,%%xmm2 \n" >+ "paddw %%xmm2,%%xmm0 \n" >+ "paddw %%xmm1,%%xmm0 \n" >+ "paddw %%xmm1,%%xmm0 \n" >+ "pxor %%xmm1,%%xmm1 \n" >+ "psubw %%xmm0,%%xmm1 \n" >+ "pmaxsw %%xmm1,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "movq %%xmm0,0x00(%0,%3,1) \n" >+ "lea 0x8(%0),%0 \n" >+ "sub $0x8,%4 \n" >+ "jg 1b \n" >+ : "+r"(src_y0), // %0 >+ "+r"(src_y1), // %1 >+ "+r"(src_y2), // %2 >+ "+r"(dst_sobelx), // %3 >+ "+r"(width) // %4 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > #endif // HAS_SOBELXROW_SSE2 > >@@ -4717,52 +5271,50 @@ void SobelXRow_SSE2(const uint8* src_y0, > // -1 -2 -1 > // 0 0 0 > // 1 2 1 >-void SobelYRow_SSE2(const uint8* src_y0, >- const uint8* src_y1, >- uint8* dst_sobely, >+void SobelYRow_SSE2(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ uint8_t* dst_sobely, > int width) { >- asm volatile ( >- "sub %0,%1 \n" >- "sub %0,%2 \n" >- "pxor %%xmm5,%%xmm5 \n" >+ asm volatile( >+ "sub %0,%1 \n" >+ "sub %0,%2 \n" >+ "pxor %%xmm5,%%xmm5 \n" > >- // 8 pixel loop. >- LABELALIGN >- "1: \n" >- "movq " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movq,0x00,0,1,1,xmm1) // movq (%0,%1,1),%%xmm1 >- "punpcklbw %%xmm5,%%xmm0 \n" >- "punpcklbw %%xmm5,%%xmm1 \n" >- "psubw %%xmm1,%%xmm0 \n" >- "movq " MEMACCESS2(0x1,0) ",%%xmm1 \n" >- MEMOPREG(movq,0x01,0,1,1,xmm2) // movq 0x1(%0,%1,1),%%xmm2 >- "punpcklbw %%xmm5,%%xmm1 \n" >- "punpcklbw %%xmm5,%%xmm2 \n" >- "psubw %%xmm2,%%xmm1 \n" >- "movq " MEMACCESS2(0x2,0) ",%%xmm2 \n" >- MEMOPREG(movq,0x02,0,1,1,xmm3) // movq 0x2(%0,%1,1),%%xmm3 >- "punpcklbw %%xmm5,%%xmm2 \n" >- "punpcklbw %%xmm5,%%xmm3 \n" >- "psubw %%xmm3,%%xmm2 \n" >- "paddw %%xmm2,%%xmm0 \n" >- "paddw %%xmm1,%%xmm0 \n" >- "paddw %%xmm1,%%xmm0 \n" >- "pxor %%xmm1,%%xmm1 \n" >- "psubw %%xmm0,%%xmm1 \n" >- "pmaxsw %%xmm1,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- MEMOPMEM(movq,xmm0,0x00,0,2,1) // movq %%xmm0,(%0,%2,1) >- "lea " MEMLEA(0x8,0) ",%0 \n" >- "sub $0x8,%3 \n" >- "jg 1b \n" >- : "+r"(src_y0), // %0 >- "+r"(src_y1), // %1 >- "+r"(dst_sobely), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ // 8 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movq (%0),%%xmm0 \n" >+ "movq 0x00(%0,%1,1),%%xmm1 \n" >+ "punpcklbw %%xmm5,%%xmm0 \n" >+ "punpcklbw %%xmm5,%%xmm1 \n" >+ "psubw %%xmm1,%%xmm0 \n" >+ "movq 0x1(%0),%%xmm1 \n" >+ "movq 0x01(%0,%1,1),%%xmm2 \n" >+ "punpcklbw %%xmm5,%%xmm1 \n" >+ "punpcklbw %%xmm5,%%xmm2 \n" >+ "psubw %%xmm2,%%xmm1 \n" >+ "movq 0x2(%0),%%xmm2 \n" >+ "movq 0x02(%0,%1,1),%%xmm3 \n" >+ "punpcklbw %%xmm5,%%xmm2 \n" >+ "punpcklbw %%xmm5,%%xmm3 \n" >+ "psubw %%xmm3,%%xmm2 \n" >+ "paddw %%xmm2,%%xmm0 \n" >+ "paddw %%xmm1,%%xmm0 \n" >+ "paddw %%xmm1,%%xmm0 \n" >+ "pxor %%xmm1,%%xmm1 \n" >+ "psubw %%xmm0,%%xmm1 \n" >+ "pmaxsw %%xmm1,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "movq %%xmm0,0x00(%0,%2,1) \n" >+ "lea 0x8(%0),%0 \n" >+ "sub $0x8,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_y0), // %0 >+ "+r"(src_y1), // %1 >+ "+r"(dst_sobely), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > #endif // HAS_SOBELYROW_SSE2 > >@@ -4772,83 +5324,79 @@ void SobelYRow_SSE2(const uint8* src_y0, > // R = Sobel > // G = Sobel > // B = Sobel >-void SobelRow_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_SSE2(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { >- asm volatile ( >- "sub %0,%1 \n" >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "pslld $0x18,%%xmm5 \n" >+ asm volatile( >+ "sub %0,%1 \n" >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "pslld $0x18,%%xmm5 \n" > >- // 8 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,1,1,xmm1) // movdqu (%0,%1,1),%%xmm1 >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "paddusb %%xmm1,%%xmm0 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "punpcklbw %%xmm0,%%xmm2 \n" >- "punpckhbw %%xmm0,%%xmm0 \n" >- "movdqa %%xmm2,%%xmm1 \n" >- "punpcklwd %%xmm2,%%xmm1 \n" >- "punpckhwd %%xmm2,%%xmm2 \n" >- "por %%xmm5,%%xmm1 \n" >- "por %%xmm5,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm3 \n" >- "punpcklwd %%xmm0,%%xmm3 \n" >- "punpckhwd %%xmm0,%%xmm0 \n" >- "por %%xmm5,%%xmm3 \n" >- "por %%xmm5,%%xmm0 \n" >- "movdqu %%xmm1," MEMACCESS(2) " \n" >- "movdqu %%xmm2," MEMACCESS2(0x10,2) " \n" >- "movdqu %%xmm3," MEMACCESS2(0x20,2) " \n" >- "movdqu %%xmm0," MEMACCESS2(0x30,2) " \n" >- "lea " MEMLEA(0x40,2) ",%2 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_sobelx), // %0 >- "+r"(src_sobely), // %1 >- "+r"(dst_argb), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ // 8 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%1,1),%%xmm1 \n" >+ "lea 0x10(%0),%0 \n" >+ "paddusb %%xmm1,%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "punpcklbw %%xmm0,%%xmm2 \n" >+ "punpckhbw %%xmm0,%%xmm0 \n" >+ "movdqa %%xmm2,%%xmm1 \n" >+ "punpcklwd %%xmm2,%%xmm1 \n" >+ "punpckhwd %%xmm2,%%xmm2 \n" >+ "por %%xmm5,%%xmm1 \n" >+ "por %%xmm5,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm3 \n" >+ "punpcklwd %%xmm0,%%xmm3 \n" >+ "punpckhwd %%xmm0,%%xmm0 \n" >+ "por %%xmm5,%%xmm3 \n" >+ "por %%xmm5,%%xmm0 \n" >+ "movdqu %%xmm1,(%2) \n" >+ "movdqu %%xmm2,0x10(%2) \n" >+ "movdqu %%xmm3,0x20(%2) \n" >+ "movdqu %%xmm0,0x30(%2) \n" >+ "lea 0x40(%2),%2 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_sobelx), // %0 >+ "+r"(src_sobely), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > #endif // HAS_SOBELROW_SSE2 > > #ifdef HAS_SOBELTOPLANEROW_SSE2 > // Adds Sobel X and Sobel Y and stores Sobel into a plane. >-void SobelToPlaneRow_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_SSE2(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_y, > int width) { >- asm volatile ( >- "sub %0,%1 \n" >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "pslld $0x18,%%xmm5 \n" >+ asm volatile( >+ "sub %0,%1 \n" >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "pslld $0x18,%%xmm5 \n" > >- // 8 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,1,1,xmm1) // movdqu (%0,%1,1),%%xmm1 >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "paddusb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_sobelx), // %0 >- "+r"(src_sobely), // %1 >- "+r"(dst_y), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1" >- ); >+ // 8 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%1,1),%%xmm1 \n" >+ "lea 0x10(%0),%0 \n" >+ "paddusb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_sobelx), // %0 >+ "+r"(src_sobely), // %1 >+ "+r"(dst_y), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1"); > } > #endif // HAS_SOBELTOPLANEROW_SSE2 > >@@ -4858,1179 +5406,1123 @@ void SobelToPlaneRow_SSE2(const uint8* src_sobelx, > // R = Sobel X > // G = Sobel > // B = Sobel Y >-void SobelXYRow_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_SSE2(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { >- asm volatile ( >- "sub %0,%1 \n" >- "pcmpeqb %%xmm5,%%xmm5 \n" >+ asm volatile( >+ "sub %0,%1 \n" >+ "pcmpeqb %%xmm5,%%xmm5 \n" > >- // 8 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,1,1,xmm1) // movdqu (%0,%1,1),%%xmm1 >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "paddusb %%xmm1,%%xmm2 \n" >- "movdqa %%xmm0,%%xmm3 \n" >- "punpcklbw %%xmm5,%%xmm3 \n" >- "punpckhbw %%xmm5,%%xmm0 \n" >- "movdqa %%xmm1,%%xmm4 \n" >- "punpcklbw %%xmm2,%%xmm4 \n" >- "punpckhbw %%xmm2,%%xmm1 \n" >- "movdqa %%xmm4,%%xmm6 \n" >- "punpcklwd %%xmm3,%%xmm6 \n" >- "punpckhwd %%xmm3,%%xmm4 \n" >- "movdqa %%xmm1,%%xmm7 \n" >- "punpcklwd %%xmm0,%%xmm7 \n" >- "punpckhwd %%xmm0,%%xmm1 \n" >- "movdqu %%xmm6," MEMACCESS(2) " \n" >- "movdqu %%xmm4," MEMACCESS2(0x10,2) " \n" >- "movdqu %%xmm7," MEMACCESS2(0x20,2) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x30,2) " \n" >- "lea " MEMLEA(0x40,2) ",%2 \n" >- "sub $0x10,%3 \n" >- "jg 1b \n" >- : "+r"(src_sobelx), // %0 >- "+r"(src_sobely), // %1 >- "+r"(dst_argb), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ // 8 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%1,1),%%xmm1 \n" >+ "lea 0x10(%0),%0 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "paddusb %%xmm1,%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm3 \n" >+ "punpcklbw %%xmm5,%%xmm3 \n" >+ "punpckhbw %%xmm5,%%xmm0 \n" >+ "movdqa %%xmm1,%%xmm4 \n" >+ "punpcklbw %%xmm2,%%xmm4 \n" >+ "punpckhbw %%xmm2,%%xmm1 \n" >+ "movdqa %%xmm4,%%xmm6 \n" >+ "punpcklwd %%xmm3,%%xmm6 \n" >+ "punpckhwd %%xmm3,%%xmm4 \n" >+ "movdqa %%xmm1,%%xmm7 \n" >+ "punpcklwd %%xmm0,%%xmm7 \n" >+ "punpckhwd %%xmm0,%%xmm1 \n" >+ "movdqu %%xmm6,(%2) \n" >+ "movdqu %%xmm4,0x10(%2) \n" >+ "movdqu %%xmm7,0x20(%2) \n" >+ "movdqu %%xmm1,0x30(%2) \n" >+ "lea 0x40(%2),%2 \n" >+ "sub $0x10,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_sobelx), // %0 >+ "+r"(src_sobely), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > #endif // HAS_SOBELXYROW_SSE2 > > #ifdef HAS_COMPUTECUMULATIVESUMROW_SSE2 > // Creates a table of cumulative sums where each value is a sum of all values > // above and to the left of the value, inclusive of the value. >-void ComputeCumulativeSumRow_SSE2(const uint8* row, >- int32* cumsum, >- const int32* previous_cumsum, >+void ComputeCumulativeSumRow_SSE2(const uint8_t* row, >+ int32_t* cumsum, >+ const int32_t* previous_cumsum, > int width) { >- asm volatile ( >- "pxor %%xmm0,%%xmm0 \n" >- "pxor %%xmm1,%%xmm1 \n" >- "sub $0x4,%3 \n" >- "jl 49f \n" >- "test $0xf,%1 \n" >- "jne 49f \n" >- >- // 4 pixel loop. >- LABELALIGN >- "40: \n" >- "movdqu " MEMACCESS(0) ",%%xmm2 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqa %%xmm2,%%xmm4 \n" >- "punpcklbw %%xmm1,%%xmm2 \n" >- "movdqa %%xmm2,%%xmm3 \n" >- "punpcklwd %%xmm1,%%xmm2 \n" >- "punpckhwd %%xmm1,%%xmm3 \n" >- "punpckhbw %%xmm1,%%xmm4 \n" >- "movdqa %%xmm4,%%xmm5 \n" >- "punpcklwd %%xmm1,%%xmm4 \n" >- "punpckhwd %%xmm1,%%xmm5 \n" >- "paddd %%xmm2,%%xmm0 \n" >- "movdqu " MEMACCESS(2) ",%%xmm2 \n" >- "paddd %%xmm0,%%xmm2 \n" >- "paddd %%xmm3,%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,2) ",%%xmm3 \n" >- "paddd %%xmm0,%%xmm3 \n" >- "paddd %%xmm4,%%xmm0 \n" >- "movdqu " MEMACCESS2(0x20,2) ",%%xmm4 \n" >- "paddd %%xmm0,%%xmm4 \n" >- "paddd %%xmm5,%%xmm0 \n" >- "movdqu " MEMACCESS2(0x30,2) ",%%xmm5 \n" >- "lea " MEMLEA(0x40,2) ",%2 \n" >- "paddd %%xmm0,%%xmm5 \n" >- "movdqu %%xmm2," MEMACCESS(1) " \n" >- "movdqu %%xmm3," MEMACCESS2(0x10,1) " \n" >- "movdqu %%xmm4," MEMACCESS2(0x20,1) " \n" >- "movdqu %%xmm5," MEMACCESS2(0x30,1) " \n" >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "sub $0x4,%3 \n" >- "jge 40b \n" >- >- "49: \n" >- "add $0x3,%3 \n" >- "jl 19f \n" >- >- // 1 pixel loop. >- LABELALIGN >- "10: \n" >- "movd " MEMACCESS(0) ",%%xmm2 \n" >- "lea " MEMLEA(0x4,0) ",%0 \n" >- "punpcklbw %%xmm1,%%xmm2 \n" >- "punpcklwd %%xmm1,%%xmm2 \n" >- "paddd %%xmm2,%%xmm0 \n" >- "movdqu " MEMACCESS(2) ",%%xmm2 \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "paddd %%xmm0,%%xmm2 \n" >- "movdqu %%xmm2," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x1,%3 \n" >- "jge 10b \n" >- >- "19: \n" >- : "+r"(row), // %0 >- "+r"(cumsum), // %1 >- "+r"(previous_cumsum), // %2 >- "+r"(width) // %3 >- : >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ asm volatile( >+ "pxor %%xmm0,%%xmm0 \n" >+ "pxor %%xmm1,%%xmm1 \n" >+ "sub $0x4,%3 \n" >+ "jl 49f \n" >+ "test $0xf,%1 \n" >+ "jne 49f \n" >+ >+ // 4 pixel loop. >+ LABELALIGN >+ "40: \n" >+ "movdqu (%0),%%xmm2 \n" >+ "lea 0x10(%0),%0 \n" >+ "movdqa %%xmm2,%%xmm4 \n" >+ "punpcklbw %%xmm1,%%xmm2 \n" >+ "movdqa %%xmm2,%%xmm3 \n" >+ "punpcklwd %%xmm1,%%xmm2 \n" >+ "punpckhwd %%xmm1,%%xmm3 \n" >+ "punpckhbw %%xmm1,%%xmm4 \n" >+ "movdqa %%xmm4,%%xmm5 \n" >+ "punpcklwd %%xmm1,%%xmm4 \n" >+ "punpckhwd %%xmm1,%%xmm5 \n" >+ "paddd %%xmm2,%%xmm0 \n" >+ "movdqu (%2),%%xmm2 \n" >+ "paddd %%xmm0,%%xmm2 \n" >+ "paddd %%xmm3,%%xmm0 \n" >+ "movdqu 0x10(%2),%%xmm3 \n" >+ "paddd %%xmm0,%%xmm3 \n" >+ "paddd %%xmm4,%%xmm0 \n" >+ "movdqu 0x20(%2),%%xmm4 \n" >+ "paddd %%xmm0,%%xmm4 \n" >+ "paddd %%xmm5,%%xmm0 \n" >+ "movdqu 0x30(%2),%%xmm5 \n" >+ "lea 0x40(%2),%2 \n" >+ "paddd %%xmm0,%%xmm5 \n" >+ "movdqu %%xmm2,(%1) \n" >+ "movdqu %%xmm3,0x10(%1) \n" >+ "movdqu %%xmm4,0x20(%1) \n" >+ "movdqu %%xmm5,0x30(%1) \n" >+ "lea 0x40(%1),%1 \n" >+ "sub $0x4,%3 \n" >+ "jge 40b \n" >+ >+ "49: \n" >+ "add $0x3,%3 \n" >+ "jl 19f \n" >+ >+ // 1 pixel loop. >+ LABELALIGN >+ "10: \n" >+ "movd (%0),%%xmm2 \n" >+ "lea 0x4(%0),%0 \n" >+ "punpcklbw %%xmm1,%%xmm2 \n" >+ "punpcklwd %%xmm1,%%xmm2 \n" >+ "paddd %%xmm2,%%xmm0 \n" >+ "movdqu (%2),%%xmm2 \n" >+ "lea 0x10(%2),%2 \n" >+ "paddd %%xmm0,%%xmm2 \n" >+ "movdqu %%xmm2,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x1,%3 \n" >+ "jge 10b \n" >+ >+ "19: \n" >+ : "+r"(row), // %0 >+ "+r"(cumsum), // %1 >+ "+r"(previous_cumsum), // %2 >+ "+r"(width) // %3 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_COMPUTECUMULATIVESUMROW_SSE2 > > #ifdef HAS_CUMULATIVESUMTOAVERAGEROW_SSE2 >-void CumulativeSumToAverageRow_SSE2(const int32* topleft, >- const int32* botleft, >+void CumulativeSumToAverageRow_SSE2(const int32_t* topleft, >+ const int32_t* botleft, > int width, > int area, >- uint8* dst, >+ uint8_t* dst, > int count) { >- asm volatile ( >- "movd %5,%%xmm5 \n" >- "cvtdq2ps %%xmm5,%%xmm5 \n" >- "rcpss %%xmm5,%%xmm4 \n" >- "pshufd $0x0,%%xmm4,%%xmm4 \n" >- "sub $0x4,%3 \n" >- "jl 49f \n" >- "cmpl $0x80,%5 \n" >- "ja 40f \n" >- >- "pshufd $0x0,%%xmm5,%%xmm5 \n" >- "pcmpeqb %%xmm6,%%xmm6 \n" >- "psrld $0x10,%%xmm6 \n" >- "cvtdq2ps %%xmm6,%%xmm6 \n" >- "addps %%xmm6,%%xmm5 \n" >- "mulps %%xmm4,%%xmm5 \n" >- "cvtps2dq %%xmm5,%%xmm5 \n" >- "packssdw %%xmm5,%%xmm5 \n" >- >- // 4 pixel small loop. >- LABELALIGN >- "4: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm3 \n" >- MEMOPREG(psubd,0x00,0,4,4,xmm0) // psubd 0x00(%0,%4,4),%%xmm0 >- MEMOPREG(psubd,0x10,0,4,4,xmm1) // psubd 0x10(%0,%4,4),%%xmm1 >- MEMOPREG(psubd,0x20,0,4,4,xmm2) // psubd 0x20(%0,%4,4),%%xmm2 >- MEMOPREG(psubd,0x30,0,4,4,xmm3) // psubd 0x30(%0,%4,4),%%xmm3 >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "psubd " MEMACCESS(1) ",%%xmm0 \n" >- "psubd " MEMACCESS2(0x10,1) ",%%xmm1 \n" >- "psubd " MEMACCESS2(0x20,1) ",%%xmm2 \n" >- "psubd " MEMACCESS2(0x30,1) ",%%xmm3 \n" >- MEMOPREG(paddd,0x00,1,4,4,xmm0) // paddd 0x00(%1,%4,4),%%xmm0 >- MEMOPREG(paddd,0x10,1,4,4,xmm1) // paddd 0x10(%1,%4,4),%%xmm1 >- MEMOPREG(paddd,0x20,1,4,4,xmm2) // paddd 0x20(%1,%4,4),%%xmm2 >- MEMOPREG(paddd,0x30,1,4,4,xmm3) // paddd 0x30(%1,%4,4),%%xmm3 >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "packssdw %%xmm1,%%xmm0 \n" >- "packssdw %%xmm3,%%xmm2 \n" >- "pmulhuw %%xmm5,%%xmm0 \n" >- "pmulhuw %%xmm5,%%xmm2 \n" >- "packuswb %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x4,%3 \n" >- "jge 4b \n" >- "jmp 49f \n" >- >- // 4 pixel loop \n" >- LABELALIGN >- "40: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "movdqu " MEMACCESS2(0x20,0) ",%%xmm2 \n" >- "movdqu " MEMACCESS2(0x30,0) ",%%xmm3 \n" >- MEMOPREG(psubd,0x00,0,4,4,xmm0) // psubd 0x00(%0,%4,4),%%xmm0 >- MEMOPREG(psubd,0x10,0,4,4,xmm1) // psubd 0x10(%0,%4,4),%%xmm1 >- MEMOPREG(psubd,0x20,0,4,4,xmm2) // psubd 0x20(%0,%4,4),%%xmm2 >- MEMOPREG(psubd,0x30,0,4,4,xmm3) // psubd 0x30(%0,%4,4),%%xmm3 >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "psubd " MEMACCESS(1) ",%%xmm0 \n" >- "psubd " MEMACCESS2(0x10,1) ",%%xmm1 \n" >- "psubd " MEMACCESS2(0x20,1) ",%%xmm2 \n" >- "psubd " MEMACCESS2(0x30,1) ",%%xmm3 \n" >- MEMOPREG(paddd,0x00,1,4,4,xmm0) // paddd 0x00(%1,%4,4),%%xmm0 >- MEMOPREG(paddd,0x10,1,4,4,xmm1) // paddd 0x10(%1,%4,4),%%xmm1 >- MEMOPREG(paddd,0x20,1,4,4,xmm2) // paddd 0x20(%1,%4,4),%%xmm2 >- MEMOPREG(paddd,0x30,1,4,4,xmm3) // paddd 0x30(%1,%4,4),%%xmm3 >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "cvtdq2ps %%xmm0,%%xmm0 \n" >- "cvtdq2ps %%xmm1,%%xmm1 \n" >- "mulps %%xmm4,%%xmm0 \n" >- "mulps %%xmm4,%%xmm1 \n" >- "cvtdq2ps %%xmm2,%%xmm2 \n" >- "cvtdq2ps %%xmm3,%%xmm3 \n" >- "mulps %%xmm4,%%xmm2 \n" >- "mulps %%xmm4,%%xmm3 \n" >- "cvtps2dq %%xmm0,%%xmm0 \n" >- "cvtps2dq %%xmm1,%%xmm1 \n" >- "cvtps2dq %%xmm2,%%xmm2 \n" >- "cvtps2dq %%xmm3,%%xmm3 \n" >- "packssdw %%xmm1,%%xmm0 \n" >- "packssdw %%xmm3,%%xmm2 \n" >- "packuswb %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x4,%3 \n" >- "jge 40b \n" >- >- "49: \n" >- "add $0x3,%3 \n" >- "jl 19f \n" >- >- // 1 pixel loop \n" >- LABELALIGN >- "10: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(psubd,0x00,0,4,4,xmm0) // psubd 0x00(%0,%4,4),%%xmm0 >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "psubd " MEMACCESS(1) ",%%xmm0 \n" >- MEMOPREG(paddd,0x00,1,4,4,xmm0) // paddd 0x00(%1,%4,4),%%xmm0 >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "cvtdq2ps %%xmm0,%%xmm0 \n" >- "mulps %%xmm4,%%xmm0 \n" >- "cvtps2dq %%xmm0,%%xmm0 \n" >- "packssdw %%xmm0,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "movd %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x4,2) ",%2 \n" >- "sub $0x1,%3 \n" >- "jge 10b \n" >- "19: \n" >- : "+r"(topleft), // %0 >- "+r"(botleft), // %1 >- "+r"(dst), // %2 >- "+rm"(count) // %3 >- : "r"((intptr_t)(width)), // %4 >- "rm"(area) // %5 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" >- ); >+ asm volatile( >+ "movd %5,%%xmm5 \n" >+ "cvtdq2ps %%xmm5,%%xmm5 \n" >+ "rcpss %%xmm5,%%xmm4 \n" >+ "pshufd $0x0,%%xmm4,%%xmm4 \n" >+ "sub $0x4,%3 \n" >+ "jl 49f \n" >+ "cmpl $0x80,%5 \n" >+ "ja 40f \n" >+ >+ "pshufd $0x0,%%xmm5,%%xmm5 \n" >+ "pcmpeqb %%xmm6,%%xmm6 \n" >+ "psrld $0x10,%%xmm6 \n" >+ "cvtdq2ps %%xmm6,%%xmm6 \n" >+ "addps %%xmm6,%%xmm5 \n" >+ "mulps %%xmm4,%%xmm5 \n" >+ "cvtps2dq %%xmm5,%%xmm5 \n" >+ "packssdw %%xmm5,%%xmm5 \n" >+ >+ // 4 pixel small loop. >+ LABELALIGN >+ "4: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm3 \n" >+ "psubd 0x00(%0,%4,4),%%xmm0 \n" >+ "psubd 0x10(%0,%4,4),%%xmm1 \n" >+ "psubd 0x20(%0,%4,4),%%xmm2 \n" >+ "psubd 0x30(%0,%4,4),%%xmm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "psubd (%1),%%xmm0 \n" >+ "psubd 0x10(%1),%%xmm1 \n" >+ "psubd 0x20(%1),%%xmm2 \n" >+ "psubd 0x30(%1),%%xmm3 \n" >+ "paddd 0x00(%1,%4,4),%%xmm0 \n" >+ "paddd 0x10(%1,%4,4),%%xmm1 \n" >+ "paddd 0x20(%1,%4,4),%%xmm2 \n" >+ "paddd 0x30(%1,%4,4),%%xmm3 \n" >+ "lea 0x40(%1),%1 \n" >+ "packssdw %%xmm1,%%xmm0 \n" >+ "packssdw %%xmm3,%%xmm2 \n" >+ "pmulhuw %%xmm5,%%xmm0 \n" >+ "pmulhuw %%xmm5,%%xmm2 \n" >+ "packuswb %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x4,%3 \n" >+ "jge 4b \n" >+ "jmp 49f \n" >+ >+ // 4 pixel loop >+ LABELALIGN >+ "40: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x20(%0),%%xmm2 \n" >+ "movdqu 0x30(%0),%%xmm3 \n" >+ "psubd 0x00(%0,%4,4),%%xmm0 \n" >+ "psubd 0x10(%0,%4,4),%%xmm1 \n" >+ "psubd 0x20(%0,%4,4),%%xmm2 \n" >+ "psubd 0x30(%0,%4,4),%%xmm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "psubd (%1),%%xmm0 \n" >+ "psubd 0x10(%1),%%xmm1 \n" >+ "psubd 0x20(%1),%%xmm2 \n" >+ "psubd 0x30(%1),%%xmm3 \n" >+ "paddd 0x00(%1,%4,4),%%xmm0 \n" >+ "paddd 0x10(%1,%4,4),%%xmm1 \n" >+ "paddd 0x20(%1,%4,4),%%xmm2 \n" >+ "paddd 0x30(%1,%4,4),%%xmm3 \n" >+ "lea 0x40(%1),%1 \n" >+ "cvtdq2ps %%xmm0,%%xmm0 \n" >+ "cvtdq2ps %%xmm1,%%xmm1 \n" >+ "mulps %%xmm4,%%xmm0 \n" >+ "mulps %%xmm4,%%xmm1 \n" >+ "cvtdq2ps %%xmm2,%%xmm2 \n" >+ "cvtdq2ps %%xmm3,%%xmm3 \n" >+ "mulps %%xmm4,%%xmm2 \n" >+ "mulps %%xmm4,%%xmm3 \n" >+ "cvtps2dq %%xmm0,%%xmm0 \n" >+ "cvtps2dq %%xmm1,%%xmm1 \n" >+ "cvtps2dq %%xmm2,%%xmm2 \n" >+ "cvtps2dq %%xmm3,%%xmm3 \n" >+ "packssdw %%xmm1,%%xmm0 \n" >+ "packssdw %%xmm3,%%xmm2 \n" >+ "packuswb %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x4,%3 \n" >+ "jge 40b \n" >+ >+ "49: \n" >+ "add $0x3,%3 \n" >+ "jl 19f \n" >+ >+ // 1 pixel loop >+ LABELALIGN >+ "10: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "psubd 0x00(%0,%4,4),%%xmm0 \n" >+ "lea 0x10(%0),%0 \n" >+ "psubd (%1),%%xmm0 \n" >+ "paddd 0x00(%1,%4,4),%%xmm0 \n" >+ "lea 0x10(%1),%1 \n" >+ "cvtdq2ps %%xmm0,%%xmm0 \n" >+ "mulps %%xmm4,%%xmm0 \n" >+ "cvtps2dq %%xmm0,%%xmm0 \n" >+ "packssdw %%xmm0,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "movd %%xmm0,(%2) \n" >+ "lea 0x4(%2),%2 \n" >+ "sub $0x1,%3 \n" >+ "jge 10b \n" >+ "19: \n" >+ : "+r"(topleft), // %0 >+ "+r"(botleft), // %1 >+ "+r"(dst), // %2 >+ "+rm"(count) // %3 >+ : "r"((intptr_t)(width)), // %4 >+ "rm"(area) // %5 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); > } > #endif // HAS_CUMULATIVESUMTOAVERAGEROW_SSE2 > > #ifdef HAS_ARGBAFFINEROW_SSE2 > // Copy ARGB pixels from source image with slope to a row of destination. > LIBYUV_API >-void ARGBAffineRow_SSE2(const uint8* src_argb, >+void ARGBAffineRow_SSE2(const uint8_t* src_argb, > int src_argb_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > const float* src_dudv, > int width) { > intptr_t src_argb_stride_temp = src_argb_stride; > intptr_t temp; >- asm volatile ( >- "movq " MEMACCESS(3) ",%%xmm2 \n" >- "movq " MEMACCESS2(0x08,3) ",%%xmm7 \n" >- "shl $0x10,%1 \n" >- "add $0x4,%1 \n" >- "movd %1,%%xmm5 \n" >- "sub $0x4,%4 \n" >- "jl 49f \n" >- >- "pshufd $0x44,%%xmm7,%%xmm7 \n" >- "pshufd $0x0,%%xmm5,%%xmm5 \n" >- "movdqa %%xmm2,%%xmm0 \n" >- "addps %%xmm7,%%xmm0 \n" >- "movlhps %%xmm0,%%xmm2 \n" >- "movdqa %%xmm7,%%xmm4 \n" >- "addps %%xmm4,%%xmm4 \n" >- "movdqa %%xmm2,%%xmm3 \n" >- "addps %%xmm4,%%xmm3 \n" >- "addps %%xmm4,%%xmm4 \n" >- >- // 4 pixel loop \n" >- LABELALIGN >- "40: \n" >- "cvttps2dq %%xmm2,%%xmm0 \n" // x, y float to int first 2 >- "cvttps2dq %%xmm3,%%xmm1 \n" // x, y float to int next 2 >- "packssdw %%xmm1,%%xmm0 \n" // x, y as 8 shorts >- "pmaddwd %%xmm5,%%xmm0 \n" // off = x * 4 + y * stride >- "movd %%xmm0,%k1 \n" >- "pshufd $0x39,%%xmm0,%%xmm0 \n" >- "movd %%xmm0,%k5 \n" >- "pshufd $0x39,%%xmm0,%%xmm0 \n" >- MEMOPREG(movd,0x00,0,1,1,xmm1) // movd (%0,%1,1),%%xmm1 >- MEMOPREG(movd,0x00,0,5,1,xmm6) // movd (%0,%5,1),%%xmm6 >- "punpckldq %%xmm6,%%xmm1 \n" >- "addps %%xmm4,%%xmm2 \n" >- "movq %%xmm1," MEMACCESS(2) " \n" >- "movd %%xmm0,%k1 \n" >- "pshufd $0x39,%%xmm0,%%xmm0 \n" >- "movd %%xmm0,%k5 \n" >- MEMOPREG(movd,0x00,0,1,1,xmm0) // movd (%0,%1,1),%%xmm0 >- MEMOPREG(movd,0x00,0,5,1,xmm6) // movd (%0,%5,1),%%xmm6 >- "punpckldq %%xmm6,%%xmm0 \n" >- "addps %%xmm4,%%xmm3 \n" >- "movq %%xmm0," MEMACCESS2(0x08,2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x4,%4 \n" >- "jge 40b \n" >- >- "49: \n" >- "add $0x3,%4 \n" >- "jl 19f \n" >- >- // 1 pixel loop \n" >- LABELALIGN >- "10: \n" >- "cvttps2dq %%xmm2,%%xmm0 \n" >- "packssdw %%xmm0,%%xmm0 \n" >- "pmaddwd %%xmm5,%%xmm0 \n" >- "addps %%xmm7,%%xmm2 \n" >- "movd %%xmm0,%k1 \n" >- MEMOPREG(movd,0x00,0,1,1,xmm0) // movd (%0,%1,1),%%xmm0 >- "movd %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x04,2) ",%2 \n" >- "sub $0x1,%4 \n" >- "jge 10b \n" >- "19: \n" >- : "+r"(src_argb), // %0 >- "+r"(src_argb_stride_temp), // %1 >- "+r"(dst_argb), // %2 >- "+r"(src_dudv), // %3 >- "+rm"(width), // %4 >- "=&r"(temp) // %5 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ asm volatile( >+ "movq (%3),%%xmm2 \n" >+ "movq 0x08(%3),%%xmm7 \n" >+ "shl $0x10,%1 \n" >+ "add $0x4,%1 \n" >+ "movd %1,%%xmm5 \n" >+ "sub $0x4,%4 \n" >+ "jl 49f \n" >+ >+ "pshufd $0x44,%%xmm7,%%xmm7 \n" >+ "pshufd $0x0,%%xmm5,%%xmm5 \n" >+ "movdqa %%xmm2,%%xmm0 \n" >+ "addps %%xmm7,%%xmm0 \n" >+ "movlhps %%xmm0,%%xmm2 \n" >+ "movdqa %%xmm7,%%xmm4 \n" >+ "addps %%xmm4,%%xmm4 \n" >+ "movdqa %%xmm2,%%xmm3 \n" >+ "addps %%xmm4,%%xmm3 \n" >+ "addps %%xmm4,%%xmm4 \n" >+ >+ // 4 pixel loop >+ LABELALIGN >+ "40: \n" >+ "cvttps2dq %%xmm2,%%xmm0 \n" // x,y float->int first 2 >+ "cvttps2dq %%xmm3,%%xmm1 \n" // x,y float->int next 2 >+ "packssdw %%xmm1,%%xmm0 \n" // x, y as 8 shorts >+ "pmaddwd %%xmm5,%%xmm0 \n" // off = x*4 + y*stride >+ "movd %%xmm0,%k1 \n" >+ "pshufd $0x39,%%xmm0,%%xmm0 \n" >+ "movd %%xmm0,%k5 \n" >+ "pshufd $0x39,%%xmm0,%%xmm0 \n" >+ "movd 0x00(%0,%1,1),%%xmm1 \n" >+ "movd 0x00(%0,%5,1),%%xmm6 \n" >+ "punpckldq %%xmm6,%%xmm1 \n" >+ "addps %%xmm4,%%xmm2 \n" >+ "movq %%xmm1,(%2) \n" >+ "movd %%xmm0,%k1 \n" >+ "pshufd $0x39,%%xmm0,%%xmm0 \n" >+ "movd %%xmm0,%k5 \n" >+ "movd 0x00(%0,%1,1),%%xmm0 \n" >+ "movd 0x00(%0,%5,1),%%xmm6 \n" >+ "punpckldq %%xmm6,%%xmm0 \n" >+ "addps %%xmm4,%%xmm3 \n" >+ "movq %%xmm0,0x08(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x4,%4 \n" >+ "jge 40b \n" >+ >+ "49: \n" >+ "add $0x3,%4 \n" >+ "jl 19f \n" >+ >+ // 1 pixel loop >+ LABELALIGN >+ "10: \n" >+ "cvttps2dq %%xmm2,%%xmm0 \n" >+ "packssdw %%xmm0,%%xmm0 \n" >+ "pmaddwd %%xmm5,%%xmm0 \n" >+ "addps %%xmm7,%%xmm2 \n" >+ "movd %%xmm0,%k1 \n" >+ "movd 0x00(%0,%1,1),%%xmm0 \n" >+ "movd %%xmm0,(%2) \n" >+ "lea 0x04(%2),%2 \n" >+ "sub $0x1,%4 \n" >+ "jge 10b \n" >+ "19: \n" >+ : "+r"(src_argb), // %0 >+ "+r"(src_argb_stride_temp), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(src_dudv), // %3 >+ "+rm"(width), // %4 >+ "=&r"(temp) // %5 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > #endif // HAS_ARGBAFFINEROW_SSE2 > > #ifdef HAS_INTERPOLATEROW_SSSE3 > // Bilinear filter 16x2 -> 16x1 >-void InterpolateRow_SSSE3(uint8* dst_ptr, >- const uint8* src_ptr, >+void InterpolateRow_SSSE3(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride, > int dst_width, > int source_y_fraction) { >- asm volatile ( >- "sub %1,%0 \n" >- "cmp $0x0,%3 \n" >- "je 100f \n" >- "cmp $0x80,%3 \n" >- "je 50f \n" >- >- "movd %3,%%xmm0 \n" >- "neg %3 \n" >- "add $0x100,%3 \n" >- "movd %3,%%xmm5 \n" >- "punpcklbw %%xmm0,%%xmm5 \n" >- "punpcklwd %%xmm5,%%xmm5 \n" >- "pshufd $0x0,%%xmm5,%%xmm5 \n" >- "mov $0x80808080,%%eax \n" >- "movd %%eax,%%xmm4 \n" >- "pshufd $0x0,%%xmm4,%%xmm4 \n" >- >- // General purpose row blend. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(1) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,1,4,1,xmm2) >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklbw %%xmm2,%%xmm0 \n" >- "punpckhbw %%xmm2,%%xmm1 \n" >- "psubb %%xmm4,%%xmm0 \n" >- "psubb %%xmm4,%%xmm1 \n" >- "movdqa %%xmm5,%%xmm2 \n" >- "movdqa %%xmm5,%%xmm3 \n" >- "pmaddubsw %%xmm0,%%xmm2 \n" >- "pmaddubsw %%xmm1,%%xmm3 \n" >- "paddw %%xmm4,%%xmm2 \n" >- "paddw %%xmm4,%%xmm3 \n" >- "psrlw $0x8,%%xmm2 \n" >- "psrlw $0x8,%%xmm3 \n" >- "packuswb %%xmm3,%%xmm2 \n" >- MEMOPMEM(movdqu,xmm2,0x00,1,0,1) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- "jmp 99f \n" >+ asm volatile( >+ "sub %1,%0 \n" >+ "cmp $0x0,%3 \n" >+ "je 100f \n" >+ "cmp $0x80,%3 \n" >+ "je 50f \n" >+ >+ "movd %3,%%xmm0 \n" >+ "neg %3 \n" >+ "add $0x100,%3 \n" >+ "movd %3,%%xmm5 \n" >+ "punpcklbw %%xmm0,%%xmm5 \n" >+ "punpcklwd %%xmm5,%%xmm5 \n" >+ "pshufd $0x0,%%xmm5,%%xmm5 \n" >+ "mov $0x80808080,%%eax \n" >+ "movd %%eax,%%xmm4 \n" >+ "pshufd $0x0,%%xmm4,%%xmm4 \n" >+ >+ // General purpose row blend. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%1),%%xmm0 \n" >+ "movdqu 0x00(%1,%4,1),%%xmm2 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpcklbw %%xmm2,%%xmm0 \n" >+ "punpckhbw %%xmm2,%%xmm1 \n" >+ "psubb %%xmm4,%%xmm0 \n" >+ "psubb %%xmm4,%%xmm1 \n" >+ "movdqa %%xmm5,%%xmm2 \n" >+ "movdqa %%xmm5,%%xmm3 \n" >+ "pmaddubsw %%xmm0,%%xmm2 \n" >+ "pmaddubsw %%xmm1,%%xmm3 \n" >+ "paddw %%xmm4,%%xmm2 \n" >+ "paddw %%xmm4,%%xmm3 \n" >+ "psrlw $0x8,%%xmm2 \n" >+ "psrlw $0x8,%%xmm3 \n" >+ "packuswb %%xmm3,%%xmm2 \n" >+ "movdqu %%xmm2,0x00(%1,%0,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ "jmp 99f \n" > >- // Blend 50 / 50. >- LABELALIGN >- "50: \n" >- "movdqu " MEMACCESS(1) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,1,4,1,xmm1) >- "pavgb %%xmm1,%%xmm0 \n" >- MEMOPMEM(movdqu,xmm0,0x00,1,0,1) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 50b \n" >- "jmp 99f \n" >- >- // Blend 100 / 0 - Copy row unchanged. >- LABELALIGN >- "100: \n" >- "movdqu " MEMACCESS(1) ",%%xmm0 \n" >- MEMOPMEM(movdqu,xmm0,0x00,1,0,1) >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 100b \n" >- >- "99: \n" >- : "+r"(dst_ptr), // %0 >- "+r"(src_ptr), // %1 >- "+rm"(dst_width), // %2 >- "+r"(source_y_fraction) // %3 >- : "r"((intptr_t)(src_stride)) // %4 >- : "memory", "cc", "eax", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ // Blend 50 / 50. >+ LABELALIGN >+ "50: \n" >+ "movdqu (%1),%%xmm0 \n" >+ "movdqu 0x00(%1,%4,1),%%xmm1 \n" >+ "pavgb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,0x00(%1,%0,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 50b \n" >+ "jmp 99f \n" >+ >+ // Blend 100 / 0 - Copy row unchanged. >+ LABELALIGN >+ "100: \n" >+ "movdqu (%1),%%xmm0 \n" >+ "movdqu %%xmm0,0x00(%1,%0,1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 100b \n" >+ >+ "99: \n" >+ : "+r"(dst_ptr), // %0 >+ "+r"(src_ptr), // %1 >+ "+rm"(dst_width), // %2 >+ "+r"(source_y_fraction) // %3 >+ : "r"((intptr_t)(src_stride)) // %4 >+ : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_INTERPOLATEROW_SSSE3 > > #ifdef HAS_INTERPOLATEROW_AVX2 > // Bilinear filter 32x2 -> 32x1 >-void InterpolateRow_AVX2(uint8* dst_ptr, >- const uint8* src_ptr, >+void InterpolateRow_AVX2(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride, > int dst_width, > int source_y_fraction) { >- asm volatile ( >- "cmp $0x0,%3 \n" >- "je 100f \n" >- "sub %1,%0 \n" >- "cmp $0x80,%3 \n" >- "je 50f \n" >- >- "vmovd %3,%%xmm0 \n" >- "neg %3 \n" >- "add $0x100,%3 \n" >- "vmovd %3,%%xmm5 \n" >- "vpunpcklbw %%xmm0,%%xmm5,%%xmm5 \n" >- "vpunpcklwd %%xmm5,%%xmm5,%%xmm5 \n" >- "vbroadcastss %%xmm5,%%ymm5 \n" >- "mov $0x80808080,%%eax \n" >- "vmovd %%eax,%%xmm4 \n" >- "vbroadcastss %%xmm4,%%ymm4 \n" >- >- // General purpose row blend. >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(1) ",%%ymm0 \n" >- MEMOPREG(vmovdqu,0x00,1,4,1,ymm2) >- "vpunpckhbw %%ymm2,%%ymm0,%%ymm1 \n" >- "vpunpcklbw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpsubb %%ymm4,%%ymm1,%%ymm1 \n" >- "vpsubb %%ymm4,%%ymm0,%%ymm0 \n" >- "vpmaddubsw %%ymm1,%%ymm5,%%ymm1 \n" >- "vpmaddubsw %%ymm0,%%ymm5,%%ymm0 \n" >- "vpaddw %%ymm4,%%ymm1,%%ymm1 \n" >- "vpaddw %%ymm4,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- MEMOPMEM(vmovdqu,ymm0,0x00,1,0,1) >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- "jmp 99f \n" >+ asm volatile( >+ "cmp $0x0,%3 \n" >+ "je 100f \n" >+ "sub %1,%0 \n" >+ "cmp $0x80,%3 \n" >+ "je 50f \n" >+ >+ "vmovd %3,%%xmm0 \n" >+ "neg %3 \n" >+ "add $0x100,%3 \n" >+ "vmovd %3,%%xmm5 \n" >+ "vpunpcklbw %%xmm0,%%xmm5,%%xmm5 \n" >+ "vpunpcklwd %%xmm5,%%xmm5,%%xmm5 \n" >+ "vbroadcastss %%xmm5,%%ymm5 \n" >+ "mov $0x80808080,%%eax \n" >+ "vmovd %%eax,%%xmm4 \n" >+ "vbroadcastss %%xmm4,%%ymm4 \n" > >- // Blend 50 / 50. >- LABELALIGN >- "50: \n" >- "vmovdqu " MEMACCESS(1) ",%%ymm0 \n" >- VMEMOPREG(vpavgb,0x00,1,4,1,ymm0,ymm0) // vpavgb (%1,%4,1),%%ymm0,%%ymm0 >- MEMOPMEM(vmovdqu,ymm0,0x00,1,0,1) >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 50b \n" >- "jmp 99f \n" >+ // General purpose row blend. >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%1),%%ymm0 \n" >+ "vmovdqu 0x00(%1,%4,1),%%ymm2 \n" >+ "vpunpckhbw %%ymm2,%%ymm0,%%ymm1 \n" >+ "vpunpcklbw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpsubb %%ymm4,%%ymm1,%%ymm1 \n" >+ "vpsubb %%ymm4,%%ymm0,%%ymm0 \n" >+ "vpmaddubsw %%ymm1,%%ymm5,%%ymm1 \n" >+ "vpmaddubsw %%ymm0,%%ymm5,%%ymm0 \n" >+ "vpaddw %%ymm4,%%ymm1,%%ymm1 \n" >+ "vpaddw %%ymm4,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,0x00(%1,%0,1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "jmp 99f \n" > >- // Blend 100 / 0 - Copy row unchanged. >- LABELALIGN >- "100: \n" >- "rep movsb " MEMMOVESTRING(1,0) " \n" >- "jmp 999f \n" >+ // Blend 50 / 50. >+ LABELALIGN >+ "50: \n" >+ "vmovdqu (%1),%%ymm0 \n" >+ "vpavgb 0x00(%1,%4,1),%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,0x00(%1,%0,1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 50b \n" >+ "jmp 99f \n" >+ >+ // Blend 100 / 0 - Copy row unchanged. >+ LABELALIGN >+ "100: \n" >+ "rep movsb \n" >+ "jmp 999f \n" > >- "99: \n" >- "vzeroupper \n" >- "999: \n" >- : "+D"(dst_ptr), // %0 >- "+S"(src_ptr), // %1 >- "+cm"(dst_width), // %2 >- "+r"(source_y_fraction) // %3 >- : "r"((intptr_t)(src_stride)) // %4 >- : "memory", "cc", "eax", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm4", "xmm5" >- ); >+ "99: \n" >+ "vzeroupper \n" >+ "999: \n" >+ : "+D"(dst_ptr), // %0 >+ "+S"(src_ptr), // %1 >+ "+cm"(dst_width), // %2 >+ "+r"(source_y_fraction) // %3 >+ : "r"((intptr_t)(src_stride)) // %4 >+ : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm4", "xmm5"); > } > #endif // HAS_INTERPOLATEROW_AVX2 > > #ifdef HAS_ARGBSHUFFLEROW_SSSE3 > // For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. >-void ARGBShuffleRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width) { >- asm volatile ( >- "movdqu " MEMACCESS(3) ",%%xmm5 \n" >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pshufb %%xmm5,%%xmm0 \n" >- "pshufb %%xmm5,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "r"(shuffler) // %3 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm5" >- ); >+ asm volatile( >+ >+ "movdqu (%3),%%xmm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "pshufb %%xmm5,%%xmm0 \n" >+ "pshufb %%xmm5,%%xmm1 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "r"(shuffler) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } > #endif // HAS_ARGBSHUFFLEROW_SSSE3 > > #ifdef HAS_ARGBSHUFFLEROW_AVX2 > // For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. >-void ARGBShuffleRow_AVX2(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width) { >- asm volatile ( >- "vbroadcastf128 " MEMACCESS(3) ",%%ymm5 \n" >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" >- "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "vmovdqu %%ymm1," MEMACCESS2(0x20,1) " \n" >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "r"(shuffler) // %3 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm5" >- ); >+ asm volatile( >+ >+ "vbroadcastf128 (%3),%%ymm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "vmovdqu %%ymm1,0x20(%1) \n" >+ "lea 0x40(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "r"(shuffler) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm5"); > } > #endif // HAS_ARGBSHUFFLEROW_AVX2 > >-#ifdef HAS_ARGBSHUFFLEROW_SSE2 >-// For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. >-void ARGBShuffleRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >- int width) { >- uintptr_t pixel_temp; >- asm volatile ( >- "pxor %%xmm5,%%xmm5 \n" >- "mov " MEMACCESS(4) ",%k2 \n" >- "cmp $0x3000102,%k2 \n" >- "je 3012f \n" >- "cmp $0x10203,%k2 \n" >- "je 123f \n" >- "cmp $0x30201,%k2 \n" >- "je 321f \n" >- "cmp $0x2010003,%k2 \n" >- "je 2103f \n" >+#ifdef HAS_I422TOYUY2ROW_SSE2 >+void I422ToYUY2Row_SSE2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_yuy2, >+ int width) { >+ asm volatile( > >- LABELALIGN >- "1: \n" >- "movzb " MEMACCESS(4) ",%2 \n" >- MEMOPARG(movzb,0x00,0,2,1,2) " \n" // movzb (%0,%2,1),%2 >- "mov %b2," MEMACCESS(1) " \n" >- "movzb " MEMACCESS2(0x1,4) ",%2 \n" >- MEMOPARG(movzb,0x00,0,2,1,2) " \n" // movzb (%0,%2,1),%2 >- "mov %b2," MEMACCESS2(0x1,1) " \n" >- "movzb " MEMACCESS2(0x2,4) ",%2 \n" >- MEMOPARG(movzb,0x00,0,2,1,2) " \n" // movzb (%0,%2,1),%2 >- "mov %b2," MEMACCESS2(0x2,1) " \n" >- "movzb " MEMACCESS2(0x3,4) ",%2 \n" >- MEMOPARG(movzb,0x00,0,2,1,2) " \n" // movzb (%0,%2,1),%2 >- "mov %b2," MEMACCESS2(0x3,1) " \n" >- "lea " MEMLEA(0x4,0) ",%0 \n" >- "lea " MEMLEA(0x4,1) ",%1 \n" >- "sub $0x1,%3 \n" >- "jg 1b \n" >- "jmp 99f \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "123: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklbw %%xmm5,%%xmm0 \n" >- "punpckhbw %%xmm5,%%xmm1 \n" >- "pshufhw $0x1b,%%xmm0,%%xmm0 \n" >- "pshuflw $0x1b,%%xmm0,%%xmm0 \n" >- "pshufhw $0x1b,%%xmm1,%%xmm1 \n" >- "pshuflw $0x1b,%%xmm1,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%3 \n" >- "jg 123b \n" >- "jmp 99f \n" >+ LABELALIGN >+ "1: \n" >+ "movq (%1),%%xmm2 \n" >+ "movq 0x00(%1,%2,1),%%xmm1 \n" >+ "add $0x8,%1 \n" >+ "punpcklbw %%xmm1,%%xmm2 \n" >+ "movdqu (%0),%%xmm0 \n" >+ "add $0x10,%0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpcklbw %%xmm2,%%xmm0 \n" >+ "punpckhbw %%xmm2,%%xmm1 \n" >+ "movdqu %%xmm0,(%3) \n" >+ "movdqu %%xmm1,0x10(%3) \n" >+ "lea 0x20(%3),%3 \n" >+ "sub $0x10,%4 \n" >+ "jg 1b \n" >+ : "+r"(src_y), // %0 >+ "+r"(src_u), // %1 >+ "+r"(src_v), // %2 >+ "+r"(dst_yuy2), // %3 >+ "+rm"(width) // %4 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); >+} >+#endif // HAS_I422TOYUY2ROW_SSE2 > >- LABELALIGN >- "321: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklbw %%xmm5,%%xmm0 \n" >- "punpckhbw %%xmm5,%%xmm1 \n" >- "pshufhw $0x39,%%xmm0,%%xmm0 \n" >- "pshuflw $0x39,%%xmm0,%%xmm0 \n" >- "pshufhw $0x39,%%xmm1,%%xmm1 \n" >- "pshuflw $0x39,%%xmm1,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%3 \n" >- "jg 321b \n" >- "jmp 99f \n" >+#ifdef HAS_I422TOUYVYROW_SSE2 >+void I422ToUYVYRow_SSE2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uyvy, >+ int width) { >+ asm volatile( > >- LABELALIGN >- "2103: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklbw %%xmm5,%%xmm0 \n" >- "punpckhbw %%xmm5,%%xmm1 \n" >- "pshufhw $0x93,%%xmm0,%%xmm0 \n" >- "pshuflw $0x93,%%xmm0,%%xmm0 \n" >- "pshufhw $0x93,%%xmm1,%%xmm1 \n" >- "pshuflw $0x93,%%xmm1,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%3 \n" >- "jg 2103b \n" >- "jmp 99f \n" >+ "sub %1,%2 \n" > >- LABELALIGN >- "3012: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklbw %%xmm5,%%xmm0 \n" >- "punpckhbw %%xmm5,%%xmm1 \n" >- "pshufhw $0xc6,%%xmm0,%%xmm0 \n" >- "pshuflw $0xc6,%%xmm0,%%xmm0 \n" >- "pshufhw $0xc6,%%xmm1,%%xmm1 \n" >- "pshuflw $0xc6,%%xmm1,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%3 \n" >- "jg 3012b \n" >- >- "99: \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "=&d"(pixel_temp), // %2 >- "+r"(width) // %3 >- : "r"(shuffler) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm5" >- ); >+ LABELALIGN >+ "1: \n" >+ "movq (%1),%%xmm2 \n" >+ "movq 0x00(%1,%2,1),%%xmm1 \n" >+ "add $0x8,%1 \n" >+ "punpcklbw %%xmm1,%%xmm2 \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqa %%xmm2,%%xmm1 \n" >+ "add $0x10,%0 \n" >+ "punpcklbw %%xmm0,%%xmm1 \n" >+ "punpckhbw %%xmm0,%%xmm2 \n" >+ "movdqu %%xmm1,(%3) \n" >+ "movdqu %%xmm2,0x10(%3) \n" >+ "lea 0x20(%3),%3 \n" >+ "sub $0x10,%4 \n" >+ "jg 1b \n" >+ : "+r"(src_y), // %0 >+ "+r"(src_u), // %1 >+ "+r"(src_v), // %2 >+ "+r"(dst_uyvy), // %3 >+ "+rm"(width) // %4 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); > } >-#endif // HAS_ARGBSHUFFLEROW_SSE2 >+#endif // HAS_I422TOUYVYROW_SSE2 > >-#ifdef HAS_I422TOYUY2ROW_SSE2 >-void I422ToYUY2Row_SSE2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_frame, >+#ifdef HAS_I422TOYUY2ROW_AVX2 >+void I422ToYUY2Row_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_yuy2, > int width) { >- asm volatile ( >- "sub %1,%2 \n" >- LABELALIGN >- "1: \n" >- "movq " MEMACCESS(1) ",%%xmm2 \n" >- MEMOPREG(movq,0x00,1,2,1,xmm3) // movq (%1,%2,1),%%xmm3 >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "punpcklbw %%xmm3,%%xmm2 \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklbw %%xmm2,%%xmm0 \n" >- "punpckhbw %%xmm2,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(3) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,3) " \n" >- "lea " MEMLEA(0x20,3) ",%3 \n" >- "sub $0x10,%4 \n" >- "jg 1b \n" >- : "+r"(src_y), // %0 >- "+r"(src_u), // %1 >- "+r"(src_v), // %2 >- "+r"(dst_frame), // %3 >- "+rm"(width) // %4 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3" >- ); >+ asm volatile( >+ >+ "sub %1,%2 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vpmovzxbw (%1),%%ymm1 \n" >+ "vpmovzxbw 0x00(%1,%2,1),%%ymm2 \n" >+ "add $0x10,%1 \n" >+ "vpsllw $0x8,%%ymm2,%%ymm2 \n" >+ "vpor %%ymm1,%%ymm2,%%ymm2 \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "add $0x20,%0 \n" >+ "vpunpcklbw %%ymm2,%%ymm0,%%ymm1 \n" >+ "vpunpckhbw %%ymm2,%%ymm0,%%ymm2 \n" >+ "vextractf128 $0x0,%%ymm1,(%3) \n" >+ "vextractf128 $0x0,%%ymm2,0x10(%3) \n" >+ "vextractf128 $0x1,%%ymm1,0x20(%3) \n" >+ "vextractf128 $0x1,%%ymm2,0x30(%3) \n" >+ "lea 0x40(%3),%3 \n" >+ "sub $0x20,%4 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_y), // %0 >+ "+r"(src_u), // %1 >+ "+r"(src_v), // %2 >+ "+r"(dst_yuy2), // %3 >+ "+rm"(width) // %4 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); > } >-#endif // HAS_I422TOYUY2ROW_SSE2 >+#endif // HAS_I422TOYUY2ROW_AVX2 > >-#ifdef HAS_I422TOUYVYROW_SSE2 >-void I422ToUYVYRow_SSE2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_frame, >+#ifdef HAS_I422TOUYVYROW_AVX2 >+void I422ToUYVYRow_AVX2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uyvy, > int width) { >- asm volatile ( >- "sub %1,%2 \n" >- LABELALIGN >- "1: \n" >- "movq " MEMACCESS(1) ",%%xmm2 \n" >- MEMOPREG(movq,0x00,1,2,1,xmm3) // movq (%1,%2,1),%%xmm3 >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "punpcklbw %%xmm3,%%xmm2 \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqa %%xmm2,%%xmm1 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "punpcklbw %%xmm0,%%xmm1 \n" >- "punpckhbw %%xmm0,%%xmm2 \n" >- "movdqu %%xmm1," MEMACCESS(3) " \n" >- "movdqu %%xmm2," MEMACCESS2(0x10,3) " \n" >- "lea " MEMLEA(0x20,3) ",%3 \n" >- "sub $0x10,%4 \n" >- "jg 1b \n" >- : "+r"(src_y), // %0 >- "+r"(src_u), // %1 >- "+r"(src_v), // %2 >- "+r"(dst_frame), // %3 >- "+rm"(width) // %4 >- : >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3" >- ); >+ asm volatile( >+ >+ "sub %1,%2 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vpmovzxbw (%1),%%ymm1 \n" >+ "vpmovzxbw 0x00(%1,%2,1),%%ymm2 \n" >+ "add $0x10,%1 \n" >+ "vpsllw $0x8,%%ymm2,%%ymm2 \n" >+ "vpor %%ymm1,%%ymm2,%%ymm2 \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "add $0x20,%0 \n" >+ "vpunpcklbw %%ymm0,%%ymm2,%%ymm1 \n" >+ "vpunpckhbw %%ymm0,%%ymm2,%%ymm2 \n" >+ "vextractf128 $0x0,%%ymm1,(%3) \n" >+ "vextractf128 $0x0,%%ymm2,0x10(%3) \n" >+ "vextractf128 $0x1,%%ymm1,0x20(%3) \n" >+ "vextractf128 $0x1,%%ymm2,0x30(%3) \n" >+ "lea 0x40(%3),%3 \n" >+ "sub $0x20,%4 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_y), // %0 >+ "+r"(src_u), // %1 >+ "+r"(src_v), // %2 >+ "+r"(dst_uyvy), // %3 >+ "+rm"(width) // %4 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2"); > } >-#endif // HAS_I422TOUYVYROW_SSE2 >+#endif // HAS_I422TOUYVYROW_AVX2 > > #ifdef HAS_ARGBPOLYNOMIALROW_SSE2 >-void ARGBPolynomialRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBPolynomialRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > const float* poly, > int width) { >- asm volatile ( >- "pxor %%xmm3,%%xmm3 \n" >+ asm volatile( > >- // 2 pixel loop. >- LABELALIGN >- "1: \n" >- "movq " MEMACCESS(0) ",%%xmm0 \n" >- "lea " MEMLEA(0x8,0) ",%0 \n" >- "punpcklbw %%xmm3,%%xmm0 \n" >- "movdqa %%xmm0,%%xmm4 \n" >- "punpcklwd %%xmm3,%%xmm0 \n" >- "punpckhwd %%xmm3,%%xmm4 \n" >- "cvtdq2ps %%xmm0,%%xmm0 \n" >- "cvtdq2ps %%xmm4,%%xmm4 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "movdqa %%xmm4,%%xmm5 \n" >- "mulps " MEMACCESS2(0x10,3) ",%%xmm0 \n" >- "mulps " MEMACCESS2(0x10,3) ",%%xmm4 \n" >- "addps " MEMACCESS(3) ",%%xmm0 \n" >- "addps " MEMACCESS(3) ",%%xmm4 \n" >- "movdqa %%xmm1,%%xmm2 \n" >- "movdqa %%xmm5,%%xmm6 \n" >- "mulps %%xmm1,%%xmm2 \n" >- "mulps %%xmm5,%%xmm6 \n" >- "mulps %%xmm2,%%xmm1 \n" >- "mulps %%xmm6,%%xmm5 \n" >- "mulps " MEMACCESS2(0x20,3) ",%%xmm2 \n" >- "mulps " MEMACCESS2(0x20,3) ",%%xmm6 \n" >- "mulps " MEMACCESS2(0x30,3) ",%%xmm1 \n" >- "mulps " MEMACCESS2(0x30,3) ",%%xmm5 \n" >- "addps %%xmm2,%%xmm0 \n" >- "addps %%xmm6,%%xmm4 \n" >- "addps %%xmm1,%%xmm0 \n" >- "addps %%xmm5,%%xmm4 \n" >- "cvttps2dq %%xmm0,%%xmm0 \n" >- "cvttps2dq %%xmm4,%%xmm4 \n" >- "packuswb %%xmm4,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x2,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "r"(poly) // %3 >- : "memory", "cc" >- , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" >- ); >+ "pxor %%xmm3,%%xmm3 \n" >+ >+ // 2 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movq (%0),%%xmm0 \n" >+ "lea 0x8(%0),%0 \n" >+ "punpcklbw %%xmm3,%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm4 \n" >+ "punpcklwd %%xmm3,%%xmm0 \n" >+ "punpckhwd %%xmm3,%%xmm4 \n" >+ "cvtdq2ps %%xmm0,%%xmm0 \n" >+ "cvtdq2ps %%xmm4,%%xmm4 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "movdqa %%xmm4,%%xmm5 \n" >+ "mulps 0x10(%3),%%xmm0 \n" >+ "mulps 0x10(%3),%%xmm4 \n" >+ "addps (%3),%%xmm0 \n" >+ "addps (%3),%%xmm4 \n" >+ "movdqa %%xmm1,%%xmm2 \n" >+ "movdqa %%xmm5,%%xmm6 \n" >+ "mulps %%xmm1,%%xmm2 \n" >+ "mulps %%xmm5,%%xmm6 \n" >+ "mulps %%xmm2,%%xmm1 \n" >+ "mulps %%xmm6,%%xmm5 \n" >+ "mulps 0x20(%3),%%xmm2 \n" >+ "mulps 0x20(%3),%%xmm6 \n" >+ "mulps 0x30(%3),%%xmm1 \n" >+ "mulps 0x30(%3),%%xmm5 \n" >+ "addps %%xmm2,%%xmm0 \n" >+ "addps %%xmm6,%%xmm4 \n" >+ "addps %%xmm1,%%xmm0 \n" >+ "addps %%xmm5,%%xmm4 \n" >+ "cvttps2dq %%xmm0,%%xmm0 \n" >+ "cvttps2dq %%xmm4,%%xmm4 \n" >+ "packuswb %%xmm4,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "movq %%xmm0,(%1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x2,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "r"(poly) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); > } > #endif // HAS_ARGBPOLYNOMIALROW_SSE2 > > #ifdef HAS_ARGBPOLYNOMIALROW_AVX2 >-void ARGBPolynomialRow_AVX2(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBPolynomialRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > const float* poly, > int width) { >- asm volatile ( >- "vbroadcastf128 " MEMACCESS(3) ",%%ymm4 \n" >- "vbroadcastf128 " MEMACCESS2(0x10,3) ",%%ymm5 \n" >- "vbroadcastf128 " MEMACCESS2(0x20,3) ",%%ymm6 \n" >- "vbroadcastf128 " MEMACCESS2(0x30,3) ",%%ymm7 \n" >+ asm volatile( >+ "vbroadcastf128 (%3),%%ymm4 \n" >+ "vbroadcastf128 0x10(%3),%%ymm5 \n" >+ "vbroadcastf128 0x20(%3),%%ymm6 \n" >+ "vbroadcastf128 0x30(%3),%%ymm7 \n" > >- // 2 pixel loop. >- LABELALIGN >- "1: \n" >- "vpmovzxbd " MEMACCESS(0) ",%%ymm0 \n" // 2 ARGB pixels >- "lea " MEMLEA(0x8,0) ",%0 \n" >- "vcvtdq2ps %%ymm0,%%ymm0 \n" // X 8 floats >- "vmulps %%ymm0,%%ymm0,%%ymm2 \n" // X * X >- "vmulps %%ymm7,%%ymm0,%%ymm3 \n" // C3 * X >- "vfmadd132ps %%ymm5,%%ymm4,%%ymm0 \n" // result = C0 + C1 * X >- "vfmadd231ps %%ymm6,%%ymm2,%%ymm0 \n" // result += C2 * X * X >- "vfmadd231ps %%ymm3,%%ymm2,%%ymm0 \n" // result += C3 * X * X * X >- "vcvttps2dq %%ymm0,%%ymm0 \n" >- "vpackusdw %%ymm0,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpackuswb %%xmm0,%%xmm0,%%xmm0 \n" >- "vmovq %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x2,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(width) // %2 >- : "r"(poly) // %3 >- : "memory", "cc", >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ // 2 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "vpmovzxbd (%0),%%ymm0 \n" // 2 ARGB pixels >+ "lea 0x8(%0),%0 \n" >+ "vcvtdq2ps %%ymm0,%%ymm0 \n" // X 8 floats >+ "vmulps %%ymm0,%%ymm0,%%ymm2 \n" // X * X >+ "vmulps %%ymm7,%%ymm0,%%ymm3 \n" // C3 * X >+ "vfmadd132ps %%ymm5,%%ymm4,%%ymm0 \n" // result = C0 + C1 * X >+ "vfmadd231ps %%ymm6,%%ymm2,%%ymm0 \n" // result += C2 * X * X >+ "vfmadd231ps %%ymm3,%%ymm2,%%ymm0 \n" // result += C3 * X * X * >+ // X >+ "vcvttps2dq %%ymm0,%%ymm0 \n" >+ "vpackusdw %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpackuswb %%xmm0,%%xmm0,%%xmm0 \n" >+ "vmovq %%xmm0,(%1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x2,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(width) // %2 >+ : "r"(poly) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > #endif // HAS_ARGBPOLYNOMIALROW_AVX2 > > #ifdef HAS_HALFFLOATROW_SSE2 > static float kScaleBias = 1.9259299444e-34f; >-void HalfFloatRow_SSE2(const uint16* src, uint16* dst, float scale, int width) { >+void HalfFloatRow_SSE2(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width) { > scale *= kScaleBias; >- asm volatile ( >- "pshufd $0x0,%3,%%xmm4 \n" >- "pxor %%xmm5,%%xmm5 \n" >- "sub %0,%1 \n" >+ asm volatile( >+ "movd %3,%%xmm4 \n" >+ "pshufd $0x0,%%xmm4,%%xmm4 \n" >+ "pxor %%xmm5,%%xmm5 \n" >+ "sub %0,%1 \n" > >- // 16 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm2 \n" // 8 shorts >- "add $0x10,%0 \n" >- "movdqa %%xmm2,%%xmm3 \n" >- "punpcklwd %%xmm5,%%xmm2 \n" // 8 ints in xmm2/1 >- "cvtdq2ps %%xmm2,%%xmm2 \n" // 8 floats >- "punpckhwd %%xmm5,%%xmm3 \n" >- "cvtdq2ps %%xmm3,%%xmm3 \n" >- "mulps %%xmm4,%%xmm2 \n" >- "mulps %%xmm4,%%xmm3 \n" >- "psrld $0xd,%%xmm2 \n" >- "psrld $0xd,%%xmm3 \n" >- "packssdw %%xmm3,%%xmm2 \n" >- MEMOPMEM(movdqu,xmm2,-0x10,0,1,1) >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >-#if defined(__x86_64__) >- : "x"(scale) // %3 >-#else >- : "m"(scale) // %3 >-#endif >- : "memory", "cc", >- "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ // 16 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm2 \n" // 8 shorts >+ "add $0x10,%0 \n" >+ "movdqa %%xmm2,%%xmm3 \n" >+ "punpcklwd %%xmm5,%%xmm2 \n" // 8 ints in xmm2/1 >+ "cvtdq2ps %%xmm2,%%xmm2 \n" // 8 floats >+ "punpckhwd %%xmm5,%%xmm3 \n" >+ "cvtdq2ps %%xmm3,%%xmm3 \n" >+ "mulps %%xmm4,%%xmm2 \n" >+ "mulps %%xmm4,%%xmm3 \n" >+ "psrld $0xd,%%xmm2 \n" >+ "psrld $0xd,%%xmm3 \n" >+ "packssdw %%xmm3,%%xmm2 \n" >+ "movdqu %%xmm2,-0x10(%0,%1,1) \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : "m"(scale) // %3 >+ : "memory", "cc", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_HALFFLOATROW_SSE2 > > #ifdef HAS_HALFFLOATROW_AVX2 >-void HalfFloatRow_AVX2(const uint16* src, uint16* dst, float scale, int width) { >+void HalfFloatRow_AVX2(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width) { > scale *= kScaleBias; >- asm volatile ( >- "vbroadcastss %3, %%ymm4 \n" >- "vpxor %%ymm5,%%ymm5,%%ymm5 \n" >- "sub %0,%1 \n" >+ asm volatile( >+ "vbroadcastss %3, %%ymm4 \n" >+ "vpxor %%ymm5,%%ymm5,%%ymm5 \n" >+ "sub %0,%1 \n" > >- // 16 pixel loop. >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm2 \n" // 16 shorts >- "add $0x20,%0 \n" >- "vpunpckhwd %%ymm5,%%ymm2,%%ymm3 \n" // mutates >- "vpunpcklwd %%ymm5,%%ymm2,%%ymm2 \n" >- "vcvtdq2ps %%ymm3,%%ymm3 \n" >- "vcvtdq2ps %%ymm2,%%ymm2 \n" >- "vmulps %%ymm3,%%ymm4,%%ymm3 \n" >- "vmulps %%ymm2,%%ymm4,%%ymm2 \n" >- "vpsrld $0xd,%%ymm3,%%ymm3 \n" >- "vpsrld $0xd,%%ymm2,%%ymm2 \n" >- "vpackssdw %%ymm3, %%ymm2, %%ymm2 \n" // unmutates >- MEMOPMEM(vmovdqu,ymm2,-0x20,0,1,1) >- "sub $0x10,%2 \n" >- "jg 1b \n" >+ // 16 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm2 \n" // 16 shorts >+ "add $0x20,%0 \n" >+ "vpunpckhwd %%ymm5,%%ymm2,%%ymm3 \n" // mutates >+ "vpunpcklwd %%ymm5,%%ymm2,%%ymm2 \n" >+ "vcvtdq2ps %%ymm3,%%ymm3 \n" >+ "vcvtdq2ps %%ymm2,%%ymm2 \n" >+ "vmulps %%ymm3,%%ymm4,%%ymm3 \n" >+ "vmulps %%ymm2,%%ymm4,%%ymm2 \n" >+ "vpsrld $0xd,%%ymm3,%%ymm3 \n" >+ "vpsrld $0xd,%%ymm2,%%ymm2 \n" >+ "vpackssdw %%ymm3, %%ymm2, %%ymm2 \n" // unmutates >+ "vmovdqu %%ymm2,-0x20(%0,%1,1) \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" > >- "vzeroupper \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >+ "vzeroupper \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 > #if defined(__x86_64__) >- : "x"(scale) // %3 >+ : "x"(scale) // %3 > #else >- : "m"(scale) // %3 >+ : "m"(scale) // %3 > #endif >- : "memory", "cc", >- "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ : "memory", "cc", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_HALFFLOATROW_AVX2 > > #ifdef HAS_HALFFLOATROW_F16C >-void HalfFloatRow_F16C(const uint16* src, uint16* dst, float scale, int width) { >- asm volatile ( >- "vbroadcastss %3, %%ymm4 \n" >- "sub %0,%1 \n" >+void HalfFloatRow_F16C(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width) { >+ asm volatile( >+ "vbroadcastss %3, %%ymm4 \n" >+ "sub %0,%1 \n" > >- // 16 pixel loop. >- LABELALIGN >- "1: \n" >- "vpmovzxwd " MEMACCESS(0) ",%%ymm2 \n" // 16 shorts -> 16 ints >- "vpmovzxwd " MEMACCESS2(0x10,0) ",%%ymm3 \n" >- "vcvtdq2ps %%ymm2,%%ymm2 \n" >- "vcvtdq2ps %%ymm3,%%ymm3 \n" >- "vmulps %%ymm2,%%ymm4,%%ymm2 \n" >- "vmulps %%ymm3,%%ymm4,%%ymm3 \n" >- "vcvtps2ph $3, %%ymm2, %%xmm2 \n" >- "vcvtps2ph $3, %%ymm3, %%xmm3 \n" >- MEMOPMEM(vmovdqu,xmm2,0x00,0,1,1) >- MEMOPMEM(vmovdqu,xmm3,0x10,0,1,1) >- "add $0x20,%0 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >+ // 16 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "vpmovzxwd (%0),%%ymm2 \n" // 16 shorts -> 16 ints >+ "vpmovzxwd 0x10(%0),%%ymm3 \n" >+ "vcvtdq2ps %%ymm2,%%ymm2 \n" >+ "vcvtdq2ps %%ymm3,%%ymm3 \n" >+ "vmulps %%ymm2,%%ymm4,%%ymm2 \n" >+ "vmulps %%ymm3,%%ymm4,%%ymm3 \n" >+ "vcvtps2ph $3, %%ymm2, %%xmm2 \n" >+ "vcvtps2ph $3, %%ymm3, %%xmm3 \n" >+ "vmovdqu %%xmm2,0x00(%0,%1,1) \n" >+ "vmovdqu %%xmm3,0x10(%0,%1,1) \n" >+ "add $0x20,%0 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 > #if defined(__x86_64__) >- : "x"(scale) // %3 >+ : "x"(scale) // %3 > #else >- : "m"(scale) // %3 >+ : "m"(scale) // %3 > #endif >- : "memory", "cc", >- "xmm2", "xmm3", "xmm4" >- ); >+ : "memory", "cc", "xmm2", "xmm3", "xmm4"); > } > #endif // HAS_HALFFLOATROW_F16C > > #ifdef HAS_HALFFLOATROW_F16C >-void HalfFloat1Row_F16C(const uint16* src, uint16* dst, float, int width) { >- asm volatile ( >- "sub %0,%1 \n" >- // 16 pixel loop. >- LABELALIGN >- "1: \n" >- "vpmovzxwd " MEMACCESS(0) ",%%ymm2 \n" // 16 shorts -> 16 ints >- "vpmovzxwd " MEMACCESS2(0x10,0) ",%%ymm3 \n" >- "vcvtdq2ps %%ymm2,%%ymm2 \n" >- "vcvtdq2ps %%ymm3,%%ymm3 \n" >- "vcvtps2ph $3, %%ymm2, %%xmm2 \n" >- "vcvtps2ph $3, %%ymm3, %%xmm3 \n" >- MEMOPMEM(vmovdqu,xmm2,0x00,0,1,1) >- MEMOPMEM(vmovdqu,xmm3,0x10,0,1,1) >- "add $0x20,%0 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src), // %0 >- "+r"(dst), // %1 >- "+r"(width) // %2 >- : >- : "memory", "cc", >- "xmm2", "xmm3" >- ); >+void HalfFloat1Row_F16C(const uint16_t* src, uint16_t* dst, float, int width) { >+ asm volatile( >+ "sub %0,%1 \n" >+ // 16 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "vpmovzxwd (%0),%%ymm2 \n" // 16 shorts -> 16 ints >+ "vpmovzxwd 0x10(%0),%%ymm3 \n" >+ "vcvtdq2ps %%ymm2,%%ymm2 \n" >+ "vcvtdq2ps %%ymm3,%%ymm3 \n" >+ "vcvtps2ph $3, %%ymm2, %%xmm2 \n" >+ "vcvtps2ph $3, %%ymm3, %%xmm3 \n" >+ "vmovdqu %%xmm2,0x00(%0,%1,1) \n" >+ "vmovdqu %%xmm3,0x10(%0,%1,1) \n" >+ "add $0x20,%0 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : >+ : "memory", "cc", "xmm2", "xmm3"); > } > #endif // HAS_HALFFLOATROW_F16C > > #ifdef HAS_ARGBCOLORTABLEROW_X86 > // Tranform ARGB pixels with color table. >-void ARGBColorTableRow_X86(uint8* dst_argb, >- const uint8* table_argb, >+void ARGBColorTableRow_X86(uint8_t* dst_argb, >+ const uint8_t* table_argb, > int width) { > uintptr_t pixel_temp; >- asm volatile ( >- // 1 pixel loop. >- LABELALIGN >- "1: \n" >- "movzb " MEMACCESS(0) ",%1 \n" >- "lea " MEMLEA(0x4,0) ",%0 \n" >- MEMOPARG(movzb,0x00,3,1,4,1) " \n" // movzb (%3,%1,4),%1 >- "mov %b1," MEMACCESS2(-0x4,0) " \n" >- "movzb " MEMACCESS2(-0x3,0) ",%1 \n" >- MEMOPARG(movzb,0x01,3,1,4,1) " \n" // movzb 0x1(%3,%1,4),%1 >- "mov %b1," MEMACCESS2(-0x3,0) " \n" >- "movzb " MEMACCESS2(-0x2,0) ",%1 \n" >- MEMOPARG(movzb,0x02,3,1,4,1) " \n" // movzb 0x2(%3,%1,4),%1 >- "mov %b1," MEMACCESS2(-0x2,0) " \n" >- "movzb " MEMACCESS2(-0x1,0) ",%1 \n" >- MEMOPARG(movzb,0x03,3,1,4,1) " \n" // movzb 0x3(%3,%1,4),%1 >- "mov %b1," MEMACCESS2(-0x1,0) " \n" >- "dec %2 \n" >- "jg 1b \n" >- : "+r"(dst_argb), // %0 >- "=&d"(pixel_temp), // %1 >- "+r"(width) // %2 >- : "r"(table_argb) // %3 >- : "memory", "cc"); >+ asm volatile( >+ // 1 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movzb (%0),%1 \n" >+ "lea 0x4(%0),%0 \n" >+ "movzb 0x00(%3,%1,4),%1 \n" >+ "mov %b1,-0x4(%0) \n" >+ "movzb -0x3(%0),%1 \n" >+ "movzb 0x01(%3,%1,4),%1 \n" >+ "mov %b1,-0x3(%0) \n" >+ "movzb -0x2(%0),%1 \n" >+ "movzb 0x02(%3,%1,4),%1 \n" >+ "mov %b1,-0x2(%0) \n" >+ "movzb -0x1(%0),%1 \n" >+ "movzb 0x03(%3,%1,4),%1 \n" >+ "mov %b1,-0x1(%0) \n" >+ "dec %2 \n" >+ "jg 1b \n" >+ : "+r"(dst_argb), // %0 >+ "=&d"(pixel_temp), // %1 >+ "+r"(width) // %2 >+ : "r"(table_argb) // %3 >+ : "memory", "cc"); > } > #endif // HAS_ARGBCOLORTABLEROW_X86 > > #ifdef HAS_RGBCOLORTABLEROW_X86 > // Tranform RGB pixels with color table. >-void RGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb, int width) { >+void RGBColorTableRow_X86(uint8_t* dst_argb, >+ const uint8_t* table_argb, >+ int width) { > uintptr_t pixel_temp; >- asm volatile ( >- // 1 pixel loop. >- LABELALIGN >- "1: \n" >- "movzb " MEMACCESS(0) ",%1 \n" >- "lea " MEMLEA(0x4,0) ",%0 \n" >- MEMOPARG(movzb,0x00,3,1,4,1) " \n" // movzb (%3,%1,4),%1 >- "mov %b1," MEMACCESS2(-0x4,0) " \n" >- "movzb " MEMACCESS2(-0x3,0) ",%1 \n" >- MEMOPARG(movzb,0x01,3,1,4,1) " \n" // movzb 0x1(%3,%1,4),%1 >- "mov %b1," MEMACCESS2(-0x3,0) " \n" >- "movzb " MEMACCESS2(-0x2,0) ",%1 \n" >- MEMOPARG(movzb,0x02,3,1,4,1) " \n" // movzb 0x2(%3,%1,4),%1 >- "mov %b1," MEMACCESS2(-0x2,0) " \n" >- "dec %2 \n" >- "jg 1b \n" >- : "+r"(dst_argb), // %0 >- "=&d"(pixel_temp), // %1 >- "+r"(width) // %2 >- : "r"(table_argb) // %3 >- : "memory", "cc"); >+ asm volatile( >+ // 1 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movzb (%0),%1 \n" >+ "lea 0x4(%0),%0 \n" >+ "movzb 0x00(%3,%1,4),%1 \n" >+ "mov %b1,-0x4(%0) \n" >+ "movzb -0x3(%0),%1 \n" >+ "movzb 0x01(%3,%1,4),%1 \n" >+ "mov %b1,-0x3(%0) \n" >+ "movzb -0x2(%0),%1 \n" >+ "movzb 0x02(%3,%1,4),%1 \n" >+ "mov %b1,-0x2(%0) \n" >+ "dec %2 \n" >+ "jg 1b \n" >+ : "+r"(dst_argb), // %0 >+ "=&d"(pixel_temp), // %1 >+ "+r"(width) // %2 >+ : "r"(table_argb) // %3 >+ : "memory", "cc"); > } > #endif // HAS_RGBCOLORTABLEROW_X86 > > #ifdef HAS_ARGBLUMACOLORTABLEROW_SSSE3 > // Tranform RGB pixels with luma table. >-void ARGBLumaColorTableRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBLumaColorTableRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- const uint8* luma, >- uint32 lumacoeff) { >+ const uint8_t* luma, >+ uint32_t lumacoeff) { > uintptr_t pixel_temp; > uintptr_t table_temp; >- asm volatile ( >- "movd %6,%%xmm3 \n" >- "pshufd $0x0,%%xmm3,%%xmm3 \n" >- "pcmpeqb %%xmm4,%%xmm4 \n" >- "psllw $0x8,%%xmm4 \n" >- "pxor %%xmm5,%%xmm5 \n" >+ asm volatile( >+ "movd %6,%%xmm3 \n" >+ "pshufd $0x0,%%xmm3,%%xmm3 \n" >+ "pcmpeqb %%xmm4,%%xmm4 \n" >+ "psllw $0x8,%%xmm4 \n" >+ "pxor %%xmm5,%%xmm5 \n" > >- // 4 pixel loop. >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(2) ",%%xmm0 \n" >- "pmaddubsw %%xmm3,%%xmm0 \n" >- "phaddw %%xmm0,%%xmm0 \n" >- "pand %%xmm4,%%xmm0 \n" >- "punpcklwd %%xmm5,%%xmm0 \n" >- "movd %%xmm0,%k1 \n" // 32 bit offset >- "add %5,%1 \n" >- "pshufd $0x39,%%xmm0,%%xmm0 \n" >- >- "movzb " MEMACCESS(2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS(3) " \n" >- "movzb " MEMACCESS2(0x1,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0x1,3) " \n" >- "movzb " MEMACCESS2(0x2,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0x2,3) " \n" >- "movzb " MEMACCESS2(0x3,2) ",%0 \n" >- "mov %b0," MEMACCESS2(0x3,3) " \n" >- >- "movd %%xmm0,%k1 \n" // 32 bit offset >- "add %5,%1 \n" >- "pshufd $0x39,%%xmm0,%%xmm0 \n" >- >- "movzb " MEMACCESS2(0x4,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0x4,3) " \n" >- "movzb " MEMACCESS2(0x5,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0x5,3) " \n" >- "movzb " MEMACCESS2(0x6,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0x6,3) " \n" >- "movzb " MEMACCESS2(0x7,2) ",%0 \n" >- "mov %b0," MEMACCESS2(0x7,3) " \n" >- >- "movd %%xmm0,%k1 \n" // 32 bit offset >- "add %5,%1 \n" >- "pshufd $0x39,%%xmm0,%%xmm0 \n" >- >- "movzb " MEMACCESS2(0x8,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0x8,3) " \n" >- "movzb " MEMACCESS2(0x9,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0x9,3) " \n" >- "movzb " MEMACCESS2(0xa,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0xa,3) " \n" >- "movzb " MEMACCESS2(0xb,2) ",%0 \n" >- "mov %b0," MEMACCESS2(0xb,3) " \n" >- >- "movd %%xmm0,%k1 \n" // 32 bit offset >- "add %5,%1 \n" >- >- "movzb " MEMACCESS2(0xc,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0xc,3) " \n" >- "movzb " MEMACCESS2(0xd,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0xd,3) " \n" >- "movzb " MEMACCESS2(0xe,2) ",%0 \n" >- MEMOPARG(movzb,0x00,1,0,1,0) " \n" // movzb (%1,%0,1),%0 >- "mov %b0," MEMACCESS2(0xe,3) " \n" >- "movzb " MEMACCESS2(0xf,2) ",%0 \n" >- "mov %b0," MEMACCESS2(0xf,3) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "lea " MEMLEA(0x10,3) ",%3 \n" >- "sub $0x4,%4 \n" >- "jg 1b \n" >- : "=&d"(pixel_temp), // %0 >- "=&a"(table_temp), // %1 >- "+r"(src_argb), // %2 >- "+r"(dst_argb), // %3 >- "+rm"(width) // %4 >- : "r"(luma), // %5 >- "rm"(lumacoeff) // %6 >- : "memory", "cc", "xmm0", "xmm3", "xmm4", "xmm5" >- ); >+ // 4 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%2),%%xmm0 \n" >+ "pmaddubsw %%xmm3,%%xmm0 \n" >+ "phaddw %%xmm0,%%xmm0 \n" >+ "pand %%xmm4,%%xmm0 \n" >+ "punpcklwd %%xmm5,%%xmm0 \n" >+ "movd %%xmm0,%k1 \n" // 32 bit offset >+ "add %5,%1 \n" >+ "pshufd $0x39,%%xmm0,%%xmm0 \n" >+ >+ "movzb (%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,(%3) \n" >+ "movzb 0x1(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0x1(%3) \n" >+ "movzb 0x2(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0x2(%3) \n" >+ "movzb 0x3(%2),%0 \n" >+ "mov %b0,0x3(%3) \n" >+ >+ "movd %%xmm0,%k1 \n" // 32 bit offset >+ "add %5,%1 \n" >+ "pshufd $0x39,%%xmm0,%%xmm0 \n" >+ >+ "movzb 0x4(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0x4(%3) \n" >+ "movzb 0x5(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0x5(%3) \n" >+ "movzb 0x6(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0x6(%3) \n" >+ "movzb 0x7(%2),%0 \n" >+ "mov %b0,0x7(%3) \n" >+ >+ "movd %%xmm0,%k1 \n" // 32 bit offset >+ "add %5,%1 \n" >+ "pshufd $0x39,%%xmm0,%%xmm0 \n" >+ >+ "movzb 0x8(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0x8(%3) \n" >+ "movzb 0x9(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0x9(%3) \n" >+ "movzb 0xa(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0xa(%3) \n" >+ "movzb 0xb(%2),%0 \n" >+ "mov %b0,0xb(%3) \n" >+ >+ "movd %%xmm0,%k1 \n" // 32 bit offset >+ "add %5,%1 \n" >+ >+ "movzb 0xc(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0xc(%3) \n" >+ "movzb 0xd(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0xd(%3) \n" >+ "movzb 0xe(%2),%0 \n" >+ "movzb 0x00(%1,%0,1),%0 \n" >+ "mov %b0,0xe(%3) \n" >+ "movzb 0xf(%2),%0 \n" >+ "mov %b0,0xf(%3) \n" >+ "lea 0x10(%2),%2 \n" >+ "lea 0x10(%3),%3 \n" >+ "sub $0x4,%4 \n" >+ "jg 1b \n" >+ : "=&d"(pixel_temp), // %0 >+ "=&a"(table_temp), // %1 >+ "+r"(src_argb), // %2 >+ "+r"(dst_argb), // %3 >+ "+rm"(width) // %4 >+ : "r"(luma), // %5 >+ "rm"(lumacoeff) // %6 >+ : "memory", "cc", "xmm0", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_ARGBLUMACOLORTABLEROW_SSSE3 > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_msa.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_msa.cc >index 5cc23450a528953532acb01e03797f994c11ce9f..66666cefcd98c4f2314bf27ac142d34f1864cfcf 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_msa.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_msa.cc >@@ -37,17 +37,17 @@ extern "C" { > } > > // Load YUV 422 pixel data >-#define READYUV422(psrc_y, psrc_u, psrc_v, out_y, out_u, out_v) \ >- { \ >- uint64 y_m; \ >- uint32 u_m, v_m; \ >- v4i32 zero_m = {0}; \ >- y_m = LD(psrc_y); \ >- u_m = LW(psrc_u); \ >- v_m = LW(psrc_v); \ >- out_y = (v16u8)__msa_insert_d((v2i64)zero_m, 0, (int64)y_m); \ >- out_u = (v16u8)__msa_insert_w(zero_m, 0, (int32)u_m); \ >- out_v = (v16u8)__msa_insert_w(zero_m, 0, (int32)v_m); \ >+#define READYUV422(psrc_y, psrc_u, psrc_v, out_y, out_u, out_v) \ >+ { \ >+ uint64_t y_m; \ >+ uint32_t u_m, v_m; \ >+ v4i32 zero_m = {0}; \ >+ y_m = LD(psrc_y); \ >+ u_m = LW(psrc_u); \ >+ v_m = LW(psrc_v); \ >+ out_y = (v16u8)__msa_insert_d((v2i64)zero_m, 0, (int64_t)y_m); \ >+ out_u = (v16u8)__msa_insert_w(zero_m, 0, (int32_t)u_m); \ >+ out_v = (v16u8)__msa_insert_w(zero_m, 0, (int32_t)v_m); \ > } > > // Clip input vector elements between 0 to 255 >@@ -275,17 +275,17 @@ extern "C" { > // Load I444 pixel data > #define READI444(psrc_y, psrc_u, psrc_v, out_y, out_u, out_v) \ > { \ >- uint64 y_m, u_m, v_m; \ >+ uint64_t y_m, u_m, v_m; \ > v2i64 zero_m = {0}; \ > y_m = LD(psrc_y); \ > u_m = LD(psrc_u); \ > v_m = LD(psrc_v); \ >- out_y = (v16u8)__msa_insert_d(zero_m, 0, (int64)y_m); \ >- out_u = (v16u8)__msa_insert_d(zero_m, 0, (int64)u_m); \ >- out_v = (v16u8)__msa_insert_d(zero_m, 0, (int64)v_m); \ >+ out_y = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)y_m); \ >+ out_u = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)u_m); \ >+ out_v = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)v_m); \ > } > >-void MirrorRow_MSA(const uint8* src, uint8* dst, int width) { >+void MirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width) { > int x; > v16u8 src0, src1, src2, src3; > v16u8 dst0, dst1, dst2, dst3; >@@ -302,7 +302,7 @@ void MirrorRow_MSA(const uint8* src, uint8* dst, int width) { > } > } > >-void ARGBMirrorRow_MSA(const uint8* src, uint8* dst, int width) { >+void ARGBMirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width) { > int x; > v16u8 src0, src1, src2, src3; > v16u8 dst0, dst1, dst2, dst3; >@@ -319,10 +319,10 @@ void ARGBMirrorRow_MSA(const uint8* src, uint8* dst, int width) { > } > } > >-void I422ToYUY2Row_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_yuy2, >+void I422ToYUY2Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_yuy2, > int width) { > int x; > v16u8 src_u0, src_v0, src_y0, src_y1, vec_uv0, vec_uv1; >@@ -343,10 +343,10 @@ void I422ToYUY2Row_MSA(const uint8* src_y, > } > } > >-void I422ToUYVYRow_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uyvy, >+void I422ToUYVYRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uyvy, > int width) { > int x; > v16u8 src_u0, src_v0, src_y0, src_y1, vec_uv0, vec_uv1; >@@ -367,10 +367,10 @@ void I422ToUYVYRow_MSA(const uint8* src_y, > } > } > >-void I422ToARGBRow_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* rgb_buf, >+void I422ToARGBRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -390,18 +390,18 @@ void I422ToARGBRow_MSA(const uint8* src_y, > src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); > YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, > vec0, vec1, vec2); >- STOREARGB(vec0, vec1, vec2, alpha, rgb_buf); >+ STOREARGB(vec0, vec1, vec2, alpha, dst_argb); > src_y += 8; > src_u += 4; > src_v += 4; >- rgb_buf += 32; >+ dst_argb += 32; > } > } > >-void I422ToRGBARow_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* rgb_buf, >+void I422ToRGBARow_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -421,23 +421,23 @@ void I422ToRGBARow_MSA(const uint8* src_y, > src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); > YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, > vec0, vec1, vec2); >- STOREARGB(alpha, vec0, vec1, vec2, rgb_buf); >+ STOREARGB(alpha, vec0, vec1, vec2, dst_argb); > src_y += 8; > src_u += 4; > src_v += 4; >- rgb_buf += 32; >+ dst_argb += 32; > } > } > >-void I422AlphaToARGBRow_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- const uint8* src_a, >- uint8* rgb_buf, >+void I422AlphaToARGBRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ const uint8_t* src_a, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > int x; >- int64 data_a; >+ int64_t data_a; > v16u8 src0, src1, src2, src3; > v8i16 vec0, vec1, vec2; > v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; >@@ -457,23 +457,23 @@ void I422AlphaToARGBRow_MSA(const uint8* src_y, > YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, > vec0, vec1, vec2); > src3 = (v16u8)__msa_ilvr_b((v16i8)src3, (v16i8)src3); >- STOREARGB(vec0, vec1, vec2, src3, rgb_buf); >+ STOREARGB(vec0, vec1, vec2, src3, dst_argb); > src_y += 8; > src_u += 4; > src_v += 4; > src_a += 8; >- rgb_buf += 32; >+ dst_argb += 32; > } > } > >-void I422ToRGB24Row_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* rgb_buf, >+void I422ToRGB24Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, >- int32 width) { >+ int32_t width) { > int x; >- int64 data_u, data_v; >+ int64_t data_u, data_v; > v16u8 src0, src1, src2, src3, src4, dst0, dst1, dst2; > v8i16 vec0, vec1, vec2, vec3, vec4, vec5; > v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; >@@ -510,20 +510,20 @@ void I422ToRGB24Row_MSA(const uint8* src_y, > dst0 = (v16u8)__msa_vshf_b(shuffler0, (v16i8)reg3, (v16i8)reg0); > dst1 = (v16u8)__msa_vshf_b(shuffler1, (v16i8)reg3, (v16i8)reg1); > dst2 = (v16u8)__msa_vshf_b(shuffler2, (v16i8)reg3, (v16i8)reg2); >- ST_UB2(dst0, dst1, rgb_buf, 16); >- ST_UB(dst2, (rgb_buf + 32)); >+ ST_UB2(dst0, dst1, dst_argb, 16); >+ ST_UB(dst2, (dst_argb + 32)); > src_y += 16; > src_u += 8; > src_v += 8; >- rgb_buf += 48; >+ dst_argb += 48; > } > } > > // TODO(fbarchard): Consider AND instead of shift to isolate 5 upper bits of R. >-void I422ToRGB565Row_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb565, >+void I422ToRGB565Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -558,10 +558,10 @@ void I422ToRGB565Row_MSA(const uint8* src_y, > } > > // TODO(fbarchard): Consider AND instead of shift to isolate 4 upper bits of G. >-void I422ToARGB4444Row_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB4444Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -598,10 +598,10 @@ void I422ToARGB4444Row_MSA(const uint8* src_y, > } > } > >-void I422ToARGB1555Row_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb1555, >+void I422ToARGB1555Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -638,7 +638,7 @@ void I422ToARGB1555Row_MSA(const uint8* src_y, > } > } > >-void YUY2ToYRow_MSA(const uint8* src_yuy2, uint8* dst_y, int width) { >+void YUY2ToYRow_MSA(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1; > >@@ -652,12 +652,12 @@ void YUY2ToYRow_MSA(const uint8* src_yuy2, uint8* dst_y, int width) { > } > } > >-void YUY2ToUVRow_MSA(const uint8* src_yuy2, >+void YUY2ToUVRow_MSA(const uint8_t* src_yuy2, > int src_stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_yuy2_next = src_yuy2 + src_stride_yuy2; >+ const uint8_t* src_yuy2_next = src_yuy2 + src_stride_yuy2; > int x; > v16u8 src0, src1, src2, src3, src4, src5, src6, src7; > v16u8 vec0, vec1, dst0, dst1; >@@ -682,9 +682,9 @@ void YUY2ToUVRow_MSA(const uint8* src_yuy2, > } > } > >-void YUY2ToUV422Row_MSA(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_MSA(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1; >@@ -703,7 +703,7 @@ void YUY2ToUV422Row_MSA(const uint8* src_yuy2, > } > } > >-void UYVYToYRow_MSA(const uint8* src_uyvy, uint8* dst_y, int width) { >+void UYVYToYRow_MSA(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1; > >@@ -717,12 +717,12 @@ void UYVYToYRow_MSA(const uint8* src_uyvy, uint8* dst_y, int width) { > } > } > >-void UYVYToUVRow_MSA(const uint8* src_uyvy, >+void UYVYToUVRow_MSA(const uint8_t* src_uyvy, > int src_stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_uyvy_next = src_uyvy + src_stride_uyvy; >+ const uint8_t* src_uyvy_next = src_uyvy + src_stride_uyvy; > int x; > v16u8 src0, src1, src2, src3, src4, src5, src6, src7; > v16u8 vec0, vec1, dst0, dst1; >@@ -747,9 +747,9 @@ void UYVYToUVRow_MSA(const uint8* src_uyvy, > } > } > >-void UYVYToUV422Row_MSA(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_MSA(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1; >@@ -768,7 +768,7 @@ void UYVYToUV422Row_MSA(const uint8* src_uyvy, > } > } > >-void ARGBToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { >+void ARGBToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { > int x; > v16u8 src0, src1, src2, src3, vec0, vec1, vec2, vec3, dst0; > v8u16 reg0, reg1, reg2, reg3, reg4, reg5; >@@ -814,13 +814,13 @@ void ARGBToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { > } > } > >-void ARGBToUVRow_MSA(const uint8* src_argb0, >+void ARGBToUVRow_MSA(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; >- const uint8* src_argb0_next = src_argb0 + src_stride_argb; >+ const uint8_t* src_argb0_next = src_argb0 + src_stride_argb; > v16u8 src0, src1, src2, src3, src4, src5, src6, src7; > v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; > v8u16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9; >@@ -932,7 +932,7 @@ void ARGBToUVRow_MSA(const uint8* src_argb0, > } > } > >-void ARGBToRGB24Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width) { >+void ARGBToRGB24Row_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1, dst2; > v16i8 shuffler0 = {0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18, 20}; >@@ -956,7 +956,7 @@ void ARGBToRGB24Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width) { > } > } > >-void ARGBToRAWRow_MSA(const uint8* src_argb, uint8* dst_rgb, int width) { >+void ARGBToRAWRow_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1, dst2; > v16i8 shuffler0 = {2, 1, 0, 6, 5, 4, 10, 9, 8, 14, 13, 12, 18, 17, 16, 22}; >@@ -980,7 +980,7 @@ void ARGBToRAWRow_MSA(const uint8* src_argb, uint8* dst_rgb, int width) { > } > } > >-void ARGBToRGB565Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width) { >+void ARGBToRGB565Row_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { > int x; > v16u8 src0, src1, dst0; > v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; >@@ -1014,7 +1014,9 @@ void ARGBToRGB565Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width) { > } > } > >-void ARGBToARGB1555Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width) { >+void ARGBToARGB1555Row_MSA(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ int width) { > int x; > v16u8 src0, src1, dst0; > v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; >@@ -1054,7 +1056,9 @@ void ARGBToARGB1555Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width) { > } > } > >-void ARGBToARGB4444Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width) { >+void ARGBToARGB4444Row_MSA(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ int width) { > int x; > v16u8 src0, src1; > v16u8 vec0, vec1; >@@ -1077,11 +1081,11 @@ void ARGBToARGB4444Row_MSA(const uint8* src_argb, uint8* dst_rgb, int width) { > } > } > >-void ARGBToUV444Row_MSA(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >- int32 width) { >- int32 x; >+void ARGBToUV444Row_MSA(const uint8_t* src_argb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, >+ int32_t width) { >+ int32_t x; > v16u8 src0, src1, src2, src3, reg0, reg1, reg2, reg3, dst0, dst1; > v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; > v8u16 vec8, vec9, vec10, vec11; >@@ -1149,9 +1153,9 @@ void ARGBToUV444Row_MSA(const uint8* src_argb, > } > } > >-void ARGBMultiplyRow_MSA(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_MSA(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > int x; > v16u8 src0, src1, dst0; >@@ -1188,9 +1192,9 @@ void ARGBMultiplyRow_MSA(const uint8* src_argb0, > } > } > >-void ARGBAddRow_MSA(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_MSA(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1; >@@ -1209,9 +1213,9 @@ void ARGBAddRow_MSA(const uint8* src_argb0, > } > } > >-void ARGBSubtractRow_MSA(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_MSA(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1; >@@ -1230,7 +1234,9 @@ void ARGBSubtractRow_MSA(const uint8* src_argb0, > } > } > >-void ARGBAttenuateRow_MSA(const uint8* src_argb, uint8* dst_argb, int width) { >+void ARGBAttenuateRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width) { > int x; > v16u8 src0, src1, dst0, dst1; > v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; >@@ -1295,9 +1301,9 @@ void ARGBAttenuateRow_MSA(const uint8* src_argb, uint8* dst_argb, int width) { > } > } > >-void ARGBToRGB565DitherRow_MSA(const uint8* src_argb, >- uint8* dst_rgb, >- uint32 dither4, >+void ARGBToRGB565DitherRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ uint32_t dither4, > int width) { > int x; > v16u8 src0, src1, dst0, vec0, vec1; >@@ -1339,15 +1345,15 @@ void ARGBToRGB565DitherRow_MSA(const uint8* src_argb, > } > } > >-void ARGBShuffleRow_MSA(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width) { > int x; > v16u8 src0, src1, dst0, dst1; > v16i8 vec0; > v16i8 shuffler_vec = {0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12}; >- int32 val = LW((int32*)shuffler); >+ int32_t val = LW((int32_t*)shuffler); > > vec0 = (v16i8)__msa_fill_w(val); > shuffler_vec += vec0; >@@ -1363,10 +1369,10 @@ void ARGBShuffleRow_MSA(const uint8* src_argb, > } > } > >-void ARGBShadeRow_MSA(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBShadeRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- uint32 value) { >+ uint32_t value) { > int x; > v16u8 src0, dst0; > v8u16 vec0, vec1; >@@ -1402,7 +1408,7 @@ void ARGBShadeRow_MSA(const uint8* src_argb, > } > } > >-void ARGBGrayRow_MSA(const uint8* src_argb, uint8* dst_argb, int width) { >+void ARGBGrayRow_MSA(const uint8_t* src_argb, uint8_t* dst_argb, int width) { > int x; > v16u8 src0, src1, vec0, vec1, dst0, dst1; > v8u16 reg0; >@@ -1427,7 +1433,7 @@ void ARGBGrayRow_MSA(const uint8* src_argb, uint8* dst_argb, int width) { > } > } > >-void ARGBSepiaRow_MSA(uint8* dst_argb, int width) { >+void ARGBSepiaRow_MSA(uint8_t* dst_argb, int width) { > int x; > v16u8 src0, src1, dst0, dst1, vec0, vec1, vec2, vec3, vec4, vec5; > v8u16 reg0, reg1, reg2; >@@ -1468,8 +1474,8 @@ void ARGBSepiaRow_MSA(uint8* dst_argb, int width) { > } > } > >-void ARGB4444ToARGBRow_MSA(const uint8* src_argb4444, >- uint8* dst_argb, >+void ARGB4444ToARGBRow_MSA(const uint8_t* src_argb4444, >+ uint8_t* dst_argb, > int width) { > int x; > v16u8 src0, src1; >@@ -1497,8 +1503,8 @@ void ARGB4444ToARGBRow_MSA(const uint8* src_argb4444, > } > } > >-void ARGB1555ToARGBRow_MSA(const uint8* src_argb1555, >- uint8* dst_argb, >+void ARGB1555ToARGBRow_MSA(const uint8_t* src_argb1555, >+ uint8_t* dst_argb, > int width) { > int x; > v8u16 src0, src1; >@@ -1547,7 +1553,9 @@ void ARGB1555ToARGBRow_MSA(const uint8* src_argb1555, > } > } > >-void RGB565ToARGBRow_MSA(const uint8* src_rgb565, uint8* dst_argb, int width) { >+void RGB565ToARGBRow_MSA(const uint8_t* src_rgb565, >+ uint8_t* dst_argb, >+ int width) { > int x; > v8u16 src0, src1, vec0, vec1, vec2, vec3, vec4, vec5; > v8u16 reg0, reg1, reg2, reg3, reg4, reg5; >@@ -1592,7 +1600,9 @@ void RGB565ToARGBRow_MSA(const uint8* src_rgb565, uint8* dst_argb, int width) { > } > } > >-void RGB24ToARGBRow_MSA(const uint8* src_rgb24, uint8* dst_argb, int width) { >+void RGB24ToARGBRow_MSA(const uint8_t* src_rgb24, >+ uint8_t* dst_argb, >+ int width) { > int x; > v16u8 src0, src1, src2; > v16u8 vec0, vec1, vec2; >@@ -1617,7 +1627,7 @@ void RGB24ToARGBRow_MSA(const uint8* src_rgb24, uint8* dst_argb, int width) { > } > } > >-void RAWToARGBRow_MSA(const uint8* src_raw, uint8* dst_argb, int width) { >+void RAWToARGBRow_MSA(const uint8_t* src_raw, uint8_t* dst_argb, int width) { > int x; > v16u8 src0, src1, src2; > v16u8 vec0, vec1, vec2; >@@ -1642,7 +1652,9 @@ void RAWToARGBRow_MSA(const uint8* src_raw, uint8* dst_argb, int width) { > } > } > >-void ARGB1555ToYRow_MSA(const uint8* src_argb1555, uint8* dst_y, int width) { >+void ARGB1555ToYRow_MSA(const uint8_t* src_argb1555, >+ uint8_t* dst_y, >+ int width) { > int x; > v8u16 src0, src1, vec0, vec1, vec2, vec3, vec4, vec5; > v8u16 reg0, reg1, reg2, reg3, reg4, reg5; >@@ -1699,7 +1711,7 @@ void ARGB1555ToYRow_MSA(const uint8* src_argb1555, uint8* dst_y, int width) { > } > } > >-void RGB565ToYRow_MSA(const uint8* src_rgb565, uint8* dst_y, int width) { >+void RGB565ToYRow_MSA(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { > int x; > v8u16 src0, src1, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; > v8u16 reg0, reg1, reg2, reg3, reg4, reg5; >@@ -1762,7 +1774,7 @@ void RGB565ToYRow_MSA(const uint8* src_rgb565, uint8* dst_y, int width) { > } > } > >-void RGB24ToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { >+void RGB24ToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { > int x; > v16u8 src0, src1, src2, reg0, reg1, reg2, reg3, dst0; > v8u16 vec0, vec1, vec2, vec3; >@@ -1803,7 +1815,7 @@ void RGB24ToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { > } > } > >-void RAWToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { >+void RAWToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { > int x; > v16u8 src0, src1, src2, reg0, reg1, reg2, reg3, dst0; > v8u16 vec0, vec1, vec2, vec3; >@@ -1844,14 +1856,14 @@ void RAWToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { > } > } > >-void ARGB1555ToUVRow_MSA(const uint8* src_argb1555, >+void ARGB1555ToUVRow_MSA(const uint8_t* src_argb1555, > int src_stride_argb1555, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; >- const uint16* s = (const uint16*)src_argb1555; >- const uint16* t = (const uint16*)(src_argb1555 + src_stride_argb1555); >+ const uint16_t* s = (const uint16_t*)src_argb1555; >+ const uint16_t* t = (const uint16_t*)(src_argb1555 + src_stride_argb1555); > int64_t res0, res1; > v8u16 src0, src1, src2, src3, reg0, reg1, reg2, reg3; > v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6; >@@ -1925,14 +1937,14 @@ void ARGB1555ToUVRow_MSA(const uint8* src_argb1555, > } > } > >-void RGB565ToUVRow_MSA(const uint8* src_rgb565, >+void RGB565ToUVRow_MSA(const uint8_t* src_rgb565, > int src_stride_rgb565, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; >- const uint16* s = (const uint16*)src_rgb565; >- const uint16* t = (const uint16*)(src_rgb565 + src_stride_rgb565); >+ const uint16_t* s = (const uint16_t*)src_rgb565; >+ const uint16_t* t = (const uint16_t*)(src_rgb565 + src_stride_rgb565); > int64_t res0, res1; > v8u16 src0, src1, src2, src3, reg0, reg1, reg2, reg3; > v8u16 vec0, vec1, vec2, vec3, vec4, vec5; >@@ -2005,15 +2017,15 @@ void RGB565ToUVRow_MSA(const uint8* src_rgb565, > } > } > >-void RGB24ToUVRow_MSA(const uint8* src_rgb0, >+void RGB24ToUVRow_MSA(const uint8_t* src_rgb0, > int src_stride_rgb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; >- const uint8* s = src_rgb0; >- const uint8* t = src_rgb0 + src_stride_rgb; >- int64 res0, res1; >+ const uint8_t* s = src_rgb0; >+ const uint8_t* t = src_rgb0 + src_stride_rgb; >+ int64_t res0, res1; > v16u8 src0, src1, src2, src3, src4, src5, src6, src7; > v16u8 inp0, inp1, inp2, inp3, inp4, inp5; > v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; >@@ -2110,15 +2122,15 @@ void RGB24ToUVRow_MSA(const uint8* src_rgb0, > } > } > >-void RAWToUVRow_MSA(const uint8* src_rgb0, >+void RAWToUVRow_MSA(const uint8_t* src_rgb0, > int src_stride_rgb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; >- const uint8* s = src_rgb0; >- const uint8* t = src_rgb0 + src_stride_rgb; >- int64 res0, res1; >+ const uint8_t* s = src_rgb0; >+ const uint8_t* t = src_rgb0 + src_stride_rgb; >+ int64_t res0, res1; > v16u8 inp0, inp1, inp2, inp3, inp4, inp5; > v16u8 src0, src1, src2, src3, src4, src5, src6, src7; > v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; >@@ -2215,13 +2227,13 @@ void RAWToUVRow_MSA(const uint8* src_rgb0, > } > } > >-void NV12ToARGBRow_MSA(const uint8* src_y, >- const uint8* src_uv, >- uint8* rgb_buf, >+void NV12ToARGBRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > int x; >- uint64 val0, val1; >+ uint64_t val0, val1; > v16u8 src0, src1, res0, res1, dst0, dst1; > v8i16 vec0, vec1, vec2; > v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; >@@ -2245,20 +2257,20 @@ void NV12ToARGBRow_MSA(const uint8* src_y, > res1 = (v16u8)__msa_ilvev_b((v16i8)alpha, (v16i8)vec1); > dst0 = (v16u8)__msa_ilvr_b((v16i8)res1, (v16i8)res0); > dst1 = (v16u8)__msa_ilvl_b((v16i8)res1, (v16i8)res0); >- ST_UB2(dst0, dst1, rgb_buf, 16); >+ ST_UB2(dst0, dst1, dst_argb, 16); > src_y += 8; > src_uv += 8; >- rgb_buf += 32; >+ dst_argb += 32; > } > } > >-void NV12ToRGB565Row_MSA(const uint8* src_y, >- const uint8* src_uv, >- uint8* rgb_buf, >+void NV12ToRGB565Row_MSA(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { > int x; >- uint64 val0, val1; >+ uint64_t val0, val1; > v16u8 src0, src1, dst0; > v8i16 vec0, vec1, vec2; > v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; >@@ -2281,20 +2293,20 @@ void NV12ToRGB565Row_MSA(const uint8* src_y, > vec1 = (vec1 >> 2) << 5; > vec2 = (vec2 >> 3) << 11; > dst0 = (v16u8)(vec0 | vec1 | vec2); >- ST_UB(dst0, rgb_buf); >+ ST_UB(dst0, dst_rgb565); > src_y += 8; > src_uv += 8; >- rgb_buf += 16; >+ dst_rgb565 += 16; > } > } > >-void NV21ToARGBRow_MSA(const uint8* src_y, >- const uint8* src_vu, >- uint8* rgb_buf, >+void NV21ToARGBRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > int x; >- uint64 val0, val1; >+ uint64_t val0, val1; > v16u8 src0, src1, res0, res1, dst0, dst1; > v8i16 vec0, vec1, vec2; > v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; >@@ -2320,16 +2332,16 @@ void NV21ToARGBRow_MSA(const uint8* src_y, > res1 = (v16u8)__msa_ilvev_b((v16i8)alpha, (v16i8)vec1); > dst0 = (v16u8)__msa_ilvr_b((v16i8)res1, (v16i8)res0); > dst1 = (v16u8)__msa_ilvl_b((v16i8)res1, (v16i8)res0); >- ST_UB2(dst0, dst1, rgb_buf, 16); >+ ST_UB2(dst0, dst1, dst_argb, 16); > src_y += 8; > src_vu += 8; >- rgb_buf += 32; >+ dst_argb += 32; > } > } > >-void SobelRow_MSA(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_MSA(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { > int x; > v16u8 src0, src1, vec0, dst0, dst1, dst2, dst3; >@@ -2355,9 +2367,9 @@ void SobelRow_MSA(const uint8* src_sobelx, > } > } > >-void SobelToPlaneRow_MSA(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_MSA(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_y, > int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1; >@@ -2376,9 +2388,9 @@ void SobelToPlaneRow_MSA(const uint8* src_sobelx, > } > } > >-void SobelXYRow_MSA(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_MSA(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { > int x; > v16u8 src0, src1, vec0, vec1, vec2; >@@ -2404,7 +2416,7 @@ void SobelXYRow_MSA(const uint8* src_sobelx, > } > } > >-void ARGBToYJRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { >+void ARGBToYJRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { > int x; > v16u8 src0, src1, src2, src3, dst0; > v16u8 const_0x4B0F = (v16u8)__msa_fill_h(0x4B0F); >@@ -2424,7 +2436,7 @@ void ARGBToYJRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { > } > } > >-void BGRAToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { >+void BGRAToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { > int x; > v16u8 src0, src1, src2, src3, dst0; > v16u8 const_0x4200 = (v16u8)__msa_fill_h(0x4200); >@@ -2444,7 +2456,7 @@ void BGRAToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { > } > } > >-void ABGRToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { >+void ABGRToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { > int x; > v16u8 src0, src1, src2, src3, dst0; > v16u8 const_0x8142 = (v16u8)__msa_fill_h(0x8142); >@@ -2464,7 +2476,7 @@ void ABGRToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { > } > } > >-void RGBAToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { >+void RGBAToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { > int x; > v16u8 src0, src1, src2, src3, dst0; > v16u8 const_0x1900 = (v16u8)__msa_fill_h(0x1900); >@@ -2484,14 +2496,14 @@ void RGBAToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) { > } > } > >-void ARGBToUVJRow_MSA(const uint8* src_rgb0, >+void ARGBToUVJRow_MSA(const uint8_t* src_rgb0, > int src_stride_rgb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; >- const uint8* s = src_rgb0; >- const uint8* t = src_rgb0 + src_stride_rgb; >+ const uint8_t* s = src_rgb0; >+ const uint8_t* t = src_rgb0 + src_stride_rgb; > v16u8 src0, src1, src2, src3, src4, src5, src6, src7; > v16u8 vec0, vec1, vec2, vec3; > v16u8 dst0, dst1; >@@ -2554,14 +2566,14 @@ void ARGBToUVJRow_MSA(const uint8* src_rgb0, > } > } > >-void BGRAToUVRow_MSA(const uint8* src_rgb0, >+void BGRAToUVRow_MSA(const uint8_t* src_rgb0, > int src_stride_rgb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; >- const uint8* s = src_rgb0; >- const uint8* t = src_rgb0 + src_stride_rgb; >+ const uint8_t* s = src_rgb0; >+ const uint8_t* t = src_rgb0 + src_stride_rgb; > v16u8 dst0, dst1, vec0, vec1, vec2, vec3; > v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; > v16i8 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15, >@@ -2587,14 +2599,14 @@ void BGRAToUVRow_MSA(const uint8* src_rgb0, > } > } > >-void ABGRToUVRow_MSA(const uint8* src_rgb0, >+void ABGRToUVRow_MSA(const uint8_t* src_rgb0, > int src_stride_rgb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; >- const uint8* s = src_rgb0; >- const uint8* t = src_rgb0 + src_stride_rgb; >+ const uint8_t* s = src_rgb0; >+ const uint8_t* t = src_rgb0 + src_stride_rgb; > v16u8 src0, src1, src2, src3; > v16u8 dst0, dst1; > v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; >@@ -2621,14 +2633,14 @@ void ABGRToUVRow_MSA(const uint8* src_rgb0, > } > } > >-void RGBAToUVRow_MSA(const uint8* src_rgb0, >+void RGBAToUVRow_MSA(const uint8_t* src_rgb0, > int src_stride_rgb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; >- const uint8* s = src_rgb0; >- const uint8* t = src_rgb0 + src_stride_rgb; >+ const uint8_t* s = src_rgb0; >+ const uint8_t* t = src_rgb0 + src_stride_rgb; > v16u8 dst0, dst1, vec0, vec1, vec2, vec3; > v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; > v16i8 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15, >@@ -2654,10 +2666,10 @@ void RGBAToUVRow_MSA(const uint8* src_rgb0, > } > } > >-void I444ToARGBRow_MSA(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* rgb_buf, >+void I444ToARGBRow_MSA(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -2714,15 +2726,15 @@ void I444ToARGBRow_MSA(const uint8* src_y, > vec1 = (v8u16)__msa_ilvev_b((v16i8)alpha, (v16i8)vec2); > dst0 = (v16u8)__msa_ilvr_h((v8i16)vec1, (v8i16)vec0); > dst1 = (v16u8)__msa_ilvl_h((v8i16)vec1, (v8i16)vec0); >- ST_UB2(dst0, dst1, rgb_buf, 16); >+ ST_UB2(dst0, dst1, dst_argb, 16); > src_y += 8; > src_u += 8; > src_v += 8; >- rgb_buf += 32; >+ dst_argb += 32; > } > } > >-void I400ToARGBRow_MSA(const uint8* src_y, uint8* rgb_buf, int width) { >+void I400ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, int width) { > int x; > v16u8 src0, res0, res1, res2, res3, res4, dst0, dst1, dst2, dst3; > v8i16 vec0, vec1; >@@ -2768,13 +2780,13 @@ void I400ToARGBRow_MSA(const uint8* src_y, uint8* rgb_buf, int width) { > dst1 = (v16u8)__msa_ilvl_b((v16i8)res3, (v16i8)res1); > dst2 = (v16u8)__msa_ilvr_b((v16i8)res4, (v16i8)res2); > dst3 = (v16u8)__msa_ilvl_b((v16i8)res4, (v16i8)res2); >- ST_UB4(dst0, dst1, dst2, dst3, rgb_buf, 16); >+ ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); > src_y += 16; >- rgb_buf += 64; >+ dst_argb += 64; > } > } > >-void J400ToARGBRow_MSA(const uint8* src_y, uint8* dst_argb, int width) { >+void J400ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, int width) { > int x; > v16u8 src0, vec0, vec1, vec2, vec3, dst0, dst1, dst2, dst3; > v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); >@@ -2795,8 +2807,8 @@ void J400ToARGBRow_MSA(const uint8* src_y, uint8* dst_argb, int width) { > } > } > >-void YUY2ToARGBRow_MSA(const uint8* src_yuy2, >- uint8* rgb_buf, >+void YUY2ToARGBRow_MSA(const uint8_t* src_yuy2, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -2817,14 +2829,14 @@ void YUY2ToARGBRow_MSA(const uint8* src_yuy2, > src2 = (v16u8)__msa_pckod_b((v16i8)src0, (v16i8)src0); > YUVTORGB(src1, src2, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, > vec0, vec1, vec2); >- STOREARGB(vec0, vec1, vec2, alpha, rgb_buf); >+ STOREARGB(vec0, vec1, vec2, alpha, dst_argb); > src_yuy2 += 16; >- rgb_buf += 32; >+ dst_argb += 32; > } > } > >-void UYVYToARGBRow_MSA(const uint8* src_uyvy, >- uint8* rgb_buf, >+void UYVYToARGBRow_MSA(const uint8_t* src_uyvy, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > int x; >@@ -2845,22 +2857,22 @@ void UYVYToARGBRow_MSA(const uint8* src_uyvy, > src2 = (v16u8)__msa_pckev_b((v16i8)src0, (v16i8)src0); > YUVTORGB(src1, src2, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, > vec0, vec1, vec2); >- STOREARGB(vec0, vec1, vec2, alpha, rgb_buf); >+ STOREARGB(vec0, vec1, vec2, alpha, dst_argb); > src_uyvy += 16; >- rgb_buf += 32; >+ dst_argb += 32; > } > } > >-void InterpolateRow_MSA(uint8* dst_ptr, >- const uint8* src_ptr, >+void InterpolateRow_MSA(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride, > int width, >- int32 source_y_fraction) { >- int32 y1_fraction = source_y_fraction; >- int32 y0_fraction = 256 - y1_fraction; >- uint16 y_fractions; >- const uint8* s = src_ptr; >- const uint8* t = src_ptr + src_stride; >+ int32_t source_y_fraction) { >+ int32_t y1_fraction = source_y_fraction; >+ int32_t y0_fraction = 256 - y1_fraction; >+ uint16_t y_fractions; >+ const uint8_t* s = src_ptr; >+ const uint8_t* t = src_ptr + src_stride; > int x; > v16u8 src0, src1, src2, src3, dst0, dst1; > v8u16 vec0, vec1, vec2, vec3, y_frac; >@@ -2886,7 +2898,7 @@ void InterpolateRow_MSA(uint8* dst_ptr, > return; > } > >- y_fractions = (uint16)(y0_fraction + (y1_fraction << 8)); >+ y_fractions = (uint16_t)(y0_fraction + (y1_fraction << 8)); > y_frac = (v8u16)__msa_fill_h(y_fractions); > > for (x = 0; x < width; x += 32) { >@@ -2915,7 +2927,7 @@ void InterpolateRow_MSA(uint8* dst_ptr, > } > } > >-void ARGBSetRow_MSA(uint8* dst_argb, uint32 v32, int width) { >+void ARGBSetRow_MSA(uint8_t* dst_argb, uint32_t v32, int width) { > int x; > v4i32 dst0 = __builtin_msa_fill_w(v32); > >@@ -2925,7 +2937,7 @@ void ARGBSetRow_MSA(uint8* dst_argb, uint32 v32, int width) { > } > } > >-void RAWToRGB24Row_MSA(const uint8* src_raw, uint8* dst_rgb24, int width) { >+void RAWToRGB24Row_MSA(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { > int x; > v16u8 src0, src1, src2, src3, src4, dst0, dst1, dst2; > v16i8 shuffler0 = {2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, 17}; >@@ -2950,9 +2962,9 @@ void RAWToRGB24Row_MSA(const uint8* src_raw, uint8* dst_rgb24, int width) { > } > } > >-void MergeUVRow_MSA(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_MSA(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width) { > int x; > v16u8 src0, src1, dst0, dst1; >@@ -2969,7 +2981,9 @@ void MergeUVRow_MSA(const uint8* src_u, > } > } > >-void ARGBExtractAlphaRow_MSA(const uint8* src_argb, uint8* dst_a, int width) { >+void ARGBExtractAlphaRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_a, >+ int width) { > int i; > v16u8 src0, src1, src2, src3, vec0, vec1, dst0; > >@@ -2987,9 +3001,9 @@ void ARGBExtractAlphaRow_MSA(const uint8* src_argb, uint8* dst_a, int width) { > } > } > >-void ARGBBlendRow_MSA(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBBlendRow_MSA(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1; >@@ -3052,7 +3066,7 @@ void ARGBBlendRow_MSA(const uint8* src_argb0, > } > } > >-void ARGBQuantizeRow_MSA(uint8* dst_argb, >+void ARGBQuantizeRow_MSA(uint8_t* dst_argb, > int scale, > int interval_size, > int interval_offset, >@@ -3158,11 +3172,11 @@ void ARGBQuantizeRow_MSA(uint8* dst_argb, > } > } > >-void ARGBColorMatrixRow_MSA(const uint8* src_argb, >- uint8* dst_argb, >- const int8* matrix_argb, >+void ARGBColorMatrixRow_MSA(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const int8_t* matrix_argb, > int width) { >- int32 x; >+ int32_t x; > v16i8 src0; > v16u8 src1, src2, dst0, dst1; > v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; >@@ -3267,9 +3281,9 @@ void ARGBColorMatrixRow_MSA(const uint8* src_argb, > } > } > >-void SplitUVRow_MSA(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void SplitUVRow_MSA(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; > v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3; >@@ -3291,7 +3305,7 @@ void SplitUVRow_MSA(const uint8* src_uv, > } > } > >-void SetRow_MSA(uint8* dst, uint8 v8, int width) { >+void SetRow_MSA(uint8_t* dst, uint8_t v8, int width) { > int x; > v16u8 dst0 = (v16u8)__msa_fill_b(v8); > >@@ -3301,9 +3315,9 @@ void SetRow_MSA(uint8* dst, uint8 v8, int width) { > } > } > >-void MirrorUVRow_MSA(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void MirrorUVRow_MSA(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > int x; > v16u8 src0, src1, src2, src3; >@@ -3330,11 +3344,11 @@ void MirrorUVRow_MSA(const uint8* src_uv, > } > } > >-void SobelXRow_MSA(const uint8* src_y0, >- const uint8* src_y1, >- const uint8* src_y2, >- uint8* dst_sobelx, >- int32 width) { >+void SobelXRow_MSA(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ const uint8_t* src_y2, >+ uint8_t* dst_sobelx, >+ int32_t width) { > int x; > v16u8 src0, src1, src2, src3, src4, src5, dst0; > v8i16 vec0, vec1, vec2, vec3, vec4, vec5; >@@ -3384,10 +3398,10 @@ void SobelXRow_MSA(const uint8* src_y0, > } > } > >-void SobelYRow_MSA(const uint8* src_y0, >- const uint8* src_y1, >- uint8* dst_sobely, >- int32 width) { >+void SobelYRow_MSA(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ uint8_t* dst_sobely, >+ int32_t width) { > int x; > v16u8 src0, src1, dst0; > v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6; >@@ -3429,7 +3443,10 @@ void SobelYRow_MSA(const uint8* src_y0, > } > } > >-void HalfFloatRow_MSA(const uint16* src, uint16* dst, float scale, int width) { >+void HalfFloatRow_MSA(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width) { > int i; > v8u16 src0, src1, src2, src3, dst0, dst1, dst2, dst3; > v4u32 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_neon.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_neon.cc >index 1af828622cdd1d55c6190ac8aa142edae43c43d3..8b6c19520722988b59ba061e1b0ec5a9d889c66d 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_neon.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_neon.cc >@@ -106,10 +106,10 @@ extern "C" { > "vqshrun.s16 d22, q9, #6 \n" /* R */ \ > "vqshrun.s16 d21, q0, #6 \n" /* G */ > >-void I444ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( >@@ -132,10 +132,10 @@ void I444ToARGBRow_NEON(const uint8* src_y, > "q12", "q13", "q14", "q15"); > } > >-void I422ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( >@@ -158,11 +158,11 @@ void I422ToARGBRow_NEON(const uint8* src_y, > "q12", "q13", "q14", "q15"); > } > >-void I422AlphaToARGBRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- const uint8* src_a, >- uint8* dst_argb, >+void I422AlphaToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ const uint8_t* src_a, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( >@@ -186,18 +186,17 @@ void I422AlphaToARGBRow_NEON(const uint8* src_y, > "q12", "q13", "q14", "q15"); > } > >-void I422ToRGBARow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToRGBARow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgba, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( > YUVTORGB_SETUP > "1: \n" READYUV422 YUVTORGB > "subs %4, %4, #8 \n" >- "vmov.u8 d19, #255 \n" // d19 modified by >- // YUVTORGB >+ "vmov.u8 d19, #255 \n" // YUVTORGB modified d19 > "vst4.8 {d19, d20, d21, d22}, [%3]! \n" > "bgt 1b \n" > : "+r"(src_y), // %0 >@@ -213,10 +212,10 @@ void I422ToRGBARow_NEON(const uint8* src_y, > "q12", "q13", "q14", "q15"); > } > >-void I422ToRGB24Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb24, >+void I422ToRGB24Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb24, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( >@@ -245,10 +244,10 @@ void I422ToRGB24Row_NEON(const uint8* src_y, > "vsri.16 q0, q8, #5 \n" /* RG */ \ > "vsri.16 q0, q9, #11 \n" /* RGB */ > >-void I422ToRGB565Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb565, >+void I422ToRGB565Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( >@@ -279,10 +278,10 @@ void I422ToRGB565Row_NEON(const uint8* src_y, > "vsri.16 q0, q9, #6 \n" /* ARG */ \ > "vsri.16 q0, q10, #11 \n" /* ARGB */ > >-void I422ToARGB1555Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb1555, >+void I422ToARGB1555Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( >@@ -291,7 +290,6 @@ void I422ToARGB1555Row_NEON(const uint8* src_y, > "subs %4, %4, #8 \n" > "vmov.u8 d23, #255 \n" ARGBTOARGB1555 > "vst1.8 {q0}, [%3]! \n" // store 8 pixels >- // ARGB1555. > "bgt 1b \n" > : "+r"(src_y), // %0 > "+r"(src_u), // %1 >@@ -315,21 +313,21 @@ void I422ToARGB1555Row_NEON(const uint8* src_y, > "vorr d1, d22, d23 \n" /* RA */ \ > "vzip.u8 d0, d1 \n" /* BGRA */ > >-void I422ToARGB4444Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB4444Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( > YUVTORGB_SETUP >- "vmov.u8 d4, #0x0f \n" // bits to clear with >- // vbic. >- "1: \n" READYUV422 YUVTORGB >+ "vmov.u8 d4, #0x0f \n" // vbic bits to clear >+ "1: \n" >+ >+ READYUV422 YUVTORGB > "subs %4, %4, #8 \n" > "vmov.u8 d23, #255 \n" ARGBTOARGB4444 > "vst1.8 {q0}, [%3]! \n" // store 8 pixels >- // ARGB4444. > "bgt 1b \n" > : "+r"(src_y), // %0 > "+r"(src_u), // %1 >@@ -344,7 +342,7 @@ void I422ToARGB4444Row_NEON(const uint8* src_y, > "q12", "q13", "q14", "q15"); > } > >-void I400ToARGBRow_NEON(const uint8* src_y, uint8* dst_argb, int width) { >+void I400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { > asm volatile( > YUVTORGB_SETUP > "vmov.u8 d23, #255 \n" >@@ -363,7 +361,7 @@ void I400ToARGBRow_NEON(const uint8* src_y, uint8* dst_argb, int width) { > "q12", "q13", "q14", "q15"); > } > >-void J400ToARGBRow_NEON(const uint8* src_y, uint8* dst_argb, int width) { >+void J400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { > asm volatile( > "vmov.u8 d23, #255 \n" > "1: \n" >@@ -380,9 +378,9 @@ void J400ToARGBRow_NEON(const uint8* src_y, uint8* dst_argb, int width) { > : "cc", "memory", "d20", "d21", "d22", "d23"); > } > >-void NV12ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile(YUVTORGB_SETUP >@@ -403,9 +401,9 @@ void NV12ToARGBRow_NEON(const uint8* src_y, > "q10", "q11", "q12", "q13", "q14", "q15"); > } > >-void NV21ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_vu, >- uint8* dst_argb, >+void NV21ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile(YUVTORGB_SETUP >@@ -426,9 +424,63 @@ void NV21ToARGBRow_NEON(const uint8* src_y, > "q10", "q11", "q12", "q13", "q14", "q15"); > } > >-void NV12ToRGB565Row_NEON(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_rgb565, >+void NV12ToRGB24Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb24, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ asm volatile( >+ >+ YUVTORGB_SETUP >+ >+ "1: \n" >+ >+ READNV12 YUVTORGB >+ "subs %3, %3, #8 \n" >+ "vst3.8 {d20, d21, d22}, [%2]! \n" >+ "bgt 1b \n" >+ : "+r"(src_y), // %0 >+ "+r"(src_uv), // %1 >+ "+r"(dst_rgb24), // %2 >+ "+r"(width) // %3 >+ : [kUVToRB] "r"(&yuvconstants->kUVToRB), >+ [kUVToG] "r"(&yuvconstants->kUVToG), >+ [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), >+ [kYToRgb] "r"(&yuvconstants->kYToRgb) >+ : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", >+ "q12", "q13", "q14", "q15"); >+} >+ >+void NV21ToRGB24Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* dst_rgb24, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ asm volatile( >+ >+ YUVTORGB_SETUP >+ >+ "1: \n" >+ >+ READNV21 YUVTORGB >+ "subs %3, %3, #8 \n" >+ "vst3.8 {d20, d21, d22}, [%2]! \n" >+ "bgt 1b \n" >+ : "+r"(src_y), // %0 >+ "+r"(src_vu), // %1 >+ "+r"(dst_rgb24), // %2 >+ "+r"(width) // %3 >+ : [kUVToRB] "r"(&yuvconstants->kUVToRB), >+ [kUVToG] "r"(&yuvconstants->kUVToG), >+ [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), >+ [kYToRgb] "r"(&yuvconstants->kYToRgb) >+ : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", >+ "q12", "q13", "q14", "q15"); >+} >+ >+void NV12ToRGB565Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( >@@ -449,8 +501,8 @@ void NV12ToRGB565Row_NEON(const uint8* src_y, > "q12", "q13", "q14", "q15"); > } > >-void YUY2ToARGBRow_NEON(const uint8* src_yuy2, >- uint8* dst_argb, >+void YUY2ToARGBRow_NEON(const uint8_t* src_yuy2, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile(YUVTORGB_SETUP >@@ -470,8 +522,8 @@ void YUY2ToARGBRow_NEON(const uint8* src_yuy2, > "q10", "q11", "q12", "q13", "q14", "q15"); > } > >-void UYVYToARGBRow_NEON(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_NEON(const uint8_t* src_uyvy, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile(YUVTORGB_SETUP >@@ -492,9 +544,9 @@ void UYVYToARGBRow_NEON(const uint8* src_uyvy, > } > > // Reads 16 pairs of UV and write even values to dst_u and odd to dst_v. >-void SplitUVRow_NEON(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void SplitUVRow_NEON(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "1: \n" >@@ -513,9 +565,9 @@ void SplitUVRow_NEON(const uint8* src_uv, > } > > // Reads 16 U's and V's and writes out 16 pairs of UV. >-void MergeUVRow_NEON(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_NEON(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width) { > asm volatile( > "1: \n" >@@ -534,10 +586,10 @@ void MergeUVRow_NEON(const uint8* src_u, > } > > // Reads 16 packed RGB and write to planar dst_r, dst_g, dst_b. >-void SplitRGBRow_NEON(const uint8* src_rgb, >- uint8* dst_r, >- uint8* dst_g, >- uint8* dst_b, >+void SplitRGBRow_NEON(const uint8_t* src_rgb, >+ uint8_t* dst_r, >+ uint8_t* dst_g, >+ uint8_t* dst_b, > int width) { > asm volatile( > "1: \n" >@@ -559,10 +611,10 @@ void SplitRGBRow_NEON(const uint8* src_rgb, > } > > // Reads 16 planar R's, G's and B's and writes out 16 packed RGB at a time >-void MergeRGBRow_NEON(const uint8* src_r, >- const uint8* src_g, >- const uint8* src_b, >- uint8* dst_rgb, >+void MergeRGBRow_NEON(const uint8_t* src_r, >+ const uint8_t* src_g, >+ const uint8_t* src_b, >+ uint8_t* dst_rgb, > int width) { > asm volatile( > "1: \n" >@@ -584,7 +636,7 @@ void MergeRGBRow_NEON(const uint8* src_r, > } > > // Copy multiple of 32. vld4.8 allow unaligned and is fastest on a15. >-void CopyRow_NEON(const uint8* src, uint8* dst, int count) { >+void CopyRow_NEON(const uint8_t* src, uint8_t* dst, int width) { > asm volatile( > "1: \n" > "vld1.8 {d0, d1, d2, d3}, [%0]! \n" // load 32 >@@ -593,14 +645,14 @@ void CopyRow_NEON(const uint8* src, uint8* dst, int count) { > "bgt 1b \n" > : "+r"(src), // %0 > "+r"(dst), // %1 >- "+r"(count) // %2 // Output registers >+ "+r"(width) // %2 // Output registers > : // Input registers > : "cc", "memory", "q0", "q1" // Clobber List > ); > } > >-// SetRow writes 'count' bytes using an 8 bit value repeated. >-void SetRow_NEON(uint8* dst, uint8 v8, int count) { >+// SetRow writes 'width' bytes using an 8 bit value repeated. >+void SetRow_NEON(uint8_t* dst, uint8_t v8, int width) { > asm volatile( > "vdup.8 q0, %2 \n" // duplicate 16 bytes > "1: \n" >@@ -608,13 +660,13 @@ void SetRow_NEON(uint8* dst, uint8 v8, int count) { > "vst1.8 {q0}, [%0]! \n" // store > "bgt 1b \n" > : "+r"(dst), // %0 >- "+r"(count) // %1 >+ "+r"(width) // %1 > : "r"(v8) // %2 > : "cc", "memory", "q0"); > } > >-// ARGBSetRow writes 'count' pixels using an 32 bit value repeated. >-void ARGBSetRow_NEON(uint8* dst, uint32 v32, int count) { >+// ARGBSetRow writes 'width' pixels using an 32 bit value repeated. >+void ARGBSetRow_NEON(uint8_t* dst, uint32_t v32, int width) { > asm volatile( > "vdup.u32 q0, %2 \n" // duplicate 4 ints > "1: \n" >@@ -622,12 +674,12 @@ void ARGBSetRow_NEON(uint8* dst, uint32 v32, int count) { > "vst1.8 {q0}, [%0]! \n" // store > "bgt 1b \n" > : "+r"(dst), // %0 >- "+r"(count) // %1 >+ "+r"(width) // %1 > : "r"(v32) // %2 > : "cc", "memory", "q0"); > } > >-void MirrorRow_NEON(const uint8* src, uint8* dst, int width) { >+void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { > asm volatile( > // Start at end of source row. > "mov r3, #-16 \n" >@@ -648,9 +700,9 @@ void MirrorRow_NEON(const uint8* src, uint8* dst, int width) { > : "cc", "memory", "r3", "q0"); > } > >-void MirrorUVRow_NEON(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void MirrorUVRow_NEON(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > // Start at end of source row. >@@ -673,7 +725,7 @@ void MirrorUVRow_NEON(const uint8* src_uv, > : "cc", "memory", "r12", "q0"); > } > >-void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width) { >+void ARGBMirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { > asm volatile( > // Start at end of source row. > "mov r3, #-16 \n" >@@ -694,7 +746,9 @@ void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width) { > : "cc", "memory", "r3", "q0"); > } > >-void RGB24ToARGBRow_NEON(const uint8* src_rgb24, uint8* dst_argb, int width) { >+void RGB24ToARGBRow_NEON(const uint8_t* src_rgb24, >+ uint8_t* dst_argb, >+ int width) { > asm volatile( > "vmov.u8 d4, #255 \n" // Alpha > "1: \n" >@@ -710,7 +764,7 @@ void RGB24ToARGBRow_NEON(const uint8* src_rgb24, uint8* dst_argb, int width) { > ); > } > >-void RAWToARGBRow_NEON(const uint8* src_raw, uint8* dst_argb, int width) { >+void RAWToARGBRow_NEON(const uint8_t* src_raw, uint8_t* dst_argb, int width) { > asm volatile( > "vmov.u8 d4, #255 \n" // Alpha > "1: \n" >@@ -727,7 +781,7 @@ void RAWToARGBRow_NEON(const uint8* src_raw, uint8* dst_argb, int width) { > ); > } > >-void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) { >+void RAWToRGB24Row_NEON(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { > asm volatile( > "1: \n" > "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RAW. >@@ -756,7 +810,9 @@ void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) { > "vorr.u8 d2, d1, d5 \n" /* R */ \ > "vorr.u8 d1, d4, d6 \n" /* G */ > >-void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) { >+void RGB565ToARGBRow_NEON(const uint8_t* src_rgb565, >+ uint8_t* dst_argb, >+ int width) { > asm volatile( > "vmov.u8 d3, #255 \n" // Alpha > "1: \n" >@@ -800,8 +856,8 @@ void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) { > "vorr.u8 d2, d1, d5 \n" /* R */ \ > "vorr.u8 d1, d4, d6 \n" /* G */ > >-void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, >- uint8* dst_argb, >+void ARGB1555ToARGBRow_NEON(const uint8_t* src_argb1555, >+ uint8_t* dst_argb, > int width) { > asm volatile( > "vmov.u8 d3, #255 \n" // Alpha >@@ -829,8 +885,8 @@ void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, > "vorr.u8 q1, q1, q2 \n" /* G,A GGGGGGGG */ \ > "vswp.u8 d1, d2 \n" /* B,R,G,A -> B,G,R,A */ > >-void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, >- uint8* dst_argb, >+void ARGB4444ToARGBRow_NEON(const uint8_t* src_argb4444, >+ uint8_t* dst_argb, > int width) { > asm volatile( > "vmov.u8 d3, #255 \n" // Alpha >@@ -848,7 +904,9 @@ void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, > ); > } > >-void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) { >+void ARGBToRGB24Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_rgb24, >+ int width) { > asm volatile( > "1: \n" > "vld4.8 {d1, d2, d3, d4}, [%0]! \n" // load 8 pixels of ARGB. >@@ -864,7 +922,7 @@ void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) { > ); > } > >-void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) { >+void ARGBToRAWRow_NEON(const uint8_t* src_argb, uint8_t* dst_raw, int width) { > asm volatile( > "1: \n" > "vld4.8 {d1, d2, d3, d4}, [%0]! \n" // load 8 pixels of ARGB. >@@ -880,7 +938,7 @@ void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) { > ); > } > >-void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) { >+void YUY2ToYRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { > asm volatile( > "1: \n" > "vld2.8 {q0, q1}, [%0]! \n" // load 16 pixels of YUY2. >@@ -895,7 +953,7 @@ void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) { > ); > } > >-void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) { >+void UYVYToYRow_NEON(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { > asm volatile( > "1: \n" > "vld2.8 {q0, q1}, [%0]! \n" // load 16 pixels of UYVY. >@@ -910,9 +968,9 @@ void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) { > ); > } > >-void YUY2ToUV422Row_NEON(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_NEON(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "1: \n" >@@ -930,9 +988,9 @@ void YUY2ToUV422Row_NEON(const uint8* src_yuy2, > ); > } > >-void UYVYToUV422Row_NEON(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_NEON(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "1: \n" >@@ -950,10 +1008,10 @@ void UYVYToUV422Row_NEON(const uint8* src_uyvy, > ); > } > >-void YUY2ToUVRow_NEON(const uint8* src_yuy2, >+void YUY2ToUVRow_NEON(const uint8_t* src_yuy2, > int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "add %1, %0, %1 \n" // stride + src_yuy2 >@@ -977,10 +1035,10 @@ void YUY2ToUVRow_NEON(const uint8* src_yuy2, > ); > } > >-void UYVYToUVRow_NEON(const uint8* src_uyvy, >+void UYVYToUVRow_NEON(const uint8_t* src_uyvy, > int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "add %1, %0, %1 \n" // stride + src_uyvy >@@ -1005,9 +1063,9 @@ void UYVYToUVRow_NEON(const uint8* src_uyvy, > } > > // For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. >-void ARGBShuffleRow_NEON(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width) { > asm volatile( > "vld1.8 {q2}, [%3] \n" // shuffler >@@ -1026,10 +1084,10 @@ void ARGBShuffleRow_NEON(const uint8* src_argb, > ); > } > >-void I422ToYUY2Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_yuy2, >+void I422ToYUY2Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_yuy2, > int width) { > asm volatile( > "1: \n" >@@ -1048,10 +1106,10 @@ void I422ToYUY2Row_NEON(const uint8* src_y, > : "cc", "memory", "d0", "d1", "d2", "d3"); > } > >-void I422ToUYVYRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uyvy, >+void I422ToUYVYRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uyvy, > int width) { > asm volatile( > "1: \n" >@@ -1070,7 +1128,9 @@ void I422ToUYVYRow_NEON(const uint8* src_y, > : "cc", "memory", "d0", "d1", "d2", "d3"); > } > >-void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) { >+void ARGBToRGB565Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_rgb565, >+ int width) { > asm volatile( > "1: \n" > "vld4.8 {d20, d21, d22, d23}, [%0]! \n" // load 8 pixels of ARGB. >@@ -1085,9 +1145,9 @@ void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) { > : "cc", "memory", "q0", "q8", "q9", "q10", "q11"); > } > >-void ARGBToRGB565DitherRow_NEON(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ const uint32_t dither4, > int width) { > asm volatile( > "vdup.32 d2, %2 \n" // dither4 >@@ -1107,8 +1167,8 @@ void ARGBToRGB565DitherRow_NEON(const uint8* src_argb, > : "cc", "memory", "q0", "q1", "q8", "q9", "q10", "q11"); > } > >-void ARGBToARGB1555Row_NEON(const uint8* src_argb, >- uint8* dst_argb1555, >+void ARGBToARGB1555Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb1555, > int width) { > asm volatile( > "1: \n" >@@ -1124,8 +1184,8 @@ void ARGBToARGB1555Row_NEON(const uint8* src_argb, > : "cc", "memory", "q0", "q8", "q9", "q10", "q11"); > } > >-void ARGBToARGB4444Row_NEON(const uint8* src_argb, >- uint8* dst_argb4444, >+void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb4444, > int width) { > asm volatile( > "vmov.u8 d4, #0x0f \n" // bits to clear with >@@ -1143,7 +1203,7 @@ void ARGBToARGB4444Row_NEON(const uint8* src_argb, > : "cc", "memory", "q0", "q8", "q9", "q10", "q11"); > } > >-void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { >+void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { > asm volatile( > "vmov.u8 d24, #13 \n" // B * 0.1016 coefficient > "vmov.u8 d25, #65 \n" // G * 0.5078 coefficient >@@ -1166,7 +1226,9 @@ void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { > : "cc", "memory", "q0", "q1", "q2", "q12", "q13"); > } > >-void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width) { >+void ARGBExtractAlphaRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_a, >+ int width) { > asm volatile( > "1: \n" > "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels >@@ -1182,7 +1244,7 @@ void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width) { > ); > } > >-void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { >+void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { > asm volatile( > "vmov.u8 d24, #15 \n" // B * 0.11400 coefficient > "vmov.u8 d25, #75 \n" // G * 0.58700 coefficient >@@ -1204,9 +1266,9 @@ void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { > } > > // 8x1 pixels. >-void ARGBToUV444Row_NEON(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUV444Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "vmov.u8 d24, #112 \n" // UB / VR 0.875 >@@ -1260,10 +1322,10 @@ void ARGBToUV444Row_NEON(const uint8* src_argb, > // clang-format on > > // TODO(fbarchard): Consider vhadd vertical, then vpaddl horizontal, avoid shr. >-void ARGBToUVRow_NEON(const uint8* src_argb, >+void ARGBToUVRow_NEON(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile ( > "add %1, %0, %1 \n" // src_stride + src_argb >@@ -1306,10 +1368,10 @@ void ARGBToUVRow_NEON(const uint8* src_argb, > } > > // TODO(fbarchard): Subsample match C code. >-void ARGBToUVJRow_NEON(const uint8* src_argb, >+void ARGBToUVJRow_NEON(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile ( > "add %1, %0, %1 \n" // src_stride + src_argb >@@ -1351,10 +1413,10 @@ void ARGBToUVJRow_NEON(const uint8* src_argb, > ); > } > >-void BGRAToUVRow_NEON(const uint8* src_bgra, >+void BGRAToUVRow_NEON(const uint8_t* src_bgra, > int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile ( > "add %1, %0, %1 \n" // src_stride + src_bgra >@@ -1396,10 +1458,10 @@ void BGRAToUVRow_NEON(const uint8* src_bgra, > ); > } > >-void ABGRToUVRow_NEON(const uint8* src_abgr, >+void ABGRToUVRow_NEON(const uint8_t* src_abgr, > int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile ( > "add %1, %0, %1 \n" // src_stride + src_abgr >@@ -1441,10 +1503,10 @@ void ABGRToUVRow_NEON(const uint8* src_abgr, > ); > } > >-void RGBAToUVRow_NEON(const uint8* src_rgba, >+void RGBAToUVRow_NEON(const uint8_t* src_rgba, > int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile ( > "add %1, %0, %1 \n" // src_stride + src_rgba >@@ -1486,10 +1548,10 @@ void RGBAToUVRow_NEON(const uint8* src_rgba, > ); > } > >-void RGB24ToUVRow_NEON(const uint8* src_rgb24, >+void RGB24ToUVRow_NEON(const uint8_t* src_rgb24, > int src_stride_rgb24, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile ( > "add %1, %0, %1 \n" // src_stride + src_rgb24 >@@ -1531,10 +1593,10 @@ void RGB24ToUVRow_NEON(const uint8* src_rgb24, > ); > } > >-void RAWToUVRow_NEON(const uint8* src_raw, >+void RAWToUVRow_NEON(const uint8_t* src_raw, > int src_stride_raw, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile ( > "add %1, %0, %1 \n" // src_stride + src_raw >@@ -1577,10 +1639,10 @@ void RAWToUVRow_NEON(const uint8* src_raw, > } > > // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. >-void RGB565ToUVRow_NEON(const uint8* src_rgb565, >+void RGB565ToUVRow_NEON(const uint8_t* src_rgb565, > int src_stride_rgb565, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "add %1, %0, %1 \n" // src_stride + src_argb >@@ -1643,10 +1705,10 @@ void RGB565ToUVRow_NEON(const uint8* src_rgb565, > } > > // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. >-void ARGB1555ToUVRow_NEON(const uint8* src_argb1555, >+void ARGB1555ToUVRow_NEON(const uint8_t* src_argb1555, > int src_stride_argb1555, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "add %1, %0, %1 \n" // src_stride + src_argb >@@ -1709,10 +1771,10 @@ void ARGB1555ToUVRow_NEON(const uint8* src_argb1555, > } > > // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. >-void ARGB4444ToUVRow_NEON(const uint8* src_argb4444, >+void ARGB4444ToUVRow_NEON(const uint8_t* src_argb4444, > int src_stride_argb4444, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "add %1, %0, %1 \n" // src_stride + src_argb >@@ -1774,7 +1836,7 @@ void ARGB4444ToUVRow_NEON(const uint8* src_argb4444, > "q9", "q10", "q11", "q12", "q13", "q14", "q15"); > } > >-void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int width) { >+void RGB565ToYRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { > asm volatile( > "vmov.u8 d24, #13 \n" // B * 0.1016 coefficient > "vmov.u8 d25, #65 \n" // G * 0.5078 coefficient >@@ -1798,7 +1860,9 @@ void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int width) { > : "cc", "memory", "q0", "q1", "q2", "q3", "q12", "q13"); > } > >-void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int width) { >+void ARGB1555ToYRow_NEON(const uint8_t* src_argb1555, >+ uint8_t* dst_y, >+ int width) { > asm volatile( > "vmov.u8 d24, #13 \n" // B * 0.1016 coefficient > "vmov.u8 d25, #65 \n" // G * 0.5078 coefficient >@@ -1822,7 +1886,9 @@ void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int width) { > : "cc", "memory", "q0", "q1", "q2", "q3", "q12", "q13"); > } > >-void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int width) { >+void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, >+ uint8_t* dst_y, >+ int width) { > asm volatile( > "vmov.u8 d24, #13 \n" // B * 0.1016 coefficient > "vmov.u8 d25, #65 \n" // G * 0.5078 coefficient >@@ -1846,7 +1912,7 @@ void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int width) { > : "cc", "memory", "q0", "q1", "q2", "q3", "q12", "q13"); > } > >-void BGRAToYRow_NEON(const uint8* src_bgra, uint8* dst_y, int width) { >+void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width) { > asm volatile( > "vmov.u8 d4, #33 \n" // R * 0.2578 coefficient > "vmov.u8 d5, #65 \n" // G * 0.5078 coefficient >@@ -1869,7 +1935,7 @@ void BGRAToYRow_NEON(const uint8* src_bgra, uint8* dst_y, int width) { > : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "q8"); > } > >-void ABGRToYRow_NEON(const uint8* src_abgr, uint8* dst_y, int width) { >+void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width) { > asm volatile( > "vmov.u8 d4, #33 \n" // R * 0.2578 coefficient > "vmov.u8 d5, #65 \n" // G * 0.5078 coefficient >@@ -1892,7 +1958,7 @@ void ABGRToYRow_NEON(const uint8* src_abgr, uint8* dst_y, int width) { > : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "q8"); > } > >-void RGBAToYRow_NEON(const uint8* src_rgba, uint8* dst_y, int width) { >+void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width) { > asm volatile( > "vmov.u8 d4, #13 \n" // B * 0.1016 coefficient > "vmov.u8 d5, #65 \n" // G * 0.5078 coefficient >@@ -1915,7 +1981,7 @@ void RGBAToYRow_NEON(const uint8* src_rgba, uint8* dst_y, int width) { > : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "q8"); > } > >-void RGB24ToYRow_NEON(const uint8* src_rgb24, uint8* dst_y, int width) { >+void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width) { > asm volatile( > "vmov.u8 d4, #13 \n" // B * 0.1016 coefficient > "vmov.u8 d5, #65 \n" // G * 0.5078 coefficient >@@ -1938,7 +2004,7 @@ void RGB24ToYRow_NEON(const uint8* src_rgb24, uint8* dst_y, int width) { > : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "q8"); > } > >-void RAWToYRow_NEON(const uint8* src_raw, uint8* dst_y, int width) { >+void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width) { > asm volatile( > "vmov.u8 d4, #33 \n" // R * 0.2578 coefficient > "vmov.u8 d5, #65 \n" // G * 0.5078 coefficient >@@ -1962,8 +2028,8 @@ void RAWToYRow_NEON(const uint8* src_raw, uint8* dst_y, int width) { > } > > // Bilinear filter 16x2 -> 16x1 >-void InterpolateRow_NEON(uint8* dst_ptr, >- const uint8* src_ptr, >+void InterpolateRow_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride, > int dst_width, > int source_y_fraction) { >@@ -2021,9 +2087,9 @@ void InterpolateRow_NEON(uint8* dst_ptr, > } > > // dr * (256 - sa) / 256 + sr = dr - dr * sa / 256 + sr >-void ARGBBlendRow_NEON(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBBlendRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > asm volatile( > "subs %3, #8 \n" >@@ -2081,7 +2147,9 @@ void ARGBBlendRow_NEON(const uint8* src_argb0, > } > > // Attenuate 8 pixels at a time. >-void ARGBAttenuateRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) { >+void ARGBAttenuateRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width) { > asm volatile( > // Attenuate 8 pixels. > "1: \n" >@@ -2104,7 +2172,7 @@ void ARGBAttenuateRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) { > > // Quantize 8 ARGB pixels (32 bytes). > // dst = (dst * scale >> 16) * interval_size + interval_offset; >-void ARGBQuantizeRow_NEON(uint8* dst_argb, >+void ARGBQuantizeRow_NEON(uint8_t* dst_argb, > int scale, > int interval_size, > int interval_offset, >@@ -2147,10 +2215,10 @@ void ARGBQuantizeRow_NEON(uint8* dst_argb, > // Shade 8 pixels at a time by specified value. > // NOTE vqrdmulh.s16 q10, q10, d0[0] must use a scaler register from 0 to 8. > // Rounding in vqrdmulh does +1 to high if high bit of low s16 is set. >-void ARGBShadeRow_NEON(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBShadeRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- uint32 value) { >+ uint32_t value) { > asm volatile( > "vdup.u32 q0, %3 \n" // duplicate scale value. > "vzip.u8 d0, d1 \n" // d0 aarrggbb. >@@ -2184,7 +2252,7 @@ void ARGBShadeRow_NEON(const uint8* src_argb, > // Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels > // Similar to ARGBToYJ but stores ARGB. > // C code is (15 * b + 75 * g + 38 * r + 64) >> 7; >-void ARGBGrayRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) { >+void ARGBGrayRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width) { > asm volatile( > "vmov.u8 d24, #15 \n" // B * 0.11400 coefficient > "vmov.u8 d25, #75 \n" // G * 0.58700 coefficient >@@ -2211,7 +2279,7 @@ void ARGBGrayRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) { > // b = (r * 35 + g * 68 + b * 17) >> 7 > // g = (r * 45 + g * 88 + b * 22) >> 7 > // r = (r * 50 + g * 98 + b * 24) >> 7 >-void ARGBSepiaRow_NEON(uint8* dst_argb, int width) { >+void ARGBSepiaRow_NEON(uint8_t* dst_argb, int width) { > asm volatile( > "vmov.u8 d20, #17 \n" // BB coefficient > "vmov.u8 d21, #68 \n" // BG coefficient >@@ -2249,9 +2317,9 @@ void ARGBSepiaRow_NEON(uint8* dst_argb, int width) { > // Tranform 8 ARGB pixels (32 bytes) with color matrix. > // TODO(fbarchard): Was same as Sepia except matrix is provided. This function > // needs to saturate. Consider doing a non-saturating version. >-void ARGBColorMatrixRow_NEON(const uint8* src_argb, >- uint8* dst_argb, >- const int8* matrix_argb, >+void ARGBColorMatrixRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const int8_t* matrix_argb, > int width) { > asm volatile( > "vld1.8 {q2}, [%3] \n" // load 3 ARGB vectors. >@@ -2308,9 +2376,9 @@ void ARGBColorMatrixRow_NEON(const uint8* src_argb, > } > > // Multiply 2 rows of ARGB pixels together, 8 pixels at a time. >-void ARGBMultiplyRow_NEON(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > asm volatile( > // 8 pixel loop. >@@ -2337,9 +2405,9 @@ void ARGBMultiplyRow_NEON(const uint8* src_argb0, > } > > // Add 2 rows of ARGB pixels together, 8 pixels at a time. >-void ARGBAddRow_NEON(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > asm volatile( > // 8 pixel loop. >@@ -2360,9 +2428,9 @@ void ARGBAddRow_NEON(const uint8* src_argb0, > } > > // Subtract 2 rows of ARGB pixels, 8 pixels at a time. >-void ARGBSubtractRow_NEON(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > asm volatile( > // 8 pixel loop. >@@ -2387,9 +2455,9 @@ void ARGBSubtractRow_NEON(const uint8* src_argb0, > // R = Sobel > // G = Sobel > // B = Sobel >-void SobelRow_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_NEON(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { > asm volatile( > "vmov.u8 d3, #255 \n" // alpha >@@ -2412,9 +2480,9 @@ void SobelRow_NEON(const uint8* src_sobelx, > } > > // Adds Sobel X and Sobel Y and stores Sobel into plane. >-void SobelToPlaneRow_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_NEON(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_y, > int width) { > asm volatile( > // 16 pixel loop. >@@ -2438,9 +2506,9 @@ void SobelToPlaneRow_NEON(const uint8* src_sobelx, > // R = Sobel X > // G = Sobel > // B = Sobel Y >-void SobelXYRow_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_NEON(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { > asm volatile( > "vmov.u8 d3, #255 \n" // alpha >@@ -2464,10 +2532,10 @@ void SobelXYRow_NEON(const uint8* src_sobelx, > // -1 0 1 > // -2 0 2 > // -1 0 1 >-void SobelXRow_NEON(const uint8* src_y0, >- const uint8* src_y1, >- const uint8* src_y2, >- uint8* dst_sobelx, >+void SobelXRow_NEON(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ const uint8_t* src_y2, >+ uint8_t* dst_sobelx, > int width) { > asm volatile( > "1: \n" >@@ -2503,9 +2571,9 @@ void SobelXRow_NEON(const uint8* src_y0, > // -1 -2 -1 > // 0 0 0 > // 1 2 1 >-void SobelYRow_NEON(const uint8* src_y0, >- const uint8* src_y1, >- uint8* dst_sobely, >+void SobelYRow_NEON(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ uint8_t* dst_sobely, > int width) { > asm volatile( > "1: \n" >@@ -2536,7 +2604,10 @@ void SobelYRow_NEON(const uint8* src_y0, > ); > } > >-void HalfFloat1Row_NEON(const uint16* src, uint16* dst, float, int width) { >+void HalfFloat1Row_NEON(const uint16_t* src, >+ uint16_t* dst, >+ float /*unused*/, >+ int width) { > asm volatile( > "vdup.32 q0, %3 \n" > >@@ -2561,7 +2632,10 @@ void HalfFloat1Row_NEON(const uint16* src, uint16* dst, float, int width) { > } > > // TODO(fbarchard): multiply by element. >-void HalfFloatRow_NEON(const uint16* src, uint16* dst, float scale, int width) { >+void HalfFloatRow_NEON(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width) { > asm volatile( > "vdup.32 q0, %3 \n" > >@@ -2585,6 +2659,32 @@ void HalfFloatRow_NEON(const uint16* src, uint16* dst, float scale, int width) { > : "cc", "memory", "q0", "q1", "q2", "q3"); > } > >+void ByteToFloatRow_NEON(const uint8_t* src, >+ float* dst, >+ float scale, >+ int width) { >+ asm volatile( >+ "vdup.32 q0, %3 \n" >+ >+ "1: \n" >+ "vld1.8 {d2}, [%0]! \n" // load 8 bytes >+ "subs %2, %2, #8 \n" // 8 pixels per loop >+ "vmovl.u8 q1, d2 \n" // 8 shorts >+ "vmovl.u16 q2, d2 \n" // 8 ints >+ "vmovl.u16 q3, d3 \n" >+ "vcvt.f32.u32 q2, q2 \n" // 8 floats >+ "vcvt.f32.u32 q3, q3 \n" >+ "vmul.f32 q2, q2, d0[0] \n" // scale >+ "vmul.f32 q3, q3, d0[0] \n" >+ "vst1.8 {q2, q3}, [%1]! \n" // store 8 floats >+ "bgt 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : "r"(scale) // %3 >+ : "cc", "memory", "q0", "q1", "q2", "q3"); >+} >+ > #endif // !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__).. > > #ifdef __cplusplus >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_neon64.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_neon64.cc >index 5616d8a5b5ffb0069d0f45dc508428e31587394f..24b4520babceade20c58d4108d0d378d170e21a4 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_neon64.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_neon64.cc >@@ -112,10 +112,10 @@ extern "C" { > ".8h, #6 \n" /* G */ \ > "sqshrun " #vR ".8b, " #vR ".8h, #6 \n" /* R */ > >-void I444ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I444ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -141,10 +141,10 @@ void I444ToARGBRow_NEON(const uint8* src_y, > ); > } > >-void I422ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+void I422ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -170,11 +170,11 @@ void I422ToARGBRow_NEON(const uint8* src_y, > ); > } > >-void I422AlphaToARGBRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- const uint8* src_a, >- uint8* dst_argb, >+void I422AlphaToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ const uint8_t* src_a, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -201,10 +201,10 @@ void I422AlphaToARGBRow_NEON(const uint8* src_y, > ); > } > >-void I422ToRGBARow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgba, >+void I422ToRGBARow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgba, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -230,10 +230,10 @@ void I422ToRGBARow_NEON(const uint8* src_y, > ); > } > >-void I422ToRGB24Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb24, >+void I422ToRGB24Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb24, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -265,10 +265,10 @@ void I422ToRGB24Row_NEON(const uint8* src_y, > "sri v0.8h, v21.8h, #5 \n" /* RG */ \ > "sri v0.8h, v20.8h, #11 \n" /* RGB */ > >-void I422ToRGB565Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_rgb565, >+void I422ToRGB565Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( >@@ -301,10 +301,10 @@ void I422ToRGB565Row_NEON(const uint8* src_y, > "sri v0.8h, v21.8h, #6 \n" /* ARG */ \ > "sri v0.8h, v20.8h, #11 \n" /* ARGB */ > >-void I422ToARGB1555Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb1555, >+void I422ToARGB1555Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb1555, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( >@@ -339,10 +339,10 @@ void I422ToARGB1555Row_NEON(const uint8* src_y, > "orr v1.8b, v22.8b, v23.8b \n" /* RA */ \ > "zip1 v0.16b, v0.16b, v1.16b \n" /* BGRA */ > >-void I422ToARGB4444Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb4444, >+void I422ToARGB4444Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb4444, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -370,7 +370,7 @@ void I422ToARGB4444Row_NEON(const uint8* src_y, > ); > } > >-void I400ToARGBRow_NEON(const uint8* src_y, uint8* dst_argb, int width) { >+void I400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { > asm volatile ( > YUVTORGB_SETUP > "movi v23.8b, #255 \n" >@@ -392,7 +392,7 @@ void I400ToARGBRow_NEON(const uint8* src_y, uint8* dst_argb, int width) { > ); > } > >-void J400ToARGBRow_NEON(const uint8* src_y, uint8* dst_argb, int width) { >+void J400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { > asm volatile( > "movi v23.8b, #255 \n" > "1: \n" >@@ -409,9 +409,9 @@ void J400ToARGBRow_NEON(const uint8* src_y, uint8* dst_argb, int width) { > : "cc", "memory", "v20", "v21", "v22", "v23"); > } > >-void NV12ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_argb, >+void NV12ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -436,9 +436,9 @@ void NV12ToARGBRow_NEON(const uint8* src_y, > ); > } > >-void NV21ToARGBRow_NEON(const uint8* src_y, >- const uint8* src_vu, >- uint8* dst_argb, >+void NV21ToARGBRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -463,9 +463,61 @@ void NV21ToARGBRow_NEON(const uint8* src_y, > ); > } > >-void NV12ToRGB565Row_NEON(const uint8* src_y, >- const uint8* src_uv, >- uint8* dst_rgb565, >+void NV12ToRGB24Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb24, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ asm volatile ( >+ YUVTORGB_SETUP >+ "1: \n" >+ READNV12 >+ YUVTORGB(v22, v21, v20) >+ "subs %w3, %w3, #8 \n" >+ "st3 {v20.8b,v21.8b,v22.8b}, [%2], #24 \n" >+ "b.gt 1b \n" >+ : "+r"(src_y), // %0 >+ "+r"(src_uv), // %1 >+ "+r"(dst_rgb24), // %2 >+ "+r"(width) // %3 >+ : [kUVToRB]"r"(&yuvconstants->kUVToRB), >+ [kUVToG]"r"(&yuvconstants->kUVToG), >+ [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), >+ [kYToRgb]"r"(&yuvconstants->kYToRgb) >+ : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", >+ "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" >+ ); >+} >+ >+void NV21ToRGB24Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_vu, >+ uint8_t* dst_rgb24, >+ const struct YuvConstants* yuvconstants, >+ int width) { >+ asm volatile ( >+ YUVTORGB_SETUP >+ "1: \n" >+ READNV21 >+ YUVTORGB(v22, v21, v20) >+ "subs %w3, %w3, #8 \n" >+ "st3 {v20.8b,v21.8b,v22.8b}, [%2], #24 \n" >+ "b.gt 1b \n" >+ : "+r"(src_y), // %0 >+ "+r"(src_vu), // %1 >+ "+r"(dst_rgb24), // %2 >+ "+r"(width) // %3 >+ : [kUVToRB]"r"(&yuvconstants->kUVToRB), >+ [kUVToG]"r"(&yuvconstants->kUVToG), >+ [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), >+ [kYToRgb]"r"(&yuvconstants->kYToRgb) >+ : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", >+ "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" >+ ); >+} >+ >+void NV12ToRGB565Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_uv, >+ uint8_t* dst_rgb565, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile( >@@ -488,8 +540,8 @@ void NV12ToRGB565Row_NEON(const uint8* src_y, > "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"); > } > >-void YUY2ToARGBRow_NEON(const uint8* src_yuy2, >- uint8* dst_argb, >+void YUY2ToARGBRow_NEON(const uint8_t* src_yuy2, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -513,8 +565,8 @@ void YUY2ToARGBRow_NEON(const uint8* src_yuy2, > ); > } > >-void UYVYToARGBRow_NEON(const uint8* src_uyvy, >- uint8* dst_argb, >+void UYVYToARGBRow_NEON(const uint8_t* src_uyvy, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > asm volatile ( >@@ -539,9 +591,9 @@ void UYVYToARGBRow_NEON(const uint8* src_uyvy, > } > > // Reads 16 pairs of UV and write even values to dst_u and odd to dst_v. >-void SplitUVRow_NEON(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void SplitUVRow_NEON(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "1: \n" >@@ -560,9 +612,9 @@ void SplitUVRow_NEON(const uint8* src_uv, > } > > // Reads 16 U's and V's and writes out 16 pairs of UV. >-void MergeUVRow_NEON(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+void MergeUVRow_NEON(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width) { > asm volatile( > "1: \n" >@@ -581,10 +633,10 @@ void MergeUVRow_NEON(const uint8* src_u, > } > > // Reads 16 packed RGB and write to planar dst_r, dst_g, dst_b. >-void SplitRGBRow_NEON(const uint8* src_rgb, >- uint8* dst_r, >- uint8* dst_g, >- uint8* dst_b, >+void SplitRGBRow_NEON(const uint8_t* src_rgb, >+ uint8_t* dst_r, >+ uint8_t* dst_g, >+ uint8_t* dst_b, > int width) { > asm volatile( > "1: \n" >@@ -605,10 +657,10 @@ void SplitRGBRow_NEON(const uint8* src_rgb, > } > > // Reads 16 planar R's, G's and B's and writes out 16 packed RGB at a time >-void MergeRGBRow_NEON(const uint8* src_r, >- const uint8* src_g, >- const uint8* src_b, >- uint8* dst_rgb, >+void MergeRGBRow_NEON(const uint8_t* src_r, >+ const uint8_t* src_g, >+ const uint8_t* src_b, >+ uint8_t* dst_rgb, > int width) { > asm volatile( > "1: \n" >@@ -629,7 +681,7 @@ void MergeRGBRow_NEON(const uint8* src_r, > } > > // Copy multiple of 32. >-void CopyRow_NEON(const uint8* src, uint8* dst, int count) { >+void CopyRow_NEON(const uint8_t* src, uint8_t* dst, int width) { > asm volatile( > "1: \n" > "ldp q0, q1, [%0], #32 \n" >@@ -638,14 +690,14 @@ void CopyRow_NEON(const uint8* src, uint8* dst, int count) { > "b.gt 1b \n" > : "+r"(src), // %0 > "+r"(dst), // %1 >- "+r"(count) // %2 // Output registers >+ "+r"(width) // %2 // Output registers > : // Input registers > : "cc", "memory", "v0", "v1" // Clobber List > ); > } > >-// SetRow writes 'count' bytes using an 8 bit value repeated. >-void SetRow_NEON(uint8* dst, uint8 v8, int count) { >+// SetRow writes 'width' bytes using an 8 bit value repeated. >+void SetRow_NEON(uint8_t* dst, uint8_t v8, int width) { > asm volatile( > "dup v0.16b, %w2 \n" // duplicate 16 bytes > "1: \n" >@@ -653,12 +705,12 @@ void SetRow_NEON(uint8* dst, uint8 v8, int count) { > "st1 {v0.16b}, [%0], #16 \n" // store > "b.gt 1b \n" > : "+r"(dst), // %0 >- "+r"(count) // %1 >+ "+r"(width) // %1 > : "r"(v8) // %2 > : "cc", "memory", "v0"); > } > >-void ARGBSetRow_NEON(uint8* dst, uint32 v32, int count) { >+void ARGBSetRow_NEON(uint8_t* dst, uint32_t v32, int width) { > asm volatile( > "dup v0.4s, %w2 \n" // duplicate 4 ints > "1: \n" >@@ -666,12 +718,12 @@ void ARGBSetRow_NEON(uint8* dst, uint32 v32, int count) { > "st1 {v0.16b}, [%0], #16 \n" // store > "b.gt 1b \n" > : "+r"(dst), // %0 >- "+r"(count) // %1 >+ "+r"(width) // %1 > : "r"(v32) // %2 > : "cc", "memory", "v0"); > } > >-void MirrorRow_NEON(const uint8* src, uint8* dst, int width) { >+void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { > asm volatile( > // Start at end of source row. > "add %0, %0, %w2, sxtw \n" >@@ -690,9 +742,9 @@ void MirrorRow_NEON(const uint8* src, uint8* dst, int width) { > : "cc", "memory", "v0"); > } > >-void MirrorUVRow_NEON(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+void MirrorUVRow_NEON(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > // Start at end of source row. >@@ -714,7 +766,7 @@ void MirrorUVRow_NEON(const uint8* src_uv, > : "cc", "memory", "v0", "v1"); > } > >-void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width) { >+void ARGBMirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { > asm volatile( > // Start at end of source row. > "add %0, %0, %w2, sxtw #2 \n" >@@ -733,7 +785,9 @@ void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width) { > : "cc", "memory", "v0"); > } > >-void RGB24ToARGBRow_NEON(const uint8* src_rgb24, uint8* dst_argb, int width) { >+void RGB24ToARGBRow_NEON(const uint8_t* src_rgb24, >+ uint8_t* dst_argb, >+ int width) { > asm volatile( > "movi v4.8b, #255 \n" // Alpha > "1: \n" >@@ -749,7 +803,7 @@ void RGB24ToARGBRow_NEON(const uint8* src_rgb24, uint8* dst_argb, int width) { > ); > } > >-void RAWToARGBRow_NEON(const uint8* src_raw, uint8* dst_argb, int width) { >+void RAWToARGBRow_NEON(const uint8_t* src_raw, uint8_t* dst_argb, int width) { > asm volatile( > "movi v5.8b, #255 \n" // Alpha > "1: \n" >@@ -767,7 +821,7 @@ void RAWToARGBRow_NEON(const uint8* src_raw, uint8* dst_argb, int width) { > ); > } > >-void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) { >+void RAWToRGB24Row_NEON(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { > asm volatile( > "1: \n" > "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // read r g b >@@ -797,7 +851,9 @@ void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) { > "orr v0.16b, v0.16b, v2.16b \n" /* R,B */ \ > "dup v2.2D, v0.D[1] \n" /* R */ > >-void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) { >+void RGB565ToARGBRow_NEON(const uint8_t* src_rgb565, >+ uint8_t* dst_argb, >+ int width) { > asm volatile( > "movi v3.8b, #255 \n" // Alpha > "1: \n" >@@ -851,8 +907,8 @@ void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) { > "orr v2.16b, v1.16b, v3.16b \n" /* R */ \ > "dup v1.2D, v0.D[1] \n" /* G */ > >-void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, >- uint8* dst_argb, >+void ARGB1555ToARGBRow_NEON(const uint8_t* src_argb1555, >+ uint8_t* dst_argb, > int width) { > asm volatile( > "movi v3.8b, #255 \n" // Alpha >@@ -883,8 +939,8 @@ void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, > "dup v0.2D, v2.D[1] \n" \ > "dup v1.2D, v3.D[1] \n" > >-void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, >- uint8* dst_argb, >+void ARGB4444ToARGBRow_NEON(const uint8_t* src_argb4444, >+ uint8_t* dst_argb, > int width) { > asm volatile( > "1: \n" >@@ -902,7 +958,9 @@ void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, > ); > } > >-void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) { >+void ARGBToRGB24Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_rgb24, >+ int width) { > asm volatile( > "1: \n" > "ld4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%0], #32 \n" // load 8 ARGB >@@ -918,7 +976,7 @@ void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) { > ); > } > >-void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) { >+void ARGBToRAWRow_NEON(const uint8_t* src_argb, uint8_t* dst_raw, int width) { > asm volatile( > "1: \n" > "ld4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%0], #32 \n" // load b g r a >@@ -935,7 +993,7 @@ void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) { > ); > } > >-void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) { >+void YUY2ToYRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { > asm volatile( > "1: \n" > "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pixels of YUY2. >@@ -950,7 +1008,7 @@ void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) { > ); > } > >-void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) { >+void UYVYToYRow_NEON(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { > asm volatile( > "1: \n" > "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pixels of UYVY. >@@ -965,9 +1023,9 @@ void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) { > ); > } > >-void YUY2ToUV422Row_NEON(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+void YUY2ToUV422Row_NEON(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "1: \n" >@@ -985,9 +1043,9 @@ void YUY2ToUV422Row_NEON(const uint8* src_yuy2, > ); > } > >-void UYVYToUV422Row_NEON(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+void UYVYToUV422Row_NEON(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "1: \n" >@@ -1005,12 +1063,12 @@ void UYVYToUV422Row_NEON(const uint8* src_uyvy, > ); > } > >-void YUY2ToUVRow_NEON(const uint8* src_yuy2, >+void YUY2ToUVRow_NEON(const uint8_t* src_yuy2, > int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_yuy2b = src_yuy2 + stride_yuy2; >+ const uint8_t* src_yuy2b = src_yuy2 + stride_yuy2; > asm volatile( > "1: \n" > "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 pixels >@@ -1032,12 +1090,12 @@ void YUY2ToUVRow_NEON(const uint8* src_yuy2, > ); > } > >-void UYVYToUVRow_NEON(const uint8* src_uyvy, >+void UYVYToUVRow_NEON(const uint8_t* src_uyvy, > int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_uyvyb = src_uyvy + stride_uyvy; >+ const uint8_t* src_uyvyb = src_uyvy + stride_uyvy; > asm volatile( > "1: \n" > "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 pixels >@@ -1060,9 +1118,9 @@ void UYVYToUVRow_NEON(const uint8* src_uyvy, > } > > // For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. >-void ARGBShuffleRow_NEON(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+void ARGBShuffleRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width) { > asm volatile( > "ld1 {v2.16b}, [%3] \n" // shuffler >@@ -1080,10 +1138,10 @@ void ARGBShuffleRow_NEON(const uint8* src_argb, > ); > } > >-void I422ToYUY2Row_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_yuy2, >+void I422ToYUY2Row_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_yuy2, > int width) { > asm volatile( > "1: \n" >@@ -1103,10 +1161,10 @@ void I422ToYUY2Row_NEON(const uint8* src_y, > : "cc", "memory", "v0", "v1", "v2", "v3"); > } > >-void I422ToUYVYRow_NEON(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uyvy, >+void I422ToUYVYRow_NEON(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uyvy, > int width) { > asm volatile( > "1: \n" >@@ -1126,7 +1184,9 @@ void I422ToUYVYRow_NEON(const uint8* src_y, > : "cc", "memory", "v0", "v1", "v2", "v3"); > } > >-void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) { >+void ARGBToRGB565Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_rgb565, >+ int width) { > asm volatile( > "1: \n" > "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n" // load 8 pixels >@@ -1141,9 +1201,9 @@ void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) { > : "cc", "memory", "v0", "v20", "v21", "v22", "v23"); > } > >-void ARGBToRGB565DitherRow_NEON(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+void ARGBToRGB565DitherRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ const uint32_t dither4, > int width) { > asm volatile( > "dup v1.4s, %w2 \n" // dither4 >@@ -1162,8 +1222,8 @@ void ARGBToRGB565DitherRow_NEON(const uint8* src_argb, > : "cc", "memory", "v0", "v1", "v20", "v21", "v22", "v23"); > } > >-void ARGBToARGB1555Row_NEON(const uint8* src_argb, >- uint8* dst_argb1555, >+void ARGBToARGB1555Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb1555, > int width) { > asm volatile( > "1: \n" >@@ -1180,8 +1240,8 @@ void ARGBToARGB1555Row_NEON(const uint8* src_argb, > : "cc", "memory", "v0", "v20", "v21", "v22", "v23"); > } > >-void ARGBToARGB4444Row_NEON(const uint8* src_argb, >- uint8* dst_argb4444, >+void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb4444, > int width) { > asm volatile( > "movi v4.16b, #0x0f \n" // bits to clear with >@@ -1200,7 +1260,7 @@ void ARGBToARGB4444Row_NEON(const uint8* src_argb, > : "cc", "memory", "v0", "v1", "v4", "v20", "v21", "v22", "v23"); > } > >-void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { >+void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { > asm volatile( > "movi v4.8b, #13 \n" // B * 0.1016 coefficient > "movi v5.8b, #65 \n" // G * 0.5078 coefficient >@@ -1223,7 +1283,9 @@ void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { > : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); > } > >-void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width) { >+void ARGBExtractAlphaRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_a, >+ int width) { > asm volatile( > "1: \n" > "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load row 16 >@@ -1239,7 +1301,7 @@ void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width) { > ); > } > >-void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { >+void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { > asm volatile( > "movi v4.8b, #15 \n" // B * 0.11400 coefficient > "movi v5.8b, #75 \n" // G * 0.58700 coefficient >@@ -1261,9 +1323,9 @@ void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { > } > > // 8x1 pixels. >-void ARGBToUV444Row_NEON(const uint8* src_argb, >- uint8* dst_u, >- uint8* dst_v, >+void ARGBToUV444Row_NEON(const uint8_t* src_argb, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > asm volatile( > "movi v24.8b, #112 \n" // UB / VR 0.875 >@@ -1328,12 +1390,12 @@ void ARGBToUV444Row_NEON(const uint8* src_argb, > // TODO(fbarchard): Consider vhadd vertical, then vpaddl horizontal, avoid shr. > // TODO(fbarchard): consider ptrdiff_t for all strides. > >-void ARGBToUVRow_NEON(const uint8* src_argb, >+void ARGBToUVRow_NEON(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_argb_1 = src_argb + src_stride_argb; >+ const uint8_t* src_argb_1 = src_argb + src_stride_argb; > asm volatile ( > RGBTOUV_SETUP_REG > "1: \n" >@@ -1368,12 +1430,12 @@ void ARGBToUVRow_NEON(const uint8* src_argb, > } > > // TODO(fbarchard): Subsample match C code. >-void ARGBToUVJRow_NEON(const uint8* src_argb, >+void ARGBToUVJRow_NEON(const uint8_t* src_argb, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_argb_1 = src_argb + src_stride_argb; >+ const uint8_t* src_argb_1 = src_argb + src_stride_argb; > asm volatile ( > "movi v20.8h, #63, lsl #0 \n" // UB/VR coeff (0.500) / 2 > "movi v21.8h, #42, lsl #0 \n" // UG coeff (-0.33126) / 2 >@@ -1411,12 +1473,12 @@ void ARGBToUVJRow_NEON(const uint8* src_argb, > ); > } > >-void BGRAToUVRow_NEON(const uint8* src_bgra, >+void BGRAToUVRow_NEON(const uint8_t* src_bgra, > int src_stride_bgra, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_bgra_1 = src_bgra + src_stride_bgra; >+ const uint8_t* src_bgra_1 = src_bgra + src_stride_bgra; > asm volatile ( > RGBTOUV_SETUP_REG > "1: \n" >@@ -1449,12 +1511,12 @@ void BGRAToUVRow_NEON(const uint8* src_bgra, > ); > } > >-void ABGRToUVRow_NEON(const uint8* src_abgr, >+void ABGRToUVRow_NEON(const uint8_t* src_abgr, > int src_stride_abgr, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_abgr_1 = src_abgr + src_stride_abgr; >+ const uint8_t* src_abgr_1 = src_abgr + src_stride_abgr; > asm volatile ( > RGBTOUV_SETUP_REG > "1: \n" >@@ -1487,12 +1549,12 @@ void ABGRToUVRow_NEON(const uint8* src_abgr, > ); > } > >-void RGBAToUVRow_NEON(const uint8* src_rgba, >+void RGBAToUVRow_NEON(const uint8_t* src_rgba, > int src_stride_rgba, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_rgba_1 = src_rgba + src_stride_rgba; >+ const uint8_t* src_rgba_1 = src_rgba + src_stride_rgba; > asm volatile ( > RGBTOUV_SETUP_REG > "1: \n" >@@ -1525,12 +1587,12 @@ void RGBAToUVRow_NEON(const uint8* src_rgba, > ); > } > >-void RGB24ToUVRow_NEON(const uint8* src_rgb24, >+void RGB24ToUVRow_NEON(const uint8_t* src_rgb24, > int src_stride_rgb24, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_rgb24_1 = src_rgb24 + src_stride_rgb24; >+ const uint8_t* src_rgb24_1 = src_rgb24 + src_stride_rgb24; > asm volatile ( > RGBTOUV_SETUP_REG > "1: \n" >@@ -1563,12 +1625,12 @@ void RGB24ToUVRow_NEON(const uint8* src_rgb24, > ); > } > >-void RAWToUVRow_NEON(const uint8* src_raw, >+void RAWToUVRow_NEON(const uint8_t* src_raw, > int src_stride_raw, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_raw_1 = src_raw + src_stride_raw; >+ const uint8_t* src_raw_1 = src_raw + src_stride_raw; > asm volatile ( > RGBTOUV_SETUP_REG > "1: \n" >@@ -1602,12 +1664,12 @@ void RAWToUVRow_NEON(const uint8* src_raw, > } > > // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. >-void RGB565ToUVRow_NEON(const uint8* src_rgb565, >+void RGB565ToUVRow_NEON(const uint8_t* src_rgb565, > int src_stride_rgb565, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_rgb565_1 = src_rgb565 + src_stride_rgb565; >+ const uint8_t* src_rgb565_1 = src_rgb565 + src_stride_rgb565; > asm volatile( > "movi v22.8h, #56, lsl #0 \n" // UB / VR coeff (0.875) / > // 2 >@@ -1673,12 +1735,12 @@ void RGB565ToUVRow_NEON(const uint8* src_rgb565, > } > > // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. >-void ARGB1555ToUVRow_NEON(const uint8* src_argb1555, >+void ARGB1555ToUVRow_NEON(const uint8_t* src_argb1555, > int src_stride_argb1555, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_argb1555_1 = src_argb1555 + src_stride_argb1555; >+ const uint8_t* src_argb1555_1 = src_argb1555 + src_stride_argb1555; > asm volatile( > RGBTOUV_SETUP_REG > "1: \n" >@@ -1738,12 +1800,12 @@ void ARGB1555ToUVRow_NEON(const uint8* src_argb1555, > } > > // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. >-void ARGB4444ToUVRow_NEON(const uint8* src_argb4444, >+void ARGB4444ToUVRow_NEON(const uint8_t* src_argb4444, > int src_stride_argb4444, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { >- const uint8* src_argb4444_1 = src_argb4444 + src_stride_argb4444; >+ const uint8_t* src_argb4444_1 = src_argb4444 + src_stride_argb4444; > asm volatile( > RGBTOUV_SETUP_REG > "1: \n" >@@ -1804,7 +1866,7 @@ void ARGB4444ToUVRow_NEON(const uint8* src_argb4444, > ); > } > >-void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int width) { >+void RGB565ToYRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { > asm volatile( > "movi v24.8b, #13 \n" // B * 0.1016 coefficient > "movi v25.8b, #65 \n" // G * 0.5078 coefficient >@@ -1829,7 +1891,9 @@ void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int width) { > "v27"); > } > >-void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int width) { >+void ARGB1555ToYRow_NEON(const uint8_t* src_argb1555, >+ uint8_t* dst_y, >+ int width) { > asm volatile( > "movi v4.8b, #13 \n" // B * 0.1016 coefficient > "movi v5.8b, #65 \n" // G * 0.5078 coefficient >@@ -1853,7 +1917,9 @@ void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int width) { > : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); > } > >-void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int width) { >+void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, >+ uint8_t* dst_y, >+ int width) { > asm volatile( > "movi v24.8b, #13 \n" // B * 0.1016 coefficient > "movi v25.8b, #65 \n" // G * 0.5078 coefficient >@@ -1877,7 +1943,7 @@ void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int width) { > : "cc", "memory", "v0", "v1", "v2", "v3", "v24", "v25", "v26", "v27"); > } > >-void BGRAToYRow_NEON(const uint8* src_bgra, uint8* dst_y, int width) { >+void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width) { > asm volatile( > "movi v4.8b, #33 \n" // R * 0.2578 coefficient > "movi v5.8b, #65 \n" // G * 0.5078 coefficient >@@ -1900,7 +1966,7 @@ void BGRAToYRow_NEON(const uint8* src_bgra, uint8* dst_y, int width) { > : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); > } > >-void ABGRToYRow_NEON(const uint8* src_abgr, uint8* dst_y, int width) { >+void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width) { > asm volatile( > "movi v4.8b, #33 \n" // R * 0.2578 coefficient > "movi v5.8b, #65 \n" // G * 0.5078 coefficient >@@ -1923,7 +1989,7 @@ void ABGRToYRow_NEON(const uint8* src_abgr, uint8* dst_y, int width) { > : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); > } > >-void RGBAToYRow_NEON(const uint8* src_rgba, uint8* dst_y, int width) { >+void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width) { > asm volatile( > "movi v4.8b, #13 \n" // B * 0.1016 coefficient > "movi v5.8b, #65 \n" // G * 0.5078 coefficient >@@ -1946,7 +2012,7 @@ void RGBAToYRow_NEON(const uint8* src_rgba, uint8* dst_y, int width) { > : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); > } > >-void RGB24ToYRow_NEON(const uint8* src_rgb24, uint8* dst_y, int width) { >+void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width) { > asm volatile( > "movi v4.8b, #13 \n" // B * 0.1016 coefficient > "movi v5.8b, #65 \n" // G * 0.5078 coefficient >@@ -1969,7 +2035,7 @@ void RGB24ToYRow_NEON(const uint8* src_rgb24, uint8* dst_y, int width) { > : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); > } > >-void RAWToYRow_NEON(const uint8* src_raw, uint8* dst_y, int width) { >+void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width) { > asm volatile( > "movi v4.8b, #33 \n" // R * 0.2578 coefficient > "movi v5.8b, #65 \n" // G * 0.5078 coefficient >@@ -1993,14 +2059,14 @@ void RAWToYRow_NEON(const uint8* src_raw, uint8* dst_y, int width) { > } > > // Bilinear filter 16x2 -> 16x1 >-void InterpolateRow_NEON(uint8* dst_ptr, >- const uint8* src_ptr, >+void InterpolateRow_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride, > int dst_width, > int source_y_fraction) { > int y1_fraction = source_y_fraction; > int y0_fraction = 256 - y1_fraction; >- const uint8* src_ptr1 = src_ptr + src_stride; >+ const uint8_t* src_ptr1 = src_ptr + src_stride; > asm volatile( > "cmp %w4, #0 \n" > "b.eq 100f \n" >@@ -2053,9 +2119,9 @@ void InterpolateRow_NEON(uint8* dst_ptr, > } > > // dr * (256 - sa) / 256 + sr = dr - dr * sa / 256 + sr >-void ARGBBlendRow_NEON(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBBlendRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > asm volatile( > "subs %w3, %w3, #8 \n" >@@ -2121,7 +2187,9 @@ void ARGBBlendRow_NEON(const uint8* src_argb0, > } > > // Attenuate 8 pixels at a time. >-void ARGBAttenuateRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) { >+void ARGBAttenuateRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ int width) { > asm volatile( > // Attenuate 8 pixels. > "1: \n" >@@ -2145,7 +2213,7 @@ void ARGBAttenuateRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) { > > // Quantize 8 ARGB pixels (32 bytes). > // dst = (dst * scale >> 16) * interval_size + interval_offset; >-void ARGBQuantizeRow_NEON(uint8* dst_argb, >+void ARGBQuantizeRow_NEON(uint8_t* dst_argb, > int scale, > int interval_size, > int interval_offset, >@@ -2188,10 +2256,10 @@ void ARGBQuantizeRow_NEON(uint8* dst_argb, > // Shade 8 pixels at a time by specified value. > // NOTE vqrdmulh.s16 q10, q10, d0[0] must use a scaler register from 0 to 8. > // Rounding in vqrdmulh does +1 to high if high bit of low s16 is set. >-void ARGBShadeRow_NEON(const uint8* src_argb, >- uint8* dst_argb, >+void ARGBShadeRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- uint32 value) { >+ uint32_t value) { > asm volatile( > "dup v0.4s, %w3 \n" // duplicate scale value. > "zip1 v0.8b, v0.8b, v0.8b \n" // v0.8b aarrggbb. >@@ -2225,7 +2293,7 @@ void ARGBShadeRow_NEON(const uint8* src_argb, > // Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels > // Similar to ARGBToYJ but stores ARGB. > // C code is (15 * b + 75 * g + 38 * r + 64) >> 7; >-void ARGBGrayRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) { >+void ARGBGrayRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width) { > asm volatile( > "movi v24.8b, #15 \n" // B * 0.11400 coefficient > "movi v25.8b, #75 \n" // G * 0.58700 coefficient >@@ -2253,7 +2321,7 @@ void ARGBGrayRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) { > // g = (r * 45 + g * 88 + b * 22) >> 7 > // r = (r * 50 + g * 98 + b * 24) >> 7 > >-void ARGBSepiaRow_NEON(uint8* dst_argb, int width) { >+void ARGBSepiaRow_NEON(uint8_t* dst_argb, int width) { > asm volatile( > "movi v20.8b, #17 \n" // BB coefficient > "movi v21.8b, #68 \n" // BG coefficient >@@ -2291,9 +2359,9 @@ void ARGBSepiaRow_NEON(uint8* dst_argb, int width) { > // Tranform 8 ARGB pixels (32 bytes) with color matrix. > // TODO(fbarchard): Was same as Sepia except matrix is provided. This function > // needs to saturate. Consider doing a non-saturating version. >-void ARGBColorMatrixRow_NEON(const uint8* src_argb, >- uint8* dst_argb, >- const int8* matrix_argb, >+void ARGBColorMatrixRow_NEON(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const int8_t* matrix_argb, > int width) { > asm volatile( > "ld1 {v2.16b}, [%3] \n" // load 3 ARGB vectors. >@@ -2351,9 +2419,9 @@ void ARGBColorMatrixRow_NEON(const uint8* src_argb, > > // TODO(fbarchard): fix vqshrun in ARGBMultiplyRow_NEON and reenable. > // Multiply 2 rows of ARGB pixels together, 8 pixels at a time. >-void ARGBMultiplyRow_NEON(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBMultiplyRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > asm volatile( > // 8 pixel loop. >@@ -2380,9 +2448,9 @@ void ARGBMultiplyRow_NEON(const uint8* src_argb0, > } > > // Add 2 rows of ARGB pixels together, 8 pixels at a time. >-void ARGBAddRow_NEON(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBAddRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > asm volatile( > // 8 pixel loop. >@@ -2405,9 +2473,9 @@ void ARGBAddRow_NEON(const uint8* src_argb0, > } > > // Subtract 2 rows of ARGB pixels, 8 pixels at a time. >-void ARGBSubtractRow_NEON(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+void ARGBSubtractRow_NEON(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > asm volatile( > // 8 pixel loop. >@@ -2434,9 +2502,9 @@ void ARGBSubtractRow_NEON(const uint8* src_argb0, > // R = Sobel > // G = Sobel > // B = Sobel >-void SobelRow_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelRow_NEON(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { > asm volatile( > "movi v3.8b, #255 \n" // alpha >@@ -2459,9 +2527,9 @@ void SobelRow_NEON(const uint8* src_sobelx, > } > > // Adds Sobel X and Sobel Y and stores Sobel into plane. >-void SobelToPlaneRow_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+void SobelToPlaneRow_NEON(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_y, > int width) { > asm volatile( > // 16 pixel loop. >@@ -2485,9 +2553,9 @@ void SobelToPlaneRow_NEON(const uint8* src_sobelx, > // R = Sobel X > // G = Sobel > // B = Sobel Y >-void SobelXYRow_NEON(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+void SobelXYRow_NEON(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { > asm volatile( > "movi v3.8b, #255 \n" // alpha >@@ -2511,10 +2579,10 @@ void SobelXYRow_NEON(const uint8* src_sobelx, > // -1 0 1 > // -2 0 2 > // -1 0 1 >-void SobelXRow_NEON(const uint8* src_y0, >- const uint8* src_y1, >- const uint8* src_y2, >- uint8* dst_sobelx, >+void SobelXRow_NEON(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ const uint8_t* src_y2, >+ uint8_t* dst_sobelx, > int width) { > asm volatile( > "1: \n" >@@ -2550,9 +2618,9 @@ void SobelXRow_NEON(const uint8* src_y0, > // -1 -2 -1 > // 0 0 0 > // 1 2 1 >-void SobelYRow_NEON(const uint8* src_y0, >- const uint8* src_y1, >- uint8* dst_sobely, >+void SobelYRow_NEON(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ uint8_t* dst_sobely, > int width) { > asm volatile( > "1: \n" >@@ -2584,7 +2652,10 @@ void SobelYRow_NEON(const uint8* src_y0, > } > > // Caveat - rounds float to half float whereas scaling version truncates. >-void HalfFloat1Row_NEON(const uint16* src, uint16* dst, float, int width) { >+void HalfFloat1Row_NEON(const uint16_t* src, >+ uint16_t* dst, >+ float /*unused*/, >+ int width) { > asm volatile( > "1: \n" > "ld1 {v1.16b}, [%0], #16 \n" // load 8 shorts >@@ -2604,7 +2675,10 @@ void HalfFloat1Row_NEON(const uint16* src, uint16* dst, float, int width) { > : "cc", "memory", "v1", "v2", "v3"); > } > >-void HalfFloatRow_NEON(const uint16* src, uint16* dst, float scale, int width) { >+void HalfFloatRow_NEON(const uint16_t* src, >+ uint16_t* dst, >+ float scale, >+ int width) { > asm volatile( > "1: \n" > "ld1 {v1.16b}, [%0], #16 \n" // load 8 shorts >@@ -2626,6 +2700,30 @@ void HalfFloatRow_NEON(const uint16* src, uint16* dst, float scale, int width) { > : "cc", "memory", "v1", "v2", "v3"); > } > >+void ByteToFloatRow_NEON(const uint8_t* src, >+ float* dst, >+ float scale, >+ int width) { >+ asm volatile( >+ "1: \n" >+ "ld1 {v1.8b}, [%0], #8 \n" // load 8 bytes >+ "subs %w2, %w2, #8 \n" // 8 pixels per loop >+ "uxtl v1.8h, v1.8b \n" // 8 shorts >+ "uxtl v2.4s, v1.4h \n" // 8 ints >+ "uxtl2 v3.4s, v1.8h \n" >+ "scvtf v2.4s, v2.4s \n" // 8 floats >+ "scvtf v3.4s, v3.4s \n" >+ "fmul v2.4s, v2.4s, %3.s[0] \n" // scale >+ "fmul v3.4s, v3.4s, %3.s[0] \n" >+ "st1 {v2.16b, v3.16b}, [%1], #32 \n" // store 8 floats >+ "b.gt 1b \n" >+ : "+r"(src), // %0 >+ "+r"(dst), // %1 >+ "+r"(width) // %2 >+ : "w"(scale) // %3 >+ : "cc", "memory", "v1", "v2", "v3"); >+} >+ > float ScaleMaxSamples_NEON(const float* src, > float* dst, > float scale, >@@ -2702,12 +2800,12 @@ void ScaleSamples_NEON(const float* src, float* dst, float scale, int width) { > } > > // filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. >-void GaussCol_NEON(const uint16* src0, >- const uint16* src1, >- const uint16* src2, >- const uint16* src3, >- const uint16* src4, >- uint32* dst, >+void GaussCol_NEON(const uint16_t* src0, >+ const uint16_t* src1, >+ const uint16_t* src2, >+ const uint16_t* src3, >+ const uint16_t* src4, >+ uint32_t* dst, > int width) { > asm volatile( > "movi v6.8h, #4 \n" // constant 4 >@@ -2742,10 +2840,10 @@ void GaussCol_NEON(const uint16* src0, > } > > // filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. >-void GaussRow_NEON(const uint32* src, uint16* dst, int width) { >- const uint32* src1 = src + 1; >- const uint32* src2 = src + 2; >- const uint32* src3 = src + 3; >+void GaussRow_NEON(const uint32_t* src, uint16_t* dst, int width) { >+ const uint32_t* src1 = src + 1; >+ const uint32_t* src2 = src + 2; >+ const uint32_t* src3 = src + 3; > asm volatile( > "movi v6.4s, #4 \n" // constant 4 > "movi v7.4s, #6 \n" // constant 6 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_win.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_win.cc >index 03a7e9506dad536e1ba3d76297eee4ed31cfdab7..5500d7f5a64e0008dcf7c61e70d345d6779c6502 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_win.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/row_win.cc >@@ -28,27 +28,27 @@ extern "C" { > #if defined(_M_X64) > > // Read 4 UV from 422, upsample to 8 UV. >-#define READYUV422 \ >- xmm0 = _mm_cvtsi32_si128(*(uint32*)u_buf); \ >- xmm1 = _mm_cvtsi32_si128(*(uint32*)(u_buf + offset)); \ >- xmm0 = _mm_unpacklo_epi8(xmm0, xmm1); \ >- xmm0 = _mm_unpacklo_epi16(xmm0, xmm0); \ >- u_buf += 4; \ >- xmm4 = _mm_loadl_epi64((__m128i*)y_buf); \ >- xmm4 = _mm_unpacklo_epi8(xmm4, xmm4); \ >+#define READYUV422 \ >+ xmm0 = _mm_cvtsi32_si128(*(uint32_t*)u_buf); \ >+ xmm1 = _mm_cvtsi32_si128(*(uint32_t*)(u_buf + offset)); \ >+ xmm0 = _mm_unpacklo_epi8(xmm0, xmm1); \ >+ xmm0 = _mm_unpacklo_epi16(xmm0, xmm0); \ >+ u_buf += 4; \ >+ xmm4 = _mm_loadl_epi64((__m128i*)y_buf); \ >+ xmm4 = _mm_unpacklo_epi8(xmm4, xmm4); \ > y_buf += 8; > > // Read 4 UV from 422, upsample to 8 UV. With 8 Alpha. >-#define READYUVA422 \ >- xmm0 = _mm_cvtsi32_si128(*(uint32*)u_buf); \ >- xmm1 = _mm_cvtsi32_si128(*(uint32*)(u_buf + offset)); \ >- xmm0 = _mm_unpacklo_epi8(xmm0, xmm1); \ >- xmm0 = _mm_unpacklo_epi16(xmm0, xmm0); \ >- u_buf += 4; \ >- xmm4 = _mm_loadl_epi64((__m128i*)y_buf); \ >- xmm4 = _mm_unpacklo_epi8(xmm4, xmm4); \ >- y_buf += 8; \ >- xmm5 = _mm_loadl_epi64((__m128i*)a_buf); \ >+#define READYUVA422 \ >+ xmm0 = _mm_cvtsi32_si128(*(uint32_t*)u_buf); \ >+ xmm1 = _mm_cvtsi32_si128(*(uint32_t*)(u_buf + offset)); \ >+ xmm0 = _mm_unpacklo_epi8(xmm0, xmm1); \ >+ xmm0 = _mm_unpacklo_epi16(xmm0, xmm0); \ >+ u_buf += 4; \ >+ xmm4 = _mm_loadl_epi64((__m128i*)y_buf); \ >+ xmm4 = _mm_unpacklo_epi8(xmm4, xmm4); \ >+ y_buf += 8; \ >+ xmm5 = _mm_loadl_epi64((__m128i*)a_buf); \ > a_buf += 8; > > // Convert 8 pixels: 8 UV and 8 Y. >@@ -84,15 +84,15 @@ extern "C" { > dst_argb += 32; > > #if defined(HAS_I422TOARGBROW_SSSE3) >-void I422ToARGBRow_SSSE3(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+void I422ToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __m128i xmm0, xmm1, xmm2, xmm4; > const __m128i xmm5 = _mm_set1_epi8(-1); >- const ptrdiff_t offset = (uint8*)v_buf - (uint8*)u_buf; >+ const ptrdiff_t offset = (uint8_t*)v_buf - (uint8_t*)u_buf; > while (width > 0) { > READYUV422 > YUVTORGB(yuvconstants) >@@ -103,15 +103,15 @@ void I422ToARGBRow_SSSE3(const uint8* y_buf, > #endif > > #if defined(HAS_I422ALPHATOARGBROW_SSSE3) >-void I422AlphaToARGBRow_SSSE3(const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+void I422AlphaToARGBRow_SSSE3(const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __m128i xmm0, xmm1, xmm2, xmm4, xmm5; >- const ptrdiff_t offset = (uint8*)v_buf - (uint8*)u_buf; >+ const ptrdiff_t offset = (uint8_t*)v_buf - (uint8_t*)u_buf; > while (width > 0) { > READYUVA422 > YUVTORGB(yuvconstants) >@@ -255,8 +255,8 @@ static const lvec8 kShuffleNV21 = { > }; > > // Duplicates gray value 3 times and fills in alpha opaque. >-__declspec(naked) void J400ToARGBRow_SSE2(const uint8* src_y, >- uint8* dst_argb, >+__declspec(naked) void J400ToARGBRow_SSE2(const uint8_t* src_y, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, [esp + 4] // src_y >@@ -285,8 +285,8 @@ __declspec(naked) void J400ToARGBRow_SSE2(const uint8* src_y, > > #ifdef HAS_J400TOARGBROW_AVX2 > // Duplicates gray value 3 times and fills in alpha opaque. >-__declspec(naked) void J400ToARGBRow_AVX2(const uint8* src_y, >- uint8* dst_argb, >+__declspec(naked) void J400ToARGBRow_AVX2(const uint8_t* src_y, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, [esp + 4] // src_y >@@ -316,8 +316,8 @@ __declspec(naked) void J400ToARGBRow_AVX2(const uint8* src_y, > } > #endif // HAS_J400TOARGBROW_AVX2 > >-__declspec(naked) void RGB24ToARGBRow_SSSE3(const uint8* src_rgb24, >- uint8* dst_argb, >+__declspec(naked) void RGB24ToARGBRow_SSSE3(const uint8_t* src_rgb24, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, [esp + 4] // src_rgb24 >@@ -355,8 +355,8 @@ __declspec(naked) void RGB24ToARGBRow_SSSE3(const uint8* src_rgb24, > } > } > >-__declspec(naked) void RAWToARGBRow_SSSE3(const uint8* src_raw, >- uint8* dst_argb, >+__declspec(naked) void RAWToARGBRow_SSSE3(const uint8_t* src_raw, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, [esp + 4] // src_raw >@@ -394,8 +394,8 @@ __declspec(naked) void RAWToARGBRow_SSSE3(const uint8* src_raw, > } > } > >-__declspec(naked) void RAWToRGB24Row_SSSE3(const uint8* src_raw, >- uint8* dst_rgb24, >+__declspec(naked) void RAWToRGB24Row_SSSE3(const uint8_t* src_raw, >+ uint8_t* dst_rgb24, > int width) { > __asm { > mov eax, [esp + 4] // src_raw >@@ -430,8 +430,8 @@ __declspec(naked) void RAWToRGB24Row_SSSE3(const uint8* src_raw, > // v * (256 + 8) > // G shift of 5 is incorporated, so shift is 5 + 8 and 5 + 3 > // 20 instructions. >-__declspec(naked) void RGB565ToARGBRow_SSE2(const uint8* src_rgb565, >- uint8* dst_argb, >+__declspec(naked) void RGB565ToARGBRow_SSE2(const uint8_t* src_rgb565, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, 0x01080108 // generate multiplier to repeat 5 bits >@@ -486,8 +486,8 @@ __declspec(naked) void RGB565ToARGBRow_SSE2(const uint8* src_rgb565, > // v * 256 + v * 8 > // v * (256 + 8) > // G shift of 5 is incorporated, so shift is 5 + 8 and 5 + 3 >-__declspec(naked) void RGB565ToARGBRow_AVX2(const uint8* src_rgb565, >- uint8* dst_argb, >+__declspec(naked) void RGB565ToARGBRow_AVX2(const uint8_t* src_rgb565, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, 0x01080108 // generate multiplier to repeat 5 bits >@@ -537,8 +537,8 @@ __declspec(naked) void RGB565ToARGBRow_AVX2(const uint8* src_rgb565, > #endif // HAS_RGB565TOARGBROW_AVX2 > > #ifdef HAS_ARGB1555TOARGBROW_AVX2 >-__declspec(naked) void ARGB1555ToARGBRow_AVX2(const uint8* src_argb1555, >- uint8* dst_argb, >+__declspec(naked) void ARGB1555ToARGBRow_AVX2(const uint8_t* src_argb1555, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, 0x01080108 // generate multiplier to repeat 5 bits >@@ -589,8 +589,8 @@ __declspec(naked) void ARGB1555ToARGBRow_AVX2(const uint8* src_argb1555, > #endif // HAS_ARGB1555TOARGBROW_AVX2 > > #ifdef HAS_ARGB4444TOARGBROW_AVX2 >-__declspec(naked) void ARGB4444ToARGBRow_AVX2(const uint8* src_argb4444, >- uint8* dst_argb, >+__declspec(naked) void ARGB4444ToARGBRow_AVX2(const uint8_t* src_argb4444, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, 0x0f0f0f0f // generate mask 0x0f0f0f0f >@@ -627,8 +627,8 @@ __declspec(naked) void ARGB4444ToARGBRow_AVX2(const uint8* src_argb4444, > #endif // HAS_ARGB4444TOARGBROW_AVX2 > > // 24 instructions >-__declspec(naked) void ARGB1555ToARGBRow_SSE2(const uint8* src_argb1555, >- uint8* dst_argb, >+__declspec(naked) void ARGB1555ToARGBRow_SSE2(const uint8_t* src_argb1555, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, 0x01080108 // generate multiplier to repeat 5 bits >@@ -680,8 +680,8 @@ __declspec(naked) void ARGB1555ToARGBRow_SSE2(const uint8* src_argb1555, > } > > // 18 instructions. >-__declspec(naked) void ARGB4444ToARGBRow_SSE2(const uint8* src_argb4444, >- uint8* dst_argb, >+__declspec(naked) void ARGB4444ToARGBRow_SSE2(const uint8_t* src_argb4444, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, 0x0f0f0f0f // generate mask 0x0f0f0f0f >@@ -718,8 +718,8 @@ __declspec(naked) void ARGB4444ToARGBRow_SSE2(const uint8* src_argb4444, > } > } > >-__declspec(naked) void ARGBToRGB24Row_SSSE3(const uint8* src_argb, >- uint8* dst_rgb, >+__declspec(naked) void ARGBToRGB24Row_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_rgb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -757,8 +757,8 @@ __declspec(naked) void ARGBToRGB24Row_SSSE3(const uint8* src_argb, > } > } > >-__declspec(naked) void ARGBToRAWRow_SSSE3(const uint8* src_argb, >- uint8* dst_rgb, >+__declspec(naked) void ARGBToRAWRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_rgb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -796,8 +796,8 @@ __declspec(naked) void ARGBToRAWRow_SSSE3(const uint8* src_argb, > } > } > >-__declspec(naked) void ARGBToRGB565Row_SSE2(const uint8* src_argb, >- uint8* dst_rgb, >+__declspec(naked) void ARGBToRGB565Row_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_rgb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -834,9 +834,9 @@ __declspec(naked) void ARGBToRGB565Row_SSE2(const uint8* src_argb, > } > } > >-__declspec(naked) void ARGBToRGB565DitherRow_SSE2(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+__declspec(naked) void ARGBToRGB565DitherRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ const uint32_t dither4, > int width) { > __asm { > >@@ -881,9 +881,9 @@ __declspec(naked) void ARGBToRGB565DitherRow_SSE2(const uint8* src_argb, > } > > #ifdef HAS_ARGBTORGB565DITHERROW_AVX2 >-__declspec(naked) void ARGBToRGB565DitherRow_AVX2(const uint8* src_argb, >- uint8* dst_rgb, >- const uint32 dither4, >+__declspec(naked) void ARGBToRGB565DitherRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_rgb, >+ const uint32_t dither4, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -925,8 +925,8 @@ __declspec(naked) void ARGBToRGB565DitherRow_AVX2(const uint8* src_argb, > #endif // HAS_ARGBTORGB565DITHERROW_AVX2 > > // TODO(fbarchard): Improve sign extension/packing. >-__declspec(naked) void ARGBToARGB1555Row_SSE2(const uint8* src_argb, >- uint8* dst_rgb, >+__declspec(naked) void ARGBToARGB1555Row_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_rgb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -967,8 +967,8 @@ __declspec(naked) void ARGBToARGB1555Row_SSE2(const uint8* src_argb, > } > } > >-__declspec(naked) void ARGBToARGB4444Row_SSE2(const uint8* src_argb, >- uint8* dst_rgb, >+__declspec(naked) void ARGBToARGB4444Row_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_rgb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -998,8 +998,8 @@ __declspec(naked) void ARGBToARGB4444Row_SSE2(const uint8* src_argb, > } > > #ifdef HAS_ARGBTORGB565ROW_AVX2 >-__declspec(naked) void ARGBToRGB565Row_AVX2(const uint8* src_argb, >- uint8* dst_rgb, >+__declspec(naked) void ARGBToRGB565Row_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_rgb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -1036,8 +1036,8 @@ __declspec(naked) void ARGBToRGB565Row_AVX2(const uint8* src_argb, > #endif // HAS_ARGBTORGB565ROW_AVX2 > > #ifdef HAS_ARGBTOARGB1555ROW_AVX2 >-__declspec(naked) void ARGBToARGB1555Row_AVX2(const uint8* src_argb, >- uint8* dst_rgb, >+__declspec(naked) void ARGBToARGB1555Row_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_rgb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -1077,8 +1077,8 @@ __declspec(naked) void ARGBToARGB1555Row_AVX2(const uint8* src_argb, > #endif // HAS_ARGBTOARGB1555ROW_AVX2 > > #ifdef HAS_ARGBTOARGB4444ROW_AVX2 >-__declspec(naked) void ARGBToARGB4444Row_AVX2(const uint8* src_argb, >- uint8* dst_rgb, >+__declspec(naked) void ARGBToARGB4444Row_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_rgb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -1109,8 +1109,8 @@ __declspec(naked) void ARGBToARGB4444Row_AVX2(const uint8* src_argb, > #endif // HAS_ARGBTOARGB4444ROW_AVX2 > > // Convert 16 ARGB pixels (64 bytes) to 16 Y values. >-__declspec(naked) void ARGBToYRow_SSSE3(const uint8* src_argb, >- uint8* dst_y, >+__declspec(naked) void ARGBToYRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] /* src_argb */ >@@ -1145,8 +1145,8 @@ __declspec(naked) void ARGBToYRow_SSSE3(const uint8* src_argb, > > // Convert 16 ARGB pixels (64 bytes) to 16 YJ values. > // Same as ARGBToYRow but different coefficients, no add 16, but do rounding. >-__declspec(naked) void ARGBToYJRow_SSSE3(const uint8* src_argb, >- uint8* dst_y, >+__declspec(naked) void ARGBToYJRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] /* src_argb */ >@@ -1185,8 +1185,8 @@ __declspec(naked) void ARGBToYJRow_SSSE3(const uint8* src_argb, > static const lvec32 kPermdARGBToY_AVX = {0, 4, 1, 5, 2, 6, 3, 7}; > > // Convert 32 ARGB pixels (128 bytes) to 32 Y values. >-__declspec(naked) void ARGBToYRow_AVX2(const uint8* src_argb, >- uint8* dst_y, >+__declspec(naked) void ARGBToYRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] /* src_argb */ >@@ -1225,8 +1225,8 @@ __declspec(naked) void ARGBToYRow_AVX2(const uint8* src_argb, > > #ifdef HAS_ARGBTOYJROW_AVX2 > // Convert 32 ARGB pixels (128 bytes) to 32 Y values. >-__declspec(naked) void ARGBToYJRow_AVX2(const uint8* src_argb, >- uint8* dst_y, >+__declspec(naked) void ARGBToYJRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] /* src_argb */ >@@ -1265,8 +1265,8 @@ __declspec(naked) void ARGBToYJRow_AVX2(const uint8* src_argb, > } > #endif // HAS_ARGBTOYJROW_AVX2 > >-__declspec(naked) void BGRAToYRow_SSSE3(const uint8* src_argb, >- uint8* dst_y, >+__declspec(naked) void BGRAToYRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] /* src_argb */ >@@ -1299,8 +1299,8 @@ __declspec(naked) void BGRAToYRow_SSSE3(const uint8* src_argb, > } > } > >-__declspec(naked) void ABGRToYRow_SSSE3(const uint8* src_argb, >- uint8* dst_y, >+__declspec(naked) void ABGRToYRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] /* src_argb */ >@@ -1333,8 +1333,8 @@ __declspec(naked) void ABGRToYRow_SSSE3(const uint8* src_argb, > } > } > >-__declspec(naked) void RGBAToYRow_SSSE3(const uint8* src_argb, >- uint8* dst_y, >+__declspec(naked) void RGBAToYRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] /* src_argb */ >@@ -1367,10 +1367,10 @@ __declspec(naked) void RGBAToYRow_SSSE3(const uint8* src_argb, > } > } > >-__declspec(naked) void ARGBToUVRow_SSSE3(const uint8* src_argb0, >+__declspec(naked) void ARGBToUVRow_SSSE3(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -1439,10 +1439,10 @@ __declspec(naked) void ARGBToUVRow_SSSE3(const uint8* src_argb0, > } > } > >-__declspec(naked) void ARGBToUVJRow_SSSE3(const uint8* src_argb0, >+__declspec(naked) void ARGBToUVJRow_SSSE3(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -1513,10 +1513,10 @@ __declspec(naked) void ARGBToUVJRow_SSSE3(const uint8* src_argb0, > } > > #ifdef HAS_ARGBTOUVROW_AVX2 >-__declspec(naked) void ARGBToUVRow_AVX2(const uint8* src_argb0, >+__declspec(naked) void ARGBToUVRow_AVX2(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -1581,10 +1581,10 @@ __declspec(naked) void ARGBToUVRow_AVX2(const uint8* src_argb0, > #endif // HAS_ARGBTOUVROW_AVX2 > > #ifdef HAS_ARGBTOUVJROW_AVX2 >-__declspec(naked) void ARGBToUVJRow_AVX2(const uint8* src_argb0, >+__declspec(naked) void ARGBToUVJRow_AVX2(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -1649,9 +1649,9 @@ __declspec(naked) void ARGBToUVJRow_AVX2(const uint8* src_argb0, > } > #endif // HAS_ARGBTOUVJROW_AVX2 > >-__declspec(naked) void ARGBToUV444Row_SSSE3(const uint8* src_argb0, >- uint8* dst_u, >- uint8* dst_v, >+__declspec(naked) void ARGBToUV444Row_SSSE3(const uint8_t* src_argb0, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push edi >@@ -1707,10 +1707,10 @@ __declspec(naked) void ARGBToUV444Row_SSSE3(const uint8* src_argb0, > } > } > >-__declspec(naked) void BGRAToUVRow_SSSE3(const uint8* src_argb0, >+__declspec(naked) void BGRAToUVRow_SSSE3(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -1779,10 +1779,10 @@ __declspec(naked) void BGRAToUVRow_SSSE3(const uint8* src_argb0, > } > } > >-__declspec(naked) void ABGRToUVRow_SSSE3(const uint8* src_argb0, >+__declspec(naked) void ABGRToUVRow_SSSE3(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -1851,10 +1851,10 @@ __declspec(naked) void ABGRToUVRow_SSSE3(const uint8* src_argb0, > } > } > >-__declspec(naked) void RGBAToUVRow_SSSE3(const uint8* src_argb0, >+__declspec(naked) void RGBAToUVRow_SSSE3(const uint8_t* src_argb0, > int src_stride_argb, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -2065,10 +2065,10 @@ __declspec(naked) void RGBAToUVRow_SSSE3(const uint8* src_argb0, > // 16 pixels > // 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). > __declspec(naked) void I422ToARGBRow_AVX2( >- const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2105,11 +2105,11 @@ __declspec(naked) void I422ToARGBRow_AVX2( > // 16 pixels > // 8 UV values upsampled to 16 UV, mixed with 16 Y and 16 A producing 16 ARGB. > __declspec(naked) void I422AlphaToARGBRow_AVX2( >- const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2148,10 +2148,10 @@ __declspec(naked) void I422AlphaToARGBRow_AVX2( > // 16 pixels > // 16 UV values with 16 Y producing 16 ARGB (64 bytes). > __declspec(naked) void I444ToARGBRow_AVX2( >- const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2187,9 +2187,9 @@ __declspec(naked) void I444ToARGBRow_AVX2( > // 16 pixels. > // 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). > __declspec(naked) void NV12ToARGBRow_AVX2( >- const uint8* y_buf, >- const uint8* uv_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2222,9 +2222,9 @@ __declspec(naked) void NV12ToARGBRow_AVX2( > // 16 pixels. > // 8 VU values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). > __declspec(naked) void NV21ToARGBRow_AVX2( >- const uint8* y_buf, >- const uint8* vu_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* vu_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2257,8 +2257,8 @@ __declspec(naked) void NV21ToARGBRow_AVX2( > // 16 pixels. > // 8 YUY2 values with 16 Y and 8 UV producing 16 ARGB (64 bytes). > __declspec(naked) void YUY2ToARGBRow_AVX2( >- const uint8* src_yuy2, >- uint8* dst_argb, >+ const uint8_t* src_yuy2, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2288,8 +2288,8 @@ __declspec(naked) void YUY2ToARGBRow_AVX2( > // 16 pixels. > // 8 UYVY values with 16 Y and 8 UV producing 16 ARGB (64 bytes). > __declspec(naked) void UYVYToARGBRow_AVX2( >- const uint8* src_uyvy, >- uint8* dst_argb, >+ const uint8_t* src_uyvy, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2319,10 +2319,10 @@ __declspec(naked) void UYVYToARGBRow_AVX2( > // 16 pixels > // 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 RGBA (64 bytes). > __declspec(naked) void I422ToRGBARow_AVX2( >- const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2551,10 +2551,10 @@ __declspec(naked) void I422ToRGBARow_AVX2( > // 8 pixels. > // 8 UV values, mixed with 8 Y producing 8 ARGB (32 bytes). > __declspec(naked) void I444ToARGBRow_SSSE3( >- const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2588,10 +2588,10 @@ __declspec(naked) void I444ToARGBRow_SSSE3( > // 8 pixels. > // 4 UV values upsampled to 8 UV, mixed with 8 Y producing 8 RGB24 (24 bytes). > __declspec(naked) void I422ToRGB24Row_SSSE3( >- const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_rgb24, >+ const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_rgb24, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2626,10 +2626,10 @@ __declspec(naked) void I422ToRGB24Row_SSSE3( > // 8 pixels > // 4 UV values upsampled to 8 UV, mixed with 8 Y producing 8 RGB565 (16 bytes). > __declspec(naked) void I422ToRGB565Row_SSSE3( >- const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* rgb565_buf, >+ const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* rgb565_buf, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2669,10 +2669,10 @@ __declspec(naked) void I422ToRGB565Row_SSSE3( > // 8 pixels. > // 4 UV values upsampled to 8 UV, mixed with 8 Y producing 8 ARGB (32 bytes). > __declspec(naked) void I422ToARGBRow_SSSE3( >- const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2706,11 +2706,11 @@ __declspec(naked) void I422ToARGBRow_SSSE3( > // 8 pixels. > // 4 UV values upsampled to 8 UV, mixed with 8 Y and 8 A producing 8 ARGB. > __declspec(naked) void I422AlphaToARGBRow_SSSE3( >- const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- const uint8* a_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ const uint8_t* a_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2746,9 +2746,9 @@ __declspec(naked) void I422AlphaToARGBRow_SSSE3( > // 8 pixels. > // 4 UV values upsampled to 8 UV, mixed with 8 Y producing 8 ARGB (32 bytes). > __declspec(naked) void NV12ToARGBRow_SSSE3( >- const uint8* y_buf, >- const uint8* uv_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* uv_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2778,9 +2778,9 @@ __declspec(naked) void NV12ToARGBRow_SSSE3( > // 8 pixels. > // 4 UV values upsampled to 8 UV, mixed with 8 Y producing 8 ARGB (32 bytes). > __declspec(naked) void NV21ToARGBRow_SSSE3( >- const uint8* y_buf, >- const uint8* vu_buf, >- uint8* dst_argb, >+ const uint8_t* y_buf, >+ const uint8_t* vu_buf, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2810,8 +2810,8 @@ __declspec(naked) void NV21ToARGBRow_SSSE3( > // 8 pixels. > // 4 YUY2 values with 8 Y and 4 UV producing 8 ARGB (32 bytes). > __declspec(naked) void YUY2ToARGBRow_SSSE3( >- const uint8* src_yuy2, >- uint8* dst_argb, >+ const uint8_t* src_yuy2, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2838,8 +2838,8 @@ __declspec(naked) void YUY2ToARGBRow_SSSE3( > // 8 pixels. > // 4 UYVY values with 8 Y and 4 UV producing 8 ARGB (32 bytes). > __declspec(naked) void UYVYToARGBRow_SSSE3( >- const uint8* src_uyvy, >- uint8* dst_argb, >+ const uint8_t* src_uyvy, >+ uint8_t* dst_argb, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2864,10 +2864,10 @@ __declspec(naked) void UYVYToARGBRow_SSSE3( > } > > __declspec(naked) void I422ToRGBARow_SSSE3( >- const uint8* y_buf, >- const uint8* u_buf, >- const uint8* v_buf, >- uint8* dst_rgba, >+ const uint8_t* y_buf, >+ const uint8_t* u_buf, >+ const uint8_t* v_buf, >+ uint8_t* dst_rgba, > const struct YuvConstants* yuvconstants, > int width) { > __asm { >@@ -2900,8 +2900,8 @@ __declspec(naked) void I422ToRGBARow_SSSE3( > > #ifdef HAS_I400TOARGBROW_SSE2 > // 8 pixels of Y converted to 8 pixels of ARGB (32 bytes). >-__declspec(naked) void I400ToARGBRow_SSE2(const uint8* y_buf, >- uint8* rgb_buf, >+__declspec(naked) void I400ToARGBRow_SSE2(const uint8_t* y_buf, >+ uint8_t* rgb_buf, > int width) { > __asm { > mov eax, 0x4a354a35 // 4a35 = 18997 = round(1.164 * 64 * 256) >@@ -2947,8 +2947,8 @@ __declspec(naked) void I400ToARGBRow_SSE2(const uint8* y_buf, > #ifdef HAS_I400TOARGBROW_AVX2 > // 16 pixels of Y converted to 16 pixels of ARGB (64 bytes). > // note: vpunpcklbw mutates and vpackuswb unmutates. >-__declspec(naked) void I400ToARGBRow_AVX2(const uint8* y_buf, >- uint8* rgb_buf, >+__declspec(naked) void I400ToARGBRow_AVX2(const uint8_t* y_buf, >+ uint8_t* rgb_buf, > int width) { > __asm { > mov eax, 0x4a354a35 // 4a35 = 18997 = round(1.164 * 64 * 256) >@@ -3000,8 +3000,8 @@ static const uvec8 kShuffleMirror = {15u, 14u, 13u, 12u, 11u, 10u, 9u, 8u, > 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u}; > > // TODO(fbarchard): Replace lea with -16 offset. >-__declspec(naked) void MirrorRow_SSSE3(const uint8* src, >- uint8* dst, >+__declspec(naked) void MirrorRow_SSSE3(const uint8_t* src, >+ uint8_t* dst, > int width) { > __asm { > mov eax, [esp + 4] // src >@@ -3022,7 +3022,9 @@ __declspec(naked) void MirrorRow_SSSE3(const uint8* src, > #endif // HAS_MIRRORROW_SSSE3 > > #ifdef HAS_MIRRORROW_AVX2 >-__declspec(naked) void MirrorRow_AVX2(const uint8* src, uint8* dst, int width) { >+__declspec(naked) void MirrorRow_AVX2(const uint8_t* src, >+ uint8_t* dst, >+ int width) { > __asm { > mov eax, [esp + 4] // src > mov edx, [esp + 8] // dst >@@ -3048,9 +3050,9 @@ __declspec(naked) void MirrorRow_AVX2(const uint8* src, uint8* dst, int width) { > static const uvec8 kShuffleMirrorUV = {14u, 12u, 10u, 8u, 6u, 4u, 2u, 0u, > 15u, 13u, 11u, 9u, 7u, 5u, 3u, 1u}; > >-__declspec(naked) void MirrorUVRow_SSSE3(const uint8* src, >- uint8* dst_u, >- uint8* dst_v, >+__declspec(naked) void MirrorUVRow_SSSE3(const uint8_t* src, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push edi >@@ -3079,8 +3081,8 @@ __declspec(naked) void MirrorUVRow_SSSE3(const uint8* src, > #endif // HAS_MIRRORUVROW_SSSE3 > > #ifdef HAS_ARGBMIRRORROW_SSE2 >-__declspec(naked) void ARGBMirrorRow_SSE2(const uint8* src, >- uint8* dst, >+__declspec(naked) void ARGBMirrorRow_SSE2(const uint8_t* src, >+ uint8_t* dst, > int width) { > __asm { > mov eax, [esp + 4] // src >@@ -3105,8 +3107,8 @@ __declspec(naked) void ARGBMirrorRow_SSE2(const uint8* src, > // Shuffle table for reversing the bytes. > static const ulvec32 kARGBShuffleMirror_AVX2 = {7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u}; > >-__declspec(naked) void ARGBMirrorRow_AVX2(const uint8* src, >- uint8* dst, >+__declspec(naked) void ARGBMirrorRow_AVX2(const uint8_t* src, >+ uint8_t* dst, > int width) { > __asm { > mov eax, [esp + 4] // src >@@ -3127,9 +3129,9 @@ __declspec(naked) void ARGBMirrorRow_AVX2(const uint8* src, > #endif // HAS_ARGBMIRRORROW_AVX2 > > #ifdef HAS_SPLITUVROW_SSE2 >-__declspec(naked) void SplitUVRow_SSE2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+__declspec(naked) void SplitUVRow_SSE2(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push edi >@@ -3167,9 +3169,9 @@ __declspec(naked) void SplitUVRow_SSE2(const uint8* src_uv, > #endif // HAS_SPLITUVROW_SSE2 > > #ifdef HAS_SPLITUVROW_AVX2 >-__declspec(naked) void SplitUVRow_AVX2(const uint8* src_uv, >- uint8* dst_u, >- uint8* dst_v, >+__declspec(naked) void SplitUVRow_AVX2(const uint8_t* src_uv, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push edi >@@ -3207,9 +3209,9 @@ __declspec(naked) void SplitUVRow_AVX2(const uint8* src_uv, > #endif // HAS_SPLITUVROW_AVX2 > > #ifdef HAS_MERGEUVROW_SSE2 >-__declspec(naked) void MergeUVRow_SSE2(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+__declspec(naked) void MergeUVRow_SSE2(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width) { > __asm { > push edi >@@ -3239,9 +3241,9 @@ __declspec(naked) void MergeUVRow_SSE2(const uint8* src_u, > #endif // HAS_MERGEUVROW_SSE2 > > #ifdef HAS_MERGEUVROW_AVX2 >-__declspec(naked) void MergeUVRow_AVX2(const uint8* src_u, >- const uint8* src_v, >- uint8* dst_uv, >+__declspec(naked) void MergeUVRow_AVX2(const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_uv, > int width) { > __asm { > push edi >@@ -3273,12 +3275,14 @@ __declspec(naked) void MergeUVRow_AVX2(const uint8* src_u, > #endif // HAS_MERGEUVROW_AVX2 > > #ifdef HAS_COPYROW_SSE2 >-// CopyRow copys 'count' bytes using a 16 byte load/store, 32 bytes at time. >-__declspec(naked) void CopyRow_SSE2(const uint8* src, uint8* dst, int count) { >+// CopyRow copys 'width' bytes using a 16 byte load/store, 32 bytes at time. >+__declspec(naked) void CopyRow_SSE2(const uint8_t* src, >+ uint8_t* dst, >+ int width) { > __asm { > mov eax, [esp + 4] // src > mov edx, [esp + 8] // dst >- mov ecx, [esp + 12] // count >+ mov ecx, [esp + 12] // width > test eax, 15 > jne convertloopu > test edx, 15 >@@ -3310,12 +3314,14 @@ __declspec(naked) void CopyRow_SSE2(const uint8* src, uint8* dst, int count) { > #endif // HAS_COPYROW_SSE2 > > #ifdef HAS_COPYROW_AVX >-// CopyRow copys 'count' bytes using a 32 byte load/store, 64 bytes at time. >-__declspec(naked) void CopyRow_AVX(const uint8* src, uint8* dst, int count) { >+// CopyRow copys 'width' bytes using a 32 byte load/store, 64 bytes at time. >+__declspec(naked) void CopyRow_AVX(const uint8_t* src, >+ uint8_t* dst, >+ int width) { > __asm { > mov eax, [esp + 4] // src > mov edx, [esp + 8] // dst >- mov ecx, [esp + 12] // count >+ mov ecx, [esp + 12] // width > > convertloop: > vmovdqu ymm0, [eax] >@@ -3334,13 +3340,15 @@ __declspec(naked) void CopyRow_AVX(const uint8* src, uint8* dst, int count) { > #endif // HAS_COPYROW_AVX > > // Multiple of 1. >-__declspec(naked) void CopyRow_ERMS(const uint8* src, uint8* dst, int count) { >+__declspec(naked) void CopyRow_ERMS(const uint8_t* src, >+ uint8_t* dst, >+ int width) { > __asm { > mov eax, esi > mov edx, edi > mov esi, [esp + 4] // src > mov edi, [esp + 8] // dst >- mov ecx, [esp + 12] // count >+ mov ecx, [esp + 12] // width > rep movsb > mov edi, edx > mov esi, eax >@@ -3350,13 +3358,13 @@ __declspec(naked) void CopyRow_ERMS(const uint8* src, uint8* dst, int count) { > > #ifdef HAS_ARGBCOPYALPHAROW_SSE2 > // width in pixels >-__declspec(naked) void ARGBCopyAlphaRow_SSE2(const uint8* src, >- uint8* dst, >+__declspec(naked) void ARGBCopyAlphaRow_SSE2(const uint8_t* src, >+ uint8_t* dst, > int width) { > __asm { > mov eax, [esp + 4] // src > mov edx, [esp + 8] // dst >- mov ecx, [esp + 12] // count >+ mov ecx, [esp + 12] // width > pcmpeqb xmm0, xmm0 // generate mask 0xff000000 > pslld xmm0, 24 > pcmpeqb xmm1, xmm1 // generate mask 0x00ffffff >@@ -3387,13 +3395,13 @@ __declspec(naked) void ARGBCopyAlphaRow_SSE2(const uint8* src, > > #ifdef HAS_ARGBCOPYALPHAROW_AVX2 > // width in pixels >-__declspec(naked) void ARGBCopyAlphaRow_AVX2(const uint8* src, >- uint8* dst, >+__declspec(naked) void ARGBCopyAlphaRow_AVX2(const uint8_t* src, >+ uint8_t* dst, > int width) { > __asm { > mov eax, [esp + 4] // src > mov edx, [esp + 8] // dst >- mov ecx, [esp + 12] // count >+ mov ecx, [esp + 12] // width > vpcmpeqb ymm0, ymm0, ymm0 > vpsrld ymm0, ymm0, 8 // generate mask 0x00ffffff > >@@ -3417,8 +3425,8 @@ __declspec(naked) void ARGBCopyAlphaRow_AVX2(const uint8* src, > > #ifdef HAS_ARGBEXTRACTALPHAROW_SSE2 > // width in pixels >-__declspec(naked) void ARGBExtractAlphaRow_SSE2(const uint8* src_argb, >- uint8* dst_a, >+__declspec(naked) void ARGBExtractAlphaRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_a, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -3445,8 +3453,8 @@ __declspec(naked) void ARGBExtractAlphaRow_SSE2(const uint8* src_argb, > > #ifdef HAS_ARGBEXTRACTALPHAROW_AVX2 > // width in pixels >-__declspec(naked) void ARGBExtractAlphaRow_AVX2(const uint8* src_argb, >- uint8* dst_a, >+__declspec(naked) void ARGBExtractAlphaRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_a, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -3481,13 +3489,13 @@ __declspec(naked) void ARGBExtractAlphaRow_AVX2(const uint8* src_argb, > > #ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2 > // width in pixels >-__declspec(naked) void ARGBCopyYToAlphaRow_SSE2(const uint8* src, >- uint8* dst, >+__declspec(naked) void ARGBCopyYToAlphaRow_SSE2(const uint8_t* src, >+ uint8_t* dst, > int width) { > __asm { > mov eax, [esp + 4] // src > mov edx, [esp + 8] // dst >- mov ecx, [esp + 12] // count >+ mov ecx, [esp + 12] // width > pcmpeqb xmm0, xmm0 // generate mask 0xff000000 > pslld xmm0, 24 > pcmpeqb xmm1, xmm1 // generate mask 0x00ffffff >@@ -3520,13 +3528,13 @@ __declspec(naked) void ARGBCopyYToAlphaRow_SSE2(const uint8* src, > > #ifdef HAS_ARGBCOPYYTOALPHAROW_AVX2 > // width in pixels >-__declspec(naked) void ARGBCopyYToAlphaRow_AVX2(const uint8* src, >- uint8* dst, >+__declspec(naked) void ARGBCopyYToAlphaRow_AVX2(const uint8_t* src, >+ uint8_t* dst, > int width) { > __asm { > mov eax, [esp + 4] // src > mov edx, [esp + 8] // dst >- mov ecx, [esp + 12] // count >+ mov ecx, [esp + 12] // width > vpcmpeqb ymm0, ymm0, ymm0 > vpsrld ymm0, ymm0, 8 // generate mask 0x00ffffff > >@@ -3551,16 +3559,16 @@ __declspec(naked) void ARGBCopyYToAlphaRow_AVX2(const uint8* src, > #endif // HAS_ARGBCOPYYTOALPHAROW_AVX2 > > #ifdef HAS_SETROW_X86 >-// Write 'count' bytes using an 8 bit value repeated. >-// Count should be multiple of 4. >-__declspec(naked) void SetRow_X86(uint8* dst, uint8 v8, int count) { >+// Write 'width' bytes using an 8 bit value repeated. >+// width should be multiple of 4. >+__declspec(naked) void SetRow_X86(uint8_t* dst, uint8_t v8, int width) { > __asm { > movzx eax, byte ptr [esp + 8] // v8 > mov edx, 0x01010101 // Duplicate byte to all bytes. > mul edx // overwrites edx with upper part of result. > mov edx, edi > mov edi, [esp + 4] // dst >- mov ecx, [esp + 12] // count >+ mov ecx, [esp + 12] // width > shr ecx, 2 > rep stosd > mov edi, edx >@@ -3568,26 +3576,28 @@ __declspec(naked) void SetRow_X86(uint8* dst, uint8 v8, int count) { > } > } > >-// Write 'count' bytes using an 8 bit value repeated. >-__declspec(naked) void SetRow_ERMS(uint8* dst, uint8 v8, int count) { >+// Write 'width' bytes using an 8 bit value repeated. >+__declspec(naked) void SetRow_ERMS(uint8_t* dst, uint8_t v8, int width) { > __asm { > mov edx, edi > mov edi, [esp + 4] // dst > mov eax, [esp + 8] // v8 >- mov ecx, [esp + 12] // count >+ mov ecx, [esp + 12] // width > rep stosb > mov edi, edx > ret > } > } > >-// Write 'count' 32 bit values. >-__declspec(naked) void ARGBSetRow_X86(uint8* dst_argb, uint32 v32, int count) { >+// Write 'width' 32 bit values. >+__declspec(naked) void ARGBSetRow_X86(uint8_t* dst_argb, >+ uint32_t v32, >+ int width) { > __asm { > mov edx, edi > mov edi, [esp + 4] // dst > mov eax, [esp + 8] // v32 >- mov ecx, [esp + 12] // count >+ mov ecx, [esp + 12] // width > rep stosd > mov edi, edx > ret >@@ -3596,8 +3606,8 @@ __declspec(naked) void ARGBSetRow_X86(uint8* dst_argb, uint32 v32, int count) { > #endif // HAS_SETROW_X86 > > #ifdef HAS_YUY2TOYROW_AVX2 >-__declspec(naked) void YUY2ToYRow_AVX2(const uint8* src_yuy2, >- uint8* dst_y, >+__declspec(naked) void YUY2ToYRow_AVX2(const uint8_t* src_yuy2, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] // src_yuy2 >@@ -3623,10 +3633,10 @@ __declspec(naked) void YUY2ToYRow_AVX2(const uint8* src_yuy2, > } > } > >-__declspec(naked) void YUY2ToUVRow_AVX2(const uint8* src_yuy2, >+__declspec(naked) void YUY2ToUVRow_AVX2(const uint8_t* src_yuy2, > int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -3669,9 +3679,9 @@ __declspec(naked) void YUY2ToUVRow_AVX2(const uint8* src_yuy2, > } > } > >-__declspec(naked) void YUY2ToUV422Row_AVX2(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+__declspec(naked) void YUY2ToUV422Row_AVX2(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push edi >@@ -3709,8 +3719,8 @@ __declspec(naked) void YUY2ToUV422Row_AVX2(const uint8* src_yuy2, > } > } > >-__declspec(naked) void UYVYToYRow_AVX2(const uint8* src_uyvy, >- uint8* dst_y, >+__declspec(naked) void UYVYToYRow_AVX2(const uint8_t* src_uyvy, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] // src_uyvy >@@ -3734,10 +3744,10 @@ __declspec(naked) void UYVYToYRow_AVX2(const uint8* src_uyvy, > } > } > >-__declspec(naked) void UYVYToUVRow_AVX2(const uint8* src_uyvy, >+__declspec(naked) void UYVYToUVRow_AVX2(const uint8_t* src_uyvy, > int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -3780,9 +3790,9 @@ __declspec(naked) void UYVYToUVRow_AVX2(const uint8* src_uyvy, > } > } > >-__declspec(naked) void UYVYToUV422Row_AVX2(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+__declspec(naked) void UYVYToUV422Row_AVX2(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push edi >@@ -3822,8 +3832,8 @@ __declspec(naked) void UYVYToUV422Row_AVX2(const uint8* src_uyvy, > #endif // HAS_YUY2TOYROW_AVX2 > > #ifdef HAS_YUY2TOYROW_SSE2 >-__declspec(naked) void YUY2ToYRow_SSE2(const uint8* src_yuy2, >- uint8* dst_y, >+__declspec(naked) void YUY2ToYRow_SSE2(const uint8_t* src_yuy2, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] // src_yuy2 >@@ -3847,10 +3857,10 @@ __declspec(naked) void YUY2ToYRow_SSE2(const uint8* src_yuy2, > } > } > >-__declspec(naked) void YUY2ToUVRow_SSE2(const uint8* src_yuy2, >+__declspec(naked) void YUY2ToUVRow_SSE2(const uint8_t* src_yuy2, > int stride_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -3892,9 +3902,9 @@ __declspec(naked) void YUY2ToUVRow_SSE2(const uint8* src_yuy2, > } > } > >-__declspec(naked) void YUY2ToUV422Row_SSE2(const uint8* src_yuy2, >- uint8* dst_u, >- uint8* dst_v, >+__declspec(naked) void YUY2ToUV422Row_SSE2(const uint8_t* src_yuy2, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push edi >@@ -3929,8 +3939,8 @@ __declspec(naked) void YUY2ToUV422Row_SSE2(const uint8* src_yuy2, > } > } > >-__declspec(naked) void UYVYToYRow_SSE2(const uint8* src_uyvy, >- uint8* dst_y, >+__declspec(naked) void UYVYToYRow_SSE2(const uint8_t* src_uyvy, >+ uint8_t* dst_y, > int width) { > __asm { > mov eax, [esp + 4] // src_uyvy >@@ -3952,10 +3962,10 @@ __declspec(naked) void UYVYToYRow_SSE2(const uint8* src_uyvy, > } > } > >-__declspec(naked) void UYVYToUVRow_SSE2(const uint8* src_uyvy, >+__declspec(naked) void UYVYToUVRow_SSE2(const uint8_t* src_uyvy, > int stride_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push esi >@@ -3997,9 +4007,9 @@ __declspec(naked) void UYVYToUVRow_SSE2(const uint8* src_uyvy, > } > } > >-__declspec(naked) void UYVYToUV422Row_SSE2(const uint8* src_uyvy, >- uint8* dst_u, >- uint8* dst_v, >+__declspec(naked) void UYVYToUV422Row_SSE2(const uint8_t* src_uyvy, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int width) { > __asm { > push edi >@@ -4041,10 +4051,10 @@ __declspec(naked) void UYVYToUV422Row_SSE2(const uint8* src_uyvy, > // =((A2*C2)+(B2*(255-C2))+255)/256 > // signed version of math > // =(((A2-128)*C2)+((B2-128)*(255-C2))+32768+127)/256 >-__declspec(naked) void BlendPlaneRow_SSSE3(const uint8* src0, >- const uint8* src1, >- const uint8* alpha, >- uint8* dst, >+__declspec(naked) void BlendPlaneRow_SSSE3(const uint8_t* src0, >+ const uint8_t* src1, >+ const uint8_t* alpha, >+ uint8_t* dst, > int width) { > __asm { > push esi >@@ -4098,10 +4108,10 @@ __declspec(naked) void BlendPlaneRow_SSSE3(const uint8* src0, > // =((A2*C2)+(B2*(255-C2))+255)/256 > // signed version of math > // =(((A2-128)*C2)+((B2-128)*(255-C2))+32768+127)/256 >-__declspec(naked) void BlendPlaneRow_AVX2(const uint8* src0, >- const uint8* src1, >- const uint8* alpha, >- uint8* dst, >+__declspec(naked) void BlendPlaneRow_AVX2(const uint8_t* src0, >+ const uint8_t* src1, >+ const uint8_t* alpha, >+ uint8_t* dst, > int width) { > __asm { > push esi >@@ -4162,9 +4172,9 @@ static const uvec8 kShuffleAlpha = {3u, 0x80, 3u, 0x80, 7u, 0x80, 7u, 0x80, > 11u, 0x80, 11u, 0x80, 15u, 0x80, 15u, 0x80}; > > // Blend 8 pixels at a time. >-__declspec(naked) void ARGBBlendRow_SSSE3(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+__declspec(naked) void ARGBBlendRow_SSSE3(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > __asm { > push esi >@@ -4253,8 +4263,8 @@ static const uvec8 kShuffleAlpha1 = { > 11u, 11u, 11u, 11u, 11u, 11u, 128u, 128u, > 15u, 15u, 15u, 15u, 15u, 15u, 128u, 128u, > }; >-__declspec(naked) void ARGBAttenuateRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >+__declspec(naked) void ARGBAttenuateRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb0 >@@ -4298,8 +4308,8 @@ __declspec(naked) void ARGBAttenuateRow_SSSE3(const uint8* src_argb, > static const uvec8 kShuffleAlpha_AVX2 = {6u, 7u, 6u, 7u, 6u, 7u, > 128u, 128u, 14u, 15u, 14u, 15u, > 14u, 15u, 128u, 128u}; >-__declspec(naked) void ARGBAttenuateRow_AVX2(const uint8* src_argb, >- uint8* dst_argb, >+__declspec(naked) void ARGBAttenuateRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb0 >@@ -4336,8 +4346,8 @@ __declspec(naked) void ARGBAttenuateRow_AVX2(const uint8* src_argb, > > #ifdef HAS_ARGBUNATTENUATEROW_SSE2 > // Unattenuate 4 pixels at a time. >-__declspec(naked) void ARGBUnattenuateRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >+__declspec(naked) void ARGBUnattenuateRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width) { > __asm { > push ebx >@@ -4392,8 +4402,8 @@ static const uvec8 kUnattenShuffleAlpha_AVX2 = { > // TODO(fbarchard): Enable USE_GATHER for future hardware if faster. > // USE_GATHER is not on by default, due to being a slow instruction. > #ifdef USE_GATHER >-__declspec(naked) void ARGBUnattenuateRow_AVX2(const uint8* src_argb, >- uint8* dst_argb, >+__declspec(naked) void ARGBUnattenuateRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, [esp + 4] // src_argb0 >@@ -4426,8 +4436,8 @@ __declspec(naked) void ARGBUnattenuateRow_AVX2(const uint8* src_argb, > } > } > #else // USE_GATHER >-__declspec(naked) void ARGBUnattenuateRow_AVX2(const uint8* src_argb, >- uint8* dst_argb, >+__declspec(naked) void ARGBUnattenuateRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width) { > __asm { > >@@ -4495,8 +4505,8 @@ __declspec(naked) void ARGBUnattenuateRow_AVX2(const uint8* src_argb, > > #ifdef HAS_ARGBGRAYROW_SSSE3 > // Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels. >-__declspec(naked) void ARGBGrayRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >+__declspec(naked) void ARGBGrayRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width) { > __asm { > mov eax, [esp + 4] /* src_argb */ >@@ -4552,7 +4562,7 @@ static const vec8 kARGBToSepiaR = {24, 98, 50, 0, 24, 98, 50, 0, > 24, 98, 50, 0, 24, 98, 50, 0}; > > // Convert 8 ARGB pixels (32 bytes) to 8 Sepia ARGB pixels. >-__declspec(naked) void ARGBSepiaRow_SSSE3(uint8* dst_argb, int width) { >+__declspec(naked) void ARGBSepiaRow_SSSE3(uint8_t* dst_argb, int width) { > __asm { > mov eax, [esp + 4] /* dst_argb */ > mov ecx, [esp + 8] /* width */ >@@ -4608,9 +4618,9 @@ __declspec(naked) void ARGBSepiaRow_SSSE3(uint8* dst_argb, int width) { > // Same as Sepia except matrix is provided. > // TODO(fbarchard): packuswbs only use half of the reg. To make RGBA, combine R > // and B into a high and low, then G/A, unpackl/hbw and then unpckl/hwd. >-__declspec(naked) void ARGBColorMatrixRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >- const int8* matrix_argb, >+__declspec(naked) void ARGBColorMatrixRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const int8_t* matrix_argb, > int width) { > __asm { > mov eax, [esp + 4] /* src_argb */ >@@ -4670,7 +4680,7 @@ __declspec(naked) void ARGBColorMatrixRow_SSSE3(const uint8* src_argb, > > #ifdef HAS_ARGBQUANTIZEROW_SSE2 > // Quantize 4 ARGB pixels (16 bytes). >-__declspec(naked) void ARGBQuantizeRow_SSE2(uint8* dst_argb, >+__declspec(naked) void ARGBQuantizeRow_SSE2(uint8_t* dst_argb, > int scale, > int interval_size, > int interval_offset, >@@ -4717,10 +4727,10 @@ __declspec(naked) void ARGBQuantizeRow_SSE2(uint8* dst_argb, > > #ifdef HAS_ARGBSHADEROW_SSE2 > // Shade 4 pixels at a time by specified value. >-__declspec(naked) void ARGBShadeRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >+__declspec(naked) void ARGBShadeRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- uint32 value) { >+ uint32_t value) { > __asm { > mov eax, [esp + 4] // src_argb > mov edx, [esp + 8] // dst_argb >@@ -4752,9 +4762,9 @@ __declspec(naked) void ARGBShadeRow_SSE2(const uint8* src_argb, > > #ifdef HAS_ARGBMULTIPLYROW_SSE2 > // Multiply 2 rows of ARGB pixels together, 4 pixels at a time. >-__declspec(naked) void ARGBMultiplyRow_SSE2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+__declspec(naked) void ARGBMultiplyRow_SSE2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > __asm { > push esi >@@ -4792,9 +4802,9 @@ __declspec(naked) void ARGBMultiplyRow_SSE2(const uint8* src_argb0, > #ifdef HAS_ARGBADDROW_SSE2 > // Add 2 rows of ARGB pixels together, 4 pixels at a time. > // TODO(fbarchard): Port this to posix, neon and other math functions. >-__declspec(naked) void ARGBAddRow_SSE2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+__declspec(naked) void ARGBAddRow_SSE2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > __asm { > push esi >@@ -4841,9 +4851,9 @@ __declspec(naked) void ARGBAddRow_SSE2(const uint8* src_argb0, > > #ifdef HAS_ARGBSUBTRACTROW_SSE2 > // Subtract 2 rows of ARGB pixels together, 4 pixels at a time. >-__declspec(naked) void ARGBSubtractRow_SSE2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+__declspec(naked) void ARGBSubtractRow_SSE2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > __asm { > push esi >@@ -4871,9 +4881,9 @@ __declspec(naked) void ARGBSubtractRow_SSE2(const uint8* src_argb0, > > #ifdef HAS_ARGBMULTIPLYROW_AVX2 > // Multiply 2 rows of ARGB pixels together, 8 pixels at a time. >-__declspec(naked) void ARGBMultiplyRow_AVX2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+__declspec(naked) void ARGBMultiplyRow_AVX2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > __asm { > push esi >@@ -4909,9 +4919,9 @@ __declspec(naked) void ARGBMultiplyRow_AVX2(const uint8* src_argb0, > > #ifdef HAS_ARGBADDROW_AVX2 > // Add 2 rows of ARGB pixels together, 8 pixels at a time. >-__declspec(naked) void ARGBAddRow_AVX2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+__declspec(naked) void ARGBAddRow_AVX2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > __asm { > push esi >@@ -4939,9 +4949,9 @@ __declspec(naked) void ARGBAddRow_AVX2(const uint8* src_argb0, > > #ifdef HAS_ARGBSUBTRACTROW_AVX2 > // Subtract 2 rows of ARGB pixels together, 8 pixels at a time. >-__declspec(naked) void ARGBSubtractRow_AVX2(const uint8* src_argb0, >- const uint8* src_argb1, >- uint8* dst_argb, >+__declspec(naked) void ARGBSubtractRow_AVX2(const uint8_t* src_argb0, >+ const uint8_t* src_argb1, >+ uint8_t* dst_argb, > int width) { > __asm { > push esi >@@ -4972,10 +4982,10 @@ __declspec(naked) void ARGBSubtractRow_AVX2(const uint8* src_argb0, > // -1 0 1 > // -2 0 2 > // -1 0 1 >-__declspec(naked) void SobelXRow_SSE2(const uint8* src_y0, >- const uint8* src_y1, >- const uint8* src_y2, >- uint8* dst_sobelx, >+__declspec(naked) void SobelXRow_SSE2(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ const uint8_t* src_y2, >+ uint8_t* dst_sobelx, > int width) { > __asm { > push esi >@@ -5030,9 +5040,9 @@ __declspec(naked) void SobelXRow_SSE2(const uint8* src_y0, > // -1 -2 -1 > // 0 0 0 > // 1 2 1 >-__declspec(naked) void SobelYRow_SSE2(const uint8* src_y0, >- const uint8* src_y1, >- uint8* dst_sobely, >+__declspec(naked) void SobelYRow_SSE2(const uint8_t* src_y0, >+ const uint8_t* src_y1, >+ uint8_t* dst_sobely, > int width) { > __asm { > push esi >@@ -5084,9 +5094,9 @@ __declspec(naked) void SobelYRow_SSE2(const uint8* src_y0, > // R = Sobel > // G = Sobel > // B = Sobel >-__declspec(naked) void SobelRow_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+__declspec(naked) void SobelRow_SSE2(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { > __asm { > push esi >@@ -5132,9 +5142,9 @@ __declspec(naked) void SobelRow_SSE2(const uint8* src_sobelx, > > #ifdef HAS_SOBELTOPLANEROW_SSE2 > // Adds Sobel X and Sobel Y and stores Sobel into a plane. >-__declspec(naked) void SobelToPlaneRow_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_y, >+__declspec(naked) void SobelToPlaneRow_SSE2(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_y, > int width) { > __asm { > push esi >@@ -5166,9 +5176,9 @@ __declspec(naked) void SobelToPlaneRow_SSE2(const uint8* src_sobelx, > // R = Sobel X > // G = Sobel > // B = Sobel Y >-__declspec(naked) void SobelXYRow_SSE2(const uint8* src_sobelx, >- const uint8* src_sobely, >- uint8* dst_argb, >+__declspec(naked) void SobelXYRow_SSE2(const uint8_t* src_sobelx, >+ const uint8_t* src_sobely, >+ uint8_t* dst_argb, > int width) { > __asm { > push esi >@@ -5225,11 +5235,11 @@ __declspec(naked) void SobelXYRow_SSE2(const uint8* src_sobelx, > // count is number of averaged pixels to produce. > // Does 4 pixels at a time. > // This function requires alignment on accumulation buffer pointers. >-void CumulativeSumToAverageRow_SSE2(const int32* topleft, >- const int32* botleft, >+void CumulativeSumToAverageRow_SSE2(const int32_t* topleft, >+ const int32_t* botleft, > int width, > int area, >- uint8* dst, >+ uint8_t* dst, > int count) { > __asm { > mov eax, topleft // eax topleft >@@ -5375,9 +5385,9 @@ void CumulativeSumToAverageRow_SSE2(const int32* topleft, > #ifdef HAS_COMPUTECUMULATIVESUMROW_SSE2 > // Creates a table of cumulative sums where each value is a sum of all values > // above and to the left of the value. >-void ComputeCumulativeSumRow_SSE2(const uint8* row, >- int32* cumsum, >- const int32* previous_cumsum, >+void ComputeCumulativeSumRow_SSE2(const uint8_t* row, >+ int32_t* cumsum, >+ const int32_t* previous_cumsum, > int width) { > __asm { > mov eax, row >@@ -5460,9 +5470,9 @@ void ComputeCumulativeSumRow_SSE2(const uint8* row, > > #ifdef HAS_ARGBAFFINEROW_SSE2 > // Copy ARGB pixels from source image with slope to a row of destination. >-__declspec(naked) LIBYUV_API void ARGBAffineRow_SSE2(const uint8* src_argb, >+__declspec(naked) LIBYUV_API void ARGBAffineRow_SSE2(const uint8_t* src_argb, > int src_argb_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > const float* uv_dudv, > int width) { > __asm { >@@ -5546,8 +5556,8 @@ __declspec(naked) LIBYUV_API void ARGBAffineRow_SSE2(const uint8* src_argb, > > #ifdef HAS_INTERPOLATEROW_AVX2 > // Bilinear filter 32x2 -> 32x1 >-__declspec(naked) void InterpolateRow_AVX2(uint8* dst_ptr, >- const uint8* src_ptr, >+__declspec(naked) void InterpolateRow_AVX2(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride, > int dst_width, > int source_y_fraction) { >@@ -5623,8 +5633,8 @@ __declspec(naked) void InterpolateRow_AVX2(uint8* dst_ptr, > > // Bilinear filter 16x2 -> 16x1 > // TODO(fbarchard): Consider allowing 256 using memcpy. >-__declspec(naked) void InterpolateRow_SSSE3(uint8* dst_ptr, >- const uint8* src_ptr, >+__declspec(naked) void InterpolateRow_SSSE3(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride, > int dst_width, > int source_y_fraction) { >@@ -5705,9 +5715,9 @@ __declspec(naked) void InterpolateRow_SSSE3(uint8* dst_ptr, > } > > // For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. >-__declspec(naked) void ARGBShuffleRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+__declspec(naked) void ARGBShuffleRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -5732,9 +5742,9 @@ __declspec(naked) void ARGBShuffleRow_SSSE3(const uint8* src_argb, > } > > #ifdef HAS_ARGBSHUFFLEROW_AVX2 >-__declspec(naked) void ARGBShuffleRow_AVX2(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >+__declspec(naked) void ARGBShuffleRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, >+ const uint8_t* shuffler, > int width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -5761,133 +5771,16 @@ __declspec(naked) void ARGBShuffleRow_AVX2(const uint8* src_argb, > } > #endif // HAS_ARGBSHUFFLEROW_AVX2 > >-__declspec(naked) void ARGBShuffleRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >- const uint8* shuffler, >- int width) { >- __asm { >- push ebx >- push esi >- mov eax, [esp + 8 + 4] // src_argb >- mov edx, [esp + 8 + 8] // dst_argb >- mov esi, [esp + 8 + 12] // shuffler >- mov ecx, [esp + 8 + 16] // width >- pxor xmm5, xmm5 >- >- mov ebx, [esi] // shuffler >- cmp ebx, 0x03000102 >- je shuf_3012 >- cmp ebx, 0x00010203 >- je shuf_0123 >- cmp ebx, 0x00030201 >- je shuf_0321 >- cmp ebx, 0x02010003 >- je shuf_2103 >- >- // TODO(fbarchard): Use one source pointer and 3 offsets. >- shuf_any1: >- movzx ebx, byte ptr [esi] >- movzx ebx, byte ptr [eax + ebx] >- mov [edx], bl >- movzx ebx, byte ptr [esi + 1] >- movzx ebx, byte ptr [eax + ebx] >- mov [edx + 1], bl >- movzx ebx, byte ptr [esi + 2] >- movzx ebx, byte ptr [eax + ebx] >- mov [edx + 2], bl >- movzx ebx, byte ptr [esi + 3] >- movzx ebx, byte ptr [eax + ebx] >- mov [edx + 3], bl >- lea eax, [eax + 4] >- lea edx, [edx + 4] >- sub ecx, 1 >- jg shuf_any1 >- jmp shuf99 >- >- shuf_0123: >- movdqu xmm0, [eax] >- lea eax, [eax + 16] >- movdqa xmm1, xmm0 >- punpcklbw xmm0, xmm5 >- punpckhbw xmm1, xmm5 >- pshufhw xmm0, xmm0, 01Bh // 1B = 00011011 = 0x0123 = BGRAToARGB >- pshuflw xmm0, xmm0, 01Bh >- pshufhw xmm1, xmm1, 01Bh >- pshuflw xmm1, xmm1, 01Bh >- packuswb xmm0, xmm1 >- movdqu [edx], xmm0 >- lea edx, [edx + 16] >- sub ecx, 4 >- jg shuf_0123 >- jmp shuf99 >- >- shuf_0321: >- movdqu xmm0, [eax] >- lea eax, [eax + 16] >- movdqa xmm1, xmm0 >- punpcklbw xmm0, xmm5 >- punpckhbw xmm1, xmm5 >- pshufhw xmm0, xmm0, 039h // 39 = 00111001 = 0x0321 = RGBAToARGB >- pshuflw xmm0, xmm0, 039h >- pshufhw xmm1, xmm1, 039h >- pshuflw xmm1, xmm1, 039h >- packuswb xmm0, xmm1 >- movdqu [edx], xmm0 >- lea edx, [edx + 16] >- sub ecx, 4 >- jg shuf_0321 >- jmp shuf99 >- >- shuf_2103: >- movdqu xmm0, [eax] >- lea eax, [eax + 16] >- movdqa xmm1, xmm0 >- punpcklbw xmm0, xmm5 >- punpckhbw xmm1, xmm5 >- pshufhw xmm0, xmm0, 093h // 93 = 10010011 = 0x2103 = ARGBToRGBA >- pshuflw xmm0, xmm0, 093h >- pshufhw xmm1, xmm1, 093h >- pshuflw xmm1, xmm1, 093h >- packuswb xmm0, xmm1 >- movdqu [edx], xmm0 >- lea edx, [edx + 16] >- sub ecx, 4 >- jg shuf_2103 >- jmp shuf99 >- >- shuf_3012: >- movdqu xmm0, [eax] >- lea eax, [eax + 16] >- movdqa xmm1, xmm0 >- punpcklbw xmm0, xmm5 >- punpckhbw xmm1, xmm5 >- pshufhw xmm0, xmm0, 0C6h // C6 = 11000110 = 0x3012 = ABGRToARGB >- pshuflw xmm0, xmm0, 0C6h >- pshufhw xmm1, xmm1, 0C6h >- pshuflw xmm1, xmm1, 0C6h >- packuswb xmm0, xmm1 >- movdqu [edx], xmm0 >- lea edx, [edx + 16] >- sub ecx, 4 >- jg shuf_3012 >- >- shuf99: >- pop esi >- pop ebx >- ret >- } >-} >- > // YUY2 - Macro-pixel = 2 image pixels > // Y0U0Y1V0....Y2U2Y3V2...Y4U4Y5V4.... > > // UYVY - Macro-pixel = 2 image pixels > // U0Y0V0Y1 > >-__declspec(naked) void I422ToYUY2Row_SSE2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_frame, >+__declspec(naked) void I422ToYUY2Row_SSE2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_frame, > int width) { > __asm { > push esi >@@ -5921,10 +5814,10 @@ __declspec(naked) void I422ToYUY2Row_SSE2(const uint8* src_y, > } > } > >-__declspec(naked) void I422ToUYVYRow_SSE2(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_frame, >+__declspec(naked) void I422ToUYVYRow_SSE2(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_frame, > int width) { > __asm { > push esi >@@ -5959,8 +5852,8 @@ __declspec(naked) void I422ToUYVYRow_SSE2(const uint8* src_y, > } > > #ifdef HAS_ARGBPOLYNOMIALROW_SSE2 >-__declspec(naked) void ARGBPolynomialRow_SSE2(const uint8* src_argb, >- uint8* dst_argb, >+__declspec(naked) void ARGBPolynomialRow_SSE2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > const float* poly, > int width) { > __asm { >@@ -6018,8 +5911,8 @@ __declspec(naked) void ARGBPolynomialRow_SSE2(const uint8* src_argb, > #endif // HAS_ARGBPOLYNOMIALROW_SSE2 > > #ifdef HAS_ARGBPOLYNOMIALROW_AVX2 >-__declspec(naked) void ARGBPolynomialRow_AVX2(const uint8* src_argb, >- uint8* dst_argb, >+__declspec(naked) void ARGBPolynomialRow_AVX2(const uint8_t* src_argb, >+ uint8_t* dst_argb, > const float* poly, > int width) { > __asm { >@@ -6058,8 +5951,8 @@ __declspec(naked) void ARGBPolynomialRow_AVX2(const uint8* src_argb, > > #ifdef HAS_HALFFLOATROW_SSE2 > static float kExpBias = 1.9259299444e-34f; >-__declspec(naked) void HalfFloatRow_SSE2(const uint16* src, >- uint16* dst, >+__declspec(naked) void HalfFloatRow_SSE2(const uint16_t* src, >+ uint16_t* dst, > float scale, > int width) { > __asm { >@@ -6095,8 +5988,8 @@ __declspec(naked) void HalfFloatRow_SSE2(const uint16* src, > #endif // HAS_HALFFLOATROW_SSE2 > > #ifdef HAS_HALFFLOATROW_AVX2 >-__declspec(naked) void HalfFloatRow_AVX2(const uint16* src, >- uint16* dst, >+__declspec(naked) void HalfFloatRow_AVX2(const uint16_t* src, >+ uint16_t* dst, > float scale, > int width) { > __asm { >@@ -6133,8 +6026,8 @@ __declspec(naked) void HalfFloatRow_AVX2(const uint16* src, > #endif // HAS_HALFFLOATROW_AVX2 > > #ifdef HAS_HALFFLOATROW_F16C >-__declspec(naked) void HalfFloatRow_F16C(const uint16* src, >- uint16* dst, >+__declspec(naked) void HalfFloatRow_F16C(const uint16_t* src, >+ uint16_t* dst, > float scale, > int width) { > __asm { >@@ -6167,8 +6060,8 @@ __declspec(naked) void HalfFloatRow_F16C(const uint16* src, > > #ifdef HAS_ARGBCOLORTABLEROW_X86 > // Tranform ARGB pixels with color table. >-__declspec(naked) void ARGBColorTableRow_X86(uint8* dst_argb, >- const uint8* table_argb, >+__declspec(naked) void ARGBColorTableRow_X86(uint8_t* dst_argb, >+ const uint8_t* table_argb, > int width) { > __asm { > push esi >@@ -6201,8 +6094,8 @@ __declspec(naked) void ARGBColorTableRow_X86(uint8* dst_argb, > > #ifdef HAS_RGBCOLORTABLEROW_X86 > // Tranform RGB pixels with color table. >-__declspec(naked) void RGBColorTableRow_X86(uint8* dst_argb, >- const uint8* table_argb, >+__declspec(naked) void RGBColorTableRow_X86(uint8_t* dst_argb, >+ const uint8_t* table_argb, > int width) { > __asm { > push esi >@@ -6233,11 +6126,11 @@ __declspec(naked) void RGBColorTableRow_X86(uint8* dst_argb, > > #ifdef HAS_ARGBLUMACOLORTABLEROW_SSSE3 > // Tranform RGB pixels with luma table. >-__declspec(naked) void ARGBLumaColorTableRow_SSSE3(const uint8* src_argb, >- uint8* dst_argb, >+__declspec(naked) void ARGBLumaColorTableRow_SSSE3(const uint8_t* src_argb, >+ uint8_t* dst_argb, > int width, >- const uint8* luma, >- uint32 lumacoeff) { >+ const uint8_t* luma, >+ uint32_t lumacoeff) { > __asm { > push esi > push edi >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale.cc >index 9104acb95fc5608c010752c323ff12ff9de6994b..2cfa1c6cb1c4b8a4be72bb590372aa7b54ccd7ee 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale.cc >@@ -39,12 +39,12 @@ static void ScalePlaneDown2(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_ptr, >- uint8* dst_ptr, >+ const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > enum FilterMode filtering) { > int y; >- void (*ScaleRowDown2)(const uint8* src_ptr, ptrdiff_t src_stride, >- uint8* dst_ptr, int dst_width) = >+ void (*ScaleRowDown2)(const uint8_t* src_ptr, ptrdiff_t src_stride, >+ uint8_t* dst_ptr, int dst_width) = > filtering == kFilterNone > ? ScaleRowDown2_C > : (filtering == kFilterLinear ? ScaleRowDown2Linear_C >@@ -103,13 +103,6 @@ static void ScalePlaneDown2(int src_width, > } > } > #endif >-#if defined(HAS_SCALEROWDOWN2_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src_ptr, 4) && >- IS_ALIGNED(src_stride, 4) && IS_ALIGNED(row_stride, 4) && >- IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { >- ScaleRowDown2 = filtering ? ScaleRowDown2Box_DSPR2 : ScaleRowDown2_DSPR2; >- } >-#endif > #if defined(HAS_SCALEROWDOWN2_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > ScaleRowDown2 = >@@ -143,12 +136,12 @@ static void ScalePlaneDown2_16(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint16* src_ptr, >- uint16* dst_ptr, >+ const uint16_t* src_ptr, >+ uint16_t* dst_ptr, > enum FilterMode filtering) { > int y; >- void (*ScaleRowDown2)(const uint16* src_ptr, ptrdiff_t src_stride, >- uint16* dst_ptr, int dst_width) = >+ void (*ScaleRowDown2)(const uint16_t* src_ptr, ptrdiff_t src_stride, >+ uint16_t* dst_ptr, int dst_width) = > filtering == kFilterNone > ? ScaleRowDown2_16_C > : (filtering == kFilterLinear ? ScaleRowDown2Linear_16_C >@@ -176,14 +169,6 @@ static void ScalePlaneDown2_16(int src_width, > : ScaleRowDown2Box_16_SSE2); > } > #endif >-#if defined(HAS_SCALEROWDOWN2_16_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src_ptr, 4) && >- IS_ALIGNED(src_stride, 4) && IS_ALIGNED(row_stride, 4) && >- IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { >- ScaleRowDown2 = >- filtering ? ScaleRowDown2Box_16_DSPR2 : ScaleRowDown2_16_DSPR2; >- } >-#endif > > if (filtering == kFilterLinear) { > src_stride = 0; >@@ -206,12 +191,12 @@ static void ScalePlaneDown4(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_ptr, >- uint8* dst_ptr, >+ const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > enum FilterMode filtering) { > int y; >- void (*ScaleRowDown4)(const uint8* src_ptr, ptrdiff_t src_stride, >- uint8* dst_ptr, int dst_width) = >+ void (*ScaleRowDown4)(const uint8_t* src_ptr, ptrdiff_t src_stride, >+ uint8_t* dst_ptr, int dst_width) = > filtering ? ScaleRowDown4Box_C : ScaleRowDown4_C; > int row_stride = src_stride << 2; > (void)src_width; >@@ -247,13 +232,6 @@ static void ScalePlaneDown4(int src_width, > } > } > #endif >-#if defined(HAS_SCALEROWDOWN4_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(row_stride, 4) && >- IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && >- IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { >- ScaleRowDown4 = filtering ? ScaleRowDown4Box_DSPR2 : ScaleRowDown4_DSPR2; >- } >-#endif > #if defined(HAS_SCALEROWDOWN4_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > ScaleRowDown4 = >@@ -280,12 +258,12 @@ static void ScalePlaneDown4_16(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint16* src_ptr, >- uint16* dst_ptr, >+ const uint16_t* src_ptr, >+ uint16_t* dst_ptr, > enum FilterMode filtering) { > int y; >- void (*ScaleRowDown4)(const uint16* src_ptr, ptrdiff_t src_stride, >- uint16* dst_ptr, int dst_width) = >+ void (*ScaleRowDown4)(const uint16_t* src_ptr, ptrdiff_t src_stride, >+ uint16_t* dst_ptr, int dst_width) = > filtering ? ScaleRowDown4Box_16_C : ScaleRowDown4_16_C; > int row_stride = src_stride << 2; > (void)src_width; >@@ -306,14 +284,6 @@ static void ScalePlaneDown4_16(int src_width, > filtering ? ScaleRowDown4Box_16_SSE2 : ScaleRowDown4_16_SSE2; > } > #endif >-#if defined(HAS_SCALEROWDOWN4_16_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(row_stride, 4) && >- IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && >- IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { >- ScaleRowDown4 = >- filtering ? ScaleRowDown4Box_16_DSPR2 : ScaleRowDown4_16_DSPR2; >- } >-#endif > > if (filtering == kFilterLinear) { > src_stride = 0; >@@ -332,14 +302,14 @@ static void ScalePlaneDown34(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_ptr, >- uint8* dst_ptr, >+ const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > enum FilterMode filtering) { > int y; >- void (*ScaleRowDown34_0)(const uint8* src_ptr, ptrdiff_t src_stride, >- uint8* dst_ptr, int dst_width); >- void (*ScaleRowDown34_1)(const uint8* src_ptr, ptrdiff_t src_stride, >- uint8* dst_ptr, int dst_width); >+ void (*ScaleRowDown34_0)(const uint8_t* src_ptr, ptrdiff_t src_stride, >+ uint8_t* dst_ptr, int dst_width); >+ void (*ScaleRowDown34_1)(const uint8_t* src_ptr, ptrdiff_t src_stride, >+ uint8_t* dst_ptr, int dst_width); > const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; > (void)src_width; > (void)src_height; >@@ -411,19 +381,6 @@ static void ScalePlaneDown34(int src_width, > } > } > #endif >-#if defined(HAS_SCALEROWDOWN34_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && (dst_width % 24 == 0) && >- IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && >- IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { >- if (!filtering) { >- ScaleRowDown34_0 = ScaleRowDown34_DSPR2; >- ScaleRowDown34_1 = ScaleRowDown34_DSPR2; >- } else { >- ScaleRowDown34_0 = ScaleRowDown34_0_Box_DSPR2; >- ScaleRowDown34_1 = ScaleRowDown34_1_Box_DSPR2; >- } >- } >-#endif > > for (y = 0; y < dst_height - 2; y += 3) { > ScaleRowDown34_0(src_ptr, filter_stride, dst_ptr, dst_width); >@@ -454,14 +411,14 @@ static void ScalePlaneDown34_16(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint16* src_ptr, >- uint16* dst_ptr, >+ const uint16_t* src_ptr, >+ uint16_t* dst_ptr, > enum FilterMode filtering) { > int y; >- void (*ScaleRowDown34_0)(const uint16* src_ptr, ptrdiff_t src_stride, >- uint16* dst_ptr, int dst_width); >- void (*ScaleRowDown34_1)(const uint16* src_ptr, ptrdiff_t src_stride, >- uint16* dst_ptr, int dst_width); >+ void (*ScaleRowDown34_0)(const uint16_t* src_ptr, ptrdiff_t src_stride, >+ uint16_t* dst_ptr, int dst_width); >+ void (*ScaleRowDown34_1)(const uint16_t* src_ptr, ptrdiff_t src_stride, >+ uint16_t* dst_ptr, int dst_width); > const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; > (void)src_width; > (void)src_height; >@@ -495,19 +452,6 @@ static void ScalePlaneDown34_16(int src_width, > } > } > #endif >-#if defined(HAS_SCALEROWDOWN34_16_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && (dst_width % 24 == 0) && >- IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && >- IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { >- if (!filtering) { >- ScaleRowDown34_0 = ScaleRowDown34_16_DSPR2; >- ScaleRowDown34_1 = ScaleRowDown34_16_DSPR2; >- } else { >- ScaleRowDown34_0 = ScaleRowDown34_0_Box_16_DSPR2; >- ScaleRowDown34_1 = ScaleRowDown34_1_Box_16_DSPR2; >- } >- } >-#endif > > for (y = 0; y < dst_height - 2; y += 3) { > ScaleRowDown34_0(src_ptr, filter_stride, dst_ptr, dst_width); >@@ -553,14 +497,14 @@ static void ScalePlaneDown38(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_ptr, >- uint8* dst_ptr, >+ const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > enum FilterMode filtering) { > int y; >- void (*ScaleRowDown38_3)(const uint8* src_ptr, ptrdiff_t src_stride, >- uint8* dst_ptr, int dst_width); >- void (*ScaleRowDown38_2)(const uint8* src_ptr, ptrdiff_t src_stride, >- uint8* dst_ptr, int dst_width); >+ void (*ScaleRowDown38_3)(const uint8_t* src_ptr, ptrdiff_t src_stride, >+ uint8_t* dst_ptr, int dst_width); >+ void (*ScaleRowDown38_2)(const uint8_t* src_ptr, ptrdiff_t src_stride, >+ uint8_t* dst_ptr, int dst_width); > const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; > assert(dst_width % 3 == 0); > (void)src_width; >@@ -612,19 +556,6 @@ static void ScalePlaneDown38(int src_width, > } > } > #endif >-#if defined(HAS_SCALEROWDOWN38_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && (dst_width % 12 == 0) && >- IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && >- IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { >- if (!filtering) { >- ScaleRowDown38_3 = ScaleRowDown38_DSPR2; >- ScaleRowDown38_2 = ScaleRowDown38_DSPR2; >- } else { >- ScaleRowDown38_3 = ScaleRowDown38_3_Box_DSPR2; >- ScaleRowDown38_2 = ScaleRowDown38_2_Box_DSPR2; >- } >- } >-#endif > #if defined(HAS_SCALEROWDOWN38_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > if (!filtering) { >@@ -675,14 +606,14 @@ static void ScalePlaneDown38_16(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint16* src_ptr, >- uint16* dst_ptr, >+ const uint16_t* src_ptr, >+ uint16_t* dst_ptr, > enum FilterMode filtering) { > int y; >- void (*ScaleRowDown38_3)(const uint16* src_ptr, ptrdiff_t src_stride, >- uint16* dst_ptr, int dst_width); >- void (*ScaleRowDown38_2)(const uint16* src_ptr, ptrdiff_t src_stride, >- uint16* dst_ptr, int dst_width); >+ void (*ScaleRowDown38_3)(const uint16_t* src_ptr, ptrdiff_t src_stride, >+ uint16_t* dst_ptr, int dst_width); >+ void (*ScaleRowDown38_2)(const uint16_t* src_ptr, ptrdiff_t src_stride, >+ uint16_t* dst_ptr, int dst_width); > const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; > (void)src_width; > (void)src_height; >@@ -716,19 +647,6 @@ static void ScalePlaneDown38_16(int src_width, > } > } > #endif >-#if defined(HAS_SCALEROWDOWN38_16_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && (dst_width % 12 == 0) && >- IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && >- IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { >- if (!filtering) { >- ScaleRowDown38_3 = ScaleRowDown38_16_DSPR2; >- ScaleRowDown38_2 = ScaleRowDown38_16_DSPR2; >- } else { >- ScaleRowDown38_3 = ScaleRowDown38_3_Box_16_DSPR2; >- ScaleRowDown38_2 = ScaleRowDown38_2_Box_16_DSPR2; >- } >- } >-#endif > > for (y = 0; y < dst_height - 2; y += 3) { > ScaleRowDown38_3(src_ptr, filter_stride, dst_ptr, dst_width); >@@ -755,8 +673,8 @@ static void ScalePlaneDown38_16(int src_width, > > #define MIN1(x) ((x) < 1 ? 1 : (x)) > >-static __inline uint32 SumPixels(int iboxwidth, const uint16* src_ptr) { >- uint32 sum = 0u; >+static __inline uint32_t SumPixels(int iboxwidth, const uint16_t* src_ptr) { >+ uint32_t sum = 0u; > int x; > assert(iboxwidth > 0); > for (x = 0; x < iboxwidth; ++x) { >@@ -765,8 +683,8 @@ static __inline uint32 SumPixels(int iboxwidth, const uint16* src_ptr) { > return sum; > } > >-static __inline uint32 SumPixels_16(int iboxwidth, const uint32* src_ptr) { >- uint32 sum = 0u; >+static __inline uint32_t SumPixels_16(int iboxwidth, const uint32_t* src_ptr) { >+ uint32_t sum = 0u; > int x; > assert(iboxwidth > 0); > for (x = 0; x < iboxwidth; ++x) { >@@ -779,8 +697,8 @@ static void ScaleAddCols2_C(int dst_width, > int boxheight, > int x, > int dx, >- const uint16* src_ptr, >- uint8* dst_ptr) { >+ const uint16_t* src_ptr, >+ uint8_t* dst_ptr) { > int i; > int scaletbl[2]; > int minboxwidth = dx >> 16; >@@ -801,8 +719,8 @@ static void ScaleAddCols2_16_C(int dst_width, > int boxheight, > int x, > int dx, >- const uint32* src_ptr, >- uint16* dst_ptr) { >+ const uint32_t* src_ptr, >+ uint16_t* dst_ptr) { > int i; > int scaletbl[2]; > int minboxwidth = dx >> 16; >@@ -823,8 +741,8 @@ static void ScaleAddCols0_C(int dst_width, > int boxheight, > int x, > int dx, >- const uint16* src_ptr, >- uint8* dst_ptr) { >+ const uint16_t* src_ptr, >+ uint8_t* dst_ptr) { > int scaleval = 65536 / boxheight; > int i; > (void)dx; >@@ -838,8 +756,8 @@ static void ScaleAddCols1_C(int dst_width, > int boxheight, > int x, > int dx, >- const uint16* src_ptr, >- uint8* dst_ptr) { >+ const uint16_t* src_ptr, >+ uint8_t* dst_ptr) { > int boxwidth = MIN1(dx >> 16); > int scaleval = 65536 / (boxwidth * boxheight); > int i; >@@ -854,8 +772,8 @@ static void ScaleAddCols1_16_C(int dst_width, > int boxheight, > int x, > int dx, >- const uint32* src_ptr, >- uint16* dst_ptr) { >+ const uint32_t* src_ptr, >+ uint16_t* dst_ptr) { > int boxwidth = MIN1(dx >> 16); > int scaleval = 65536 / (boxwidth * boxheight); > int i; >@@ -878,8 +796,8 @@ static void ScalePlaneBox(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_ptr, >- uint8* dst_ptr) { >+ const uint8_t* src_ptr, >+ uint8_t* dst_ptr) { > int j, k; > // Initial source x/y coordinate and step values as 16.16 fixed point. > int x = 0; >@@ -891,14 +809,14 @@ static void ScalePlaneBox(int src_width, > &dx, &dy); > src_width = Abs(src_width); > { >- // Allocate a row buffer of uint16. >+ // Allocate a row buffer of uint16_t. > align_buffer_64(row16, src_width * 2); > void (*ScaleAddCols)(int dst_width, int boxheight, int x, int dx, >- const uint16* src_ptr, uint8* dst_ptr) = >+ const uint16_t* src_ptr, uint8_t* dst_ptr) = > (dx & 0xffff) ? ScaleAddCols2_C > : ((dx != 0x10000) ? ScaleAddCols1_C : ScaleAddCols0_C); >- void (*ScaleAddRow)(const uint8* src_ptr, uint16* dst_ptr, int src_width) = >- ScaleAddRow_C; >+ void (*ScaleAddRow)(const uint8_t* src_ptr, uint16_t* dst_ptr, >+ int src_width) = ScaleAddRow_C; > #if defined(HAS_SCALEADDROW_SSE2) > if (TestCpuFlag(kCpuHasSSE2)) { > ScaleAddRow = ScaleAddRow_Any_SSE2; >@@ -931,19 +849,11 @@ static void ScalePlaneBox(int src_width, > } > } > #endif >-#if defined(HAS_SCALEADDROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- ScaleAddRow = ScaleAddRow_Any_DSPR2; >- if (IS_ALIGNED(src_width, 16)) { >- ScaleAddRow = ScaleAddRow_DSPR2; >- } >- } >-#endif > > for (j = 0; j < dst_height; ++j) { > int boxheight; > int iy = y >> 16; >- const uint8* src = src_ptr + iy * src_stride; >+ const uint8_t* src = src_ptr + iy * src_stride; > y += dy; > if (y > max_y) { > y = max_y; >@@ -951,10 +861,10 @@ static void ScalePlaneBox(int src_width, > boxheight = MIN1((y >> 16) - iy); > memset(row16, 0, src_width * 2); > for (k = 0; k < boxheight; ++k) { >- ScaleAddRow(src, (uint16*)(row16), src_width); >+ ScaleAddRow(src, (uint16_t*)(row16), src_width); > src += src_stride; > } >- ScaleAddCols(dst_width, boxheight, x, dx, (uint16*)(row16), dst_ptr); >+ ScaleAddCols(dst_width, boxheight, x, dx, (uint16_t*)(row16), dst_ptr); > dst_ptr += dst_stride; > } > free_aligned_buffer_64(row16); >@@ -967,8 +877,8 @@ static void ScalePlaneBox_16(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint16* src_ptr, >- uint16* dst_ptr) { >+ const uint16_t* src_ptr, >+ uint16_t* dst_ptr) { > int j, k; > // Initial source x/y coordinate and step values as 16.16 fixed point. > int x = 0; >@@ -980,13 +890,13 @@ static void ScalePlaneBox_16(int src_width, > &dx, &dy); > src_width = Abs(src_width); > { >- // Allocate a row buffer of uint32. >+ // Allocate a row buffer of uint32_t. > align_buffer_64(row32, src_width * 4); > void (*ScaleAddCols)(int dst_width, int boxheight, int x, int dx, >- const uint32* src_ptr, uint16* dst_ptr) = >+ const uint32_t* src_ptr, uint16_t* dst_ptr) = > (dx & 0xffff) ? ScaleAddCols2_16_C : ScaleAddCols1_16_C; >- void (*ScaleAddRow)(const uint16* src_ptr, uint32* dst_ptr, int src_width) = >- ScaleAddRow_16_C; >+ void (*ScaleAddRow)(const uint16_t* src_ptr, uint32_t* dst_ptr, >+ int src_width) = ScaleAddRow_16_C; > > #if defined(HAS_SCALEADDROW_16_SSE2) > if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(src_width, 16)) { >@@ -997,7 +907,7 @@ static void ScalePlaneBox_16(int src_width, > for (j = 0; j < dst_height; ++j) { > int boxheight; > int iy = y >> 16; >- const uint16* src = src_ptr + iy * src_stride; >+ const uint16_t* src = src_ptr + iy * src_stride; > y += dy; > if (y > max_y) { > y = max_y; >@@ -1005,10 +915,10 @@ static void ScalePlaneBox_16(int src_width, > boxheight = MIN1((y >> 16) - iy); > memset(row32, 0, src_width * 4); > for (k = 0; k < boxheight; ++k) { >- ScaleAddRow(src, (uint32*)(row32), src_width); >+ ScaleAddRow(src, (uint32_t*)(row32), src_width); > src += src_stride; > } >- ScaleAddCols(dst_width, boxheight, x, dx, (uint32*)(row32), dst_ptr); >+ ScaleAddCols(dst_width, boxheight, x, dx, (uint32_t*)(row32), dst_ptr); > dst_ptr += dst_stride; > } > free_aligned_buffer_64(row32); >@@ -1022,8 +932,8 @@ void ScalePlaneBilinearDown(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_ptr, >- uint8* dst_ptr, >+ const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > enum FilterMode filtering) { > // Initial source x/y coordinate and step values as 16.16 fixed point. > int x = 0; >@@ -1036,10 +946,10 @@ void ScalePlaneBilinearDown(int src_width, > > const int max_y = (src_height - 1) << 16; > int j; >- void (*ScaleFilterCols)(uint8 * dst_ptr, const uint8* src_ptr, int dst_width, >- int x, int dx) = >+ void (*ScaleFilterCols)(uint8_t * dst_ptr, const uint8_t* src_ptr, >+ int dst_width, int x, int dx) = > (src_width >= 32768) ? ScaleFilterCols64_C : ScaleFilterCols_C; >- void (*InterpolateRow)(uint8 * dst_ptr, const uint8* src_ptr, >+ void (*InterpolateRow)(uint8_t * dst_ptr, const uint8_t* src_ptr, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_C; > ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y, >@@ -1070,14 +980,6 @@ void ScalePlaneBilinearDown(int src_width, > } > } > #endif >-#if defined(HAS_INTERPOLATEROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- InterpolateRow = InterpolateRow_Any_DSPR2; >- if (IS_ALIGNED(src_width, 4)) { >- InterpolateRow = InterpolateRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_INTERPOLATEROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > InterpolateRow = InterpolateRow_Any_MSA; >@@ -1114,7 +1016,7 @@ void ScalePlaneBilinearDown(int src_width, > > for (j = 0; j < dst_height; ++j) { > int yi = y >> 16; >- const uint8* src = src_ptr + yi * src_stride; >+ const uint8_t* src = src_ptr + yi * src_stride; > if (filtering == kFilterLinear) { > ScaleFilterCols(dst_ptr, src, dst_width, x, dx); > } else { >@@ -1137,8 +1039,8 @@ void ScalePlaneBilinearDown_16(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint16* src_ptr, >- uint16* dst_ptr, >+ const uint16_t* src_ptr, >+ uint16_t* dst_ptr, > enum FilterMode filtering) { > // Initial source x/y coordinate and step values as 16.16 fixed point. > int x = 0; >@@ -1151,10 +1053,10 @@ void ScalePlaneBilinearDown_16(int src_width, > > const int max_y = (src_height - 1) << 16; > int j; >- void (*ScaleFilterCols)(uint16 * dst_ptr, const uint16* src_ptr, >+ void (*ScaleFilterCols)(uint16_t * dst_ptr, const uint16_t* src_ptr, > int dst_width, int x, int dx) = > (src_width >= 32768) ? ScaleFilterCols64_16_C : ScaleFilterCols_16_C; >- void (*InterpolateRow)(uint16 * dst_ptr, const uint16* src_ptr, >+ void (*InterpolateRow)(uint16_t * dst_ptr, const uint16_t* src_ptr, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_16_C; > ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y, >@@ -1193,14 +1095,6 @@ void ScalePlaneBilinearDown_16(int src_width, > } > } > #endif >-#if defined(HAS_INTERPOLATEROW_16_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- InterpolateRow = InterpolateRow_Any_16_DSPR2; >- if (IS_ALIGNED(src_width, 4)) { >- InterpolateRow = InterpolateRow_16_DSPR2; >- } >- } >-#endif > > #if defined(HAS_SCALEFILTERCOLS_16_SSSE3) > if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { >@@ -1213,13 +1107,13 @@ void ScalePlaneBilinearDown_16(int src_width, > > for (j = 0; j < dst_height; ++j) { > int yi = y >> 16; >- const uint16* src = src_ptr + yi * src_stride; >+ const uint16_t* src = src_ptr + yi * src_stride; > if (filtering == kFilterLinear) { > ScaleFilterCols(dst_ptr, src, dst_width, x, dx); > } else { > int yf = (y >> 8) & 255; >- InterpolateRow((uint16*)row, src, src_stride, src_width, yf); >- ScaleFilterCols(dst_ptr, (uint16*)row, dst_width, x, dx); >+ InterpolateRow((uint16_t*)row, src, src_stride, src_width, yf); >+ ScaleFilterCols(dst_ptr, (uint16_t*)row, dst_width, x, dx); > } > dst_ptr += dst_stride; > y += dy; >@@ -1237,8 +1131,8 @@ void ScalePlaneBilinearUp(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_ptr, >- uint8* dst_ptr, >+ const uint8_t* src_ptr, >+ uint8_t* dst_ptr, > enum FilterMode filtering) { > int j; > // Initial source x/y coordinate and step values as 16.16 fixed point. >@@ -1247,11 +1141,11 @@ void ScalePlaneBilinearUp(int src_width, > int dx = 0; > int dy = 0; > const int max_y = (src_height - 1) << 16; >- void (*InterpolateRow)(uint8 * dst_ptr, const uint8* src_ptr, >+ void (*InterpolateRow)(uint8_t * dst_ptr, const uint8_t* src_ptr, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_C; >- void (*ScaleFilterCols)(uint8 * dst_ptr, const uint8* src_ptr, int dst_width, >- int x, int dx) = >+ void (*ScaleFilterCols)(uint8_t * dst_ptr, const uint8_t* src_ptr, >+ int dst_width, int x, int dx) = > filtering ? ScaleFilterCols_C : ScaleCols_C; > ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y, > &dx, &dy); >@@ -1281,14 +1175,6 @@ void ScalePlaneBilinearUp(int src_width, > } > } > #endif >-#if defined(HAS_INTERPOLATEROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- InterpolateRow = InterpolateRow_Any_DSPR2; >- if (IS_ALIGNED(dst_width, 4)) { >- InterpolateRow = InterpolateRow_DSPR2; >- } >- } >-#endif > > if (filtering && src_width >= 32768) { > ScaleFilterCols = ScaleFilterCols64_C; >@@ -1328,13 +1214,13 @@ void ScalePlaneBilinearUp(int src_width, > } > { > int yi = y >> 16; >- const uint8* src = src_ptr + yi * src_stride; >+ const uint8_t* src = src_ptr + yi * src_stride; > > // Allocate 2 row buffers. > const int kRowSize = (dst_width + 31) & ~31; > align_buffer_64(row, kRowSize * 2); > >- uint8* rowptr = row; >+ uint8_t* rowptr = row; > int rowstride = kRowSize; > int lasty = yi; > >@@ -1380,8 +1266,8 @@ void ScalePlaneBilinearUp_16(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint16* src_ptr, >- uint16* dst_ptr, >+ const uint16_t* src_ptr, >+ uint16_t* dst_ptr, > enum FilterMode filtering) { > int j; > // Initial source x/y coordinate and step values as 16.16 fixed point. >@@ -1390,10 +1276,10 @@ void ScalePlaneBilinearUp_16(int src_width, > int dx = 0; > int dy = 0; > const int max_y = (src_height - 1) << 16; >- void (*InterpolateRow)(uint16 * dst_ptr, const uint16* src_ptr, >+ void (*InterpolateRow)(uint16_t * dst_ptr, const uint16_t* src_ptr, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_16_C; >- void (*ScaleFilterCols)(uint16 * dst_ptr, const uint16* src_ptr, >+ void (*ScaleFilterCols)(uint16_t * dst_ptr, const uint16_t* src_ptr, > int dst_width, int x, int dx) = > filtering ? ScaleFilterCols_16_C : ScaleCols_16_C; > ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y, >@@ -1432,14 +1318,6 @@ void ScalePlaneBilinearUp_16(int src_width, > } > } > #endif >-#if defined(HAS_INTERPOLATEROW_16_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2)) { >- InterpolateRow = InterpolateRow_Any_16_DSPR2; >- if (IS_ALIGNED(dst_width, 4)) { >- InterpolateRow = InterpolateRow_16_DSPR2; >- } >- } >-#endif > > if (filtering && src_width >= 32768) { > ScaleFilterCols = ScaleFilterCols64_16_C; >@@ -1463,13 +1341,13 @@ void ScalePlaneBilinearUp_16(int src_width, > } > { > int yi = y >> 16; >- const uint16* src = src_ptr + yi * src_stride; >+ const uint16_t* src = src_ptr + yi * src_stride; > > // Allocate 2 row buffers. > const int kRowSize = (dst_width + 31) & ~31; > align_buffer_64(row, kRowSize * 4); > >- uint16* rowptr = (uint16*)row; >+ uint16_t* rowptr = (uint16_t*)row; > int rowstride = kRowSize; > int lasty = yi; > >@@ -1520,11 +1398,11 @@ static void ScalePlaneSimple(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_ptr, >- uint8* dst_ptr) { >+ const uint8_t* src_ptr, >+ uint8_t* dst_ptr) { > int i; >- void (*ScaleCols)(uint8 * dst_ptr, const uint8* src_ptr, int dst_width, int x, >- int dx) = ScaleCols_C; >+ void (*ScaleCols)(uint8_t * dst_ptr, const uint8_t* src_ptr, int dst_width, >+ int x, int dx) = ScaleCols_C; > // Initial source x/y coordinate and step values as 16.16 fixed point. > int x = 0; > int y = 0; >@@ -1556,10 +1434,10 @@ static void ScalePlaneSimple_16(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint16* src_ptr, >- uint16* dst_ptr) { >+ const uint16_t* src_ptr, >+ uint16_t* dst_ptr) { > int i; >- void (*ScaleCols)(uint16 * dst_ptr, const uint16* src_ptr, int dst_width, >+ void (*ScaleCols)(uint16_t * dst_ptr, const uint16_t* src_ptr, int dst_width, > int x, int dx) = ScaleCols_16_C; > // Initial source x/y coordinate and step values as 16.16 fixed point. > int x = 0; >@@ -1590,11 +1468,11 @@ static void ScalePlaneSimple_16(int src_width, > // This function dispatches to a specialized scaler based on scale factor. > > LIBYUV_API >-void ScalePlane(const uint8* src, >+void ScalePlane(const uint8_t* src, > int src_stride, > int src_width, > int src_height, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int dst_width, > int dst_height, >@@ -1673,11 +1551,11 @@ void ScalePlane(const uint8* src, > } > > LIBYUV_API >-void ScalePlane_16(const uint16* src, >+void ScalePlane_16(const uint16_t* src, > int src_stride, > int src_width, > int src_height, >- uint16* dst, >+ uint16_t* dst, > int dst_stride, > int dst_width, > int dst_height, >@@ -1759,19 +1637,19 @@ void ScalePlane_16(const uint16* src, > // This function in turn calls a scaling function for each plane. > > LIBYUV_API >-int I420Scale(const uint8* src_y, >+int I420Scale(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, > int src_width, > int src_height, >- uint8* dst_y, >+ uint8_t* dst_y, > int dst_stride_y, >- uint8* dst_u, >+ uint8_t* dst_u, > int dst_stride_u, >- uint8* dst_v, >+ uint8_t* dst_v, > int dst_stride_v, > int dst_width, > int dst_height, >@@ -1796,19 +1674,19 @@ int I420Scale(const uint8* src_y, > } > > LIBYUV_API >-int I420Scale_16(const uint16* src_y, >+int I420Scale_16(const uint16_t* src_y, > int src_stride_y, >- const uint16* src_u, >+ const uint16_t* src_u, > int src_stride_u, >- const uint16* src_v, >+ const uint16_t* src_v, > int src_stride_v, > int src_width, > int src_height, >- uint16* dst_y, >+ uint16_t* dst_y, > int dst_stride_y, >- uint16* dst_u, >+ uint16_t* dst_u, > int dst_stride_u, >- uint16* dst_v, >+ uint16_t* dst_v, > int dst_stride_v, > int dst_width, > int dst_height, >@@ -1834,17 +1712,17 @@ int I420Scale_16(const uint16* src_y, > > // Deprecated api > LIBYUV_API >-int Scale(const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >+int Scale(const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, > int src_stride_y, > int src_stride_u, > int src_stride_v, > int src_width, > int src_height, >- uint8* dst_y, >- uint8* dst_u, >- uint8* dst_v, >+ uint8_t* dst_y, >+ uint8_t* dst_u, >+ uint8_t* dst_v, > int dst_stride_y, > int dst_stride_u, > int dst_stride_v, >@@ -1857,43 +1735,6 @@ int Scale(const uint8* src_y, > dst_height, interpolate ? kFilterBox : kFilterNone); > } > >-// Deprecated api >-LIBYUV_API >-int ScaleOffset(const uint8* src, >- int src_width, >- int src_height, >- uint8* dst, >- int dst_width, >- int dst_height, >- int dst_yoffset, >- LIBYUV_BOOL interpolate) { >- // Chroma requires offset to multiple of 2. >- int dst_yoffset_even = dst_yoffset & ~1; >- int src_halfwidth = SUBSAMPLE(src_width, 1, 1); >- int src_halfheight = SUBSAMPLE(src_height, 1, 1); >- int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); >- int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); >- int aheight = dst_height - dst_yoffset_even * 2; // actual output height >- const uint8* src_y = src; >- const uint8* src_u = src + src_width * src_height; >- const uint8* src_v = >- src + src_width * src_height + src_halfwidth * src_halfheight; >- uint8* dst_y = dst + dst_yoffset_even * dst_width; >- uint8* dst_u = >- dst + dst_width * dst_height + (dst_yoffset_even >> 1) * dst_halfwidth; >- uint8* dst_v = dst + dst_width * dst_height + dst_halfwidth * dst_halfheight + >- (dst_yoffset_even >> 1) * dst_halfwidth; >- if (!src || src_width <= 0 || src_height <= 0 || !dst || dst_width <= 0 || >- dst_height <= 0 || dst_yoffset_even < 0 || >- dst_yoffset_even >= dst_height) { >- return -1; >- } >- return I420Scale(src_y, src_width, src_u, src_halfwidth, src_v, src_halfwidth, >- src_width, src_height, dst_y, dst_width, dst_u, >- dst_halfwidth, dst_v, dst_halfwidth, dst_width, aheight, >- interpolate ? kFilterBox : kFilterNone); >-} >- > #ifdef __cplusplus > } // extern "C" > } // namespace libyuv >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_any.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_any.cc >index c4d6626ab729a32124e5259b348082672ea47561..53ad136404995333e572364b70076334c5eb8d69 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_any.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_any.cc >@@ -19,15 +19,15 @@ extern "C" { > #endif > > // Definition for ScaleFilterCols, ScaleARGBCols and ScaleARGBFilterCols >-#define CANY(NAMEANY, TERP_SIMD, TERP_C, BPP, MASK) \ >- void NAMEANY(uint8* dst_ptr, const uint8* src_ptr, int dst_width, int x, \ >- int dx) { \ >- int r = dst_width & MASK; \ >- int n = dst_width & ~MASK; \ >- if (n > 0) { \ >- TERP_SIMD(dst_ptr, src_ptr, n, x, dx); \ >- } \ >- TERP_C(dst_ptr + n * BPP, src_ptr, r, x + n * dx, dx); \ >+#define CANY(NAMEANY, TERP_SIMD, TERP_C, BPP, MASK) \ >+ void NAMEANY(uint8_t* dst_ptr, const uint8_t* src_ptr, int dst_width, int x, \ >+ int dx) { \ >+ int r = dst_width & MASK; \ >+ int n = dst_width & ~MASK; \ >+ if (n > 0) { \ >+ TERP_SIMD(dst_ptr, src_ptr, n, x, dx); \ >+ } \ >+ TERP_C(dst_ptr + n * BPP, src_ptr, r, x + n * dx, dx); \ > } > > #ifdef HAS_SCALEFILTERCOLS_NEON >@@ -60,31 +60,31 @@ CANY(ScaleARGBFilterCols_Any_MSA, > > // Fixed scale down. > // Mask may be non-power of 2, so use MOD >-#define SDANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK) \ >- void NAMEANY(const uint8* src_ptr, ptrdiff_t src_stride, uint8* dst_ptr, \ >- int dst_width) { \ >- int r = (int)((unsigned int)dst_width % (MASK + 1)); /* NOLINT */ \ >- int n = dst_width - r; \ >- if (n > 0) { \ >- SCALEROWDOWN_SIMD(src_ptr, src_stride, dst_ptr, n); \ >- } \ >- SCALEROWDOWN_C(src_ptr + (n * FACTOR) * BPP, src_stride, \ >- dst_ptr + n * BPP, r); \ >+#define SDANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK) \ >+ void NAMEANY(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst_ptr, \ >+ int dst_width) { \ >+ int r = (int)((unsigned int)dst_width % (MASK + 1)); /* NOLINT */ \ >+ int n = dst_width - r; \ >+ if (n > 0) { \ >+ SCALEROWDOWN_SIMD(src_ptr, src_stride, dst_ptr, n); \ >+ } \ >+ SCALEROWDOWN_C(src_ptr + (n * FACTOR) * BPP, src_stride, \ >+ dst_ptr + n * BPP, r); \ > } > > // Fixed scale down for odd source width. Used by I420Blend subsampling. > // Since dst_width is (width + 1) / 2, this function scales one less pixel > // and copies the last pixel. >-#define SDODD(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK) \ >- void NAMEANY(const uint8* src_ptr, ptrdiff_t src_stride, uint8* dst_ptr, \ >- int dst_width) { \ >- int r = (int)((unsigned int)(dst_width - 1) % (MASK + 1)); /* NOLINT */ \ >- int n = (dst_width - 1) - r; \ >- if (n > 0) { \ >- SCALEROWDOWN_SIMD(src_ptr, src_stride, dst_ptr, n); \ >- } \ >- SCALEROWDOWN_C(src_ptr + (n * FACTOR) * BPP, src_stride, \ >- dst_ptr + n * BPP, r + 1); \ >+#define SDODD(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK) \ >+ void NAMEANY(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst_ptr, \ >+ int dst_width) { \ >+ int r = (int)((unsigned int)(dst_width - 1) % (MASK + 1)); /* NOLINT */ \ >+ int n = (dst_width - 1) - r; \ >+ if (n > 0) { \ >+ SCALEROWDOWN_SIMD(src_ptr, src_stride, dst_ptr, n); \ >+ } \ >+ SCALEROWDOWN_C(src_ptr + (n * FACTOR) * BPP, src_stride, \ >+ dst_ptr + n * BPP, r + 1); \ > } > > #ifdef HAS_SCALEROWDOWN2_SSSE3 >@@ -385,16 +385,16 @@ SDANY(ScaleARGBRowDown2Box_Any_MSA, > #undef SDANY > > // Scale down by even scale factor. >-#define SDAANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, BPP, MASK) \ >- void NAMEANY(const uint8* src_ptr, ptrdiff_t src_stride, int src_stepx, \ >- uint8* dst_ptr, int dst_width) { \ >- int r = dst_width & MASK; \ >- int n = dst_width & ~MASK; \ >- if (n > 0) { \ >- SCALEROWDOWN_SIMD(src_ptr, src_stride, src_stepx, dst_ptr, n); \ >- } \ >- SCALEROWDOWN_C(src_ptr + (n * src_stepx) * BPP, src_stride, src_stepx, \ >- dst_ptr + n * BPP, r); \ >+#define SDAANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, BPP, MASK) \ >+ void NAMEANY(const uint8_t* src_ptr, ptrdiff_t src_stride, int src_stepx, \ >+ uint8_t* dst_ptr, int dst_width) { \ >+ int r = dst_width & MASK; \ >+ int n = dst_width & ~MASK; \ >+ if (n > 0) { \ >+ SCALEROWDOWN_SIMD(src_ptr, src_stride, src_stepx, dst_ptr, n); \ >+ } \ >+ SCALEROWDOWN_C(src_ptr + (n * src_stepx) * BPP, src_stride, src_stepx, \ >+ dst_ptr + n * BPP, r); \ > } > > #ifdef HAS_SCALEARGBROWDOWNEVEN_SSE2 >@@ -435,13 +435,13 @@ SDAANY(ScaleARGBRowDownEvenBox_Any_MSA, > #endif > > // Add rows box filter scale down. >-#define SAANY(NAMEANY, SCALEADDROW_SIMD, SCALEADDROW_C, MASK) \ >- void NAMEANY(const uint8* src_ptr, uint16* dst_ptr, int src_width) { \ >- int n = src_width & ~MASK; \ >- if (n > 0) { \ >- SCALEADDROW_SIMD(src_ptr, dst_ptr, n); \ >- } \ >- SCALEADDROW_C(src_ptr + n, dst_ptr + n, src_width & MASK); \ >+#define SAANY(NAMEANY, SCALEADDROW_SIMD, SCALEADDROW_C, MASK) \ >+ void NAMEANY(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width) { \ >+ int n = src_width & ~MASK; \ >+ if (n > 0) { \ >+ SCALEADDROW_SIMD(src_ptr, dst_ptr, n); \ >+ } \ >+ SCALEADDROW_C(src_ptr + n, dst_ptr + n, src_width & MASK); \ > } > > #ifdef HAS_SCALEADDROW_SSE2 >@@ -456,9 +456,6 @@ SAANY(ScaleAddRow_Any_NEON, ScaleAddRow_NEON, ScaleAddRow_C, 15) > #ifdef HAS_SCALEADDROW_MSA > SAANY(ScaleAddRow_Any_MSA, ScaleAddRow_MSA, ScaleAddRow_C, 15) > #endif >-#ifdef HAS_SCALEADDROW_DSPR2 >-SAANY(ScaleAddRow_Any_DSPR2, ScaleAddRow_DSPR2, ScaleAddRow_C, 15) >-#endif > #undef SAANY > > #ifdef __cplusplus >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_argb.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_argb.cc >index c3ec7d6bb674e1e4da5a4be8a9242b4eaad3f5f1..53a22e8b41ea1273fc2ae15215dbf91aa409aec6 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_argb.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_argb.cc >@@ -36,8 +36,8 @@ static void ScaleARGBDown2(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_argb, >- uint8* dst_argb, >+ const uint8_t* src_argb, >+ uint8_t* dst_argb, > int x, > int dx, > int y, >@@ -45,8 +45,8 @@ static void ScaleARGBDown2(int src_width, > enum FilterMode filtering) { > int j; > int row_stride = src_stride * (dy >> 16); >- void (*ScaleARGBRowDown2)(const uint8* src_argb, ptrdiff_t src_stride, >- uint8* dst_argb, int dst_width) = >+ void (*ScaleARGBRowDown2)(const uint8_t* src_argb, ptrdiff_t src_stride, >+ uint8_t* dst_argb, int dst_width) = > filtering == kFilterNone > ? ScaleARGBRowDown2_C > : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_C >@@ -131,8 +131,8 @@ static void ScaleARGBDown4Box(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_argb, >- uint8* dst_argb, >+ const uint8_t* src_argb, >+ uint8_t* dst_argb, > int x, > int dx, > int y, >@@ -142,8 +142,8 @@ static void ScaleARGBDown4Box(int src_width, > const int kRowSize = (dst_width * 2 * 4 + 31) & ~31; > align_buffer_64(row, kRowSize * 2); > int row_stride = src_stride * (dy >> 16); >- void (*ScaleARGBRowDown2)(const uint8* src_argb, ptrdiff_t src_stride, >- uint8* dst_argb, int dst_width) = >+ void (*ScaleARGBRowDown2)(const uint8_t* src_argb, ptrdiff_t src_stride, >+ uint8_t* dst_argb, int dst_width) = > ScaleARGBRowDown2Box_C; > // Advance to odd row, even column. > src_argb += (y >> 16) * src_stride + (x >> 16) * 4; >@@ -189,8 +189,8 @@ static void ScaleARGBDownEven(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_argb, >- uint8* dst_argb, >+ const uint8_t* src_argb, >+ uint8_t* dst_argb, > int x, > int dx, > int y, >@@ -199,8 +199,8 @@ static void ScaleARGBDownEven(int src_width, > int j; > int col_step = dx >> 16; > int row_stride = (dy >> 16) * src_stride; >- void (*ScaleARGBRowDownEven)(const uint8* src_argb, ptrdiff_t src_stride, >- int src_step, uint8* dst_argb, int dst_width) = >+ void (*ScaleARGBRowDownEven)(const uint8_t* src_argb, ptrdiff_t src_stride, >+ int src_step, uint8_t* dst_argb, int dst_width) = > filtering ? ScaleARGBRowDownEvenBox_C : ScaleARGBRowDownEven_C; > (void)src_width; > (void)src_height; >@@ -255,23 +255,23 @@ static void ScaleARGBBilinearDown(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_argb, >- uint8* dst_argb, >+ const uint8_t* src_argb, >+ uint8_t* dst_argb, > int x, > int dx, > int y, > int dy, > enum FilterMode filtering) { > int j; >- void (*InterpolateRow)(uint8 * dst_argb, const uint8* src_argb, >+ void (*InterpolateRow)(uint8_t * dst_argb, const uint8_t* src_argb, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_C; >- void (*ScaleARGBFilterCols)(uint8 * dst_argb, const uint8* src_argb, >+ void (*ScaleARGBFilterCols)(uint8_t * dst_argb, const uint8_t* src_argb, > int dst_width, int x, int dx) = > (src_width >= 32768) ? ScaleARGBFilterCols64_C : ScaleARGBFilterCols_C; >- int64 xlast = x + (int64)(dst_width - 1) * dx; >- int64 xl = (dx >= 0) ? x : xlast; >- int64 xr = (dx >= 0) ? xlast : x; >+ int64_t xlast = x + (int64_t)(dst_width - 1) * dx; >+ int64_t xl = (dx >= 0) ? x : xlast; >+ int64_t xr = (dx >= 0) ? xlast : x; > int clip_src_width; > xl = (xl >> 16) & ~3; // Left edge aligned. > xr = (xr >> 16) + 1; // Right most pixel used. Bilinear uses 2 pixels. >@@ -306,15 +306,6 @@ static void ScaleARGBBilinearDown(int src_width, > } > } > #endif >-#if defined(HAS_INTERPOLATEROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src_argb, 4) && >- IS_ALIGNED(src_stride, 4)) { >- InterpolateRow = InterpolateRow_Any_DSPR2; >- if (IS_ALIGNED(clip_src_width, 4)) { >- InterpolateRow = InterpolateRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_INTERPOLATEROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > InterpolateRow = InterpolateRow_Any_MSA; >@@ -355,7 +346,7 @@ static void ScaleARGBBilinearDown(int src_width, > } > for (j = 0; j < dst_height; ++j) { > int yi = y >> 16; >- const uint8* src = src_argb + yi * src_stride; >+ const uint8_t* src = src_argb + yi * src_stride; > if (filtering == kFilterLinear) { > ScaleARGBFilterCols(dst_argb, src, dst_width, x, dx); > } else { >@@ -380,18 +371,18 @@ static void ScaleARGBBilinearUp(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_argb, >- uint8* dst_argb, >+ const uint8_t* src_argb, >+ uint8_t* dst_argb, > int x, > int dx, > int y, > int dy, > enum FilterMode filtering) { > int j; >- void (*InterpolateRow)(uint8 * dst_argb, const uint8* src_argb, >+ void (*InterpolateRow)(uint8_t * dst_argb, const uint8_t* src_argb, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_C; >- void (*ScaleARGBFilterCols)(uint8 * dst_argb, const uint8* src_argb, >+ void (*ScaleARGBFilterCols)(uint8_t * dst_argb, const uint8_t* src_argb, > int dst_width, int x, int dx) = > filtering ? ScaleARGBFilterCols_C : ScaleARGBCols_C; > const int max_y = (src_height - 1) << 16; >@@ -419,12 +410,6 @@ static void ScaleARGBBilinearUp(int src_width, > } > } > #endif >-#if defined(HAS_INTERPOLATEROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(dst_argb, 4) && >- IS_ALIGNED(dst_stride, 4)) { >- InterpolateRow = InterpolateRow_DSPR2; >- } >-#endif > #if defined(HAS_INTERPOLATEROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > InterpolateRow = InterpolateRow_Any_MSA; >@@ -494,13 +479,13 @@ static void ScaleARGBBilinearUp(int src_width, > > { > int yi = y >> 16; >- const uint8* src = src_argb + yi * src_stride; >+ const uint8_t* src = src_argb + yi * src_stride; > > // Allocate 2 rows of ARGB. > const int kRowSize = (dst_width * 4 + 31) & ~31; > align_buffer_64(row, kRowSize * 2); > >- uint8* rowptr = row; >+ uint8_t* rowptr = row; > int rowstride = kRowSize; > int lasty = yi; > >@@ -550,18 +535,18 @@ static void ScaleYUVToARGBBilinearUp(int src_width, > int src_stride_u, > int src_stride_v, > int dst_stride_argb, >- const uint8* src_y, >- const uint8* src_u, >- const uint8* src_v, >- uint8* dst_argb, >+ const uint8_t* src_y, >+ const uint8_t* src_u, >+ const uint8_t* src_v, >+ uint8_t* dst_argb, > int x, > int dx, > int y, > int dy, > enum FilterMode filtering) { > int j; >- void (*I422ToARGBRow)(const uint8* y_buf, const uint8* u_buf, >- const uint8* v_buf, uint8* rgb_buf, int width) = >+ void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, >+ const uint8_t* v_buf, uint8_t* rgb_buf, int width) = > I422ToARGBRow_C; > #if defined(HAS_I422TOARGBROW_SSSE3) > if (TestCpuFlag(kCpuHasSSSE3)) { >@@ -587,15 +572,6 @@ static void ScaleYUVToARGBBilinearUp(int src_width, > } > } > #endif >-#if defined(HAS_I422TOARGBROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src_width, 4) && >- IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && >- IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && >- IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) && >- IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) { >- I422ToARGBRow = I422ToARGBRow_DSPR2; >- } >-#endif > #if defined(HAS_I422TOARGBROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > I422ToARGBRow = I422ToARGBRow_Any_MSA; >@@ -605,7 +581,7 @@ static void ScaleYUVToARGBBilinearUp(int src_width, > } > #endif > >- void (*InterpolateRow)(uint8 * dst_argb, const uint8* src_argb, >+ void (*InterpolateRow)(uint8_t * dst_argb, const uint8_t* src_argb, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_C; > #if defined(HAS_INTERPOLATEROW_SSSE3) >@@ -632,12 +608,6 @@ static void ScaleYUVToARGBBilinearUp(int src_width, > } > } > #endif >-#if defined(HAS_INTERPOLATEROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(dst_argb, 4) && >- IS_ALIGNED(dst_stride_argb, 4)) { >- InterpolateRow = InterpolateRow_DSPR2; >- } >-#endif > #if defined(HAS_INTERPOLATEROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > InterpolateRow = InterpolateRow_Any_MSA; >@@ -647,7 +617,7 @@ static void ScaleYUVToARGBBilinearUp(int src_width, > } > #endif > >- void (*ScaleARGBFilterCols)(uint8 * dst_argb, const uint8* src_argb, >+ void (*ScaleARGBFilterCols)(uint8_t * dst_argb, const uint8_t* src_argb, > int dst_width, int x, int dx) = > filtering ? ScaleARGBFilterCols_C : ScaleARGBCols_C; > if (src_width >= 32768) { >@@ -712,9 +682,9 @@ static void ScaleYUVToARGBBilinearUp(int src_width, > const int kYShift = 1; // Shift Y by 1 to convert Y plane to UV coordinate. > int yi = y >> 16; > int uv_yi = yi >> kYShift; >- const uint8* src_row_y = src_y + yi * src_stride_y; >- const uint8* src_row_u = src_u + uv_yi * src_stride_u; >- const uint8* src_row_v = src_v + uv_yi * src_stride_v; >+ const uint8_t* src_row_y = src_y + yi * src_stride_y; >+ const uint8_t* src_row_u = src_u + uv_yi * src_stride_u; >+ const uint8_t* src_row_v = src_v + uv_yi * src_stride_v; > > // Allocate 2 rows of ARGB. > const int kRowSize = (dst_width * 4 + 31) & ~31; >@@ -723,7 +693,7 @@ static void ScaleYUVToARGBBilinearUp(int src_width, > // Allocate 1 row of ARGB for source conversion. > align_buffer_64(argb_row, src_width * 4); > >- uint8* rowptr = row; >+ uint8_t* rowptr = row; > int rowstride = kRowSize; > int lasty = yi; > >@@ -795,15 +765,15 @@ static void ScaleARGBSimple(int src_width, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_argb, >- uint8* dst_argb, >+ const uint8_t* src_argb, >+ uint8_t* dst_argb, > int x, > int dx, > int y, > int dy) { > int j; >- void (*ScaleARGBCols)(uint8 * dst_argb, const uint8* src_argb, int dst_width, >- int x, int dx) = >+ void (*ScaleARGBCols)(uint8_t * dst_argb, const uint8_t* src_argb, >+ int dst_width, int x, int dx) = > (src_width >= 32768) ? ScaleARGBCols64_C : ScaleARGBCols_C; > (void)src_height; > #if defined(HAS_SCALEARGBCOLS_SSE2) >@@ -847,11 +817,11 @@ static void ScaleARGBSimple(int src_width, > // ScaleARGB a ARGB. > // This function in turn calls a scaling function > // suitable for handling the desired resolutions. >-static void ScaleARGB(const uint8* src, >+static void ScaleARGB(const uint8_t* src, > int src_stride, > int src_width, > int src_height, >- uint8* dst, >+ uint8_t* dst, > int dst_stride, > int dst_width, > int dst_height, >@@ -880,13 +850,13 @@ static void ScaleARGB(const uint8* src, > &dx, &dy); > src_width = Abs(src_width); > if (clip_x) { >- int64 clipf = (int64)(clip_x)*dx; >+ int64_t clipf = (int64_t)(clip_x)*dx; > x += (clipf & 0xffff); > src += (clipf >> 16) * 4; > dst += clip_x * 4; > } > if (clip_y) { >- int64 clipf = (int64)(clip_y)*dy; >+ int64_t clipf = (int64_t)(clip_y)*dy; > y += (clipf & 0xffff); > src += (clipf >> 16) * src_stride; > dst += clip_y * dst_stride; >@@ -952,11 +922,11 @@ static void ScaleARGB(const uint8* src, > } > > LIBYUV_API >-int ARGBScaleClip(const uint8* src_argb, >+int ARGBScaleClip(const uint8_t* src_argb, > int src_stride_argb, > int src_width, > int src_height, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int dst_width, > int dst_height, >@@ -980,11 +950,11 @@ int ARGBScaleClip(const uint8* src_argb, > > // Scale an ARGB image. > LIBYUV_API >-int ARGBScale(const uint8* src_argb, >+int ARGBScale(const uint8_t* src_argb, > int src_stride_argb, > int src_width, > int src_height, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int dst_width, > int dst_height, >@@ -1001,18 +971,18 @@ int ARGBScale(const uint8* src_argb, > > // Scale with YUV conversion to ARGB and clipping. > LIBYUV_API >-int YUVToARGBScaleClip(const uint8* src_y, >+int YUVToARGBScaleClip(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint32 src_fourcc, >+ uint32_t src_fourcc, > int src_width, > int src_height, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- uint32 dst_fourcc, >+ uint32_t dst_fourcc, > int dst_width, > int dst_height, > int clip_x, >@@ -1020,7 +990,7 @@ int YUVToARGBScaleClip(const uint8* src_y, > int clip_width, > int clip_height, > enum FilterMode filtering) { >- uint8* argb_buffer = (uint8*)malloc(src_width * src_height * 4); >+ uint8_t* argb_buffer = (uint8_t*)malloc(src_width * src_height * 4); > int r; > (void)src_fourcc; // TODO(fbarchard): implement and/or assert. > (void)dst_fourcc; >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_common.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_common.cc >index fefb027bf7672cd2e8459d542b10c717819bf9c1..b28d7da41fce9b6230aa3ccf6c110bdebe072e10 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_common.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_common.cc >@@ -28,9 +28,9 @@ static __inline int Abs(int v) { > } > > // CPU agnostic row functions >-void ScaleRowDown2_C(const uint8* src_ptr, >+void ScaleRowDown2_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > int x; > (void)src_stride; >@@ -45,9 +45,9 @@ void ScaleRowDown2_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown2_16_C(const uint16* src_ptr, >+void ScaleRowDown2_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width) { > int x; > (void)src_stride; >@@ -62,11 +62,11 @@ void ScaleRowDown2_16_C(const uint16* src_ptr, > } > } > >-void ScaleRowDown2Linear_C(const uint8* src_ptr, >+void ScaleRowDown2Linear_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { >- const uint8* s = src_ptr; >+ const uint8_t* s = src_ptr; > int x; > (void)src_stride; > for (x = 0; x < dst_width - 1; x += 2) { >@@ -80,11 +80,11 @@ void ScaleRowDown2Linear_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown2Linear_16_C(const uint16* src_ptr, >+void ScaleRowDown2Linear_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width) { >- const uint16* s = src_ptr; >+ const uint16_t* s = src_ptr; > int x; > (void)src_stride; > for (x = 0; x < dst_width - 1; x += 2) { >@@ -98,12 +98,12 @@ void ScaleRowDown2Linear_16_C(const uint16* src_ptr, > } > } > >-void ScaleRowDown2Box_C(const uint8* src_ptr, >+void ScaleRowDown2Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { >- const uint8* s = src_ptr; >- const uint8* t = src_ptr + src_stride; >+ const uint8_t* s = src_ptr; >+ const uint8_t* t = src_ptr + src_stride; > int x; > for (x = 0; x < dst_width - 1; x += 2) { > dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; >@@ -117,12 +117,12 @@ void ScaleRowDown2Box_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown2Box_Odd_C(const uint8* src_ptr, >+void ScaleRowDown2Box_Odd_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { >- const uint8* s = src_ptr; >- const uint8* t = src_ptr + src_stride; >+ const uint8_t* s = src_ptr; >+ const uint8_t* t = src_ptr + src_stride; > int x; > dst_width -= 1; > for (x = 0; x < dst_width - 1; x += 2) { >@@ -141,12 +141,12 @@ void ScaleRowDown2Box_Odd_C(const uint8* src_ptr, > dst[0] = (s[0] + t[0] + 1) >> 1; > } > >-void ScaleRowDown2Box_16_C(const uint16* src_ptr, >+void ScaleRowDown2Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width) { >- const uint16* s = src_ptr; >- const uint16* t = src_ptr + src_stride; >+ const uint16_t* s = src_ptr; >+ const uint16_t* t = src_ptr + src_stride; > int x; > for (x = 0; x < dst_width - 1; x += 2) { > dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; >@@ -160,9 +160,9 @@ void ScaleRowDown2Box_16_C(const uint16* src_ptr, > } > } > >-void ScaleRowDown4_C(const uint8* src_ptr, >+void ScaleRowDown4_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > int x; > (void)src_stride; >@@ -177,9 +177,9 @@ void ScaleRowDown4_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown4_16_C(const uint16* src_ptr, >+void ScaleRowDown4_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width) { > int x; > (void)src_stride; >@@ -194,9 +194,9 @@ void ScaleRowDown4_16_C(const uint16* src_ptr, > } > } > >-void ScaleRowDown4Box_C(const uint8* src_ptr, >+void ScaleRowDown4Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > intptr_t stride = src_stride; > int x; >@@ -232,9 +232,9 @@ void ScaleRowDown4Box_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown4Box_16_C(const uint16* src_ptr, >+void ScaleRowDown4Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width) { > intptr_t stride = src_stride; > int x; >@@ -270,9 +270,9 @@ void ScaleRowDown4Box_16_C(const uint16* src_ptr, > } > } > >-void ScaleRowDown34_C(const uint8* src_ptr, >+void ScaleRowDown34_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > int x; > (void)src_stride; >@@ -286,9 +286,9 @@ void ScaleRowDown34_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown34_16_C(const uint16* src_ptr, >+void ScaleRowDown34_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width) { > int x; > (void)src_stride; >@@ -303,21 +303,21 @@ void ScaleRowDown34_16_C(const uint16* src_ptr, > } > > // Filter rows 0 and 1 together, 3 : 1 >-void ScaleRowDown34_0_Box_C(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* d, >+ uint8_t* d, > int dst_width) { >- const uint8* s = src_ptr; >- const uint8* t = src_ptr + src_stride; >+ const uint8_t* s = src_ptr; >+ const uint8_t* t = src_ptr + src_stride; > int x; > assert((dst_width % 3 == 0) && (dst_width > 0)); > for (x = 0; x < dst_width; x += 3) { >- uint8 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; >- uint8 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; >- uint8 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; >- uint8 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; >- uint8 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; >- uint8 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; >+ uint8_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; >+ uint8_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; >+ uint8_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; >+ uint8_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; >+ uint8_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; >+ uint8_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; > d[0] = (a0 * 3 + b0 + 2) >> 2; > d[1] = (a1 * 3 + b1 + 2) >> 2; > d[2] = (a2 * 3 + b2 + 2) >> 2; >@@ -327,21 +327,21 @@ void ScaleRowDown34_0_Box_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown34_0_Box_16_C(const uint16* src_ptr, >+void ScaleRowDown34_0_Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* d, >+ uint16_t* d, > int dst_width) { >- const uint16* s = src_ptr; >- const uint16* t = src_ptr + src_stride; >+ const uint16_t* s = src_ptr; >+ const uint16_t* t = src_ptr + src_stride; > int x; > assert((dst_width % 3 == 0) && (dst_width > 0)); > for (x = 0; x < dst_width; x += 3) { >- uint16 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; >- uint16 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; >- uint16 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; >- uint16 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; >- uint16 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; >- uint16 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; >+ uint16_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; >+ uint16_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; >+ uint16_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; >+ uint16_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; >+ uint16_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; >+ uint16_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; > d[0] = (a0 * 3 + b0 + 2) >> 2; > d[1] = (a1 * 3 + b1 + 2) >> 2; > d[2] = (a2 * 3 + b2 + 2) >> 2; >@@ -352,21 +352,21 @@ void ScaleRowDown34_0_Box_16_C(const uint16* src_ptr, > } > > // Filter rows 1 and 2 together, 1 : 1 >-void ScaleRowDown34_1_Box_C(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* d, >+ uint8_t* d, > int dst_width) { >- const uint8* s = src_ptr; >- const uint8* t = src_ptr + src_stride; >+ const uint8_t* s = src_ptr; >+ const uint8_t* t = src_ptr + src_stride; > int x; > assert((dst_width % 3 == 0) && (dst_width > 0)); > for (x = 0; x < dst_width; x += 3) { >- uint8 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; >- uint8 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; >- uint8 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; >- uint8 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; >- uint8 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; >- uint8 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; >+ uint8_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; >+ uint8_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; >+ uint8_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; >+ uint8_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; >+ uint8_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; >+ uint8_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; > d[0] = (a0 + b0 + 1) >> 1; > d[1] = (a1 + b1 + 1) >> 1; > d[2] = (a2 + b2 + 1) >> 1; >@@ -376,21 +376,21 @@ void ScaleRowDown34_1_Box_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown34_1_Box_16_C(const uint16* src_ptr, >+void ScaleRowDown34_1_Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* d, >+ uint16_t* d, > int dst_width) { >- const uint16* s = src_ptr; >- const uint16* t = src_ptr + src_stride; >+ const uint16_t* s = src_ptr; >+ const uint16_t* t = src_ptr + src_stride; > int x; > assert((dst_width % 3 == 0) && (dst_width > 0)); > for (x = 0; x < dst_width; x += 3) { >- uint16 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; >- uint16 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; >- uint16 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; >- uint16 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; >- uint16 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; >- uint16 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; >+ uint16_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; >+ uint16_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; >+ uint16_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; >+ uint16_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; >+ uint16_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; >+ uint16_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; > d[0] = (a0 + b0 + 1) >> 1; > d[1] = (a1 + b1 + 1) >> 1; > d[2] = (a2 + b2 + 1) >> 1; >@@ -401,8 +401,8 @@ void ScaleRowDown34_1_Box_16_C(const uint16* src_ptr, > } > > // Scales a single row of pixels using point sampling. >-void ScaleCols_C(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleCols_C(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx) { >@@ -419,8 +419,8 @@ void ScaleCols_C(uint8* dst_ptr, > } > } > >-void ScaleCols_16_C(uint16* dst_ptr, >- const uint16* src_ptr, >+void ScaleCols_16_C(uint16_t* dst_ptr, >+ const uint16_t* src_ptr, > int dst_width, > int x, > int dx) { >@@ -438,8 +438,8 @@ void ScaleCols_16_C(uint16* dst_ptr, > } > > // Scales a single row of pixels up by 2x using point sampling. >-void ScaleColsUp2_C(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleColsUp2_C(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx) { >@@ -456,8 +456,8 @@ void ScaleColsUp2_C(uint8* dst_ptr, > } > } > >-void ScaleColsUp2_16_C(uint16* dst_ptr, >- const uint16* src_ptr, >+void ScaleColsUp2_16_C(uint16_t* dst_ptr, >+ const uint16_t* src_ptr, > int dst_width, > int x, > int dx) { >@@ -477,15 +477,15 @@ void ScaleColsUp2_16_C(uint16* dst_ptr, > // (1-f)a + fb can be replaced with a + f(b-a) > #if defined(__arm__) || defined(__aarch64__) > #define BLENDER(a, b, f) \ >- (uint8)((int)(a) + ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) >+ (uint8_t)((int)(a) + ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) > #else > // Intel uses 7 bit math with rounding. > #define BLENDER(a, b, f) \ >- (uint8)((int)(a) + (((int)((f) >> 9) * ((int)(b) - (int)(a)) + 0x40) >> 7)) >+ (uint8_t)((int)(a) + (((int)((f) >> 9) * ((int)(b) - (int)(a)) + 0x40) >> 7)) > #endif > >-void ScaleFilterCols_C(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols_C(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx) { >@@ -511,15 +511,15 @@ void ScaleFilterCols_C(uint8* dst_ptr, > } > } > >-void ScaleFilterCols64_C(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols64_C(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x32, > int dx) { >- int64 x = (int64)(x32); >+ int64_t x = (int64_t)(x32); > int j; > for (j = 0; j < dst_width - 1; j += 2) { >- int64 xi = x >> 16; >+ int64_t xi = x >> 16; > int a = src_ptr[xi]; > int b = src_ptr[xi + 1]; > dst_ptr[0] = BLENDER(a, b, x & 0xffff); >@@ -532,7 +532,7 @@ void ScaleFilterCols64_C(uint8* dst_ptr, > dst_ptr += 2; > } > if (dst_width & 1) { >- int64 xi = x >> 16; >+ int64_t xi = x >> 16; > int a = src_ptr[xi]; > int b = src_ptr[xi + 1]; > dst_ptr[0] = BLENDER(a, b, x & 0xffff); >@@ -540,12 +540,12 @@ void ScaleFilterCols64_C(uint8* dst_ptr, > } > #undef BLENDER > >-// Same as 8 bit arm blender but return is cast to uint16 >+// Same as 8 bit arm blender but return is cast to uint16_t > #define BLENDER(a, b, f) \ >- (uint16)((int)(a) + ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) >+ (uint16_t)((int)(a) + ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) > >-void ScaleFilterCols_16_C(uint16* dst_ptr, >- const uint16* src_ptr, >+void ScaleFilterCols_16_C(uint16_t* dst_ptr, >+ const uint16_t* src_ptr, > int dst_width, > int x, > int dx) { >@@ -571,15 +571,15 @@ void ScaleFilterCols_16_C(uint16* dst_ptr, > } > } > >-void ScaleFilterCols64_16_C(uint16* dst_ptr, >- const uint16* src_ptr, >+void ScaleFilterCols64_16_C(uint16_t* dst_ptr, >+ const uint16_t* src_ptr, > int dst_width, > int x32, > int dx) { >- int64 x = (int64)(x32); >+ int64_t x = (int64_t)(x32); > int j; > for (j = 0; j < dst_width - 1; j += 2) { >- int64 xi = x >> 16; >+ int64_t xi = x >> 16; > int a = src_ptr[xi]; > int b = src_ptr[xi + 1]; > dst_ptr[0] = BLENDER(a, b, x & 0xffff); >@@ -592,7 +592,7 @@ void ScaleFilterCols64_16_C(uint16* dst_ptr, > dst_ptr += 2; > } > if (dst_width & 1) { >- int64 xi = x >> 16; >+ int64_t xi = x >> 16; > int a = src_ptr[xi]; > int b = src_ptr[xi + 1]; > dst_ptr[0] = BLENDER(a, b, x & 0xffff); >@@ -600,9 +600,9 @@ void ScaleFilterCols64_16_C(uint16* dst_ptr, > } > #undef BLENDER > >-void ScaleRowDown38_C(const uint8* src_ptr, >+void ScaleRowDown38_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > int x; > (void)src_stride; >@@ -616,9 +616,9 @@ void ScaleRowDown38_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown38_16_C(const uint16* src_ptr, >+void ScaleRowDown38_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width) { > int x; > (void)src_stride; >@@ -633,9 +633,9 @@ void ScaleRowDown38_16_C(const uint16* src_ptr, > } > > // 8x3 -> 3x1 >-void ScaleRowDown38_3_Box_C(const uint8* src_ptr, >+void ScaleRowDown38_3_Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > intptr_t stride = src_stride; > int i; >@@ -663,9 +663,9 @@ void ScaleRowDown38_3_Box_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown38_3_Box_16_C(const uint16* src_ptr, >+void ScaleRowDown38_3_Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst_ptr, >+ uint16_t* dst_ptr, > int dst_width) { > intptr_t stride = src_stride; > int i; >@@ -694,9 +694,9 @@ void ScaleRowDown38_3_Box_16_C(const uint16* src_ptr, > } > > // 8x2 -> 3x1 >-void ScaleRowDown38_2_Box_C(const uint8* src_ptr, >+void ScaleRowDown38_2_Box_C(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > intptr_t stride = src_stride; > int i; >@@ -719,9 +719,9 @@ void ScaleRowDown38_2_Box_C(const uint8* src_ptr, > } > } > >-void ScaleRowDown38_2_Box_16_C(const uint16* src_ptr, >+void ScaleRowDown38_2_Box_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst_ptr, >+ uint16_t* dst_ptr, > int dst_width) { > intptr_t stride = src_stride; > int i; >@@ -744,7 +744,7 @@ void ScaleRowDown38_2_Box_16_C(const uint16* src_ptr, > } > } > >-void ScaleAddRow_C(const uint8* src_ptr, uint16* dst_ptr, int src_width) { >+void ScaleAddRow_C(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width) { > int x; > assert(src_width > 0); > for (x = 0; x < src_width - 1; x += 2) { >@@ -758,7 +758,9 @@ void ScaleAddRow_C(const uint8* src_ptr, uint16* dst_ptr, int src_width) { > } > } > >-void ScaleAddRow_16_C(const uint16* src_ptr, uint32* dst_ptr, int src_width) { >+void ScaleAddRow_16_C(const uint16_t* src_ptr, >+ uint32_t* dst_ptr, >+ int src_width) { > int x; > assert(src_width > 0); > for (x = 0; x < src_width - 1; x += 2) { >@@ -772,12 +774,12 @@ void ScaleAddRow_16_C(const uint16* src_ptr, uint32* dst_ptr, int src_width) { > } > } > >-void ScaleARGBRowDown2_C(const uint8* src_argb, >+void ScaleARGBRowDown2_C(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { >- const uint32* src = (const uint32*)(src_argb); >- uint32* dst = (uint32*)(dst_argb); >+ const uint32_t* src = (const uint32_t*)(src_argb); >+ uint32_t* dst = (uint32_t*)(dst_argb); > int x; > (void)src_stride; > for (x = 0; x < dst_width - 1; x += 2) { >@@ -791,9 +793,9 @@ void ScaleARGBRowDown2_C(const uint8* src_argb, > } > } > >-void ScaleARGBRowDown2Linear_C(const uint8* src_argb, >+void ScaleARGBRowDown2Linear_C(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > int x; > (void)src_stride; >@@ -807,9 +809,9 @@ void ScaleARGBRowDown2Linear_C(const uint8* src_argb, > } > } > >-void ScaleARGBRowDown2Box_C(const uint8* src_argb, >+void ScaleARGBRowDown2Box_C(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > int x; > for (x = 0; x < dst_width; ++x) { >@@ -830,13 +832,13 @@ void ScaleARGBRowDown2Box_C(const uint8* src_argb, > } > } > >-void ScaleARGBRowDownEven_C(const uint8* src_argb, >+void ScaleARGBRowDownEven_C(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { >- const uint32* src = (const uint32*)(src_argb); >- uint32* dst = (uint32*)(dst_argb); >+ const uint32_t* src = (const uint32_t*)(src_argb); >+ uint32_t* dst = (uint32_t*)(dst_argb); > (void)src_stride; > int x; > for (x = 0; x < dst_width - 1; x += 2) { >@@ -850,10 +852,10 @@ void ScaleARGBRowDownEven_C(const uint8* src_argb, > } > } > >-void ScaleARGBRowDownEvenBox_C(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_C(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > int x; > for (x = 0; x < dst_width; ++x) { >@@ -875,13 +877,13 @@ void ScaleARGBRowDownEvenBox_C(const uint8* src_argb, > } > > // Scales a single row of pixels using point sampling. >-void ScaleARGBCols_C(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_C(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { >- const uint32* src = (const uint32*)(src_argb); >- uint32* dst = (uint32*)(dst_argb); >+ const uint32_t* src = (const uint32_t*)(src_argb); >+ uint32_t* dst = (uint32_t*)(dst_argb); > int j; > for (j = 0; j < dst_width - 1; j += 2) { > dst[0] = src[x >> 16]; >@@ -895,14 +897,14 @@ void ScaleARGBCols_C(uint8* dst_argb, > } > } > >-void ScaleARGBCols64_C(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols64_C(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x32, > int dx) { >- int64 x = (int64)(x32); >- const uint32* src = (const uint32*)(src_argb); >- uint32* dst = (uint32*)(dst_argb); >+ int64_t x = (int64_t)(x32); >+ const uint32_t* src = (const uint32_t*)(src_argb); >+ uint32_t* dst = (uint32_t*)(dst_argb); > int j; > for (j = 0; j < dst_width - 1; j += 2) { > dst[0] = src[x >> 16]; >@@ -917,13 +919,13 @@ void ScaleARGBCols64_C(uint8* dst_argb, > } > > // Scales a single row of pixels up by 2x using point sampling. >-void ScaleARGBColsUp2_C(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBColsUp2_C(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { >- const uint32* src = (const uint32*)(src_argb); >- uint32* dst = (uint32*)(dst_argb); >+ const uint32_t* src = (const uint32_t*)(src_argb); >+ uint32_t* dst = (uint32_t*)(dst_argb); > int j; > (void)x; > (void)dx; >@@ -941,24 +943,24 @@ void ScaleARGBColsUp2_C(uint8* dst_argb, > // Mimics SSSE3 blender > #define BLENDER1(a, b, f) ((a) * (0x7f ^ f) + (b)*f) >> 7 > #define BLENDERC(a, b, f, s) \ >- (uint32)(BLENDER1(((a) >> s) & 255, ((b) >> s) & 255, f) << s) >+ (uint32_t)(BLENDER1(((a) >> s) & 255, ((b) >> s) & 255, f) << s) > #define BLENDER(a, b, f) \ > BLENDERC(a, b, f, 24) | BLENDERC(a, b, f, 16) | BLENDERC(a, b, f, 8) | \ > BLENDERC(a, b, f, 0) > >-void ScaleARGBFilterCols_C(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_C(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { >- const uint32* src = (const uint32*)(src_argb); >- uint32* dst = (uint32*)(dst_argb); >+ const uint32_t* src = (const uint32_t*)(src_argb); >+ uint32_t* dst = (uint32_t*)(dst_argb); > int j; > for (j = 0; j < dst_width - 1; j += 2) { > int xi = x >> 16; > int xf = (x >> 9) & 0x7f; >- uint32 a = src[xi]; >- uint32 b = src[xi + 1]; >+ uint32_t a = src[xi]; >+ uint32_t b = src[xi + 1]; > dst[0] = BLENDER(a, b, xf); > x += dx; > xi = x >> 16; >@@ -972,26 +974,26 @@ void ScaleARGBFilterCols_C(uint8* dst_argb, > if (dst_width & 1) { > int xi = x >> 16; > int xf = (x >> 9) & 0x7f; >- uint32 a = src[xi]; >- uint32 b = src[xi + 1]; >+ uint32_t a = src[xi]; >+ uint32_t b = src[xi + 1]; > dst[0] = BLENDER(a, b, xf); > } > } > >-void ScaleARGBFilterCols64_C(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols64_C(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x32, > int dx) { >- int64 x = (int64)(x32); >- const uint32* src = (const uint32*)(src_argb); >- uint32* dst = (uint32*)(dst_argb); >+ int64_t x = (int64_t)(x32); >+ const uint32_t* src = (const uint32_t*)(src_argb); >+ uint32_t* dst = (uint32_t*)(dst_argb); > int j; > for (j = 0; j < dst_width - 1; j += 2) { >- int64 xi = x >> 16; >+ int64_t xi = x >> 16; > int xf = (x >> 9) & 0x7f; >- uint32 a = src[xi]; >- uint32 b = src[xi + 1]; >+ uint32_t a = src[xi]; >+ uint32_t b = src[xi + 1]; > dst[0] = BLENDER(a, b, xf); > x += dx; > xi = x >> 16; >@@ -1003,10 +1005,10 @@ void ScaleARGBFilterCols64_C(uint8* dst_argb, > dst += 2; > } > if (dst_width & 1) { >- int64 xi = x >> 16; >+ int64_t xi = x >> 16; > int xf = (x >> 9) & 0x7f; >- uint32 a = src[xi]; >- uint32 b = src[xi + 1]; >+ uint32_t a = src[xi]; >+ uint32_t b = src[xi + 1]; > dst[0] = BLENDER(a, b, xf); > } > } >@@ -1020,8 +1022,8 @@ void ScalePlaneVertical(int src_height, > int dst_height, > int src_stride, > int dst_stride, >- const uint8* src_argb, >- uint8* dst_argb, >+ const uint8_t* src_argb, >+ uint8_t* dst_argb, > int x, > int y, > int dy, >@@ -1029,7 +1031,7 @@ void ScalePlaneVertical(int src_height, > enum FilterMode filtering) { > // TODO(fbarchard): Allow higher bpp. > int dst_width_bytes = dst_width * bpp; >- void (*InterpolateRow)(uint8 * dst_argb, const uint8* src_argb, >+ void (*InterpolateRow)(uint8_t * dst_argb, const uint8_t* src_argb, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_C; > const int max_y = (src_height > 1) ? ((src_height - 1) << 16) - 1 : 0; >@@ -1063,16 +1065,6 @@ void ScalePlaneVertical(int src_height, > } > } > #endif >-#if defined(HAS_INTERPOLATEROW_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src_argb, 4) && >- IS_ALIGNED(src_stride, 4) && IS_ALIGNED(dst_argb, 4) && >- IS_ALIGNED(dst_stride, 4)) { >- InterpolateRow = InterpolateRow_Any_DSPR2; >- if (IS_ALIGNED(dst_width_bytes, 4)) { >- InterpolateRow = InterpolateRow_DSPR2; >- } >- } >-#endif > #if defined(HAS_INTERPOLATEROW_MSA) > if (TestCpuFlag(kCpuHasMSA)) { > InterpolateRow = InterpolateRow_Any_MSA; >@@ -1100,8 +1092,8 @@ void ScalePlaneVertical_16(int src_height, > int dst_height, > int src_stride, > int dst_stride, >- const uint16* src_argb, >- uint16* dst_argb, >+ const uint16_t* src_argb, >+ uint16_t* dst_argb, > int x, > int y, > int dy, >@@ -1109,7 +1101,7 @@ void ScalePlaneVertical_16(int src_height, > enum FilterMode filtering) { > // TODO(fbarchard): Allow higher wpp. > int dst_width_words = dst_width * wpp; >- void (*InterpolateRow)(uint16 * dst_argb, const uint16* src_argb, >+ void (*InterpolateRow)(uint16_t * dst_argb, const uint16_t* src_argb, > ptrdiff_t src_stride, int dst_width, > int source_y_fraction) = InterpolateRow_16_C; > const int max_y = (src_height > 1) ? ((src_height - 1) << 16) - 1 : 0; >@@ -1150,16 +1142,6 @@ void ScalePlaneVertical_16(int src_height, > InterpolateRow = InterpolateRow_16_NEON; > } > } >-#endif >-#if defined(HAS_INTERPOLATEROW_16_DSPR2) >- if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(src_argb, 4) && >- IS_ALIGNED(src_stride, 4) && IS_ALIGNED(dst_argb, 4) && >- IS_ALIGNED(dst_stride, 4)) { >- InterpolateRow = InterpolateRow_Any_16_DSPR2; >- if (IS_ALIGNED(dst_width_bytes, 4)) { >- InterpolateRow = InterpolateRow_16_DSPR2; >- } >- } > #endif > for (j = 0; j < dst_height; ++j) { > int yi; >@@ -1222,12 +1204,12 @@ enum FilterMode ScaleFilterReduce(int src_width, > > // Divide num by div and return as 16.16 fixed point result. > int FixedDiv_C(int num, int div) { >- return (int)(((int64)(num) << 16) / div); >+ return (int)(((int64_t)(num) << 16) / div); > } > > // Divide num by div and return as 16.16 fixed point result. > int FixedDiv1_C(int num, int div) { >- return (int)((((int64)(num) << 16) - 0x00010001) / (div - 1)); >+ return (int)((((int64_t)(num) << 16) - 0x00010001) / (div - 1)); > } > > #define CENTERSTART(dx, s) (dx < 0) ? -((-dx >> 1) + s) : ((dx >> 1) + s) >@@ -1308,18 +1290,18 @@ void ScaleSlope(int src_width, > > // Read 8x2 upsample with filtering and write 16x1. > // actually reads an extra pixel, so 9x2. >-void ScaleRowUp2_16_C(const uint16* src_ptr, >+void ScaleRowUp2_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width) { >- const uint16* src2 = src_ptr + src_stride; >+ const uint16_t* src2 = src_ptr + src_stride; > > int x; > for (x = 0; x < dst_width - 1; x += 2) { >- uint16 p0 = src_ptr[0]; >- uint16 p1 = src_ptr[1]; >- uint16 p2 = src2[0]; >- uint16 p3 = src2[1]; >+ uint16_t p0 = src_ptr[0]; >+ uint16_t p1 = src_ptr[1]; >+ uint16_t p2 = src2[0]; >+ uint16_t p3 = src2[1]; > dst[0] = (p0 * 9 + p1 * 3 + p2 * 3 + p3 + 8) >> 4; > dst[1] = (p0 * 3 + p1 * 9 + p2 + p3 * 3 + 8) >> 4; > ++src_ptr; >@@ -1327,10 +1309,10 @@ void ScaleRowUp2_16_C(const uint16* src_ptr, > dst += 2; > } > if (dst_width & 1) { >- uint16 p0 = src_ptr[0]; >- uint16 p1 = src_ptr[1]; >- uint16 p2 = src2[0]; >- uint16 p3 = src2[1]; >+ uint16_t p0 = src_ptr[0]; >+ uint16_t p1 = src_ptr[1]; >+ uint16_t p2 = src2[0]; >+ uint16_t p3 = src2[1]; > dst[0] = (p0 * 9 + p1 * 3 + p2 * 3 + p3 + 8) >> 4; > } > } >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_gcc.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_gcc.cc >index f0ac56fcb06f3ca13d24762dbfc3e54074d54ea3..312236d2df8eff9e9d68f3ae0ea3aad5c43a131d 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_gcc.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_gcc.cc >@@ -21,462 +21,458 @@ extern "C" { > (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) > > // Offsets for source bytes 0 to 9 >-static uvec8 kShuf0 = {0, 1, 3, 4, 5, 7, 8, 9, >- 128, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShuf0 = {0, 1, 3, 4, 5, 7, 8, 9, >+ 128, 128, 128, 128, 128, 128, 128, 128}; > > // Offsets for source bytes 11 to 20 with 8 subtracted = 3 to 12. >-static uvec8 kShuf1 = {3, 4, 5, 7, 8, 9, 11, 12, >- 128, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShuf1 = {3, 4, 5, 7, 8, 9, 11, 12, >+ 128, 128, 128, 128, 128, 128, 128, 128}; > > // Offsets for source bytes 21 to 31 with 16 subtracted = 5 to 31. >-static uvec8 kShuf2 = {5, 7, 8, 9, 11, 12, 13, 15, >- 128, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShuf2 = {5, 7, 8, 9, 11, 12, 13, 15, >+ 128, 128, 128, 128, 128, 128, 128, 128}; > > // Offsets for source bytes 0 to 10 >-static uvec8 kShuf01 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10}; >+static const uvec8 kShuf01 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10}; > > // Offsets for source bytes 10 to 21 with 8 subtracted = 3 to 13. >-static uvec8 kShuf11 = {2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 12, 13}; >+static const uvec8 kShuf11 = {2, 3, 4, 5, 5, 6, 6, 7, >+ 8, 9, 9, 10, 10, 11, 12, 13}; > > // Offsets for source bytes 21 to 31 with 16 subtracted = 5 to 31. >-static uvec8 kShuf21 = {5, 6, 6, 7, 8, 9, 9, 10, >- 10, 11, 12, 13, 13, 14, 14, 15}; >+static const uvec8 kShuf21 = {5, 6, 6, 7, 8, 9, 9, 10, >+ 10, 11, 12, 13, 13, 14, 14, 15}; > > // Coefficients for source bytes 0 to 10 >-static uvec8 kMadd01 = {3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2}; >+static const uvec8 kMadd01 = {3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2}; > > // Coefficients for source bytes 10 to 21 >-static uvec8 kMadd11 = {1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1}; >+static const uvec8 kMadd11 = {1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1}; > > // Coefficients for source bytes 21 to 31 >-static uvec8 kMadd21 = {2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3}; >+static const uvec8 kMadd21 = {2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3}; > > // Coefficients for source bytes 21 to 31 >-static vec16 kRound34 = {2, 2, 2, 2, 2, 2, 2, 2}; >+static const vec16 kRound34 = {2, 2, 2, 2, 2, 2, 2, 2}; > >-static uvec8 kShuf38a = {0, 3, 6, 8, 11, 14, 128, 128, >- 128, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShuf38a = {0, 3, 6, 8, 11, 14, 128, 128, >+ 128, 128, 128, 128, 128, 128, 128, 128}; > >-static uvec8 kShuf38b = {128, 128, 128, 128, 128, 128, 0, 3, >- 6, 8, 11, 14, 128, 128, 128, 128}; >+static const uvec8 kShuf38b = {128, 128, 128, 128, 128, 128, 0, 3, >+ 6, 8, 11, 14, 128, 128, 128, 128}; > > // Arrange words 0,3,6 into 0,1,2 >-static uvec8 kShufAc = {0, 1, 6, 7, 12, 13, 128, 128, >- 128, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShufAc = {0, 1, 6, 7, 12, 13, 128, 128, >+ 128, 128, 128, 128, 128, 128, 128, 128}; > > // Arrange words 0,3,6 into 3,4,5 >-static uvec8 kShufAc3 = {128, 128, 128, 128, 128, 128, 0, 1, >- 6, 7, 12, 13, 128, 128, 128, 128}; >+static const uvec8 kShufAc3 = {128, 128, 128, 128, 128, 128, 0, 1, >+ 6, 7, 12, 13, 128, 128, 128, 128}; > > // Scaling values for boxes of 3x3 and 2x3 >-static uvec16 kScaleAc33 = {65536 / 9, 65536 / 9, 65536 / 6, 65536 / 9, >- 65536 / 9, 65536 / 6, 0, 0}; >+static const uvec16 kScaleAc33 = {65536 / 9, 65536 / 9, 65536 / 6, 65536 / 9, >+ 65536 / 9, 65536 / 6, 0, 0}; > > // Arrange first value for pixels 0,1,2,3,4,5 >-static uvec8 kShufAb0 = {0, 128, 3, 128, 6, 128, 8, 128, >- 11, 128, 14, 128, 128, 128, 128, 128}; >+static const uvec8 kShufAb0 = {0, 128, 3, 128, 6, 128, 8, 128, >+ 11, 128, 14, 128, 128, 128, 128, 128}; > > // Arrange second value for pixels 0,1,2,3,4,5 >-static uvec8 kShufAb1 = {1, 128, 4, 128, 7, 128, 9, 128, >- 12, 128, 15, 128, 128, 128, 128, 128}; >+static const uvec8 kShufAb1 = {1, 128, 4, 128, 7, 128, 9, 128, >+ 12, 128, 15, 128, 128, 128, 128, 128}; > > // Arrange third value for pixels 0,1,2,3,4,5 >-static uvec8 kShufAb2 = {2, 128, 5, 128, 128, 128, 10, 128, >- 13, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShufAb2 = {2, 128, 5, 128, 128, 128, 10, 128, >+ 13, 128, 128, 128, 128, 128, 128, 128}; > > // Scaling values for boxes of 3x2 and 2x2 >-static uvec16 kScaleAb2 = {65536 / 3, 65536 / 3, 65536 / 2, 65536 / 3, >- 65536 / 3, 65536 / 2, 0, 0}; >+static const uvec16 kScaleAb2 = {65536 / 3, 65536 / 3, 65536 / 2, 65536 / 3, >+ 65536 / 3, 65536 / 2, 0, 0}; > > // GCC versions of row functions are verbatim conversions from Visual C. > // Generated using gcc disassembly on Visual C object file: > // objdump -D yuvscaler.obj >yuvscaler.txt > >-void ScaleRowDown2_SSSE3(const uint8* src_ptr, >+void ScaleRowDown2_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "psrlw $0x8,%%xmm0 \n" >- "psrlw $0x8,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", "xmm0", "xmm1" >- ); >+ asm volatile( >+ // 16 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "psrlw $0x8,%%xmm0 \n" >+ "psrlw $0x8,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1"); > } > >-void ScaleRowDown2Linear_SSSE3(const uint8* src_ptr, >+void ScaleRowDown2Linear_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; >- asm volatile ( >- "pcmpeqb %%xmm4,%%xmm4 \n" >- "psrlw $0xf,%%xmm4 \n" >- "packuswb %%xmm4,%%xmm4 \n" >- "pxor %%xmm5,%%xmm5 \n" >- >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10, 0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "pavgw %%xmm5,%%xmm0 \n" >- "pavgw %%xmm5,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", "xmm0", "xmm1", "xmm4", "xmm5" >- ); >+ asm volatile( >+ "pcmpeqb %%xmm4,%%xmm4 \n" >+ "psrlw $0xf,%%xmm4 \n" >+ "packuswb %%xmm4,%%xmm4 \n" >+ "pxor %%xmm5,%%xmm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "pavgw %%xmm5,%%xmm0 \n" >+ "pavgw %%xmm5,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm4", "xmm5"); > } > >-void ScaleRowDown2Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown2Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { >- asm volatile ( >- "pcmpeqb %%xmm4,%%xmm4 \n" >- "psrlw $0xf,%%xmm4 \n" >- "packuswb %%xmm4,%%xmm4 \n" >- "pxor %%xmm5,%%xmm5 \n" >- >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- MEMOPREG(movdqu,0x00,0,3,1,xmm2) // movdqu (%0,%3,1),%%xmm2 >- MEMOPREG(movdqu,0x10,0,3,1,xmm3) // movdqu 0x10(%0,%3,1),%%xmm3 >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm4,%%xmm3 \n" >- "paddw %%xmm2,%%xmm0 \n" >- "paddw %%xmm3,%%xmm1 \n" >- "psrlw $0x1,%%xmm0 \n" >- "psrlw $0x1,%%xmm1 \n" >- "pavgw %%xmm5,%%xmm0 \n" >- "pavgw %%xmm5,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- : "r"((intptr_t)(src_stride)) // %3 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ asm volatile( >+ "pcmpeqb %%xmm4,%%xmm4 \n" >+ "psrlw $0xf,%%xmm4 \n" >+ "packuswb %%xmm4,%%xmm4 \n" >+ "pxor %%xmm5,%%xmm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x00(%0,%3,1),%%xmm2 \n" >+ "movdqu 0x10(%0,%3,1),%%xmm3 \n" >+ "lea 0x20(%0),%0 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm4,%%xmm3 \n" >+ "paddw %%xmm2,%%xmm0 \n" >+ "paddw %%xmm3,%%xmm1 \n" >+ "psrlw $0x1,%%xmm0 \n" >+ "psrlw $0x1,%%xmm1 \n" >+ "pavgw %%xmm5,%%xmm0 \n" >+ "pavgw %%xmm5,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ : "r"((intptr_t)(src_stride)) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > > #ifdef HAS_SCALEROWDOWN2_AVX2 >-void ScaleRowDown2_AVX2(const uint8* src_ptr, >+void ScaleRowDown2_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; >- asm volatile ( >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", "xmm0", "xmm1" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x8,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1"); > } > >-void ScaleRowDown2Linear_AVX2(const uint8* src_ptr, >+void ScaleRowDown2Linear_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; >- asm volatile ( >- "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" >- "vpsrlw $0xf,%%ymm4,%%ymm4 \n" >- "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" >- "vpxor %%ymm5,%%ymm5,%%ymm5 \n" >- >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20, 0) ",%%ymm1 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" >- "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" >- "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" >- "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", "xmm0", "xmm1", "xmm4", "xmm5" >- ); >+ asm volatile( >+ "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" >+ "vpsrlw $0xf,%%ymm4,%%ymm4 \n" >+ "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" >+ "vpxor %%ymm5,%%ymm5,%%ymm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" >+ "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" >+ "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm4", "xmm5"); > } > >-void ScaleRowDown2Box_AVX2(const uint8* src_ptr, >+void ScaleRowDown2Box_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { >- asm volatile ( >- "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" >- "vpsrlw $0xf,%%ymm4,%%ymm4 \n" >- "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" >- "vpxor %%ymm5,%%ymm5,%%ymm5 \n" >- >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- MEMOPREG(vmovdqu,0x00,0,3,1,ymm2) // vmovdqu (%0,%3,1),%%ymm2 >- MEMOPREG(vmovdqu,0x20,0,3,1,ymm3) // vmovdqu 0x20(%0,%3,1),%%ymm3 >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" >- "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" >- "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >- "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >- "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" >- "vpsrlw $0x1,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x1,%%ymm1,%%ymm1 \n" >- "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" >- "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- : "r"((intptr_t)(src_stride)) // %3 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+ asm volatile( >+ "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" >+ "vpsrlw $0xf,%%ymm4,%%ymm4 \n" >+ "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" >+ "vpxor %%ymm5,%%ymm5,%%ymm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "vmovdqu 0x00(%0,%3,1),%%ymm2 \n" >+ "vmovdqu 0x20(%0,%3,1),%%ymm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" >+ "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" >+ "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >+ "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >+ "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" >+ "vpsrlw $0x1,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x1,%%ymm1,%%ymm1 \n" >+ "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ : "r"((intptr_t)(src_stride)) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > #endif // HAS_SCALEROWDOWN2_AVX2 > >-void ScaleRowDown4_SSSE3(const uint8* src_ptr, >+void ScaleRowDown4_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; >- asm volatile ( >- "pcmpeqb %%xmm5,%%xmm5 \n" >- "psrld $0x18,%%xmm5 \n" >- "pslld $0x10,%%xmm5 \n" >- >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pand %%xmm5,%%xmm0 \n" >- "pand %%xmm5,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm0 \n" >- "psrlw $0x8,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", "xmm0", "xmm1", "xmm5" >- ); >+ asm volatile( >+ "pcmpeqb %%xmm5,%%xmm5 \n" >+ "psrld $0x18,%%xmm5 \n" >+ "pslld $0x10,%%xmm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "pand %%xmm5,%%xmm0 \n" >+ "pand %%xmm5,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm0 \n" >+ "psrlw $0x8,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "movq %%xmm0,(%1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm5"); > } > >-void ScaleRowDown4Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown4Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > intptr_t stridex3; >- asm volatile ( >- "pcmpeqb %%xmm4,%%xmm4 \n" >- "psrlw $0xf,%%xmm4 \n" >- "movdqa %%xmm4,%%xmm5 \n" >- "packuswb %%xmm4,%%xmm4 \n" >- "psllw $0x3,%%xmm5 \n" >- "lea " MEMLEA4(0x00,4,4,2) ",%3 \n" >- >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- MEMOPREG(movdqu,0x00,0,4,1,xmm2) // movdqu (%0,%4,1),%%xmm2 >- MEMOPREG(movdqu,0x10,0,4,1,xmm3) // movdqu 0x10(%0,%4,1),%%xmm3 >- "pmaddubsw %%xmm4,%%xmm0 \n" >- "pmaddubsw %%xmm4,%%xmm1 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm4,%%xmm3 \n" >- "paddw %%xmm2,%%xmm0 \n" >- "paddw %%xmm3,%%xmm1 \n" >- MEMOPREG(movdqu,0x00,0,4,2,xmm2) // movdqu (%0,%4,2),%%xmm2 >- MEMOPREG(movdqu,0x10,0,4,2,xmm3) // movdqu 0x10(%0,%4,2),%%xmm3 >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm4,%%xmm3 \n" >- "paddw %%xmm2,%%xmm0 \n" >- "paddw %%xmm3,%%xmm1 \n" >- MEMOPREG(movdqu,0x00,0,3,1,xmm2) // movdqu (%0,%3,1),%%xmm2 >- MEMOPREG(movdqu,0x10,0,3,1,xmm3) // movdqu 0x10(%0,%3,1),%%xmm3 >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pmaddubsw %%xmm4,%%xmm2 \n" >- "pmaddubsw %%xmm4,%%xmm3 \n" >- "paddw %%xmm2,%%xmm0 \n" >- "paddw %%xmm3,%%xmm1 \n" >- "phaddw %%xmm1,%%xmm0 \n" >- "paddw %%xmm5,%%xmm0 \n" >- "psrlw $0x4,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x8,1) ",%1 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width), // %2 >- "=&r"(stridex3) // %3 >- : "r"((intptr_t)(src_stride)) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ asm volatile( >+ "pcmpeqb %%xmm4,%%xmm4 \n" >+ "psrlw $0xf,%%xmm4 \n" >+ "movdqa %%xmm4,%%xmm5 \n" >+ "packuswb %%xmm4,%%xmm4 \n" >+ "psllw $0x3,%%xmm5 \n" >+ "lea 0x00(%4,%4,2),%3 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x00(%0,%4,1),%%xmm2 \n" >+ "movdqu 0x10(%0,%4,1),%%xmm3 \n" >+ "pmaddubsw %%xmm4,%%xmm0 \n" >+ "pmaddubsw %%xmm4,%%xmm1 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm4,%%xmm3 \n" >+ "paddw %%xmm2,%%xmm0 \n" >+ "paddw %%xmm3,%%xmm1 \n" >+ "movdqu 0x00(%0,%4,2),%%xmm2 \n" >+ "movdqu 0x10(%0,%4,2),%%xmm3 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm4,%%xmm3 \n" >+ "paddw %%xmm2,%%xmm0 \n" >+ "paddw %%xmm3,%%xmm1 \n" >+ "movdqu 0x00(%0,%3,1),%%xmm2 \n" >+ "movdqu 0x10(%0,%3,1),%%xmm3 \n" >+ "lea 0x20(%0),%0 \n" >+ "pmaddubsw %%xmm4,%%xmm2 \n" >+ "pmaddubsw %%xmm4,%%xmm3 \n" >+ "paddw %%xmm2,%%xmm0 \n" >+ "paddw %%xmm3,%%xmm1 \n" >+ "phaddw %%xmm1,%%xmm0 \n" >+ "paddw %%xmm5,%%xmm0 \n" >+ "psrlw $0x4,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "movq %%xmm0,(%1) \n" >+ "lea 0x8(%1),%1 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width), // %2 >+ "=&r"(stridex3) // %3 >+ : "r"((intptr_t)(src_stride)) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > > #ifdef HAS_SCALEROWDOWN4_AVX2 >-void ScaleRowDown4_AVX2(const uint8* src_ptr, >+void ScaleRowDown4_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; >- asm volatile ( >- "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >- "vpsrld $0x18,%%ymm5,%%ymm5 \n" >- "vpslld $0x10,%%ymm5,%%ymm5 \n" >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpand %%ymm5,%%ymm0,%%ymm0 \n" >- "vpand %%ymm5,%%ymm1,%%ymm1 \n" >- "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >- "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vmovdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", "xmm0", "xmm1", "xmm5" >- ); >+ asm volatile( >+ "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" >+ "vpsrld $0x18,%%ymm5,%%ymm5 \n" >+ "vpslld $0x10,%%ymm5,%%ymm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpand %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpand %%ymm5,%%ymm1,%%ymm1 \n" >+ "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" >+ "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm5"); > } > >-void ScaleRowDown4Box_AVX2(const uint8* src_ptr, >+void ScaleRowDown4Box_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { >- asm volatile ( >- "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" >- "vpsrlw $0xf,%%ymm4,%%ymm4 \n" >- "vpsllw $0x3,%%ymm4,%%ymm5 \n" >- "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" >- >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm0 \n" >- "vmovdqu " MEMACCESS2(0x20,0) ",%%ymm1 \n" >- MEMOPREG(vmovdqu,0x00,0,3,1,ymm2) // vmovdqu (%0,%3,1),%%ymm2 >- MEMOPREG(vmovdqu,0x20,0,3,1,ymm3) // vmovdqu 0x20(%0,%3,1),%%ymm3 >- "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" >- "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" >- "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >- "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >- "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" >- MEMOPREG(vmovdqu,0x00,0,3,2,ymm2) // vmovdqu (%0,%3,2),%%ymm2 >- MEMOPREG(vmovdqu,0x20,0,3,2,ymm3) // vmovdqu 0x20(%0,%3,2),%%ymm3 >- "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >- "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >- "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" >- MEMOPREG(vmovdqu,0x00,0,4,1,ymm2) // vmovdqu (%0,%4,1),%%ymm2 >- MEMOPREG(vmovdqu,0x20,0,4,1,ymm3) // vmovdqu 0x20(%0,%4,1),%%ymm3 >- "lea " MEMLEA(0x40,0) ",%0 \n" >- "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >- "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >- "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" >- "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" >- "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" >- "vpsrlw $0x4,%%ymm0,%%ymm0 \n" >- "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >- "vpermq $0xd8,%%ymm0,%%ymm0 \n" >- "vmovdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- : "r"((intptr_t)(src_stride)), // %3 >- "r"((intptr_t)(src_stride * 3)) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ asm volatile( >+ "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" >+ "vpsrlw $0xf,%%ymm4,%%ymm4 \n" >+ "vpsllw $0x3,%%ymm4,%%ymm5 \n" >+ "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm0 \n" >+ "vmovdqu 0x20(%0),%%ymm1 \n" >+ "vmovdqu 0x00(%0,%3,1),%%ymm2 \n" >+ "vmovdqu 0x20(%0,%3,1),%%ymm3 \n" >+ "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" >+ "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" >+ "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >+ "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >+ "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" >+ "vmovdqu 0x00(%0,%3,2),%%ymm2 \n" >+ "vmovdqu 0x20(%0,%3,2),%%ymm3 \n" >+ "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >+ "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >+ "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" >+ "vmovdqu 0x00(%0,%4,1),%%ymm2 \n" >+ "vmovdqu 0x20(%0,%4,1),%%ymm3 \n" >+ "lea 0x40(%0),%0 \n" >+ "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" >+ "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" >+ "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" >+ "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" >+ "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" >+ "vpsrlw $0x4,%%ymm0,%%ymm0 \n" >+ "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" >+ "vpermq $0xd8,%%ymm0,%%ymm0 \n" >+ "vmovdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ : "r"((intptr_t)(src_stride)), // %3 >+ "r"((intptr_t)(src_stride * 3)) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > #endif // HAS_SCALEROWDOWN4_AVX2 > >-void ScaleRowDown34_SSSE3(const uint8* src_ptr, >+void ScaleRowDown34_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -488,33 +484,34 @@ void ScaleRowDown34_SSSE3(const uint8* src_ptr, > "m"(kShuf1), // %1 > "m"(kShuf2) // %2 > ); >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm2 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "movdqa %%xmm2,%%xmm1 \n" >- "palignr $0x8,%%xmm0,%%xmm1 \n" >- "pshufb %%xmm3,%%xmm0 \n" >- "pshufb %%xmm4,%%xmm1 \n" >- "pshufb %%xmm5,%%xmm2 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- "movq %%xmm1," MEMACCESS2(0x8,1) " \n" >- "movq %%xmm2," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x18,1) ",%1 \n" >- "sub $0x18,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm2 \n" >+ "lea 0x20(%0),%0 \n" >+ "movdqa %%xmm2,%%xmm1 \n" >+ "palignr $0x8,%%xmm0,%%xmm1 \n" >+ "pshufb %%xmm3,%%xmm0 \n" >+ "pshufb %%xmm4,%%xmm1 \n" >+ "pshufb %%xmm5,%%xmm2 \n" >+ "movq %%xmm0,(%1) \n" >+ "movq %%xmm1,0x8(%1) \n" >+ "movq %%xmm2,0x10(%1) \n" >+ "lea 0x18(%1),%1 \n" >+ "sub $0x18,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); > } > >-void ScaleRowDown34_1_Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > asm volatile( > "movdqa %0,%%xmm2 \n" // kShuf01 >@@ -534,53 +531,53 @@ void ScaleRowDown34_1_Box_SSSE3(const uint8* src_ptr, > "m"(kMadd11), // %1 > "m"(kRound34) // %2 > ); >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x00,0,3,1,xmm7) // movdqu (%0,%3),%%xmm7 >- "pavgb %%xmm7,%%xmm6 \n" >- "pshufb %%xmm2,%%xmm6 \n" >- "pmaddubsw %%xmm5,%%xmm6 \n" >- "paddsw %%xmm1,%%xmm6 \n" >- "psrlw $0x2,%%xmm6 \n" >- "packuswb %%xmm6,%%xmm6 \n" >- "movq %%xmm6," MEMACCESS(1) " \n" >- "movdqu " MEMACCESS2(0x8,0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x8,0,3,1,xmm7) // movdqu 0x8(%0,%3),%%xmm7 >- "pavgb %%xmm7,%%xmm6 \n" >- "pshufb %%xmm3,%%xmm6 \n" >- "pmaddubsw %%xmm0,%%xmm6 \n" >- "paddsw %%xmm1,%%xmm6 \n" >- "psrlw $0x2,%%xmm6 \n" >- "packuswb %%xmm6,%%xmm6 \n" >- "movq %%xmm6," MEMACCESS2(0x8,1) " \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x10,0,3,1,xmm7) // movdqu 0x10(%0,%3),%%xmm7 >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pavgb %%xmm7,%%xmm6 \n" >- "pshufb %%xmm4,%%xmm6 \n" >- "pmaddubsw %4,%%xmm6 \n" >- "paddsw %%xmm1,%%xmm6 \n" >- "psrlw $0x2,%%xmm6 \n" >- "packuswb %%xmm6,%%xmm6 \n" >- "movq %%xmm6," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x18,1) ",%1 \n" >- "sub $0x18,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- : "r"((intptr_t)(src_stride)), // %3 >- "m"(kMadd21) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm6 \n" >+ "movdqu 0x00(%0,%3,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ "pshufb %%xmm2,%%xmm6 \n" >+ "pmaddubsw %%xmm5,%%xmm6 \n" >+ "paddsw %%xmm1,%%xmm6 \n" >+ "psrlw $0x2,%%xmm6 \n" >+ "packuswb %%xmm6,%%xmm6 \n" >+ "movq %%xmm6,(%1) \n" >+ "movdqu 0x8(%0),%%xmm6 \n" >+ "movdqu 0x8(%0,%3,1),%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ "pshufb %%xmm3,%%xmm6 \n" >+ "pmaddubsw %%xmm0,%%xmm6 \n" >+ "paddsw %%xmm1,%%xmm6 \n" >+ "psrlw $0x2,%%xmm6 \n" >+ "packuswb %%xmm6,%%xmm6 \n" >+ "movq %%xmm6,0x8(%1) \n" >+ "movdqu 0x10(%0),%%xmm6 \n" >+ "movdqu 0x10(%0,%3,1),%%xmm7 \n" >+ "lea 0x20(%0),%0 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ "pshufb %%xmm4,%%xmm6 \n" >+ "pmaddubsw %4,%%xmm6 \n" >+ "paddsw %%xmm1,%%xmm6 \n" >+ "psrlw $0x2,%%xmm6 \n" >+ "packuswb %%xmm6,%%xmm6 \n" >+ "movq %%xmm6,0x10(%1) \n" >+ "lea 0x18(%1),%1 \n" >+ "sub $0x18,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ : "r"((intptr_t)(src_stride)), // %3 >+ "m"(kMadd21) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > >-void ScaleRowDown34_0_Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > asm volatile( > "movdqa %0,%%xmm2 \n" // kShuf01 >@@ -601,88 +598,87 @@ void ScaleRowDown34_0_Box_SSSE3(const uint8* src_ptr, > "m"(kRound34) // %2 > ); > >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x00,0,3,1,xmm7) // movdqu (%0,%3,1),%%xmm7 >- "pavgb %%xmm6,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm6 \n" >- "pshufb %%xmm2,%%xmm6 \n" >- "pmaddubsw %%xmm5,%%xmm6 \n" >- "paddsw %%xmm1,%%xmm6 \n" >- "psrlw $0x2,%%xmm6 \n" >- "packuswb %%xmm6,%%xmm6 \n" >- "movq %%xmm6," MEMACCESS(1) " \n" >- "movdqu " MEMACCESS2(0x8,0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x8,0,3,1,xmm7) // movdqu 0x8(%0,%3,1),%%xmm7 >- "pavgb %%xmm6,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm6 \n" >- "pshufb %%xmm3,%%xmm6 \n" >- "pmaddubsw %%xmm0,%%xmm6 \n" >- "paddsw %%xmm1,%%xmm6 \n" >- "psrlw $0x2,%%xmm6 \n" >- "packuswb %%xmm6,%%xmm6 \n" >- "movq %%xmm6," MEMACCESS2(0x8,1) " \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm6 \n" >- MEMOPREG(movdqu,0x10,0,3,1,xmm7) // movdqu 0x10(%0,%3,1),%%xmm7 >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pavgb %%xmm6,%%xmm7 \n" >- "pavgb %%xmm7,%%xmm6 \n" >- "pshufb %%xmm4,%%xmm6 \n" >- "pmaddubsw %4,%%xmm6 \n" >- "paddsw %%xmm1,%%xmm6 \n" >- "psrlw $0x2,%%xmm6 \n" >- "packuswb %%xmm6,%%xmm6 \n" >- "movq %%xmm6," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x18,1) ",%1 \n" >- "sub $0x18,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- : "r"((intptr_t)(src_stride)), // %3 >- "m"(kMadd21) // %4 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm6 \n" >+ "movdqu 0x00(%0,%3,1),%%xmm7 \n" >+ "pavgb %%xmm6,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ "pshufb %%xmm2,%%xmm6 \n" >+ "pmaddubsw %%xmm5,%%xmm6 \n" >+ "paddsw %%xmm1,%%xmm6 \n" >+ "psrlw $0x2,%%xmm6 \n" >+ "packuswb %%xmm6,%%xmm6 \n" >+ "movq %%xmm6,(%1) \n" >+ "movdqu 0x8(%0),%%xmm6 \n" >+ "movdqu 0x8(%0,%3,1),%%xmm7 \n" >+ "pavgb %%xmm6,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ "pshufb %%xmm3,%%xmm6 \n" >+ "pmaddubsw %%xmm0,%%xmm6 \n" >+ "paddsw %%xmm1,%%xmm6 \n" >+ "psrlw $0x2,%%xmm6 \n" >+ "packuswb %%xmm6,%%xmm6 \n" >+ "movq %%xmm6,0x8(%1) \n" >+ "movdqu 0x10(%0),%%xmm6 \n" >+ "movdqu 0x10(%0,%3,1),%%xmm7 \n" >+ "lea 0x20(%0),%0 \n" >+ "pavgb %%xmm6,%%xmm7 \n" >+ "pavgb %%xmm7,%%xmm6 \n" >+ "pshufb %%xmm4,%%xmm6 \n" >+ "pmaddubsw %4,%%xmm6 \n" >+ "paddsw %%xmm1,%%xmm6 \n" >+ "psrlw $0x2,%%xmm6 \n" >+ "packuswb %%xmm6,%%xmm6 \n" >+ "movq %%xmm6,0x10(%1) \n" >+ "lea 0x18(%1),%1 \n" >+ "sub $0x18,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ : "r"((intptr_t)(src_stride)), // %3 >+ "m"(kMadd21) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > >-void ScaleRowDown38_SSSE3(const uint8* src_ptr, >+void ScaleRowDown38_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; >- asm volatile ( >- "movdqa %3,%%xmm4 \n" >- "movdqa %4,%%xmm5 \n" >- >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pshufb %%xmm4,%%xmm0 \n" >- "pshufb %%xmm5,%%xmm1 \n" >- "paddusb %%xmm1,%%xmm0 \n" >- "movq %%xmm0," MEMACCESS(1) " \n" >- "movhlps %%xmm0,%%xmm1 \n" >- "movd %%xmm1," MEMACCESS2(0x8,1) " \n" >- "lea " MEMLEA(0xc,1) ",%1 \n" >- "sub $0xc,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- : "m"(kShuf38a), // %3 >- "m"(kShuf38b) // %4 >- : "memory", "cc", "xmm0", "xmm1", "xmm4", "xmm5" >- ); >+ asm volatile( >+ "movdqa %3,%%xmm4 \n" >+ "movdqa %4,%%xmm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "pshufb %%xmm4,%%xmm0 \n" >+ "pshufb %%xmm5,%%xmm1 \n" >+ "paddusb %%xmm1,%%xmm0 \n" >+ "movq %%xmm0,(%1) \n" >+ "movhlps %%xmm0,%%xmm1 \n" >+ "movd %%xmm1,0x8(%1) \n" >+ "lea 0xc(%1),%1 \n" >+ "sub $0xc,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ : "m"(kShuf38a), // %3 >+ "m"(kShuf38b) // %4 >+ : "memory", "cc", "xmm0", "xmm1", "xmm4", "xmm5"); > } > >-void ScaleRowDown38_2_Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown38_2_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > asm volatile( > "movdqa %0,%%xmm2 \n" >@@ -695,40 +691,39 @@ void ScaleRowDown38_2_Box_SSSE3(const uint8* src_ptr, > "m"(kShufAb2), // %2 > "m"(kScaleAb2) // %3 > ); >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,3,1,xmm1) // movdqu (%0,%3,1),%%xmm1 >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "pavgb %%xmm1,%%xmm0 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "pshufb %%xmm2,%%xmm1 \n" >- "movdqa %%xmm0,%%xmm6 \n" >- "pshufb %%xmm3,%%xmm6 \n" >- "paddusw %%xmm6,%%xmm1 \n" >- "pshufb %%xmm4,%%xmm0 \n" >- "paddusw %%xmm0,%%xmm1 \n" >- "pmulhuw %%xmm5,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm1 \n" >- "movd %%xmm1," MEMACCESS(1) " \n" >- "psrlq $0x10,%%xmm1 \n" >- "movd %%xmm1," MEMACCESS2(0x2,1) " \n" >- "lea " MEMLEA(0x6,1) ",%1 \n" >- "sub $0x6,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- : "r"((intptr_t)(src_stride)) // %3 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%3,1),%%xmm1 \n" >+ "lea 0x10(%0),%0 \n" >+ "pavgb %%xmm1,%%xmm0 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "pshufb %%xmm2,%%xmm1 \n" >+ "movdqa %%xmm0,%%xmm6 \n" >+ "pshufb %%xmm3,%%xmm6 \n" >+ "paddusw %%xmm6,%%xmm1 \n" >+ "pshufb %%xmm4,%%xmm0 \n" >+ "paddusw %%xmm0,%%xmm1 \n" >+ "pmulhuw %%xmm5,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm1 \n" >+ "movd %%xmm1,(%1) \n" >+ "psrlq $0x10,%%xmm1 \n" >+ "movd %%xmm1,0x2(%1) \n" >+ "lea 0x6(%1),%1 \n" >+ "sub $0x6,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ : "r"((intptr_t)(src_stride)) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); > } > >-void ScaleRowDown38_3_Box_SSSE3(const uint8* src_ptr, >+void ScaleRowDown38_3_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > asm volatile( > "movdqa %0,%%xmm2 \n" >@@ -740,529 +735,533 @@ void ScaleRowDown38_3_Box_SSSE3(const uint8* src_ptr, > "m"(kShufAc3), // %1 > "m"(kScaleAc33) // %2 > ); >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movdqu,0x00,0,3,1,xmm6) // movdqu (%0,%3,1),%%xmm6 >- "movhlps %%xmm0,%%xmm1 \n" >- "movhlps %%xmm6,%%xmm7 \n" >- "punpcklbw %%xmm5,%%xmm0 \n" >- "punpcklbw %%xmm5,%%xmm1 \n" >- "punpcklbw %%xmm5,%%xmm6 \n" >- "punpcklbw %%xmm5,%%xmm7 \n" >- "paddusw %%xmm6,%%xmm0 \n" >- "paddusw %%xmm7,%%xmm1 \n" >- MEMOPREG(movdqu,0x00,0,3,2,xmm6) // movdqu (%0,%3,2),%%xmm6 >- "lea " MEMLEA(0x10,0) ",%0 \n" >- "movhlps %%xmm6,%%xmm7 \n" >- "punpcklbw %%xmm5,%%xmm6 \n" >- "punpcklbw %%xmm5,%%xmm7 \n" >- "paddusw %%xmm6,%%xmm0 \n" >- "paddusw %%xmm7,%%xmm1 \n" >- "movdqa %%xmm0,%%xmm6 \n" >- "psrldq $0x2,%%xmm0 \n" >- "paddusw %%xmm0,%%xmm6 \n" >- "psrldq $0x2,%%xmm0 \n" >- "paddusw %%xmm0,%%xmm6 \n" >- "pshufb %%xmm2,%%xmm6 \n" >- "movdqa %%xmm1,%%xmm7 \n" >- "psrldq $0x2,%%xmm1 \n" >- "paddusw %%xmm1,%%xmm7 \n" >- "psrldq $0x2,%%xmm1 \n" >- "paddusw %%xmm1,%%xmm7 \n" >- "pshufb %%xmm3,%%xmm7 \n" >- "paddusw %%xmm7,%%xmm6 \n" >- "pmulhuw %%xmm4,%%xmm6 \n" >- "packuswb %%xmm6,%%xmm6 \n" >- "movd %%xmm6," MEMACCESS(1) " \n" >- "psrlq $0x10,%%xmm6 \n" >- "movd %%xmm6," MEMACCESS2(0x2,1) " \n" >- "lea " MEMLEA(0x6,1) ",%1 \n" >- "sub $0x6,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(dst_width) // %2 >- : "r"((intptr_t)(src_stride)) // %3 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x00(%0,%3,1),%%xmm6 \n" >+ "movhlps %%xmm0,%%xmm1 \n" >+ "movhlps %%xmm6,%%xmm7 \n" >+ "punpcklbw %%xmm5,%%xmm0 \n" >+ "punpcklbw %%xmm5,%%xmm1 \n" >+ "punpcklbw %%xmm5,%%xmm6 \n" >+ "punpcklbw %%xmm5,%%xmm7 \n" >+ "paddusw %%xmm6,%%xmm0 \n" >+ "paddusw %%xmm7,%%xmm1 \n" >+ "movdqu 0x00(%0,%3,2),%%xmm6 \n" >+ "lea 0x10(%0),%0 \n" >+ "movhlps %%xmm6,%%xmm7 \n" >+ "punpcklbw %%xmm5,%%xmm6 \n" >+ "punpcklbw %%xmm5,%%xmm7 \n" >+ "paddusw %%xmm6,%%xmm0 \n" >+ "paddusw %%xmm7,%%xmm1 \n" >+ "movdqa %%xmm0,%%xmm6 \n" >+ "psrldq $0x2,%%xmm0 \n" >+ "paddusw %%xmm0,%%xmm6 \n" >+ "psrldq $0x2,%%xmm0 \n" >+ "paddusw %%xmm0,%%xmm6 \n" >+ "pshufb %%xmm2,%%xmm6 \n" >+ "movdqa %%xmm1,%%xmm7 \n" >+ "psrldq $0x2,%%xmm1 \n" >+ "paddusw %%xmm1,%%xmm7 \n" >+ "psrldq $0x2,%%xmm1 \n" >+ "paddusw %%xmm1,%%xmm7 \n" >+ "pshufb %%xmm3,%%xmm7 \n" >+ "paddusw %%xmm7,%%xmm6 \n" >+ "pmulhuw %%xmm4,%%xmm6 \n" >+ "packuswb %%xmm6,%%xmm6 \n" >+ "movd %%xmm6,(%1) \n" >+ "psrlq $0x10,%%xmm6 \n" >+ "movd %%xmm6,0x2(%1) \n" >+ "lea 0x6(%1),%1 \n" >+ "sub $0x6,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(dst_width) // %2 >+ : "r"((intptr_t)(src_stride)) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > > // Reads 16xN bytes and produces 16 shorts at a time. >-void ScaleAddRow_SSE2(const uint8* src_ptr, uint16* dst_ptr, int src_width) { >- asm volatile ( >- "pxor %%xmm5,%%xmm5 \n" >- >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm3 \n" >- "lea " MEMLEA(0x10,0) ",%0 \n" // src_ptr += 16 >- "movdqu " MEMACCESS(1) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,1) ",%%xmm1 \n" >- "movdqa %%xmm3,%%xmm2 \n" >- "punpcklbw %%xmm5,%%xmm2 \n" >- "punpckhbw %%xmm5,%%xmm3 \n" >- "paddusw %%xmm2,%%xmm0 \n" >- "paddusw %%xmm3,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,1) " \n" >- "lea " MEMLEA(0x20,1) ",%1 \n" >- "sub $0x10,%2 \n" >- "jg 1b \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(src_width) // %2 >- : >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+void ScaleAddRow_SSE2(const uint8_t* src_ptr, >+ uint16_t* dst_ptr, >+ int src_width) { >+ asm volatile( >+ >+ "pxor %%xmm5,%%xmm5 \n" >+ >+ // 16 pixel loop. >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm3 \n" >+ "lea 0x10(%0),%0 \n" // src_ptr += 16 >+ "movdqu (%1),%%xmm0 \n" >+ "movdqu 0x10(%1),%%xmm1 \n" >+ "movdqa %%xmm3,%%xmm2 \n" >+ "punpcklbw %%xmm5,%%xmm2 \n" >+ "punpckhbw %%xmm5,%%xmm3 \n" >+ "paddusw %%xmm2,%%xmm0 \n" >+ "paddusw %%xmm3,%%xmm1 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "movdqu %%xmm1,0x10(%1) \n" >+ "lea 0x20(%1),%1 \n" >+ "sub $0x10,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(src_width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > > #ifdef HAS_SCALEADDROW_AVX2 > // Reads 32 bytes and accumulates to 32 shorts at a time. >-void ScaleAddRow_AVX2(const uint8* src_ptr, uint16* dst_ptr, int src_width) { >- asm volatile ( >- "vpxor %%ymm5,%%ymm5,%%ymm5 \n" >- >- LABELALIGN >- "1: \n" >- "vmovdqu " MEMACCESS(0) ",%%ymm3 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" // src_ptr += 32 >- "vpermq $0xd8,%%ymm3,%%ymm3 \n" >- "vpunpcklbw %%ymm5,%%ymm3,%%ymm2 \n" >- "vpunpckhbw %%ymm5,%%ymm3,%%ymm3 \n" >- "vpaddusw " MEMACCESS(1) ",%%ymm2,%%ymm0 \n" >- "vpaddusw " MEMACCESS2(0x20,1) ",%%ymm3,%%ymm1 \n" >- "vmovdqu %%ymm0," MEMACCESS(1) " \n" >- "vmovdqu %%ymm1," MEMACCESS2(0x20,1) " \n" >- "lea " MEMLEA(0x40,1) ",%1 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- "vzeroupper \n" >- : "+r"(src_ptr), // %0 >- "+r"(dst_ptr), // %1 >- "+r"(src_width) // %2 >- : >- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" >- ); >+void ScaleAddRow_AVX2(const uint8_t* src_ptr, >+ uint16_t* dst_ptr, >+ int src_width) { >+ asm volatile( >+ >+ "vpxor %%ymm5,%%ymm5,%%ymm5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "vmovdqu (%0),%%ymm3 \n" >+ "lea 0x20(%0),%0 \n" // src_ptr += 32 >+ "vpermq $0xd8,%%ymm3,%%ymm3 \n" >+ "vpunpcklbw %%ymm5,%%ymm3,%%ymm2 \n" >+ "vpunpckhbw %%ymm5,%%ymm3,%%ymm3 \n" >+ "vpaddusw (%1),%%ymm2,%%ymm0 \n" >+ "vpaddusw 0x20(%1),%%ymm3,%%ymm1 \n" >+ "vmovdqu %%ymm0,(%1) \n" >+ "vmovdqu %%ymm1,0x20(%1) \n" >+ "lea 0x40(%1),%1 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ "vzeroupper \n" >+ : "+r"(src_ptr), // %0 >+ "+r"(dst_ptr), // %1 >+ "+r"(src_width) // %2 >+ : >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); > } > #endif // HAS_SCALEADDROW_AVX2 > > // Constant for making pixels signed to avoid pmaddubsw > // saturation. >-static uvec8 kFsub80 = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, >- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; >+static const uvec8 kFsub80 = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, >+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; > > // Constant for making pixels unsigned and adding .5 for rounding. >-static uvec16 kFadd40 = {0x4040, 0x4040, 0x4040, 0x4040, >- 0x4040, 0x4040, 0x4040, 0x4040}; >+static const uvec16 kFadd40 = {0x4040, 0x4040, 0x4040, 0x4040, >+ 0x4040, 0x4040, 0x4040, 0x4040}; > > // Bilinear column filtering. SSSE3 version. >-void ScaleFilterCols_SSSE3(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols_SSSE3(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx) { > intptr_t x0, x1, temp_pixel; >- asm volatile ( >- "movd %6,%%xmm2 \n" >- "movd %7,%%xmm3 \n" >- "movl $0x04040000,%k2 \n" >- "movd %k2,%%xmm5 \n" >- "pcmpeqb %%xmm6,%%xmm6 \n" >- "psrlw $0x9,%%xmm6 \n" // 0x007f007f >- "pcmpeqb %%xmm7,%%xmm7 \n" >- "psrlw $15,%%xmm7 \n" // 0x00010001 >- >- "pextrw $0x1,%%xmm2,%k3 \n" >- "subl $0x2,%5 \n" >- "jl 29f \n" >- "movdqa %%xmm2,%%xmm0 \n" >- "paddd %%xmm3,%%xmm0 \n" >- "punpckldq %%xmm0,%%xmm2 \n" >- "punpckldq %%xmm3,%%xmm3 \n" >- "paddd %%xmm3,%%xmm3 \n" >- "pextrw $0x3,%%xmm2,%k4 \n" >- >- LABELALIGN >- "2: \n" >- "movdqa %%xmm2,%%xmm1 \n" >- "paddd %%xmm3,%%xmm2 \n" >- MEMOPARG(movzwl,0x00,1,3,1,k2) // movzwl (%1,%3,1),%k2 >- "movd %k2,%%xmm0 \n" >- "psrlw $0x9,%%xmm1 \n" >- MEMOPARG(movzwl,0x00,1,4,1,k2) // movzwl (%1,%4,1),%k2 >- "movd %k2,%%xmm4 \n" >- "pshufb %%xmm5,%%xmm1 \n" >- "punpcklwd %%xmm4,%%xmm0 \n" >- "psubb %8,%%xmm0 \n" // make pixels signed. >- "pxor %%xmm6,%%xmm1 \n" // 128 - f = (f ^ 127 ) + 1 >- "paddusb %%xmm7,%%xmm1 \n" >- "pmaddubsw %%xmm0,%%xmm1 \n" >- "pextrw $0x1,%%xmm2,%k3 \n" >- "pextrw $0x3,%%xmm2,%k4 \n" >- "paddw %9,%%xmm1 \n" // make pixels unsigned. >- "psrlw $0x7,%%xmm1 \n" >- "packuswb %%xmm1,%%xmm1 \n" >- "movd %%xmm1,%k2 \n" >- "mov %w2," MEMACCESS(0) " \n" >- "lea " MEMLEA(0x2,0) ",%0 \n" >- "subl $0x2,%5 \n" >- "jge 2b \n" >- >- LABELALIGN >- "29: \n" >- "addl $0x1,%5 \n" >- "jl 99f \n" >- MEMOPARG(movzwl,0x00,1,3,1,k2) // movzwl (%1,%3,1),%k2 >- "movd %k2,%%xmm0 \n" >- "psrlw $0x9,%%xmm2 \n" >- "pshufb %%xmm5,%%xmm2 \n" >- "psubb %8,%%xmm0 \n" // make pixels signed. >- "pxor %%xmm6,%%xmm2 \n" >- "paddusb %%xmm7,%%xmm2 \n" >- "pmaddubsw %%xmm0,%%xmm2 \n" >- "paddw %9,%%xmm2 \n" // make pixels unsigned. >- "psrlw $0x7,%%xmm2 \n" >- "packuswb %%xmm2,%%xmm2 \n" >- "movd %%xmm2,%k2 \n" >- "mov %b2," MEMACCESS(0) " \n" >- "99: \n" >- : "+r"(dst_ptr), // %0 >- "+r"(src_ptr), // %1 >- "=&a"(temp_pixel), // %2 >- "=&r"(x0), // %3 >- "=&r"(x1), // %4 >+ asm volatile( >+ "movd %6,%%xmm2 \n" >+ "movd %7,%%xmm3 \n" >+ "movl $0x04040000,%k2 \n" >+ "movd %k2,%%xmm5 \n" >+ "pcmpeqb %%xmm6,%%xmm6 \n" >+ "psrlw $0x9,%%xmm6 \n" // 0x007f007f >+ "pcmpeqb %%xmm7,%%xmm7 \n" >+ "psrlw $15,%%xmm7 \n" // 0x00010001 >+ >+ "pextrw $0x1,%%xmm2,%k3 \n" >+ "subl $0x2,%5 \n" >+ "jl 29f \n" >+ "movdqa %%xmm2,%%xmm0 \n" >+ "paddd %%xmm3,%%xmm0 \n" >+ "punpckldq %%xmm0,%%xmm2 \n" >+ "punpckldq %%xmm3,%%xmm3 \n" >+ "paddd %%xmm3,%%xmm3 \n" >+ "pextrw $0x3,%%xmm2,%k4 \n" >+ >+ LABELALIGN >+ "2: \n" >+ "movdqa %%xmm2,%%xmm1 \n" >+ "paddd %%xmm3,%%xmm2 \n" >+ "movzwl 0x00(%1,%3,1),%k2 \n" >+ "movd %k2,%%xmm0 \n" >+ "psrlw $0x9,%%xmm1 \n" >+ "movzwl 0x00(%1,%4,1),%k2 \n" >+ "movd %k2,%%xmm4 \n" >+ "pshufb %%xmm5,%%xmm1 \n" >+ "punpcklwd %%xmm4,%%xmm0 \n" >+ "psubb %8,%%xmm0 \n" // make pixels signed. >+ "pxor %%xmm6,%%xmm1 \n" // 128 - f = (f ^ 127 ) + >+ // 1 >+ "paddusb %%xmm7,%%xmm1 \n" >+ "pmaddubsw %%xmm0,%%xmm1 \n" >+ "pextrw $0x1,%%xmm2,%k3 \n" >+ "pextrw $0x3,%%xmm2,%k4 \n" >+ "paddw %9,%%xmm1 \n" // make pixels unsigned. >+ "psrlw $0x7,%%xmm1 \n" >+ "packuswb %%xmm1,%%xmm1 \n" >+ "movd %%xmm1,%k2 \n" >+ "mov %w2,(%0) \n" >+ "lea 0x2(%0),%0 \n" >+ "subl $0x2,%5 \n" >+ "jge 2b \n" >+ >+ LABELALIGN >+ "29: \n" >+ "addl $0x1,%5 \n" >+ "jl 99f \n" >+ "movzwl 0x00(%1,%3,1),%k2 \n" >+ "movd %k2,%%xmm0 \n" >+ "psrlw $0x9,%%xmm2 \n" >+ "pshufb %%xmm5,%%xmm2 \n" >+ "psubb %8,%%xmm0 \n" // make pixels signed. >+ "pxor %%xmm6,%%xmm2 \n" >+ "paddusb %%xmm7,%%xmm2 \n" >+ "pmaddubsw %%xmm0,%%xmm2 \n" >+ "paddw %9,%%xmm2 \n" // make pixels unsigned. >+ "psrlw $0x7,%%xmm2 \n" >+ "packuswb %%xmm2,%%xmm2 \n" >+ "movd %%xmm2,%k2 \n" >+ "mov %b2,(%0) \n" >+ "99: \n" >+ : "+r"(dst_ptr), // %0 >+ "+r"(src_ptr), // %1 >+ "=&a"(temp_pixel), // %2 >+ "=&r"(x0), // %3 >+ "=&r"(x1), // %4 > #if defined(__x86_64__) >- "+rm"(dst_width) // %5 >+ "+rm"(dst_width) // %5 > #else >- "+m"(dst_width) // %5 >+ "+m"(dst_width) // %5 > #endif >- : "rm"(x), // %6 >- "rm"(dx), // %7 >+ : "rm"(x), // %6 >+ "rm"(dx), // %7 > #if defined(__x86_64__) >- "x"(kFsub80), // %8 >- "x"(kFadd40) // %9 >+ "x"(kFsub80), // %8 >+ "x"(kFadd40) // %9 > #else >- "m"(kFsub80), // %8 >- "m"(kFadd40) // %9 >+ "m"(kFsub80), // %8 >+ "m"(kFadd40) // %9 > #endif >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" >- ); >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", >+ "xmm7"); > } > > // Reads 4 pixels, duplicates them and writes 8 pixels. > // Alignment requirement: src_argb 16 byte aligned, dst_argb 16 byte aligned. >-void ScaleColsUp2_SSE2(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleColsUp2_SSE2(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx) { > (void)x; > (void)dx; >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(1) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpcklbw %%xmm0,%%xmm0 \n" >- "punpckhbw %%xmm1,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(0) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,0) " \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "sub $0x20,%2 \n" >- "jg 1b \n" >- >- : "+r"(dst_ptr), // %0 >- "+r"(src_ptr), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", "xmm0", "xmm1" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%1),%%xmm0 \n" >+ "lea 0x10(%1),%1 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpcklbw %%xmm0,%%xmm0 \n" >+ "punpckhbw %%xmm1,%%xmm1 \n" >+ "movdqu %%xmm0,(%0) \n" >+ "movdqu %%xmm1,0x10(%0) \n" >+ "lea 0x20(%0),%0 \n" >+ "sub $0x20,%2 \n" >+ "jg 1b \n" >+ >+ : "+r"(dst_ptr), // %0 >+ "+r"(src_ptr), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1"); > } > >-void ScaleARGBRowDown2_SSE2(const uint8* src_argb, >+void ScaleARGBRowDown2_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > (void)src_stride; >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "shufps $0xdd,%%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", "xmm0", "xmm1" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "shufps $0xdd,%%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1"); > } > >-void ScaleARGBRowDown2Linear_SSE2(const uint8* src_argb, >+void ScaleARGBRowDown2Linear_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > (void)src_stride; >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "shufps $0x88,%%xmm1,%%xmm0 \n" >- "shufps $0xdd,%%xmm1,%%xmm2 \n" >- "pavgb %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", "xmm0", "xmm1" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "lea 0x20(%0),%0 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "shufps $0x88,%%xmm1,%%xmm0 \n" >+ "shufps $0xdd,%%xmm1,%%xmm2 \n" >+ "pavgb %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1"); > } > >-void ScaleARGBRowDown2Box_SSE2(const uint8* src_argb, >+void ScaleARGBRowDown2Box_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(0) ",%%xmm0 \n" >- "movdqu " MEMACCESS2(0x10,0) ",%%xmm1 \n" >- MEMOPREG(movdqu,0x00,0,3,1,xmm2) // movdqu (%0,%3,1),%%xmm2 >- MEMOPREG(movdqu,0x10,0,3,1,xmm3) // movdqu 0x10(%0,%3,1),%%xmm3 >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "pavgb %%xmm2,%%xmm0 \n" >- "pavgb %%xmm3,%%xmm1 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "shufps $0x88,%%xmm1,%%xmm0 \n" >- "shufps $0xdd,%%xmm1,%%xmm2 \n" >- "pavgb %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(1) " \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "sub $0x4,%2 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(dst_width) // %2 >- : "r"((intptr_t)(src_stride)) // %3 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%0),%%xmm0 \n" >+ "movdqu 0x10(%0),%%xmm1 \n" >+ "movdqu 0x00(%0,%3,1),%%xmm2 \n" >+ "movdqu 0x10(%0,%3,1),%%xmm3 \n" >+ "lea 0x20(%0),%0 \n" >+ "pavgb %%xmm2,%%xmm0 \n" >+ "pavgb %%xmm3,%%xmm1 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "shufps $0x88,%%xmm1,%%xmm0 \n" >+ "shufps $0xdd,%%xmm1,%%xmm2 \n" >+ "pavgb %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%1) \n" >+ "lea 0x10(%1),%1 \n" >+ "sub $0x4,%2 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(dst_width) // %2 >+ : "r"((intptr_t)(src_stride)) // %3 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3"); > } > > // Reads 4 pixels at a time. > // Alignment requirement: dst_argb 16 byte aligned. >-void ScaleARGBRowDownEven_SSE2(const uint8* src_argb, >+void ScaleARGBRowDownEven_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > intptr_t src_stepx_x4 = (intptr_t)(src_stepx); > intptr_t src_stepx_x12; > (void)src_stride; >- asm volatile ( >- "lea " MEMLEA3(0x00,1,4) ",%1 \n" >- "lea " MEMLEA4(0x00,1,1,2) ",%4 \n" >- LABELALIGN >- "1: \n" >- "movd " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movd,0x00,0,1,1,xmm1) // movd (%0,%1,1),%%xmm1 >- "punpckldq %%xmm1,%%xmm0 \n" >- MEMOPREG(movd,0x00,0,1,2,xmm2) // movd (%0,%1,2),%%xmm2 >- MEMOPREG(movd,0x00,0,4,1,xmm3) // movd (%0,%4,1),%%xmm3 >- "lea " MEMLEA4(0x00,0,1,4) ",%0 \n" >- "punpckldq %%xmm3,%%xmm2 \n" >- "punpcklqdq %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x4,%3 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(src_stepx_x4), // %1 >- "+r"(dst_argb), // %2 >- "+r"(dst_width), // %3 >- "=&r"(src_stepx_x12) // %4 >- :: "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3" >- ); >+ asm volatile( >+ "lea 0x00(,%1,4),%1 \n" >+ "lea 0x00(%1,%1,2),%4 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movd (%0),%%xmm0 \n" >+ "movd 0x00(%0,%1,1),%%xmm1 \n" >+ "punpckldq %%xmm1,%%xmm0 \n" >+ "movd 0x00(%0,%1,2),%%xmm2 \n" >+ "movd 0x00(%0,%4,1),%%xmm3 \n" >+ "lea 0x00(%0,%1,4),%0 \n" >+ "punpckldq %%xmm3,%%xmm2 \n" >+ "punpcklqdq %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x4,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(src_stepx_x4), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(dst_width), // %3 >+ "=&r"(src_stepx_x12) // %4 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm2", "xmm3"); > } > > // Blends four 2x2 to 4x1. > // Alignment requirement: dst_argb 16 byte aligned. >-void ScaleARGBRowDownEvenBox_SSE2(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > intptr_t src_stepx_x4 = (intptr_t)(src_stepx); > intptr_t src_stepx_x12; > intptr_t row1 = (intptr_t)(src_stride); >- asm volatile ( >- "lea " MEMLEA3(0x00,1,4) ",%1 \n" >- "lea " MEMLEA4(0x00,1,1,2) ",%4 \n" >- "lea " MEMLEA4(0x00,0,5,1) ",%5 \n" >- >- LABELALIGN >- "1: \n" >- "movq " MEMACCESS(0) ",%%xmm0 \n" >- MEMOPREG(movhps,0x00,0,1,1,xmm0) // movhps (%0,%1,1),%%xmm0 >- MEMOPREG(movq,0x00,0,1,2,xmm1) // movq (%0,%1,2),%%xmm1 >- MEMOPREG(movhps,0x00,0,4,1,xmm1) // movhps (%0,%4,1),%%xmm1 >- "lea " MEMLEA4(0x00,0,1,4) ",%0 \n" >- "movq " MEMACCESS(5) ",%%xmm2 \n" >- MEMOPREG(movhps,0x00,5,1,1,xmm2) // movhps (%5,%1,1),%%xmm2 >- MEMOPREG(movq,0x00,5,1,2,xmm3) // movq (%5,%1,2),%%xmm3 >- MEMOPREG(movhps,0x00,5,4,1,xmm3) // movhps (%5,%4,1),%%xmm3 >- "lea " MEMLEA4(0x00,5,1,4) ",%5 \n" >- "pavgb %%xmm2,%%xmm0 \n" >- "pavgb %%xmm3,%%xmm1 \n" >- "movdqa %%xmm0,%%xmm2 \n" >- "shufps $0x88,%%xmm1,%%xmm0 \n" >- "shufps $0xdd,%%xmm1,%%xmm2 \n" >- "pavgb %%xmm2,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x4,%3 \n" >- "jg 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(src_stepx_x4), // %1 >- "+r"(dst_argb), // %2 >- "+rm"(dst_width), // %3 >- "=&r"(src_stepx_x12), // %4 >- "+r"(row1) // %5 >- :: "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3" >- ); >+ asm volatile( >+ "lea 0x00(,%1,4),%1 \n" >+ "lea 0x00(%1,%1,2),%4 \n" >+ "lea 0x00(%0,%5,1),%5 \n" >+ >+ LABELALIGN >+ "1: \n" >+ "movq (%0),%%xmm0 \n" >+ "movhps 0x00(%0,%1,1),%%xmm0 \n" >+ "movq 0x00(%0,%1,2),%%xmm1 \n" >+ "movhps 0x00(%0,%4,1),%%xmm1 \n" >+ "lea 0x00(%0,%1,4),%0 \n" >+ "movq (%5),%%xmm2 \n" >+ "movhps 0x00(%5,%1,1),%%xmm2 \n" >+ "movq 0x00(%5,%1,2),%%xmm3 \n" >+ "movhps 0x00(%5,%4,1),%%xmm3 \n" >+ "lea 0x00(%5,%1,4),%5 \n" >+ "pavgb %%xmm2,%%xmm0 \n" >+ "pavgb %%xmm3,%%xmm1 \n" >+ "movdqa %%xmm0,%%xmm2 \n" >+ "shufps $0x88,%%xmm1,%%xmm0 \n" >+ "shufps $0xdd,%%xmm1,%%xmm2 \n" >+ "pavgb %%xmm2,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x4,%3 \n" >+ "jg 1b \n" >+ : "+r"(src_argb), // %0 >+ "+r"(src_stepx_x4), // %1 >+ "+r"(dst_argb), // %2 >+ "+rm"(dst_width), // %3 >+ "=&r"(src_stepx_x12), // %4 >+ "+r"(row1) // %5 >+ ::"memory", >+ "cc", "xmm0", "xmm1", "xmm2", "xmm3"); > } > >-void ScaleARGBCols_SSE2(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_SSE2(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { > intptr_t x0, x1; >- asm volatile ( >- "movd %5,%%xmm2 \n" >- "movd %6,%%xmm3 \n" >- "pshufd $0x0,%%xmm2,%%xmm2 \n" >- "pshufd $0x11,%%xmm3,%%xmm0 \n" >- "paddd %%xmm0,%%xmm2 \n" >- "paddd %%xmm3,%%xmm3 \n" >- "pshufd $0x5,%%xmm3,%%xmm0 \n" >- "paddd %%xmm0,%%xmm2 \n" >- "paddd %%xmm3,%%xmm3 \n" >- "pshufd $0x0,%%xmm3,%%xmm3 \n" >- "pextrw $0x1,%%xmm2,%k0 \n" >- "pextrw $0x3,%%xmm2,%k1 \n" >- "cmp $0x0,%4 \n" >- "jl 99f \n" >- "sub $0x4,%4 \n" >- "jl 49f \n" >- >- LABELALIGN >- "40: \n" >- MEMOPREG(movd,0x00,3,0,4,xmm0) // movd (%3,%0,4),%%xmm0 >- MEMOPREG(movd,0x00,3,1,4,xmm1) // movd (%3,%1,4),%%xmm1 >- "pextrw $0x5,%%xmm2,%k0 \n" >- "pextrw $0x7,%%xmm2,%k1 \n" >- "paddd %%xmm3,%%xmm2 \n" >- "punpckldq %%xmm1,%%xmm0 \n" >- MEMOPREG(movd,0x00,3,0,4,xmm1) // movd (%3,%0,4),%%xmm1 >- MEMOPREG(movd,0x00,3,1,4,xmm4) // movd (%3,%1,4),%%xmm4 >- "pextrw $0x1,%%xmm2,%k0 \n" >- "pextrw $0x3,%%xmm2,%k1 \n" >- "punpckldq %%xmm4,%%xmm1 \n" >- "punpcklqdq %%xmm1,%%xmm0 \n" >- "movdqu %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x10,2) ",%2 \n" >- "sub $0x4,%4 \n" >- "jge 40b \n" >- >- "49: \n" >- "test $0x2,%4 \n" >- "je 29f \n" >- MEMOPREG(movd,0x00,3,0,4,xmm0) // movd (%3,%0,4),%%xmm0 >- MEMOPREG(movd,0x00,3,1,4,xmm1) // movd (%3,%1,4),%%xmm1 >- "pextrw $0x5,%%xmm2,%k0 \n" >- "punpckldq %%xmm1,%%xmm0 \n" >- "movq %%xmm0," MEMACCESS(2) " \n" >- "lea " MEMLEA(0x8,2) ",%2 \n" >- "29: \n" >- "test $0x1,%4 \n" >- "je 99f \n" >- MEMOPREG(movd,0x00,3,0,4,xmm0) // movd (%3,%0,4),%%xmm0 >- "movd %%xmm0," MEMACCESS(2) " \n" >- "99: \n" >- : "=&a"(x0), // %0 >- "=&d"(x1), // %1 >- "+r"(dst_argb), // %2 >- "+r"(src_argb), // %3 >- "+r"(dst_width) // %4 >- : "rm"(x), // %5 >- "rm"(dx) // %6 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4" >- ); >+ asm volatile( >+ "movd %5,%%xmm2 \n" >+ "movd %6,%%xmm3 \n" >+ "pshufd $0x0,%%xmm2,%%xmm2 \n" >+ "pshufd $0x11,%%xmm3,%%xmm0 \n" >+ "paddd %%xmm0,%%xmm2 \n" >+ "paddd %%xmm3,%%xmm3 \n" >+ "pshufd $0x5,%%xmm3,%%xmm0 \n" >+ "paddd %%xmm0,%%xmm2 \n" >+ "paddd %%xmm3,%%xmm3 \n" >+ "pshufd $0x0,%%xmm3,%%xmm3 \n" >+ "pextrw $0x1,%%xmm2,%k0 \n" >+ "pextrw $0x3,%%xmm2,%k1 \n" >+ "cmp $0x0,%4 \n" >+ "jl 99f \n" >+ "sub $0x4,%4 \n" >+ "jl 49f \n" >+ >+ LABELALIGN >+ "40: \n" >+ "movd 0x00(%3,%0,4),%%xmm0 \n" >+ "movd 0x00(%3,%1,4),%%xmm1 \n" >+ "pextrw $0x5,%%xmm2,%k0 \n" >+ "pextrw $0x7,%%xmm2,%k1 \n" >+ "paddd %%xmm3,%%xmm2 \n" >+ "punpckldq %%xmm1,%%xmm0 \n" >+ "movd 0x00(%3,%0,4),%%xmm1 \n" >+ "movd 0x00(%3,%1,4),%%xmm4 \n" >+ "pextrw $0x1,%%xmm2,%k0 \n" >+ "pextrw $0x3,%%xmm2,%k1 \n" >+ "punpckldq %%xmm4,%%xmm1 \n" >+ "punpcklqdq %%xmm1,%%xmm0 \n" >+ "movdqu %%xmm0,(%2) \n" >+ "lea 0x10(%2),%2 \n" >+ "sub $0x4,%4 \n" >+ "jge 40b \n" >+ >+ "49: \n" >+ "test $0x2,%4 \n" >+ "je 29f \n" >+ "movd 0x00(%3,%0,4),%%xmm0 \n" >+ "movd 0x00(%3,%1,4),%%xmm1 \n" >+ "pextrw $0x5,%%xmm2,%k0 \n" >+ "punpckldq %%xmm1,%%xmm0 \n" >+ "movq %%xmm0,(%2) \n" >+ "lea 0x8(%2),%2 \n" >+ "29: \n" >+ "test $0x1,%4 \n" >+ "je 99f \n" >+ "movd 0x00(%3,%0,4),%%xmm0 \n" >+ "movd %%xmm0,(%2) \n" >+ "99: \n" >+ : "=&a"(x0), // %0 >+ "=&d"(x1), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(src_argb), // %3 >+ "+r"(dst_width) // %4 >+ : "rm"(x), // %5 >+ "rm"(dx) // %6 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); > } > > // Reads 4 pixels, duplicates them and writes 8 pixels. > // Alignment requirement: src_argb 16 byte aligned, dst_argb 16 byte aligned. >-void ScaleARGBColsUp2_SSE2(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBColsUp2_SSE2(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { > (void)x; > (void)dx; >- asm volatile ( >- LABELALIGN >- "1: \n" >- "movdqu " MEMACCESS(1) ",%%xmm0 \n" >- "lea " MEMLEA(0x10,1) ",%1 \n" >- "movdqa %%xmm0,%%xmm1 \n" >- "punpckldq %%xmm0,%%xmm0 \n" >- "punpckhdq %%xmm1,%%xmm1 \n" >- "movdqu %%xmm0," MEMACCESS(0) " \n" >- "movdqu %%xmm1," MEMACCESS2(0x10,0) " \n" >- "lea " MEMLEA(0x20,0) ",%0 \n" >- "sub $0x8,%2 \n" >- "jg 1b \n" >- >- : "+r"(dst_argb), // %0 >- "+r"(src_argb), // %1 >- "+r"(dst_width) // %2 >- :: "memory", "cc", NACL_R14 >- "xmm0", "xmm1" >- ); >+ asm volatile( >+ >+ LABELALIGN >+ "1: \n" >+ "movdqu (%1),%%xmm0 \n" >+ "lea 0x10(%1),%1 \n" >+ "movdqa %%xmm0,%%xmm1 \n" >+ "punpckldq %%xmm0,%%xmm0 \n" >+ "punpckhdq %%xmm1,%%xmm1 \n" >+ "movdqu %%xmm0,(%0) \n" >+ "movdqu %%xmm1,0x10(%0) \n" >+ "lea 0x20(%0),%0 \n" >+ "sub $0x8,%2 \n" >+ "jg 1b \n" >+ >+ : "+r"(dst_argb), // %0 >+ "+r"(src_argb), // %1 >+ "+r"(dst_width) // %2 >+ ::"memory", >+ "cc", "xmm0", "xmm1"); > } > > // Shuffle table for arranging 2 pixels into pairs for pmaddubsw >-static uvec8 kShuffleColARGB = { >+static const uvec8 kShuffleColARGB = { > 0u, 4u, 1u, 5u, 2u, 6u, 3u, 7u, // bbggrraa 1st pixel > 8u, 12u, 9u, 13u, 10u, 14u, 11u, 15u // bbggrraa 2nd pixel > }; > > // Shuffle table for duplicating 2 fractions into 8 bytes each >-static uvec8 kShuffleFractions = { >+static const uvec8 kShuffleFractions = { > 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, > }; > > // Bilinear row filtering combines 4x2 -> 4x1. SSSE3 version >-void ScaleARGBFilterCols_SSSE3(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_SSSE3(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { >@@ -1275,67 +1274,65 @@ void ScaleARGBFilterCols_SSSE3(uint8* dst_argb, > "m"(kShuffleFractions) // %1 > ); > >- asm volatile ( >- "movd %5,%%xmm2 \n" >- "movd %6,%%xmm3 \n" >- "pcmpeqb %%xmm6,%%xmm6 \n" >- "psrlw $0x9,%%xmm6 \n" >- "pextrw $0x1,%%xmm2,%k3 \n" >- "sub $0x2,%2 \n" >- "jl 29f \n" >- "movdqa %%xmm2,%%xmm0 \n" >- "paddd %%xmm3,%%xmm0 \n" >- "punpckldq %%xmm0,%%xmm2 \n" >- "punpckldq %%xmm3,%%xmm3 \n" >- "paddd %%xmm3,%%xmm3 \n" >- "pextrw $0x3,%%xmm2,%k4 \n" >- >- LABELALIGN >- "2: \n" >- "movdqa %%xmm2,%%xmm1 \n" >- "paddd %%xmm3,%%xmm2 \n" >- MEMOPREG(movq,0x00,1,3,4,xmm0) // movq (%1,%3,4),%%xmm0 >- "psrlw $0x9,%%xmm1 \n" >- MEMOPREG(movhps,0x00,1,4,4,xmm0) // movhps (%1,%4,4),%%xmm0 >- "pshufb %%xmm5,%%xmm1 \n" >- "pshufb %%xmm4,%%xmm0 \n" >- "pxor %%xmm6,%%xmm1 \n" >- "pmaddubsw %%xmm1,%%xmm0 \n" >- "psrlw $0x7,%%xmm0 \n" >- "pextrw $0x1,%%xmm2,%k3 \n" >- "pextrw $0x3,%%xmm2,%k4 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "movq %%xmm0," MEMACCESS(0) " \n" >- "lea " MEMLEA(0x8,0) ",%0 \n" >- "sub $0x2,%2 \n" >- "jge 2b \n" >- >- LABELALIGN >- "29: \n" >- "add $0x1,%2 \n" >- "jl 99f \n" >- "psrlw $0x9,%%xmm2 \n" >- MEMOPREG(movq,0x00,1,3,4,xmm0) // movq (%1,%3,4),%%xmm0 >- "pshufb %%xmm5,%%xmm2 \n" >- "pshufb %%xmm4,%%xmm0 \n" >- "pxor %%xmm6,%%xmm2 \n" >- "pmaddubsw %%xmm2,%%xmm0 \n" >- "psrlw $0x7,%%xmm0 \n" >- "packuswb %%xmm0,%%xmm0 \n" >- "movd %%xmm0," MEMACCESS(0) " \n" >- >- LABELALIGN >- "99: \n" >- : "+r"(dst_argb), // %0 >- "+r"(src_argb), // %1 >- "+rm"(dst_width), // %2 >- "=&r"(x0), // %3 >- "=&r"(x1) // %4 >- : "rm"(x), // %5 >- "rm"(dx) // %6 >- : "memory", "cc", NACL_R14 >- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" >- ); >+ asm volatile( >+ "movd %5,%%xmm2 \n" >+ "movd %6,%%xmm3 \n" >+ "pcmpeqb %%xmm6,%%xmm6 \n" >+ "psrlw $0x9,%%xmm6 \n" >+ "pextrw $0x1,%%xmm2,%k3 \n" >+ "sub $0x2,%2 \n" >+ "jl 29f \n" >+ "movdqa %%xmm2,%%xmm0 \n" >+ "paddd %%xmm3,%%xmm0 \n" >+ "punpckldq %%xmm0,%%xmm2 \n" >+ "punpckldq %%xmm3,%%xmm3 \n" >+ "paddd %%xmm3,%%xmm3 \n" >+ "pextrw $0x3,%%xmm2,%k4 \n" >+ >+ LABELALIGN >+ "2: \n" >+ "movdqa %%xmm2,%%xmm1 \n" >+ "paddd %%xmm3,%%xmm2 \n" >+ "movq 0x00(%1,%3,4),%%xmm0 \n" >+ "psrlw $0x9,%%xmm1 \n" >+ "movhps 0x00(%1,%4,4),%%xmm0 \n" >+ "pshufb %%xmm5,%%xmm1 \n" >+ "pshufb %%xmm4,%%xmm0 \n" >+ "pxor %%xmm6,%%xmm1 \n" >+ "pmaddubsw %%xmm1,%%xmm0 \n" >+ "psrlw $0x7,%%xmm0 \n" >+ "pextrw $0x1,%%xmm2,%k3 \n" >+ "pextrw $0x3,%%xmm2,%k4 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "movq %%xmm0,(%0) \n" >+ "lea 0x8(%0),%0 \n" >+ "sub $0x2,%2 \n" >+ "jge 2b \n" >+ >+ LABELALIGN >+ "29: \n" >+ "add $0x1,%2 \n" >+ "jl 99f \n" >+ "psrlw $0x9,%%xmm2 \n" >+ "movq 0x00(%1,%3,4),%%xmm0 \n" >+ "pshufb %%xmm5,%%xmm2 \n" >+ "pshufb %%xmm4,%%xmm0 \n" >+ "pxor %%xmm6,%%xmm2 \n" >+ "pmaddubsw %%xmm2,%%xmm0 \n" >+ "psrlw $0x7,%%xmm0 \n" >+ "packuswb %%xmm0,%%xmm0 \n" >+ "movd %%xmm0,(%0) \n" >+ >+ LABELALIGN "99: \n" // clang-format error. >+ >+ : "+r"(dst_argb), // %0 >+ "+r"(src_argb), // %1 >+ "+rm"(dst_width), // %2 >+ "=&r"(x0), // %3 >+ "=&r"(x1) // %4 >+ : "rm"(x), // %5 >+ "rm"(dx) // %6 >+ : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); > } > > // Divide num by div and return as 16.16 fixed point result. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_msa.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_msa.cc >index df1f482be6d9df3d6f43dd93816ce81741fce833..482a521f0d2faae8f5b479abf993b9e95e9b9ed7 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_msa.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_msa.cc >@@ -127,13 +127,13 @@ void ScaleARGBRowDownEven_MSA(const uint8_t* src_argb, > } > } > >-void ScaleARGBRowDownEvenBox_MSA(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_MSA(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > int x; >- const uint8* nxt_argb = src_argb + src_stride; >+ const uint8_t* nxt_argb = src_argb + src_stride; > int32_t stepx = src_stepx * 4; > int64_t data0, data1, data2, data3; > v16u8 src0 = {0}, src1 = {0}, src2 = {0}, src3 = {0}; >@@ -553,8 +553,8 @@ void ScaleAddRow_MSA(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width) { > } > } > >-void ScaleFilterCols_MSA(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols_MSA(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx) { >@@ -630,13 +630,13 @@ void ScaleFilterCols_MSA(uint8* dst_ptr, > } > } > >-void ScaleARGBCols_MSA(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_MSA(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { >- const uint32* src = (const uint32*)(src_argb); >- uint32* dst = (uint32*)(dst_argb); >+ const uint32_t* src = (const uint32_t*)(src_argb); >+ uint32_t* dst = (uint32_t*)(dst_argb); > int j; > v4i32 x_vec = __msa_fill_w(x); > v4i32 dx_vec = __msa_fill_w(dx); >@@ -657,12 +657,12 @@ void ScaleARGBCols_MSA(uint8* dst_argb, > } > } > >-void ScaleARGBFilterCols_MSA(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_MSA(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { >- const uint32* src = (const uint32*)(src_argb); >+ const uint32_t* src = (const uint32_t*)(src_argb); > int j; > v4u32 src0, src1, src2, src3; > v4u32 vec0, vec1, vec2, vec3; >@@ -722,9 +722,9 @@ void ScaleARGBFilterCols_MSA(uint8* dst_argb, > } > } > >-void ScaleRowDown34_MSA(const uint8* src_ptr, >+void ScaleRowDown34_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > int x; > (void)src_stride; >@@ -753,12 +753,12 @@ void ScaleRowDown34_MSA(const uint8* src_ptr, > } > } > >-void ScaleRowDown34_0_Box_MSA(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* d, >+ uint8_t* d, > int dst_width) { >- const uint8* s = src_ptr; >- const uint8* t = src_ptr + src_stride; >+ const uint8_t* s = src_ptr; >+ const uint8_t* t = src_ptr + src_stride; > int x; > v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0, dst1, dst2; > v16u8 vec0, vec1, vec2, vec3, vec4, vec5; >@@ -847,12 +847,12 @@ void ScaleRowDown34_0_Box_MSA(const uint8* src_ptr, > } > } > >-void ScaleRowDown34_1_Box_MSA(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_MSA(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* d, >+ uint8_t* d, > int dst_width) { >- const uint8* s = src_ptr; >- const uint8* t = src_ptr + src_stride; >+ const uint8_t* s = src_ptr; >+ const uint8_t* t = src_ptr + src_stride; > int x; > v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0, dst1, dst2; > v16u8 vec0, vec1, vec2, vec3, vec4, vec5; >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_neon.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_neon.cc >index b03a828213d8b99bc369b0da23f28b146b165e50..459a2995dfe7530eaac460864436387d2130224c 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_neon.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_neon.cc >@@ -23,9 +23,9 @@ extern "C" { > // Provided by Fritz Koenig > > // Read 32x1 throw away even pixels, and write 16x1. >-void ScaleRowDown2_NEON(const uint8* src_ptr, >+void ScaleRowDown2_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -44,9 +44,9 @@ void ScaleRowDown2_NEON(const uint8* src_ptr, > } > > // Read 32x1 average down and write 16x1. >-void ScaleRowDown2Linear_NEON(const uint8* src_ptr, >+void ScaleRowDown2Linear_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -65,9 +65,9 @@ void ScaleRowDown2Linear_NEON(const uint8* src_ptr, > } > > // Read 32x2 average down and write 16x1. >-void ScaleRowDown2Box_NEON(const uint8* src_ptr, >+void ScaleRowDown2Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > asm volatile( > // change the stride to row 2 pointer >@@ -95,9 +95,9 @@ void ScaleRowDown2Box_NEON(const uint8* src_ptr, > ); > } > >-void ScaleRowDown4_NEON(const uint8* src_ptr, >+void ScaleRowDown4_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -113,13 +113,13 @@ void ScaleRowDown4_NEON(const uint8* src_ptr, > : "q0", "q1", "memory", "cc"); > } > >-void ScaleRowDown4Box_NEON(const uint8* src_ptr, >+void ScaleRowDown4Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { >- const uint8* src_ptr1 = src_ptr + src_stride; >- const uint8* src_ptr2 = src_ptr + src_stride * 2; >- const uint8* src_ptr3 = src_ptr + src_stride * 3; >+ const uint8_t* src_ptr1 = src_ptr + src_stride; >+ const uint8_t* src_ptr2 = src_ptr + src_stride * 2; >+ const uint8_t* src_ptr3 = src_ptr + src_stride * 3; > asm volatile( > "1: \n" > "vld1.8 {q0}, [%0]! \n" // load up 16x4 >@@ -149,9 +149,9 @@ void ScaleRowDown4Box_NEON(const uint8* src_ptr, > // Down scale from 4 to 3 pixels. Use the neon multilane read/write > // to load up the every 4th pixel into a 4 different registers. > // Point samples 32 pixels to 24 pixels. >-void ScaleRowDown34_NEON(const uint8* src_ptr, >+void ScaleRowDown34_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -168,9 +168,9 @@ void ScaleRowDown34_NEON(const uint8* src_ptr, > : "d0", "d1", "d2", "d3", "memory", "cc"); > } > >-void ScaleRowDown34_0_Box_NEON(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > asm volatile( > "vmov.u8 d24, #3 \n" >@@ -225,9 +225,9 @@ void ScaleRowDown34_0_Box_NEON(const uint8* src_ptr, > "cc"); > } > >-void ScaleRowDown34_1_Box_NEON(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > asm volatile( > "vmov.u8 d24, #3 \n" >@@ -264,18 +264,21 @@ void ScaleRowDown34_1_Box_NEON(const uint8* src_ptr, > } > > #define HAS_SCALEROWDOWN38_NEON >-static uvec8 kShuf38 = {0, 3, 6, 8, 11, 14, 16, 19, 22, 24, 27, 30, 0, 0, 0, 0}; >-static uvec8 kShuf38_2 = {0, 8, 16, 2, 10, 17, 4, 12, >- 18, 6, 14, 19, 0, 0, 0, 0}; >-static vec16 kMult38_Div6 = {65536 / 12, 65536 / 12, 65536 / 12, 65536 / 12, >- 65536 / 12, 65536 / 12, 65536 / 12, 65536 / 12}; >-static vec16 kMult38_Div9 = {65536 / 18, 65536 / 18, 65536 / 18, 65536 / 18, >- 65536 / 18, 65536 / 18, 65536 / 18, 65536 / 18}; >+static const uvec8 kShuf38 = {0, 3, 6, 8, 11, 14, 16, 19, >+ 22, 24, 27, 30, 0, 0, 0, 0}; >+static const uvec8 kShuf38_2 = {0, 8, 16, 2, 10, 17, 4, 12, >+ 18, 6, 14, 19, 0, 0, 0, 0}; >+static const vec16 kMult38_Div6 = {65536 / 12, 65536 / 12, 65536 / 12, >+ 65536 / 12, 65536 / 12, 65536 / 12, >+ 65536 / 12, 65536 / 12}; >+static const vec16 kMult38_Div9 = {65536 / 18, 65536 / 18, 65536 / 18, >+ 65536 / 18, 65536 / 18, 65536 / 18, >+ 65536 / 18, 65536 / 18}; > > // 32 -> 12 >-void ScaleRowDown38_NEON(const uint8* src_ptr, >+void ScaleRowDown38_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -296,11 +299,11 @@ void ScaleRowDown38_NEON(const uint8* src_ptr, > } > > // 32x3 -> 12x1 >-void OMITFP ScaleRowDown38_3_Box_NEON(const uint8* src_ptr, >+void OMITFP ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { >- const uint8* src_ptr1 = src_ptr + src_stride * 2; >+ const uint8_t* src_ptr1 = src_ptr + src_stride * 2; > > asm volatile( > "vld1.16 {q13}, [%5] \n" >@@ -408,9 +411,9 @@ void OMITFP ScaleRowDown38_3_Box_NEON(const uint8* src_ptr, > } > > // 32x2 -> 12x1 >-void ScaleRowDown38_2_Box_NEON(const uint8* src_ptr, >+void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > asm volatile( > "vld1.16 {q13}, [%4] \n" >@@ -501,12 +504,12 @@ void ScaleRowDown38_2_Box_NEON(const uint8* src_ptr, > : "q0", "q1", "q2", "q3", "q13", "q14", "memory", "cc"); > } > >-void ScaleAddRows_NEON(const uint8* src_ptr, >+void ScaleAddRows_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst_ptr, >+ uint16_t* dst_ptr, > int src_width, > int src_height) { >- const uint8* src_tmp; >+ const uint8_t* src_tmp; > asm volatile( > "1: \n" > "mov %0, %1 \n" >@@ -544,17 +547,17 @@ void ScaleAddRows_NEON(const uint8* src_ptr, > "vld2.8 {d6[" #n "], d7[" #n "]}, [%6] \n" > > // The NEON version mimics this formula (from row_common.cc): >-// #define BLENDER(a, b, f) (uint8)((int)(a) + >+// #define BLENDER(a, b, f) (uint8_t)((int)(a) + > // ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) > >-void ScaleFilterCols_NEON(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx) { > int dx_offset[4] = {0, 1, 2, 3}; > int* tmp = dx_offset; >- const uint8* src_tmp = src_ptr; >+ const uint8_t* src_tmp = src_ptr; > asm volatile ( > "vdup.32 q0, %3 \n" // x > "vdup.32 q1, %4 \n" // dx >@@ -612,8 +615,8 @@ void ScaleFilterCols_NEON(uint8* dst_ptr, > #undef LOAD2_DATA8_LANE > > // 16x2 -> 16x1 >-void ScaleFilterRows_NEON(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterRows_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride, > int dst_width, > int source_y_fraction) { >@@ -696,9 +699,9 @@ void ScaleFilterRows_NEON(uint8* dst_ptr, > : "q0", "q1", "d4", "d5", "q13", "q14", "memory", "cc"); > } > >-void ScaleARGBRowDown2_NEON(const uint8* src_ptr, >+void ScaleARGBRowDown2_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -724,9 +727,9 @@ void ScaleARGBRowDown2_NEON(const uint8* src_ptr, > // 54: f942 038d vst2.32 {d16-d19}, [r2]! > // 58: d1f5 bne.n 46 <ScaleARGBRowDown2_C+0x46> > >-void ScaleARGBRowDown2Linear_NEON(const uint8* src_argb, >+void ScaleARGBRowDown2Linear_NEON(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -746,9 +749,9 @@ void ScaleARGBRowDown2Linear_NEON(const uint8* src_argb, > ); > } > >-void ScaleARGBRowDown2Box_NEON(const uint8* src_ptr, >+void ScaleARGBRowDown2Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > asm volatile( > // change the stride to row 2 pointer >@@ -783,10 +786,10 @@ void ScaleARGBRowDown2Box_NEON(const uint8* src_ptr, > > // Reads 4 pixels at a time. > // Alignment requirement: src_argb 4 byte aligned. >-void ScaleARGBRowDownEven_NEON(const uint8* src_argb, >+void ScaleARGBRowDownEven_NEON(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -808,10 +811,10 @@ void ScaleARGBRowDownEven_NEON(const uint8* src_argb, > > // Reads 4 pixels at a time. > // Alignment requirement: src_argb 4 byte aligned. >-void ScaleARGBRowDownEvenBox_NEON(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_NEON(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > asm volatile( > "mov r12, %4, lsl #2 \n" >@@ -854,13 +857,13 @@ void ScaleARGBRowDownEvenBox_NEON(const uint8* src_argb, > "add %3, %3, %4 \n" \ > "vld1.32 {" #dn "[" #n "]}, [%6] \n" > >-void ScaleARGBCols_NEON(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_NEON(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { > int tmp; >- const uint8* src_tmp = src_argb; >+ const uint8_t* src_tmp = src_argb; > asm volatile( > "1: \n" > // clang-format off >@@ -897,14 +900,14 @@ void ScaleARGBCols_NEON(uint8* dst_argb, > "add %3, %3, %4 \n" \ > "vld2.32 {" #dn1 "[" #n "], " #dn2 "[" #n "]}, [%6] \n" > >-void ScaleARGBFilterCols_NEON(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_NEON(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { > int dx_offset[4] = {0, 1, 2, 3}; > int* tmp = dx_offset; >- const uint8* src_tmp = src_argb; >+ const uint8_t* src_tmp = src_argb; > asm volatile ( > "vdup.32 q0, %3 \n" // x > "vdup.32 q1, %4 \n" // dx >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_neon64.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_neon64.cc >index 93fe67bf1e6b7364939ebda36dcaa9cd62857bee..494a9cfbfbe3c383e5ebf872c098a832fb82b238 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_neon64.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_neon64.cc >@@ -21,9 +21,9 @@ extern "C" { > #if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) > > // Read 32x1 throw away even pixels, and write 16x1. >-void ScaleRowDown2_NEON(const uint8* src_ptr, >+void ScaleRowDown2_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -42,9 +42,9 @@ void ScaleRowDown2_NEON(const uint8* src_ptr, > } > > // Read 32x1 average down and write 16x1. >-void ScaleRowDown2Linear_NEON(const uint8* src_ptr, >+void ScaleRowDown2Linear_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -64,9 +64,9 @@ void ScaleRowDown2Linear_NEON(const uint8* src_ptr, > } > > // Read 32x2 average down and write 16x1. >-void ScaleRowDown2Box_NEON(const uint8* src_ptr, >+void ScaleRowDown2Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > asm volatile( > // change the stride to row 2 pointer >@@ -92,9 +92,9 @@ void ScaleRowDown2Box_NEON(const uint8* src_ptr, > ); > } > >-void ScaleRowDown4_NEON(const uint8* src_ptr, >+void ScaleRowDown4_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -110,13 +110,13 @@ void ScaleRowDown4_NEON(const uint8* src_ptr, > : "v0", "v1", "v2", "v3", "memory", "cc"); > } > >-void ScaleRowDown4Box_NEON(const uint8* src_ptr, >+void ScaleRowDown4Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { >- const uint8* src_ptr1 = src_ptr + src_stride; >- const uint8* src_ptr2 = src_ptr + src_stride * 2; >- const uint8* src_ptr3 = src_ptr + src_stride * 3; >+ const uint8_t* src_ptr1 = src_ptr + src_stride; >+ const uint8_t* src_ptr2 = src_ptr + src_stride * 2; >+ const uint8_t* src_ptr3 = src_ptr + src_stride * 3; > asm volatile( > "1: \n" > "ld1 {v0.16b}, [%0], #16 \n" // load up 16x4 >@@ -145,9 +145,9 @@ void ScaleRowDown4Box_NEON(const uint8* src_ptr, > // Down scale from 4 to 3 pixels. Use the neon multilane read/write > // to load up the every 4th pixel into a 4 different registers. > // Point samples 32 pixels to 24 pixels. >-void ScaleRowDown34_NEON(const uint8* src_ptr, >+void ScaleRowDown34_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -164,9 +164,9 @@ void ScaleRowDown34_NEON(const uint8* src_ptr, > : "v0", "v1", "v2", "v3", "memory", "cc"); > } > >-void ScaleRowDown34_0_Box_NEON(const uint8* src_ptr, >+void ScaleRowDown34_0_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > asm volatile( > "movi v20.8b, #3 \n" >@@ -221,9 +221,9 @@ void ScaleRowDown34_0_Box_NEON(const uint8* src_ptr, > "v19", "v20", "memory", "cc"); > } > >-void ScaleRowDown34_1_Box_NEON(const uint8* src_ptr, >+void ScaleRowDown34_1_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > asm volatile( > "movi v20.8b, #3 \n" >@@ -261,18 +261,21 @@ void ScaleRowDown34_1_Box_NEON(const uint8* src_ptr, > : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", "memory", "cc"); > } > >-static uvec8 kShuf38 = {0, 3, 6, 8, 11, 14, 16, 19, 22, 24, 27, 30, 0, 0, 0, 0}; >-static uvec8 kShuf38_2 = {0, 16, 32, 2, 18, 33, 4, 20, >- 34, 6, 22, 35, 0, 0, 0, 0}; >-static vec16 kMult38_Div6 = {65536 / 12, 65536 / 12, 65536 / 12, 65536 / 12, >- 65536 / 12, 65536 / 12, 65536 / 12, 65536 / 12}; >-static vec16 kMult38_Div9 = {65536 / 18, 65536 / 18, 65536 / 18, 65536 / 18, >- 65536 / 18, 65536 / 18, 65536 / 18, 65536 / 18}; >+static const uvec8 kShuf38 = {0, 3, 6, 8, 11, 14, 16, 19, >+ 22, 24, 27, 30, 0, 0, 0, 0}; >+static const uvec8 kShuf38_2 = {0, 16, 32, 2, 18, 33, 4, 20, >+ 34, 6, 22, 35, 0, 0, 0, 0}; >+static const vec16 kMult38_Div6 = {65536 / 12, 65536 / 12, 65536 / 12, >+ 65536 / 12, 65536 / 12, 65536 / 12, >+ 65536 / 12, 65536 / 12}; >+static const vec16 kMult38_Div9 = {65536 / 18, 65536 / 18, 65536 / 18, >+ 65536 / 18, 65536 / 18, 65536 / 18, >+ 65536 / 18, 65536 / 18}; > > // 32 -> 12 >-void ScaleRowDown38_NEON(const uint8* src_ptr, >+void ScaleRowDown38_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -292,11 +295,11 @@ void ScaleRowDown38_NEON(const uint8* src_ptr, > } > > // 32x3 -> 12x1 >-void OMITFP ScaleRowDown38_3_Box_NEON(const uint8* src_ptr, >+void OMITFP ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { >- const uint8* src_ptr1 = src_ptr + src_stride * 2; >+ const uint8_t* src_ptr1 = src_ptr + src_stride * 2; > ptrdiff_t tmp_src_stride = src_stride; > > asm volatile( >@@ -412,9 +415,9 @@ void OMITFP ScaleRowDown38_3_Box_NEON(const uint8* src_ptr, > } > > // 32x2 -> 12x1 >-void ScaleRowDown38_2_Box_NEON(const uint8* src_ptr, >+void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > // TODO(fbarchard): use src_stride directly for clang 3.5+. > ptrdiff_t tmp_src_stride = src_stride; >@@ -512,12 +515,12 @@ void ScaleRowDown38_2_Box_NEON(const uint8* src_ptr, > "v19", "v30", "v31", "memory", "cc"); > } > >-void ScaleAddRows_NEON(const uint8* src_ptr, >+void ScaleAddRows_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst_ptr, >+ uint16_t* dst_ptr, > int src_width, > int src_height) { >- const uint8* src_tmp; >+ const uint8_t* src_tmp; > asm volatile( > "1: \n" > "mov %0, %1 \n" >@@ -555,19 +558,19 @@ void ScaleAddRows_NEON(const uint8* src_ptr, > "ld2 {v4.b, v5.b}[" #n "], [%6] \n" > > // The NEON version mimics this formula (from row_common.cc): >-// #define BLENDER(a, b, f) (uint8)((int)(a) + >+// #define BLENDER(a, b, f) (uint8_t)((int)(a) + > // ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) > >-void ScaleFilterCols_NEON(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterCols_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx) { > int dx_offset[4] = {0, 1, 2, 3}; > int* tmp = dx_offset; >- const uint8* src_tmp = src_ptr; >- int64 x64 = (int64)x; // NOLINT >- int64 dx64 = (int64)dx; // NOLINT >+ const uint8_t* src_tmp = src_ptr; >+ int64_t x64 = (int64_t)x; // NOLINT >+ int64_t dx64 = (int64_t)dx; // NOLINT > asm volatile ( > "dup v0.4s, %w3 \n" // x > "dup v1.4s, %w4 \n" // dx >@@ -625,8 +628,8 @@ void ScaleFilterCols_NEON(uint8* dst_ptr, > #undef LOAD2_DATA8_LANE > > // 16x2 -> 16x1 >-void ScaleFilterRows_NEON(uint8* dst_ptr, >- const uint8* src_ptr, >+void ScaleFilterRows_NEON(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > ptrdiff_t src_stride, > int dst_width, > int source_y_fraction) { >@@ -710,9 +713,9 @@ void ScaleFilterRows_NEON(uint8* dst_ptr, > : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "memory", "cc"); > } > >-void ScaleARGBRowDown2_NEON(const uint8* src_ptr, >+void ScaleARGBRowDown2_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -731,9 +734,9 @@ void ScaleARGBRowDown2_NEON(const uint8* src_ptr, > ); > } > >-void ScaleARGBRowDown2Linear_NEON(const uint8* src_argb, >+void ScaleARGBRowDown2Linear_NEON(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -754,9 +757,9 @@ void ScaleARGBRowDown2Linear_NEON(const uint8* src_argb, > ); > } > >-void ScaleARGBRowDown2Box_NEON(const uint8* src_ptr, >+void ScaleARGBRowDown2Box_NEON(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst, >+ uint8_t* dst, > int dst_width) { > asm volatile( > // change the stride to row 2 pointer >@@ -789,10 +792,10 @@ void ScaleARGBRowDown2Box_NEON(const uint8* src_ptr, > > // Reads 4 pixels at a time. > // Alignment requirement: src_argb 4 byte aligned. >-void ScaleARGBRowDownEven_NEON(const uint8* src_argb, >+void ScaleARGBRowDownEven_NEON(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > (void)src_stride; > asm volatile( >@@ -804,10 +807,10 @@ void ScaleARGBRowDownEven_NEON(const uint8* src_argb, > "subs %w2, %w2, #4 \n" // 4 pixels per loop. > "st1 {v0.16b}, [%1], #16 \n" > "b.gt 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(dst_argb), // %1 >- "+r"(dst_width) // %2 >- : "r"((int64)(src_stepx * 4)) // %3 >+ : "+r"(src_argb), // %0 >+ "+r"(dst_argb), // %1 >+ "+r"(dst_width) // %2 >+ : "r"((int64_t)(src_stepx * 4)) // %3 > : "memory", "cc", "v0"); > } > >@@ -815,10 +818,10 @@ void ScaleARGBRowDownEven_NEON(const uint8* src_argb, > // Alignment requirement: src_argb 4 byte aligned. > // TODO(Yang Zhang): Might be worth another optimization pass in future. > // It could be upgraded to 8 pixels at a time to start with. >-void ScaleARGBRowDownEvenBox_NEON(const uint8* src_argb, >+void ScaleARGBRowDownEvenBox_NEON(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > asm volatile( > "add %1, %1, %0 \n" >@@ -848,11 +851,11 @@ void ScaleARGBRowDownEvenBox_NEON(const uint8* src_argb, > "subs %w3, %w3, #4 \n" // 4 pixels per loop. > "st1 {v0.16b}, [%2], #16 \n" > "b.gt 1b \n" >- : "+r"(src_argb), // %0 >- "+r"(src_stride), // %1 >- "+r"(dst_argb), // %2 >- "+r"(dst_width) // %3 >- : "r"((int64)(src_stepx * 4)) // %4 >+ : "+r"(src_argb), // %0 >+ "+r"(src_stride), // %1 >+ "+r"(dst_argb), // %2 >+ "+r"(dst_width) // %3 >+ : "r"((int64_t)(src_stepx * 4)) // %4 > : "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); > } > >@@ -864,15 +867,15 @@ void ScaleARGBRowDownEvenBox_NEON(const uint8* src_argb, > "add %3, %3, %4 \n" \ > "ld1 {" #vn ".s}[" #n "], [%6] \n" > >-void ScaleARGBCols_NEON(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBCols_NEON(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { >- const uint8* src_tmp = src_argb; >- int64 x64 = (int64)x; // NOLINT >- int64 dx64 = (int64)dx; // NOLINT >- int64 tmp64; >+ const uint8_t* src_tmp = src_argb; >+ int64_t x64 = (int64_t)x; // NOLINT >+ int64_t dx64 = (int64_t)dx; // NOLINT >+ int64_t tmp64; > asm volatile( > "1: \n" > // clang-format off >@@ -909,16 +912,16 @@ void ScaleARGBCols_NEON(uint8* dst_argb, > "add %3, %3, %4 \n" \ > "ld2 {" #vn1 ".s, " #vn2 ".s}[" #n "], [%6] \n" > >-void ScaleARGBFilterCols_NEON(uint8* dst_argb, >- const uint8* src_argb, >+void ScaleARGBFilterCols_NEON(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { > int dx_offset[4] = {0, 1, 2, 3}; > int* tmp = dx_offset; >- const uint8* src_tmp = src_argb; >- int64 x64 = (int64)x; // NOLINT >- int64 dx64 = (int64)dx; // NOLINT >+ const uint8_t* src_tmp = src_argb; >+ int64_t x64 = (int64_t)x; // NOLINT >+ int64_t dx64 = (int64_t)dx; // NOLINT > asm volatile ( > "dup v0.4s, %w3 \n" // x > "dup v1.4s, %w4 \n" // dx >@@ -975,9 +978,9 @@ void ScaleARGBFilterCols_NEON(uint8* dst_argb, > #undef LOAD2_DATA32_LANE > > // Read 16x2 average down and write 8x1. >-void ScaleRowDown2Box_16_NEON(const uint16* src_ptr, >+void ScaleRowDown2Box_16_NEON(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width) { > asm volatile( > // change the stride to row 2 pointer >@@ -1005,9 +1008,9 @@ void ScaleRowDown2Box_16_NEON(const uint16* src_ptr, > > // Read 8x2 upsample with filtering and write 16x1. > // Actually reads an extra pixel, so 9x2. >-void ScaleRowUp2_16_NEON(const uint16* src_ptr, >+void ScaleRowUp2_16_NEON(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width) { > asm volatile( > "add %1, %0, %1, lsl #1 \n" // ptr + stide * 2 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_win.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_win.cc >index b5fd6638262f98aea296171847413c2061b43b3f..c5fc86f3e96cd449efd66d5b4a7b060328f8c595 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_win.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/scale_win.cc >@@ -20,77 +20,78 @@ extern "C" { > #if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) > > // Offsets for source bytes 0 to 9 >-static uvec8 kShuf0 = {0, 1, 3, 4, 5, 7, 8, 9, >- 128, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShuf0 = {0, 1, 3, 4, 5, 7, 8, 9, >+ 128, 128, 128, 128, 128, 128, 128, 128}; > > // Offsets for source bytes 11 to 20 with 8 subtracted = 3 to 12. >-static uvec8 kShuf1 = {3, 4, 5, 7, 8, 9, 11, 12, >- 128, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShuf1 = {3, 4, 5, 7, 8, 9, 11, 12, >+ 128, 128, 128, 128, 128, 128, 128, 128}; > > // Offsets for source bytes 21 to 31 with 16 subtracted = 5 to 31. >-static uvec8 kShuf2 = {5, 7, 8, 9, 11, 12, 13, 15, >- 128, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShuf2 = {5, 7, 8, 9, 11, 12, 13, 15, >+ 128, 128, 128, 128, 128, 128, 128, 128}; > > // Offsets for source bytes 0 to 10 >-static uvec8 kShuf01 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10}; >+static const uvec8 kShuf01 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10}; > > // Offsets for source bytes 10 to 21 with 8 subtracted = 3 to 13. >-static uvec8 kShuf11 = {2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 12, 13}; >+static const uvec8 kShuf11 = {2, 3, 4, 5, 5, 6, 6, 7, >+ 8, 9, 9, 10, 10, 11, 12, 13}; > > // Offsets for source bytes 21 to 31 with 16 subtracted = 5 to 31. >-static uvec8 kShuf21 = {5, 6, 6, 7, 8, 9, 9, 10, >- 10, 11, 12, 13, 13, 14, 14, 15}; >+static const uvec8 kShuf21 = {5, 6, 6, 7, 8, 9, 9, 10, >+ 10, 11, 12, 13, 13, 14, 14, 15}; > > // Coefficients for source bytes 0 to 10 >-static uvec8 kMadd01 = {3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2}; >+static const uvec8 kMadd01 = {3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2}; > > // Coefficients for source bytes 10 to 21 >-static uvec8 kMadd11 = {1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1}; >+static const uvec8 kMadd11 = {1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1}; > > // Coefficients for source bytes 21 to 31 >-static uvec8 kMadd21 = {2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3}; >+static const uvec8 kMadd21 = {2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3}; > > // Coefficients for source bytes 21 to 31 >-static vec16 kRound34 = {2, 2, 2, 2, 2, 2, 2, 2}; >+static const vec16 kRound34 = {2, 2, 2, 2, 2, 2, 2, 2}; > >-static uvec8 kShuf38a = {0, 3, 6, 8, 11, 14, 128, 128, >- 128, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShuf38a = {0, 3, 6, 8, 11, 14, 128, 128, >+ 128, 128, 128, 128, 128, 128, 128, 128}; > >-static uvec8 kShuf38b = {128, 128, 128, 128, 128, 128, 0, 3, >- 6, 8, 11, 14, 128, 128, 128, 128}; >+static const uvec8 kShuf38b = {128, 128, 128, 128, 128, 128, 0, 3, >+ 6, 8, 11, 14, 128, 128, 128, 128}; > > // Arrange words 0,3,6 into 0,1,2 >-static uvec8 kShufAc = {0, 1, 6, 7, 12, 13, 128, 128, >- 128, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShufAc = {0, 1, 6, 7, 12, 13, 128, 128, >+ 128, 128, 128, 128, 128, 128, 128, 128}; > > // Arrange words 0,3,6 into 3,4,5 >-static uvec8 kShufAc3 = {128, 128, 128, 128, 128, 128, 0, 1, >- 6, 7, 12, 13, 128, 128, 128, 128}; >+static const uvec8 kShufAc3 = {128, 128, 128, 128, 128, 128, 0, 1, >+ 6, 7, 12, 13, 128, 128, 128, 128}; > > // Scaling values for boxes of 3x3 and 2x3 >-static uvec16 kScaleAc33 = {65536 / 9, 65536 / 9, 65536 / 6, 65536 / 9, >- 65536 / 9, 65536 / 6, 0, 0}; >+static const uvec16 kScaleAc33 = {65536 / 9, 65536 / 9, 65536 / 6, 65536 / 9, >+ 65536 / 9, 65536 / 6, 0, 0}; > > // Arrange first value for pixels 0,1,2,3,4,5 >-static uvec8 kShufAb0 = {0, 128, 3, 128, 6, 128, 8, 128, >- 11, 128, 14, 128, 128, 128, 128, 128}; >+static const uvec8 kShufAb0 = {0, 128, 3, 128, 6, 128, 8, 128, >+ 11, 128, 14, 128, 128, 128, 128, 128}; > > // Arrange second value for pixels 0,1,2,3,4,5 >-static uvec8 kShufAb1 = {1, 128, 4, 128, 7, 128, 9, 128, >- 12, 128, 15, 128, 128, 128, 128, 128}; >+static const uvec8 kShufAb1 = {1, 128, 4, 128, 7, 128, 9, 128, >+ 12, 128, 15, 128, 128, 128, 128, 128}; > > // Arrange third value for pixels 0,1,2,3,4,5 >-static uvec8 kShufAb2 = {2, 128, 5, 128, 128, 128, 10, 128, >- 13, 128, 128, 128, 128, 128, 128, 128}; >+static const uvec8 kShufAb2 = {2, 128, 5, 128, 128, 128, 10, 128, >+ 13, 128, 128, 128, 128, 128, 128, 128}; > > // Scaling values for boxes of 3x2 and 2x2 >-static uvec16 kScaleAb2 = {65536 / 3, 65536 / 3, 65536 / 2, 65536 / 3, >- 65536 / 3, 65536 / 2, 0, 0}; >+static const uvec16 kScaleAb2 = {65536 / 3, 65536 / 3, 65536 / 2, 65536 / 3, >+ 65536 / 3, 65536 / 2, 0, 0}; > > // Reads 32 pixels, throws half away and writes 16 pixels. >-__declspec(naked) void ScaleRowDown2_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown2_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > mov eax, [esp + 4] // src_ptr >@@ -115,9 +116,9 @@ __declspec(naked) void ScaleRowDown2_SSSE3(const uint8* src_ptr, > } > > // Blends 32x1 rectangle to 16x1. >-__declspec(naked) void ScaleRowDown2Linear_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown2Linear_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > mov eax, [esp + 4] // src_ptr >@@ -149,9 +150,9 @@ __declspec(naked) void ScaleRowDown2Linear_SSSE3(const uint8* src_ptr, > } > > // Blends 32x2 rectangle to 16x1. >-__declspec(naked) void ScaleRowDown2Box_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown2Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > push esi >@@ -194,9 +195,9 @@ __declspec(naked) void ScaleRowDown2Box_SSSE3(const uint8* src_ptr, > > #ifdef HAS_SCALEROWDOWN2_AVX2 > // Reads 64 pixels, throws half away and writes 32 pixels. >-__declspec(naked) void ScaleRowDown2_AVX2(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown2_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > mov eax, [esp + 4] // src_ptr >@@ -223,9 +224,9 @@ __declspec(naked) void ScaleRowDown2_AVX2(const uint8* src_ptr, > } > > // Blends 64x1 rectangle to 32x1. >-__declspec(naked) void ScaleRowDown2Linear_AVX2(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown2Linear_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > mov eax, [esp + 4] // src_ptr >@@ -261,9 +262,9 @@ __declspec(naked) void ScaleRowDown2Linear_AVX2(const uint8* src_ptr, > // For rounding, average = (sum + 2) / 4 > // becomes average((sum >> 1), 0) > // Blends 64x2 rectangle to 32x1. >-__declspec(naked) void ScaleRowDown2Box_AVX2(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown2Box_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > push esi >@@ -308,9 +309,9 @@ __declspec(naked) void ScaleRowDown2Box_AVX2(const uint8* src_ptr, > #endif // HAS_SCALEROWDOWN2_AVX2 > > // Point samples 32 pixels to 8 pixels. >-__declspec(naked) void ScaleRowDown4_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown4_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > mov eax, [esp + 4] // src_ptr >@@ -340,9 +341,9 @@ __declspec(naked) void ScaleRowDown4_SSSE3(const uint8* src_ptr, > } > > // Blends 32x4 rectangle to 8x1. >-__declspec(naked) void ScaleRowDown4Box_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown4Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > push esi >@@ -399,9 +400,9 @@ __declspec(naked) void ScaleRowDown4Box_SSSE3(const uint8* src_ptr, > > #ifdef HAS_SCALEROWDOWN4_AVX2 > // Point samples 64 pixels to 16 pixels. >-__declspec(naked) void ScaleRowDown4_AVX2(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown4_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > mov eax, [esp + 4] // src_ptr >@@ -434,9 +435,9 @@ __declspec(naked) void ScaleRowDown4_AVX2(const uint8* src_ptr, > } > > // Blends 64x4 rectangle to 16x1. >-__declspec(naked) void ScaleRowDown4Box_AVX2(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown4Box_AVX2(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > push esi >@@ -498,9 +499,9 @@ __declspec(naked) void ScaleRowDown4Box_AVX2(const uint8* src_ptr, > // Produces three 8 byte values. For each 8 bytes, 16 bytes are read. > // Then shuffled to do the scaling. > >-__declspec(naked) void ScaleRowDown34_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown34_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > mov eax, [esp + 4] // src_ptr >@@ -546,9 +547,9 @@ __declspec(naked) void ScaleRowDown34_SSSE3(const uint8* src_ptr, > // xmm7 kRound34 > > // Note that movdqa+palign may be better than movdqu. >-__declspec(naked) void ScaleRowDown34_1_Box_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown34_1_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > push esi >@@ -603,9 +604,9 @@ __declspec(naked) void ScaleRowDown34_1_Box_SSSE3(const uint8* src_ptr, > } > > // Note that movdqa+palign may be better than movdqu. >-__declspec(naked) void ScaleRowDown34_0_Box_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown34_0_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > push esi >@@ -665,9 +666,9 @@ __declspec(naked) void ScaleRowDown34_0_Box_SSSE3(const uint8* src_ptr, > // 3/8 point sampler > > // Scale 32 pixels to 12 >-__declspec(naked) void ScaleRowDown38_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown38_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > mov eax, [esp + 4] // src_ptr >@@ -697,9 +698,9 @@ __declspec(naked) void ScaleRowDown38_SSSE3(const uint8* src_ptr, > } > > // Scale 16x3 pixels to 6x1 with interpolation >-__declspec(naked) void ScaleRowDown38_3_Box_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown38_3_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > push esi >@@ -762,9 +763,9 @@ __declspec(naked) void ScaleRowDown38_3_Box_SSSE3(const uint8* src_ptr, > } > > // Scale 16x2 pixels to 6x1 with interpolation >-__declspec(naked) void ScaleRowDown38_2_Box_SSSE3(const uint8* src_ptr, >+__declspec(naked) void ScaleRowDown38_2_Box_SSSE3(const uint8_t* src_ptr, > ptrdiff_t src_stride, >- uint8* dst_ptr, >+ uint8_t* dst_ptr, > int dst_width) { > __asm { > push esi >@@ -807,8 +808,8 @@ __declspec(naked) void ScaleRowDown38_2_Box_SSSE3(const uint8* src_ptr, > } > > // Reads 16 bytes and accumulates to 16 shorts at a time. >-__declspec(naked) void ScaleAddRow_SSE2(const uint8* src_ptr, >- uint16* dst_ptr, >+__declspec(naked) void ScaleAddRow_SSE2(const uint8_t* src_ptr, >+ uint16_t* dst_ptr, > int src_width) { > __asm { > mov eax, [esp + 4] // src_ptr >@@ -838,8 +839,8 @@ __declspec(naked) void ScaleAddRow_SSE2(const uint8* src_ptr, > > #ifdef HAS_SCALEADDROW_AVX2 > // Reads 32 bytes and accumulates to 32 shorts at a time. >-__declspec(naked) void ScaleAddRow_AVX2(const uint8* src_ptr, >- uint16* dst_ptr, >+__declspec(naked) void ScaleAddRow_AVX2(const uint8_t* src_ptr, >+ uint16_t* dst_ptr, > int src_width) { > __asm { > mov eax, [esp + 4] // src_ptr >@@ -870,16 +871,16 @@ __declspec(naked) void ScaleAddRow_AVX2(const uint8* src_ptr, > > // Constant for making pixels signed to avoid pmaddubsw > // saturation. >-static uvec8 kFsub80 = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, >- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; >+static const uvec8 kFsub80 = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, >+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; > > // Constant for making pixels unsigned and adding .5 for rounding. >-static uvec16 kFadd40 = {0x4040, 0x4040, 0x4040, 0x4040, >- 0x4040, 0x4040, 0x4040, 0x4040}; >+static const uvec16 kFadd40 = {0x4040, 0x4040, 0x4040, 0x4040, >+ 0x4040, 0x4040, 0x4040, 0x4040}; > > // Bilinear column filtering. SSSE3 version. >-__declspec(naked) void ScaleFilterCols_SSSE3(uint8* dst_ptr, >- const uint8* src_ptr, >+__declspec(naked) void ScaleFilterCols_SSSE3(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx) { >@@ -964,8 +965,8 @@ __declspec(naked) void ScaleFilterCols_SSSE3(uint8* dst_ptr, > } > > // Reads 16 pixels, duplicates them and writes 32 pixels. >-__declspec(naked) void ScaleColsUp2_SSE2(uint8* dst_ptr, >- const uint8* src_ptr, >+__declspec(naked) void ScaleColsUp2_SSE2(uint8_t* dst_ptr, >+ const uint8_t* src_ptr, > int dst_width, > int x, > int dx) { >@@ -991,9 +992,9 @@ __declspec(naked) void ScaleColsUp2_SSE2(uint8* dst_ptr, > } > > // Reads 8 pixels, throws half away and writes 4 even pixels (0, 2, 4, 6) >-__declspec(naked) void ScaleARGBRowDown2_SSE2(const uint8* src_argb, >+__declspec(naked) void ScaleARGBRowDown2_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -1016,9 +1017,9 @@ __declspec(naked) void ScaleARGBRowDown2_SSE2(const uint8* src_argb, > } > > // Blends 8x1 rectangle to 4x1. >-__declspec(naked) void ScaleARGBRowDown2Linear_SSE2(const uint8* src_argb, >+__declspec(naked) void ScaleARGBRowDown2Linear_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > __asm { > mov eax, [esp + 4] // src_argb >@@ -1044,9 +1045,9 @@ __declspec(naked) void ScaleARGBRowDown2Linear_SSE2(const uint8* src_argb, > } > > // Blends 8x2 rectangle to 4x1. >-__declspec(naked) void ScaleARGBRowDown2Box_SSE2(const uint8* src_argb, >+__declspec(naked) void ScaleARGBRowDown2Box_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > __asm { > push esi >@@ -1078,10 +1079,10 @@ __declspec(naked) void ScaleARGBRowDown2Box_SSE2(const uint8* src_argb, > } > > // Reads 4 pixels at a time. >-__declspec(naked) void ScaleARGBRowDownEven_SSE2(const uint8* src_argb, >+__declspec(naked) void ScaleARGBRowDownEven_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > __asm { > push ebx >@@ -1115,10 +1116,10 @@ __declspec(naked) void ScaleARGBRowDownEven_SSE2(const uint8* src_argb, > } > > // Blends four 2x2 to 4x1. >-__declspec(naked) void ScaleARGBRowDownEvenBox_SSE2(const uint8* src_argb, >+__declspec(naked) void ScaleARGBRowDownEvenBox_SSE2(const uint8_t* src_argb, > ptrdiff_t src_stride, > int src_stepx, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_width) { > __asm { > push ebx >@@ -1163,8 +1164,8 @@ __declspec(naked) void ScaleARGBRowDownEvenBox_SSE2(const uint8* src_argb, > } > > // Column scaling unfiltered. SSE2 version. >-__declspec(naked) void ScaleARGBCols_SSE2(uint8* dst_argb, >- const uint8* src_argb, >+__declspec(naked) void ScaleARGBCols_SSE2(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { >@@ -1246,18 +1247,18 @@ __declspec(naked) void ScaleARGBCols_SSE2(uint8* dst_argb, > // TODO(fbarchard): Port to Neon > > // Shuffle table for arranging 2 pixels into pairs for pmaddubsw >-static uvec8 kShuffleColARGB = { >+static const uvec8 kShuffleColARGB = { > 0u, 4u, 1u, 5u, 2u, 6u, 3u, 7u, // bbggrraa 1st pixel > 8u, 12u, 9u, 13u, 10u, 14u, 11u, 15u // bbggrraa 2nd pixel > }; > > // Shuffle table for duplicating 2 fractions into 8 bytes each >-static uvec8 kShuffleFractions = { >+static const uvec8 kShuffleFractions = { > 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, > }; > >-__declspec(naked) void ScaleARGBFilterCols_SSSE3(uint8* dst_argb, >- const uint8* src_argb, >+__declspec(naked) void ScaleARGBFilterCols_SSSE3(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { >@@ -1329,8 +1330,8 @@ __declspec(naked) void ScaleARGBFilterCols_SSSE3(uint8* dst_argb, > } > > // Reads 4 pixels, duplicates them and writes 8 pixels. >-__declspec(naked) void ScaleARGBColsUp2_SSE2(uint8* dst_argb, >- const uint8* src_argb, >+__declspec(naked) void ScaleARGBColsUp2_SSE2(uint8_t* dst_argb, >+ const uint8_t* src_argb, > int dst_width, > int x, > int dx) { >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/video_common.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/video_common.cc >index 3e9c6a295022ca72f070f2460b43f3b857de017d..92384c050cdabb84ef2bfc25aa05332a6c45b1ef 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/video_common.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/source/video_common.cc >@@ -15,14 +15,13 @@ namespace libyuv { > extern "C" { > #endif > >-#define ARRAY_SIZE(x) (int)(sizeof(x) / sizeof(x[0])) >- > struct FourCCAliasEntry { >- uint32 alias; >- uint32 canonical; >+ uint32_t alias; >+ uint32_t canonical; > }; > >-static const struct FourCCAliasEntry kFourCCAliases[] = { >+#define NUM_ALIASES 18 >+static const struct FourCCAliasEntry kFourCCAliases[NUM_ALIASES] = { > {FOURCC_IYUV, FOURCC_I420}, > {FOURCC_YU12, FOURCC_I420}, > {FOURCC_YU16, FOURCC_I422}, >@@ -46,9 +45,9 @@ static const struct FourCCAliasEntry kFourCCAliases[] = { > // {FOURCC_BGRA, FOURCC_ARGB}, // kCMPixelFormat_32BGRA > > LIBYUV_API >-uint32 CanonicalFourCC(uint32 fourcc) { >+uint32_t CanonicalFourCC(uint32_t fourcc) { > int i; >- for (i = 0; i < ARRAY_SIZE(kFourCCAliases); ++i) { >+ for (i = 0; i < NUM_ALIASES; ++i) { > if (kFourCCAliases[i].alias == fourcc) { > return kFourCCAliases[i].canonical; > } >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/autoroller/roll_deps.py b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/autoroller/roll_deps.py >index efea81e07b120f39f05b5884cc977df684d1394b..09ddc40e730ff9c4fb93e8d4bcac5e4492b9a071 100755 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/autoroller/roll_deps.py >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/autoroller/roll_deps.py >@@ -207,7 +207,13 @@ def BuildDepsentryDict(deps_dict): > """Builds a dict of paths to DepsEntry objects from a raw parsed deps dict.""" > result = {} > def AddDepsEntries(deps_subdict): >- for path, deps_url in deps_subdict.iteritems(): >+ for path, deps_url_spec in deps_subdict.iteritems(): >+ # The deps url is either an URL and a condition, or just the URL. >+ if isinstance(deps_url_spec, dict): >+ deps_url = deps_url_spec['url'] >+ else: >+ deps_url = deps_url_spec >+ > if not result.has_key(path): > url, revision = deps_url.split('@') if deps_url else (None, None) > result[path] = DepsEntry(path, url, revision) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/get_landmines.py b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/get_landmines.py >index 3dc78bb973f67d0d6744e0fab46dbe989d3083d2..c554f04a39aae81782e67544194207b6de3bfc91 100755 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/get_landmines.py >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/get_landmines.py >@@ -12,20 +12,8 @@ This file emits the list of reasons why a particular build needs to be clobbered > (or a list of 'landmines'). > """ > >-import os > import sys > >-script_dir = os.path.dirname(os.path.realpath(__file__)) >-checkout_root = os.path.abspath(os.path.join(script_dir, os.pardir)) >-sys.path.insert(0, os.path.join(checkout_root, 'build')) >-import landmine_utils >- >- >-distributor = landmine_utils.distributor >-gyp_defines = landmine_utils.gyp_defines >-gyp_msvs_version = landmine_utils.gyp_msvs_version >-platform = landmine_utils.platform >- > > def print_landmines(): > """ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/chrome_tests.bat b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/chrome_tests.bat >old mode 100644 >new mode 100755 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/chrome_tests.py b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/chrome_tests.py >old mode 100644 >new mode 100755 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/chrome_tests.sh b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/chrome_tests.sh >old mode 100644 >new mode 100755 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/locate_valgrind.sh b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/locate_valgrind.sh >old mode 100644 >new mode 100755 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/memcheck_analyze.py b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/memcheck_analyze.py >old mode 100644 >new mode 100755 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/valgrind.sh b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/valgrind.sh >old mode 100644 >new mode 100755 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/valgrind_test.py b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/tools_libyuv/valgrind/valgrind_test.py >old mode 100644 >new mode 100755 >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/basictypes_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/basictypes_test.cc >index 89f7644d58e540ea5d28c9b3d4b868f4e46434a8..9aaa2dcd989fec8841b700e4cde5836ce839165c 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/basictypes_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/basictypes_test.cc >@@ -13,25 +13,15 @@ > > namespace libyuv { > >-TEST_F(LibYUVBaseTest, Endian) { >- uint16 v16 = 0x1234u; >- uint8 first_byte = *reinterpret_cast<uint8*>(&v16); >-#if defined(LIBYUV_LITTLE_ENDIAN) >- EXPECT_EQ(0x34u, first_byte); >-#else >- EXPECT_EQ(0x12u, first_byte); >-#endif >-} >- > TEST_F(LibYUVBaseTest, SizeOfTypes) { >- int8 i8 = -1; >- uint8 u8 = 1u; >- int16 i16 = -1; >- uint16 u16 = 1u; >- int32 i32 = -1; >- uint32 u32 = 1u; >- int64 i64 = -1; >- uint64 u64 = 1u; >+ int8_t i8 = -1; >+ uint8_t u8 = 1u; >+ int16_t i16 = -1; >+ uint16_t u16 = 1u; >+ int32_t i32 = -1; >+ uint32_t u32 = 1u; >+ int64_t i64 = -1; >+ uint64_t u64 = 1u; > EXPECT_EQ(1u, sizeof(i8)); > EXPECT_EQ(1u, sizeof(u8)); > EXPECT_EQ(2u, sizeof(i16)); >@@ -50,11 +40,4 @@ TEST_F(LibYUVBaseTest, SizeOfTypes) { > EXPECT_LT(0u, u64); > } > >-TEST_F(LibYUVBaseTest, SizeOfConstants) { >- EXPECT_EQ(8u, sizeof(INT64_C(0))); >- EXPECT_EQ(8u, sizeof(UINT64_C(0))); >- EXPECT_EQ(8u, sizeof(INT64_C(0x1234567887654321))); >- EXPECT_EQ(8u, sizeof(UINT64_C(0x8765432112345678))); >-} >- > } // namespace libyuv >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/color_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/color_test.cc >index 30b6411283f12a4e93c00275b421d652476172a4..4bb448d56fe1bba7bda82192a5c53dce99d286dd 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/color_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/color_test.cc >@@ -63,10 +63,10 @@ namespace libyuv { > \ > /* The test is overall for color conversion matrix being reversible, so */ \ > /* this initializes the pixel with 2x2 blocks to eliminate subsampling. */ \ >- uint8* p = orig_y; \ >+ uint8_t* p = orig_y; \ > for (int y = 0; y < benchmark_height_ - HS1; y += HS) { \ > for (int x = 0; x < benchmark_width_ - 1; x += 2) { \ >- uint8 r = static_cast<uint8>(fastrand()); \ >+ uint8_t r = static_cast<uint8_t>(fastrand()); \ > p[0] = r; \ > p[1] = r; \ > p[HN] = r; \ >@@ -74,7 +74,7 @@ namespace libyuv { > p += 2; \ > } \ > if (benchmark_width_ & 1) { \ >- uint8 r = static_cast<uint8>(fastrand()); \ >+ uint8_t r = static_cast<uint8_t>(fastrand()); \ > p[0] = r; \ > p[HN] = r; \ > p += 1; \ >@@ -83,13 +83,13 @@ namespace libyuv { > } \ > if ((benchmark_height_ & 1) && HS == 2) { \ > for (int x = 0; x < benchmark_width_ - 1; x += 2) { \ >- uint8 r = static_cast<uint8>(fastrand()); \ >+ uint8_t r = static_cast<uint8_t>(fastrand()); \ > p[0] = r; \ > p[1] = r; \ > p += 2; \ > } \ > if (benchmark_width_ & 1) { \ >- uint8 r = static_cast<uint8>(fastrand()); \ >+ uint8_t r = static_cast<uint8_t>(fastrand()); \ > p[0] = r; \ > p += 1; \ > } \ >@@ -147,10 +147,10 @@ static void YUVToRGB(int y, int u, int v, int* r, int* g, int* b) { > const int kPixels = kWidth * kHeight; > const int kHalfPixels = ((kWidth + 1) / 2) * ((kHeight + 1) / 2); > >- SIMD_ALIGNED(uint8 orig_y[16]); >- SIMD_ALIGNED(uint8 orig_u[8]); >- SIMD_ALIGNED(uint8 orig_v[8]); >- SIMD_ALIGNED(uint8 orig_pixels[16 * 4]); >+ SIMD_ALIGNED(uint8_t orig_y[16]); >+ SIMD_ALIGNED(uint8_t orig_u[8]); >+ SIMD_ALIGNED(uint8_t orig_v[8]); >+ SIMD_ALIGNED(uint8_t orig_pixels[16 * 4]); > memset(orig_y, y, kPixels); > memset(orig_u, u, kHalfPixels); > memset(orig_v, v, kHalfPixels); >@@ -170,10 +170,10 @@ static void YUVJToRGB(int y, int u, int v, int* r, int* g, int* b) { > const int kPixels = kWidth * kHeight; > const int kHalfPixels = ((kWidth + 1) / 2) * ((kHeight + 1) / 2); > >- SIMD_ALIGNED(uint8 orig_y[16]); >- SIMD_ALIGNED(uint8 orig_u[8]); >- SIMD_ALIGNED(uint8 orig_v[8]); >- SIMD_ALIGNED(uint8 orig_pixels[16 * 4]); >+ SIMD_ALIGNED(uint8_t orig_y[16]); >+ SIMD_ALIGNED(uint8_t orig_u[8]); >+ SIMD_ALIGNED(uint8_t orig_v[8]); >+ SIMD_ALIGNED(uint8_t orig_pixels[16 * 4]); > memset(orig_y, y, kPixels); > memset(orig_u, u, kHalfPixels); > memset(orig_v, v, kHalfPixels); >@@ -192,8 +192,8 @@ static void YToRGB(int y, int* r, int* g, int* b) { > const int kHeight = 1; > const int kPixels = kWidth * kHeight; > >- SIMD_ALIGNED(uint8 orig_y[16]); >- SIMD_ALIGNED(uint8 orig_pixels[16 * 4]); >+ SIMD_ALIGNED(uint8_t orig_y[16]); >+ SIMD_ALIGNED(uint8_t orig_pixels[16 * 4]); > memset(orig_y, y, kPixels); > > /* YUV converted to ARGB. */ >@@ -209,8 +209,8 @@ static void YJToRGB(int y, int* r, int* g, int* b) { > const int kHeight = 1; > const int kPixels = kWidth * kHeight; > >- SIMD_ALIGNED(uint8 orig_y[16]); >- SIMD_ALIGNED(uint8 orig_pixels[16 * 4]); >+ SIMD_ALIGNED(uint8_t orig_y[16]); >+ SIMD_ALIGNED(uint8_t orig_pixels[16 * 4]); > memset(orig_y, y, kPixels); > > /* YUV converted to ARGB. */ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/compare_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/compare_test.cc >index ff39b2b0f609baaecc47b98e3afeecad85086599..136254e169b807f5d3e8a48c71fd5af1ad75bb5a 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/compare_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/compare_test.cc >@@ -22,8 +22,10 @@ > namespace libyuv { > > // hash seed of 5381 recommended. >-static uint32 ReferenceHashDjb2(const uint8* src, uint64 count, uint32 seed) { >- uint32 hash = seed; >+static uint32_t ReferenceHashDjb2(const uint8_t* src, >+ uint64_t count, >+ uint32_t seed) { >+ uint32_t hash = seed; > if (count > 0) { > do { > hash = hash * 33 + *src++; >@@ -41,8 +43,8 @@ TEST_F(LibYUVCompareTest, Djb2_Test) { > "The quick brown fox jumps over the lazy dog" > " and feels as if he were in the seventh heaven of typography" > " together with Hermann Zapf"; >- uint32 foxhash = HashDjb2(reinterpret_cast<const uint8*>(fox), 131, 5381); >- const uint32 kExpectedFoxHash = 2611006483u; >+ uint32_t foxhash = HashDjb2(reinterpret_cast<const uint8_t*>(fox), 131, 5381); >+ const uint32_t kExpectedFoxHash = 2611006483u; > EXPECT_EQ(kExpectedFoxHash, foxhash); > > for (int i = 0; i < kMaxTest; ++i) { >@@ -50,8 +52,8 @@ TEST_F(LibYUVCompareTest, Djb2_Test) { > src_b[i] = (fastrand() & 0xff); > } > // Compare different buffers. Expect hash is different. >- uint32 h1 = HashDjb2(src_a, kMaxTest, 5381); >- uint32 h2 = HashDjb2(src_b, kMaxTest, 5381); >+ uint32_t h1 = HashDjb2(src_a, kMaxTest, 5381); >+ uint32_t h2 = HashDjb2(src_b, kMaxTest, 5381); > EXPECT_NE(h1, h2); > > // Make last half same. Expect hash is different. >@@ -124,8 +126,8 @@ TEST_F(LibYUVCompareTest, BenchmarkDjb2_Opt) { > for (int i = 0; i < kMaxTest; ++i) { > src_a[i] = i; > } >- uint32 h2 = ReferenceHashDjb2(src_a, kMaxTest, 5381); >- uint32 h1; >+ uint32_t h2 = ReferenceHashDjb2(src_a, kMaxTest, 5381); >+ uint32_t h1; > for (int i = 0; i < benchmark_iterations_; ++i) { > h1 = HashDjb2(src_a, kMaxTest, 5381); > } >@@ -139,8 +141,8 @@ TEST_F(LibYUVCompareTest, BenchmarkDjb2_Unaligned) { > for (int i = 0; i < kMaxTest; ++i) { > src_a[i + 1] = i; > } >- uint32 h2 = ReferenceHashDjb2(src_a + 1, kMaxTest, 5381); >- uint32 h1; >+ uint32_t h2 = ReferenceHashDjb2(src_a + 1, kMaxTest, 5381); >+ uint32_t h1; > for (int i = 0; i < benchmark_iterations_; ++i) { > h1 = HashDjb2(src_a + 1, kMaxTest, 5381); > } >@@ -149,7 +151,7 @@ TEST_F(LibYUVCompareTest, BenchmarkDjb2_Unaligned) { > } > > TEST_F(LibYUVCompareTest, BenchmarkARGBDetect_Opt) { >- uint32 fourcc; >+ uint32_t fourcc; > const int kMaxTest = benchmark_width_ * benchmark_height_ * 4; > align_buffer_page_end(src_a, kMaxTest); > for (int i = 0; i < kMaxTest; ++i) { >@@ -159,12 +161,12 @@ TEST_F(LibYUVCompareTest, BenchmarkARGBDetect_Opt) { > src_a[0] = 0; > fourcc = ARGBDetect(src_a, benchmark_width_ * 4, benchmark_width_, > benchmark_height_); >- EXPECT_EQ(static_cast<uint32>(libyuv::FOURCC_BGRA), fourcc); >+ EXPECT_EQ(static_cast<uint32_t>(libyuv::FOURCC_BGRA), fourcc); > src_a[0] = 255; > src_a[3] = 0; > fourcc = ARGBDetect(src_a, benchmark_width_ * 4, benchmark_width_, > benchmark_height_); >- EXPECT_EQ(static_cast<uint32>(libyuv::FOURCC_ARGB), fourcc); >+ EXPECT_EQ(static_cast<uint32_t>(libyuv::FOURCC_ARGB), fourcc); > src_a[3] = 255; > > for (int i = 0; i < benchmark_iterations_; ++i) { >@@ -177,7 +179,7 @@ TEST_F(LibYUVCompareTest, BenchmarkARGBDetect_Opt) { > } > > TEST_F(LibYUVCompareTest, BenchmarkARGBDetect_Unaligned) { >- uint32 fourcc; >+ uint32_t fourcc; > const int kMaxTest = benchmark_width_ * benchmark_height_ * 4 + 1; > align_buffer_page_end(src_a, kMaxTest); > for (int i = 1; i < kMaxTest; ++i) { >@@ -187,12 +189,12 @@ TEST_F(LibYUVCompareTest, BenchmarkARGBDetect_Unaligned) { > src_a[0 + 1] = 0; > fourcc = ARGBDetect(src_a + 1, benchmark_width_ * 4, benchmark_width_, > benchmark_height_); >- EXPECT_EQ(static_cast<uint32>(libyuv::FOURCC_BGRA), fourcc); >+ EXPECT_EQ(static_cast<uint32_t>(libyuv::FOURCC_BGRA), fourcc); > src_a[0 + 1] = 255; > src_a[3 + 1] = 0; > fourcc = ARGBDetect(src_a + 1, benchmark_width_ * 4, benchmark_width_, > benchmark_height_); >- EXPECT_EQ(static_cast<uint32>(libyuv::FOURCC_ARGB), fourcc); >+ EXPECT_EQ(static_cast<uint32_t>(libyuv::FOURCC_ARGB), fourcc); > src_a[3 + 1] = 255; > > for (int i = 0; i < benchmark_iterations_; ++i) { >@@ -214,14 +216,14 @@ TEST_F(LibYUVCompareTest, BenchmarkHammingDistance_Opt) { > // Test known value > memcpy(src_a, "test0123test4567", 16); > memcpy(src_b, "tick0123tock4567", 16); >- uint32 h1 = HammingDistance_C(src_a, src_b, 16); >+ uint32_t h1 = HammingDistance_C(src_a, src_b, 16); > EXPECT_EQ(16u, h1); > > // Test C vs OPT on random buffer > MemRandomize(src_a, kMaxWidth); > MemRandomize(src_b, kMaxWidth); > >- uint32 h0 = HammingDistance_C(src_a, src_b, kMaxWidth); >+ uint32_t h0 = HammingDistance_C(src_a, src_b, kMaxWidth); > > int count = > benchmark_iterations_ * >@@ -273,14 +275,14 @@ TEST_F(LibYUVCompareTest, BenchmarkHammingDistance_C) { > // Test known value > memcpy(src_a, "test0123test4567", 16); > memcpy(src_b, "tick0123tock4567", 16); >- uint32 h1 = HammingDistance_C(src_a, src_b, 16); >+ uint32_t h1 = HammingDistance_C(src_a, src_b, 16); > EXPECT_EQ(16u, h1); > > // Test C vs OPT on random buffer > MemRandomize(src_a, kMaxWidth); > MemRandomize(src_b, kMaxWidth); > >- uint32 h0 = HammingDistance_C(src_a, src_b, kMaxWidth); >+ uint32_t h0 = HammingDistance_C(src_a, src_b, kMaxWidth); > > int count = > benchmark_iterations_ * >@@ -304,14 +306,14 @@ TEST_F(LibYUVCompareTest, BenchmarkHammingDistance) { > > memcpy(src_a, "test0123test4567", 16); > memcpy(src_b, "tick0123tock4567", 16); >- uint64 h1 = ComputeHammingDistance(src_a, src_b, 16); >+ uint64_t h1 = ComputeHammingDistance(src_a, src_b, 16); > EXPECT_EQ(16u, h1); > > // Test C vs OPT on random buffer > MemRandomize(src_a, kMaxWidth); > MemRandomize(src_b, kMaxWidth); > >- uint32 h0 = HammingDistance_C(src_a, src_b, kMaxWidth); >+ uint32_t h0 = HammingDistance_C(src_a, src_b, kMaxWidth); > > int count = > benchmark_iterations_ * >@@ -337,14 +339,14 @@ static const int kMaxOptCount = (1 << (32 - 3)) - 64; // 536870848 > #endif > > TEST_F(LibYUVCompareTest, TestHammingDistance_Opt) { >- uint32 h1 = 0; >- const int kMaxWidth = benchmark_width_ * benchmark_height_; >+ uint32_t h1 = 0; >+ const int kMaxWidth = (benchmark_width_ * benchmark_height_ + 31) & ~31; > align_buffer_page_end(src_a, kMaxWidth); > align_buffer_page_end(src_b, kMaxWidth); > memset(src_a, 255u, kMaxWidth); > memset(src_b, 0u, kMaxWidth); > >- uint64 h0 = ComputeHammingDistance(src_a, src_b, kMaxWidth); >+ uint64_t h0 = ComputeHammingDistance(src_a, src_b, kMaxWidth); > EXPECT_EQ(kMaxWidth * 8ULL, h0); > > for (int i = 0; i < benchmark_iterations_; ++i) { >@@ -385,7 +387,7 @@ TEST_F(LibYUVCompareTest, TestHammingDistance_Opt) { > if (kMaxWidth <= kMaxOptCount) { > EXPECT_EQ(kMaxWidth * 8U, h1); > } else { >- if (kMaxWidth * 8ULL != static_cast<uint64>(h1)) { >+ if (kMaxWidth * 8ULL != static_cast<uint64_t>(h1)) { > printf( > "warning - HammingDistance_Opt %u does not match %llu " > "but length of %u is longer than guaranteed.\n", >@@ -408,7 +410,7 @@ TEST_F(LibYUVCompareTest, TestHammingDistance) { > memset(src_a, 255u, benchmark_width_ * benchmark_height_); > memset(src_b, 0, benchmark_width_ * benchmark_height_); > >- uint64 h1 = 0; >+ uint64_t h1 = 0; > for (int i = 0; i < benchmark_iterations_; ++i) { > h1 = ComputeHammingDistance(src_a, src_b, > benchmark_width_ * benchmark_height_); >@@ -428,7 +430,7 @@ TEST_F(LibYUVCompareTest, BenchmarkSumSquareError_Opt) { > > memcpy(src_a, "test0123test4567", 16); > memcpy(src_b, "tick0123tock4567", 16); >- uint64 h1 = ComputeSumSquareError(src_a, src_b, 16); >+ uint64_t h1 = ComputeSumSquareError(src_a, src_b, 16); > EXPECT_EQ(790u, h1); > > for (int i = 0; i < kMaxWidth; ++i) { >@@ -458,7 +460,7 @@ TEST_F(LibYUVCompareTest, SumSquareError) { > memset(src_a, 0, kMaxWidth); > memset(src_b, 0, kMaxWidth); > >- uint64 err; >+ uint64_t err; > err = ComputeSumSquareError(src_a, src_b, kMaxWidth); > > EXPECT_EQ(0u, err); >@@ -480,10 +482,10 @@ TEST_F(LibYUVCompareTest, SumSquareError) { > } > > MaskCpuFlags(disable_cpu_flags_); >- uint64 c_err = ComputeSumSquareError(src_a, src_b, kMaxWidth); >+ uint64_t c_err = ComputeSumSquareError(src_a, src_b, kMaxWidth); > > MaskCpuFlags(benchmark_cpu_info_); >- uint64 opt_err = ComputeSumSquareError(src_a, src_b, kMaxWidth); >+ uint64_t opt_err = ComputeSumSquareError(src_a, src_b, kMaxWidth); > > EXPECT_EQ(c_err, opt_err); > >@@ -502,9 +504,10 @@ TEST_F(LibYUVCompareTest, BenchmarkPsnr_Opt) { > MaskCpuFlags(benchmark_cpu_info_); > > double opt_time = get_time(); >- for (int i = 0; i < benchmark_iterations_; ++i) >+ for (int i = 0; i < benchmark_iterations_; ++i) { > CalcFramePsnr(src_a, benchmark_width_, src_b, benchmark_width_, > benchmark_width_, benchmark_height_); >+ } > > opt_time = (get_time() - opt_time) / benchmark_iterations_; > printf("BenchmarkPsnr_Opt - %8.2f us opt\n", opt_time * 1e6); >@@ -526,9 +529,10 @@ TEST_F(LibYUVCompareTest, BenchmarkPsnr_Unaligned) { > MaskCpuFlags(benchmark_cpu_info_); > > double opt_time = get_time(); >- for (int i = 0; i < benchmark_iterations_; ++i) >+ for (int i = 0; i < benchmark_iterations_; ++i) { > CalcFramePsnr(src_a + 1, benchmark_width_, src_b, benchmark_width_, > benchmark_width_, benchmark_height_); >+ } > > opt_time = (get_time() - opt_time) / benchmark_iterations_; > printf("BenchmarkPsnr_Opt - %8.2f us opt\n", opt_time * 1e6); >@@ -627,9 +631,10 @@ TEST_F(LibYUVCompareTest, DISABLED_BenchmarkSsim_Opt) { > MaskCpuFlags(benchmark_cpu_info_); > > double opt_time = get_time(); >- for (int i = 0; i < benchmark_iterations_; ++i) >+ for (int i = 0; i < benchmark_iterations_; ++i) { > CalcFrameSsim(src_a, benchmark_width_, src_b, benchmark_width_, > benchmark_width_, benchmark_height_); >+ } > > opt_time = (get_time() - opt_time) / benchmark_iterations_; > printf("BenchmarkSsim_Opt - %8.2f us opt\n", opt_time * 1e6); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/convert_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/convert_test.cc >index 56b6364e5eb830c6b84cf2d55c79443ab037d761..39281ae08076d7d5ed2d209ab36998f269817fbd 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/convert_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/convert_test.cc >@@ -8,9 +8,12 @@ > * be found in the AUTHORS file in the root of the source tree. > */ > >+#include <assert.h> > #include <stdlib.h> > #include <time.h> > >+#include "libyuv/row.h" /* For ARGBToAR30Row_AVX2 */ >+ > #include "libyuv/basic_types.h" > #include "libyuv/compare.h" > #include "libyuv/convert.h" >@@ -26,102 +29,91 @@ > #include "libyuv/rotate.h" > #include "libyuv/video_common.h" > >+#if defined(__arm__) || defined(__aarch64__) >+// arm version subsamples by summing 4 pixels then multiplying by matrix with >+// 4x smaller coefficients which are rounded to nearest integer. >+#define ARM_YUV_ERROR 4 >+#else >+#define ARM_YUV_ERROR 0 >+#endif >+ > namespace libyuv { > >+// Alias to copy pixels as is >+#define AR30ToAR30 ARGBCopy >+#define ABGRToABGR ARGBCopy >+ > #define SUBSAMPLE(v, a) ((((v) + (a)-1)) / (a)) > >-#define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ >- FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \ >+// Planar test >+ >+#define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, \ >+ SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC, \ >+ DST_SUBSAMP_X, DST_SUBSAMP_Y, W1280, N, NEG, OFF) \ > TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ >+ static_assert(SRC_BPC == 1 || SRC_BPC == 2, "SRC BPC unsupported"); \ >+ static_assert(DST_BPC == 1 || DST_BPC == 2, "DST BPC unsupported"); \ >+ static_assert(SRC_SUBSAMP_X == 1 || SRC_SUBSAMP_X == 2, \ >+ "DST SRC_SUBSAMP_X unsupported"); \ >+ static_assert(SRC_SUBSAMP_Y == 1 || SRC_SUBSAMP_Y == 2, \ >+ "DST SRC_SUBSAMP_Y unsupported"); \ >+ static_assert(DST_SUBSAMP_X == 1 || DST_SUBSAMP_X == 2, \ >+ "DST DST_SUBSAMP_X unsupported"); \ >+ static_assert(DST_SUBSAMP_Y == 1 || DST_SUBSAMP_Y == 2, \ >+ "DST DST_SUBSAMP_Y unsupported"); \ > const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ > const int kHeight = benchmark_height_; \ >- align_buffer_page_end(src_y, kWidth* kHeight + OFF); \ >- align_buffer_page_end(src_u, SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ >- SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + \ >- OFF); \ >- align_buffer_page_end(src_v, SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ >- SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + \ >- OFF); \ >- align_buffer_page_end(dst_y_c, kWidth* kHeight); \ >- align_buffer_page_end(dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X) * \ >- SUBSAMPLE(kHeight, SUBSAMP_Y)); \ >- align_buffer_page_end(dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X) * \ >- SUBSAMPLE(kHeight, SUBSAMP_Y)); \ >- align_buffer_page_end(dst_y_opt, kWidth* kHeight); \ >- align_buffer_page_end(dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * \ >- SUBSAMPLE(kHeight, SUBSAMP_Y)); \ >- align_buffer_page_end(dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * \ >- SUBSAMPLE(kHeight, SUBSAMP_Y)); \ >- for (int i = 0; i < kHeight; ++i) \ >- for (int j = 0; j < kWidth; ++j) \ >- src_y[i * kWidth + j + OFF] = (fastrand() & 0xff); \ >- for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \ >- for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \ >- src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ >- (fastrand() & 0xff); \ >- src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ >- (fastrand() & 0xff); \ >- } \ >- } \ >- memset(dst_y_c, 1, kWidth* kHeight); \ >- memset(dst_u_c, 2, \ >- SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ >- memset(dst_v_c, 3, \ >- SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ >- memset(dst_y_opt, 101, kWidth* kHeight); \ >- memset(dst_u_opt, 102, \ >- SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ >- memset(dst_v_opt, 103, \ >- SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ >+ const int kSrcHalfWidth = SUBSAMPLE(kWidth, SRC_SUBSAMP_X); \ >+ const int kSrcHalfHeight = SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); \ >+ const int kDstHalfWidth = SUBSAMPLE(kWidth, DST_SUBSAMP_X); \ >+ const int kDstHalfHeight = SUBSAMPLE(kHeight, DST_SUBSAMP_Y); \ >+ align_buffer_page_end(src_y, kWidth* kHeight* SRC_BPC + OFF); \ >+ align_buffer_page_end(src_u, \ >+ kSrcHalfWidth* kSrcHalfHeight* SRC_BPC + OFF); \ >+ align_buffer_page_end(src_v, \ >+ kSrcHalfWidth* kSrcHalfHeight* SRC_BPC + OFF); \ >+ align_buffer_page_end(dst_y_c, kWidth* kHeight* DST_BPC); \ >+ align_buffer_page_end(dst_u_c, kDstHalfWidth* kDstHalfHeight* DST_BPC); \ >+ align_buffer_page_end(dst_v_c, kDstHalfWidth* kDstHalfHeight* DST_BPC); \ >+ align_buffer_page_end(dst_y_opt, kWidth* kHeight* DST_BPC); \ >+ align_buffer_page_end(dst_u_opt, kDstHalfWidth* kDstHalfHeight* DST_BPC); \ >+ align_buffer_page_end(dst_v_opt, kDstHalfWidth* kDstHalfHeight* DST_BPC); \ >+ MemRandomize(src_y + OFF, kWidth * kHeight * SRC_BPC); \ >+ MemRandomize(src_u + OFF, kSrcHalfWidth * kSrcHalfHeight * SRC_BPC); \ >+ MemRandomize(src_v + OFF, kSrcHalfWidth * kSrcHalfHeight * SRC_BPC); \ >+ memset(dst_y_c, 1, kWidth* kHeight* DST_BPC); \ >+ memset(dst_u_c, 2, kDstHalfWidth* kDstHalfHeight* DST_BPC); \ >+ memset(dst_v_c, 3, kDstHalfWidth* kDstHalfHeight* DST_BPC); \ >+ memset(dst_y_opt, 101, kWidth* kHeight* DST_BPC); \ >+ memset(dst_u_opt, 102, kDstHalfWidth* kDstHalfHeight* DST_BPC); \ >+ memset(dst_v_opt, 103, kDstHalfWidth* kDstHalfHeight* DST_BPC); \ > MaskCpuFlags(disable_cpu_flags_); \ > SRC_FMT_PLANAR##To##FMT_PLANAR( \ >- src_y + OFF, kWidth, src_u + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ >- src_v + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), dst_y_c, kWidth, \ >- dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), dst_v_c, \ >- SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, NEG kHeight); \ >+ reinterpret_cast<SRC_T*>(src_y + OFF), kWidth, \ >+ reinterpret_cast<SRC_T*>(src_u + OFF), kSrcHalfWidth, \ >+ reinterpret_cast<SRC_T*>(src_v + OFF), kSrcHalfWidth, \ >+ reinterpret_cast<DST_T*>(dst_y_c), kWidth, \ >+ reinterpret_cast<DST_T*>(dst_u_c), kDstHalfWidth, \ >+ reinterpret_cast<DST_T*>(dst_v_c), kDstHalfWidth, kWidth, \ >+ NEG kHeight); \ > MaskCpuFlags(benchmark_cpu_info_); \ > for (int i = 0; i < benchmark_iterations_; ++i) { \ > SRC_FMT_PLANAR##To##FMT_PLANAR( \ >- src_y + OFF, kWidth, src_u + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ >- src_v + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), dst_y_opt, kWidth, \ >- dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), dst_v_opt, \ >- SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, NEG kHeight); \ >+ reinterpret_cast<SRC_T*>(src_y + OFF), kWidth, \ >+ reinterpret_cast<SRC_T*>(src_u + OFF), kSrcHalfWidth, \ >+ reinterpret_cast<SRC_T*>(src_v + OFF), kSrcHalfWidth, \ >+ reinterpret_cast<DST_T*>(dst_y_opt), kWidth, \ >+ reinterpret_cast<DST_T*>(dst_u_opt), kDstHalfWidth, \ >+ reinterpret_cast<DST_T*>(dst_v_opt), kDstHalfWidth, kWidth, \ >+ NEG kHeight); \ > } \ >- int max_diff = 0; \ >- for (int i = 0; i < kHeight; ++i) { \ >- for (int j = 0; j < kWidth; ++j) { \ >- int abs_diff = abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ >- static_cast<int>(dst_y_opt[i * kWidth + j])); \ >- if (abs_diff > max_diff) { \ >- max_diff = abs_diff; \ >- } \ >- } \ >- } \ >- EXPECT_EQ(0, max_diff); \ >- for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ >- for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ >- int abs_diff = abs( \ >- static_cast<int>(dst_u_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ >- static_cast<int>( \ >- dst_u_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ >- if (abs_diff > max_diff) { \ >- max_diff = abs_diff; \ >- } \ >- } \ >+ for (int i = 0; i < kHeight * kWidth * DST_BPC; ++i) { \ >+ EXPECT_EQ(dst_y_c[i], dst_y_opt[i]); \ > } \ >- EXPECT_LE(max_diff, 3); \ >- for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ >- for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ >- int abs_diff = abs( \ >- static_cast<int>(dst_v_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ >- static_cast<int>( \ >- dst_v_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ >- if (abs_diff > max_diff) { \ >- max_diff = abs_diff; \ >- } \ >- } \ >+ for (int i = 0; i < kDstHalfWidth * kDstHalfHeight * DST_BPC; ++i) { \ >+ EXPECT_EQ(dst_u_c[i], dst_u_opt[i]); \ >+ EXPECT_EQ(dst_v_c[i], dst_v_opt[i]); \ > } \ >- EXPECT_LE(max_diff, 3); \ > free_aligned_buffer_page_end(dst_y_c); \ > free_aligned_buffer_page_end(dst_u_c); \ > free_aligned_buffer_page_end(dst_v_c); \ >@@ -133,25 +125,36 @@ namespace libyuv { > free_aligned_buffer_page_end(src_v); \ > } > >-#define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ >- FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ >- TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, FMT_PLANAR, \ >- SUBSAMP_X, SUBSAMP_Y, benchmark_width_ - 4, _Any, +, 0) \ >- TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, FMT_PLANAR, \ >- SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Unaligned, +, 1) \ >- TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, FMT_PLANAR, \ >- SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Invert, -, 0) \ >- TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, FMT_PLANAR, \ >- SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Opt, +, 0) >- >-TESTPLANARTOP(I420, 2, 2, I420, 2, 2) >-TESTPLANARTOP(I422, 2, 1, I420, 2, 2) >-TESTPLANARTOP(I444, 1, 1, I420, 2, 2) >-TESTPLANARTOP(I420, 2, 2, I422, 2, 1) >-TESTPLANARTOP(I420, 2, 2, I444, 1, 1) >-TESTPLANARTOP(I420, 2, 2, I420Mirror, 2, 2) >-TESTPLANARTOP(I422, 2, 1, I422, 2, 1) >-TESTPLANARTOP(I444, 1, 1, I444, 1, 1) >+#define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, \ >+ SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC, \ >+ DST_SUBSAMP_X, DST_SUBSAMP_Y) \ >+ TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ >+ FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y, \ >+ benchmark_width_ - 4, _Any, +, 0) \ >+ TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ >+ FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y, \ >+ benchmark_width_, _Unaligned, +, 1) \ >+ TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ >+ FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y, \ >+ benchmark_width_, _Invert, -, 0) \ >+ TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ >+ FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y, \ >+ benchmark_width_, _Opt, +, 0) >+ >+TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I420, uint8_t, 1, 2, 2) >+TESTPLANARTOP(I422, uint8_t, 1, 2, 1, I420, uint8_t, 1, 2, 2) >+TESTPLANARTOP(I444, uint8_t, 1, 1, 1, I420, uint8_t, 1, 2, 2) >+TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I422, uint8_t, 1, 2, 1) >+TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I444, uint8_t, 1, 1, 1) >+TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I420Mirror, uint8_t, 1, 2, 2) >+TESTPLANARTOP(I422, uint8_t, 1, 2, 1, I422, uint8_t, 1, 2, 1) >+TESTPLANARTOP(I444, uint8_t, 1, 1, 1, I444, uint8_t, 1, 1, 1) >+TESTPLANARTOP(I010, uint16_t, 2, 2, 2, I010, uint16_t, 2, 2, 2) >+TESTPLANARTOP(I010, uint16_t, 2, 2, 2, I420, uint8_t, 1, 2, 2) >+TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I010, uint16_t, 2, 2, 2) >+TESTPLANARTOP(H010, uint16_t, 2, 2, 2, H010, uint16_t, 2, 2, 2) >+TESTPLANARTOP(H010, uint16_t, 2, 2, 2, H420, uint8_t, 1, 2, 2) >+TESTPLANARTOP(H420, uint8_t, 1, 2, 2, H010, uint16_t, 2, 2, 2) > > // Test Android 420 to I420 > #define TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, \ >@@ -175,8 +178,8 @@ TESTPLANARTOP(I444, 1, 1, I444, 1, 1) > SUBSAMPLE(kHeight, SUBSAMP_Y)); \ > align_buffer_page_end(dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * \ > SUBSAMPLE(kHeight, SUBSAMP_Y)); \ >- uint8* src_u = src_uv + OFF_U; \ >- uint8* src_v = src_uv + (PIXEL_STRIDE == 1 ? kSizeUV : OFF_V); \ >+ uint8_t* src_u = src_uv + OFF_U; \ >+ uint8_t* src_v = src_uv + (PIXEL_STRIDE == 1 ? kSizeUV : OFF_V); \ > int src_stride_uv = SUBSAMPLE(kWidth, SUBSAMP_X) * PIXEL_STRIDE; \ > for (int i = 0; i < kHeight; ++i) \ > for (int j = 0; j < kWidth; ++j) \ >@@ -491,110 +494,100 @@ TESTBIPLANARTOP(NV21, 2, 2, I420, 2, 2) > > #define ALIGNINT(V, ALIGN) (((V) + (ALIGN)-1) / (ALIGN) * (ALIGN)) > >-#define TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >- YALIGN, W1280, DIFF, N, NEG, OFF, FMT_C, BPP_C) \ >- TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##N) { \ >- const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ >- const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \ >- const int kStrideB = ALIGNINT(kWidth * BPP_B, ALIGN); \ >- const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ >- const int kSizeUV = kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y); \ >- align_buffer_page_end(src_y, kWidth* kHeight + OFF); \ >- align_buffer_page_end(src_u, kSizeUV + OFF); \ >- align_buffer_page_end(src_v, kSizeUV + OFF); \ >- align_buffer_page_end(dst_argb_c, kStrideB* kHeight + OFF); \ >- align_buffer_page_end(dst_argb_opt, kStrideB* kHeight + OFF); \ >- for (int i = 0; i < kWidth * kHeight; ++i) { \ >- src_y[i + OFF] = (fastrand() & 0xff); \ >- } \ >- for (int i = 0; i < kSizeUV; ++i) { \ >- src_u[i + OFF] = (fastrand() & 0xff); \ >- src_v[i + OFF] = (fastrand() & 0xff); \ >- } \ >- memset(dst_argb_c + OFF, 1, kStrideB * kHeight); \ >- memset(dst_argb_opt + OFF, 101, kStrideB * kHeight); \ >- MaskCpuFlags(disable_cpu_flags_); \ >- FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, src_u + OFF, kStrideUV, \ >- src_v + OFF, kStrideUV, dst_argb_c + OFF, kStrideB, \ >- kWidth, NEG kHeight); \ >- MaskCpuFlags(benchmark_cpu_info_); \ >- for (int i = 0; i < benchmark_iterations_; ++i) { \ >- FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, src_u + OFF, kStrideUV, \ >- src_v + OFF, kStrideUV, dst_argb_opt + OFF, \ >- kStrideB, kWidth, NEG kHeight); \ >- } \ >- int max_diff = 0; \ >- /* Convert to ARGB so 565 is expanded to bytes that can be compared. */ \ >- align_buffer_page_end(dst_argb32_c, kWidth* BPP_C* kHeight); \ >- align_buffer_page_end(dst_argb32_opt, kWidth* BPP_C* kHeight); \ >- memset(dst_argb32_c, 2, kWidth* BPP_C* kHeight); \ >- memset(dst_argb32_opt, 102, kWidth* BPP_C* kHeight); \ >- FMT_B##To##FMT_C(dst_argb_c + OFF, kStrideB, dst_argb32_c, kWidth * BPP_C, \ >- kWidth, kHeight); \ >- FMT_B##To##FMT_C(dst_argb_opt + OFF, kStrideB, dst_argb32_opt, \ >- kWidth * BPP_C, kWidth, kHeight); \ >- for (int i = 0; i < kWidth * BPP_C * kHeight; ++i) { \ >- int abs_diff = abs(static_cast<int>(dst_argb32_c[i]) - \ >- static_cast<int>(dst_argb32_opt[i])); \ >- if (abs_diff > max_diff) { \ >- max_diff = abs_diff; \ >- } \ >- } \ >- EXPECT_LE(max_diff, DIFF); \ >- free_aligned_buffer_page_end(src_y); \ >- free_aligned_buffer_page_end(src_u); \ >- free_aligned_buffer_page_end(src_v); \ >- free_aligned_buffer_page_end(dst_argb_c); \ >- free_aligned_buffer_page_end(dst_argb_opt); \ >- free_aligned_buffer_page_end(dst_argb32_c); \ >- free_aligned_buffer_page_end(dst_argb32_opt); \ >+#define TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN, W1280, N, NEG, OFF) \ >+ TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##N) { \ >+ const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ >+ const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \ >+ const int kStrideB = ALIGNINT(kWidth * BPP_B, ALIGN); \ >+ const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ >+ const int kSizeUV = kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y); \ >+ align_buffer_page_end(src_y, kWidth* kHeight + OFF); \ >+ align_buffer_page_end(src_u, kSizeUV + OFF); \ >+ align_buffer_page_end(src_v, kSizeUV + OFF); \ >+ align_buffer_page_end(dst_argb_c, kStrideB* kHeight + OFF); \ >+ align_buffer_page_end(dst_argb_opt, kStrideB* kHeight + OFF); \ >+ for (int i = 0; i < kWidth * kHeight; ++i) { \ >+ src_y[i + OFF] = (fastrand() & 0xff); \ >+ } \ >+ for (int i = 0; i < kSizeUV; ++i) { \ >+ src_u[i + OFF] = (fastrand() & 0xff); \ >+ src_v[i + OFF] = (fastrand() & 0xff); \ >+ } \ >+ memset(dst_argb_c + OFF, 1, kStrideB * kHeight); \ >+ memset(dst_argb_opt + OFF, 101, kStrideB * kHeight); \ >+ MaskCpuFlags(disable_cpu_flags_); \ >+ double time0 = get_time(); \ >+ FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, src_u + OFF, kStrideUV, \ >+ src_v + OFF, kStrideUV, dst_argb_c + OFF, kStrideB, \ >+ kWidth, NEG kHeight); \ >+ double time1 = get_time(); \ >+ MaskCpuFlags(benchmark_cpu_info_); \ >+ for (int i = 0; i < benchmark_iterations_; ++i) { \ >+ FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, src_u + OFF, kStrideUV, \ >+ src_v + OFF, kStrideUV, dst_argb_opt + OFF, \ >+ kStrideB, kWidth, NEG kHeight); \ >+ } \ >+ double time2 = get_time(); \ >+ printf(" %8d us C - %8d us OPT\n", \ >+ static_cast<int>((time1 - time0) * 1e6), \ >+ static_cast<int>((time2 - time1) * 1e6 / benchmark_iterations_)); \ >+ for (int i = 0; i < kWidth * BPP_B * kHeight; ++i) { \ >+ EXPECT_EQ(dst_argb_c[i + OFF], dst_argb_opt[i + OFF]); \ >+ } \ >+ free_aligned_buffer_page_end(src_y); \ >+ free_aligned_buffer_page_end(src_u); \ >+ free_aligned_buffer_page_end(src_v); \ >+ free_aligned_buffer_page_end(dst_argb_c); \ >+ free_aligned_buffer_page_end(dst_argb_opt); \ > } > >-#define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >- YALIGN, DIFF, FMT_C, BPP_C) \ >- TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >- YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, FMT_C, BPP_C) \ >- TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >- YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, FMT_C, \ >- BPP_C) \ >- TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >- YALIGN, benchmark_width_, DIFF, _Invert, -, 0, FMT_C, BPP_C) \ >- TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >- YALIGN, benchmark_width_, DIFF, _Opt, +, 0, FMT_C, BPP_C) >- >-TESTPLANARTOB(I420, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(J420, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(J420, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(H420, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(H420, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, BGRA, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, RAW, 3, 3, 1, 2, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3, 1, 2, ARGB, 4) >-TESTPLANARTOB(H420, 2, 2, RAW, 3, 3, 1, 2, ARGB, 4) >-TESTPLANARTOB(H420, 2, 2, RGB24, 3, 3, 1, 2, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, ARGB1555, 2, 2, 1, 9, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, ARGB4444, 2, 2, 1, 17, ARGB, 4) >-TESTPLANARTOB(I422, 2, 1, ARGB, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I422, 2, 1, RGB565, 2, 2, 1, 9, ARGB, 4) >-TESTPLANARTOB(J422, 2, 1, ARGB, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(J422, 2, 1, ABGR, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(H422, 2, 1, ARGB, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(H422, 2, 1, ABGR, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I422, 2, 1, BGRA, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I422, 2, 1, ABGR, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I422, 2, 1, RGBA, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I444, 1, 1, ARGB, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(J444, 1, 1, ARGB, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I444, 1, 1, ABGR, 4, 4, 1, 2, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, YUY2, 2, 4, 1, 1, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, UYVY, 2, 4, 1, 1, ARGB, 4) >-TESTPLANARTOB(I422, 2, 1, YUY2, 2, 4, 1, 0, ARGB, 4) >-TESTPLANARTOB(I422, 2, 1, UYVY, 2, 4, 1, 0, ARGB, 4) >-TESTPLANARTOB(I420, 2, 2, I400, 1, 1, 1, 0, ARGB, 4) >-TESTPLANARTOB(J420, 2, 2, J400, 1, 1, 1, 0, ARGB, 4) >+#define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN) \ >+ TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN, benchmark_width_ - 4, _Any, +, 0) \ >+ TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN, benchmark_width_, _Unaligned, +, 1) \ >+ TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN, benchmark_width_, _Invert, -, 0) \ >+ TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN, benchmark_width_, _Opt, +, 0) >+ >+TESTPLANARTOB(I420, 2, 2, ARGB, 4, 4, 1) >+TESTPLANARTOB(J420, 2, 2, ARGB, 4, 4, 1) >+TESTPLANARTOB(J420, 2, 2, ABGR, 4, 4, 1) >+TESTPLANARTOB(H420, 2, 2, ARGB, 4, 4, 1) >+TESTPLANARTOB(H420, 2, 2, ABGR, 4, 4, 1) >+TESTPLANARTOB(I420, 2, 2, BGRA, 4, 4, 1) >+TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4, 1) >+TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4, 1) >+TESTPLANARTOB(I420, 2, 2, RAW, 3, 3, 1) >+TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3, 1) >+TESTPLANARTOB(H420, 2, 2, RAW, 3, 3, 1) >+TESTPLANARTOB(H420, 2, 2, RGB24, 3, 3, 1) >+TESTPLANARTOB(I420, 2, 2, RGB565, 2, 2, 1) >+TESTPLANARTOB(I420, 2, 2, ARGB1555, 2, 2, 1) >+TESTPLANARTOB(I420, 2, 2, ARGB4444, 2, 2, 1) >+TESTPLANARTOB(I422, 2, 1, ARGB, 4, 4, 1) >+TESTPLANARTOB(I422, 2, 1, RGB565, 2, 2, 1) >+TESTPLANARTOB(J422, 2, 1, ARGB, 4, 4, 1) >+TESTPLANARTOB(J422, 2, 1, ABGR, 4, 4, 1) >+TESTPLANARTOB(H422, 2, 1, ARGB, 4, 4, 1) >+TESTPLANARTOB(H422, 2, 1, ABGR, 4, 4, 1) >+TESTPLANARTOB(I422, 2, 1, BGRA, 4, 4, 1) >+TESTPLANARTOB(I422, 2, 1, ABGR, 4, 4, 1) >+TESTPLANARTOB(I422, 2, 1, RGBA, 4, 4, 1) >+TESTPLANARTOB(I444, 1, 1, ARGB, 4, 4, 1) >+TESTPLANARTOB(J444, 1, 1, ARGB, 4, 4, 1) >+TESTPLANARTOB(I444, 1, 1, ABGR, 4, 4, 1) >+TESTPLANARTOB(I420, 2, 2, YUY2, 2, 4, 1) >+TESTPLANARTOB(I420, 2, 2, UYVY, 2, 4, 1) >+TESTPLANARTOB(I422, 2, 1, YUY2, 2, 4, 1) >+TESTPLANARTOB(I422, 2, 1, UYVY, 2, 4, 1) >+TESTPLANARTOB(I420, 2, 2, I400, 1, 1, 1) >+TESTPLANARTOB(J420, 2, 2, J400, 1, 1, 1) >+TESTPLANARTOB(I420, 2, 2, AR30, 4, 4, 1) >+TESTPLANARTOB(H420, 2, 2, AR30, 4, 4, 1) > > #define TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ > YALIGN, W1280, DIFF, N, NEG, OFF, ATTEN) \ >@@ -737,6 +730,10 @@ TESTQPLANARTOB(I420Alpha, 2, 2, ABGR, 4, 4, 1, 2) > > TESTBIPLANARTOB(NV12, 2, 2, ARGB, 4, 2) > TESTBIPLANARTOB(NV21, 2, 2, ARGB, 4, 2) >+TESTBIPLANARTOB(NV12, 2, 2, ABGR, 4, 2) >+TESTBIPLANARTOB(NV21, 2, 2, ABGR, 4, 2) >+TESTBIPLANARTOB(NV12, 2, 2, RGB24, 3, 2) >+TESTBIPLANARTOB(NV21, 2, 2, RGB24, 3, 2) > TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2, 9) > > #ifdef DO_THREE_PLANES >@@ -865,15 +862,8 @@ TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2, 9) > benchmark_width_, DIFF, _Opt, +, 0) > > TESTATOPLANAR(ARGB, 4, 1, I420, 2, 2, 4) >-#if defined(__arm__) || defined(__aarch64__) >-// arm version subsamples by summing 4 pixels then multiplying by matrix with >-// 4x smaller coefficients which are rounded to nearest integer. >-TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 4) >-TESTATOPLANAR(ARGB, 4, 1, J422, 2, 1, 4) >-#else >-TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 0) >-TESTATOPLANAR(ARGB, 4, 1, J422, 2, 1, 0) >-#endif >+TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, ARM_YUV_ERROR) >+TESTATOPLANAR(ARGB, 4, 1, J422, 2, 1, ARM_YUV_ERROR) > TESTATOPLANAR(BGRA, 4, 1, I420, 2, 2, 4) > TESTATOPLANAR(ABGR, 4, 1, I420, 2, 2, 4) > TESTATOPLANAR(RGBA, 4, 1, I420, 2, 2, 4) >@@ -1069,6 +1059,8 @@ TESTATOB(ARGB, 4, 4, 1, RGB24, 3, 3, 1, 0) > TESTATOB(ARGB, 4, 4, 1, RGB565, 2, 2, 1, 0) > TESTATOB(ARGB, 4, 4, 1, ARGB1555, 2, 2, 1, 0) > TESTATOB(ARGB, 4, 4, 1, ARGB4444, 2, 2, 1, 0) >+TESTATOB(ABGR, 4, 4, 1, AR30, 4, 4, 1, 0) >+TESTATOB(ARGB, 4, 4, 1, AR30, 4, 4, 1, 0) > TESTATOB(ARGB, 4, 4, 1, YUY2, 2, 4, 1, 4) > TESTATOB(ARGB, 4, 4, 1, UYVY, 2, 4, 1, 4) > TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1, 2) >@@ -1076,14 +1068,20 @@ TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1, 2) > TESTATOB(BGRA, 4, 4, 1, ARGB, 4, 4, 1, 0) > TESTATOB(ABGR, 4, 4, 1, ARGB, 4, 4, 1, 0) > TESTATOB(RGBA, 4, 4, 1, ARGB, 4, 4, 1, 0) >+TESTATOB(AR30, 4, 4, 1, AR30, 4, 4, 1, 0) > TESTATOB(RAW, 3, 3, 1, ARGB, 4, 4, 1, 0) > TESTATOB(RAW, 3, 3, 1, RGB24, 3, 3, 1, 0) > TESTATOB(RGB24, 3, 3, 1, ARGB, 4, 4, 1, 0) > TESTATOB(RGB565, 2, 2, 1, ARGB, 4, 4, 1, 0) > TESTATOB(ARGB1555, 2, 2, 1, ARGB, 4, 4, 1, 0) > TESTATOB(ARGB4444, 2, 2, 1, ARGB, 4, 4, 1, 0) >-TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1, 4) >-TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1, 4) >+TESTATOB(AR30, 4, 4, 1, ARGB, 4, 4, 1, 0) >+TESTATOB(AR30, 4, 4, 1, ABGR, 4, 4, 1, 0) >+TESTATOB(AB30, 4, 4, 1, ARGB, 4, 4, 1, 0) >+TESTATOB(AB30, 4, 4, 1, ABGR, 4, 4, 1, 0) >+TESTATOB(AR30, 4, 4, 1, AB30, 4, 4, 1, 0) >+TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1, ARM_YUV_ERROR) >+TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1, ARM_YUV_ERROR) > TESTATOB(YUY2, 2, 4, 1, Y, 1, 1, 1, 0) > TESTATOB(I400, 1, 1, 1, ARGB, 4, 4, 1, 0) > TESTATOB(J400, 1, 1, 1, ARGB, 4, 4, 1, 0) >@@ -1240,8 +1238,8 @@ TESTSYM(BGRAToARGB, 4, 4, 1) > TESTSYM(ABGRToARGB, 4, 4, 1) > > TEST_F(LibYUVConvertTest, Test565) { >- SIMD_ALIGNED(uint8 orig_pixels[256][4]); >- SIMD_ALIGNED(uint8 pixels565[256][2]); >+ SIMD_ALIGNED(uint8_t orig_pixels[256][4]); >+ SIMD_ALIGNED(uint8_t pixels565[256][2]); > > for (int i = 0; i < 256; ++i) { > for (int j = 0; j < 4; ++j) { >@@ -1249,7 +1247,7 @@ TEST_F(LibYUVConvertTest, Test565) { > } > } > ARGBToRGB565(&orig_pixels[0][0], 0, &pixels565[0][0], 0, 256, 1); >- uint32 checksum = HashDjb2(&pixels565[0][0], sizeof(pixels565), 5381); >+ uint32_t checksum = HashDjb2(&pixels565[0][0], sizeof(pixels565), 5381); > EXPECT_EQ(610919429u, checksum); > } > >@@ -1444,7 +1442,7 @@ TEST_F(LibYUVConvertTest, NV12Crop) { > const int sample_size = > kWidth * kHeight + kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y) * 2; > align_buffer_page_end(src_y, sample_size); >- uint8* src_uv = src_y + kWidth * kHeight; >+ uint8_t* src_uv = src_y + kWidth * kHeight; > > align_buffer_page_end(dst_y, kDestWidth * kDestHeight); > align_buffer_page_end(dst_u, SUBSAMPLE(kDestWidth, SUBSAMP_X) * >@@ -1512,13 +1510,13 @@ TEST_F(LibYUVConvertTest, NV12Crop) { > } > > TEST_F(LibYUVConvertTest, TestYToARGB) { >- uint8 y[32]; >- uint8 expectedg[32]; >+ uint8_t y[32]; >+ uint8_t expectedg[32]; > for (int i = 0; i < 32; ++i) { > y[i] = i * 5 + 17; > expectedg[i] = static_cast<int>((y[i] - 16) * 1.164f + 0.5f); > } >- uint8 argb[32 * 4]; >+ uint8_t argb[32 * 4]; > YToARGB(y, 0, argb, 0, 32, 1); > > for (int i = 0; i < 32; ++i) { >@@ -1530,7 +1528,7 @@ TEST_F(LibYUVConvertTest, TestYToARGB) { > } > } > >-static const uint8 kNoDither4x4[16] = { >+static const uint8_t kNoDither4x4[16] = { > 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > }; > >@@ -1557,7 +1555,7 @@ TEST_F(LibYUVConvertTest, TestNoDither) { > } > > // Ordered 4x4 dither for 888 to 565. Values from 0 to 7. >-static const uint8 kDither565_4x4[16] = { >+static const uint8_t kDither565_4x4[16] = { > 0, 4, 1, 5, 6, 2, 7, 3, 1, 5, 0, 4, 7, 3, 6, 2, > }; > >@@ -1728,6 +1726,8 @@ TESTPLANARTOBD(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4) > TESTPTOB(TestYUY2ToNV12, YUY2ToI420, YUY2ToNV12) > TESTPTOB(TestUYVYToNV12, UYVYToI420, UYVYToNV12) > >+// Transitive tests. A to B to C is same as A to C. >+ > #define TESTPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ > W1280, N, NEG, OFF, FMT_C, BPP_C) \ > TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##_##FMT_C##N) { \ >@@ -1893,6 +1893,64 @@ TESTPLANARTOE(I422, 2, 1, UYVY, 2, 4, ARGB, 4) > TESTQPLANARTOE(I420Alpha, 2, 2, ARGB, 1, 4, ABGR, 4) > TESTQPLANARTOE(I420Alpha, 2, 2, ABGR, 1, 4, ARGB, 4) > >+#define TESTPLANETOEI(FMT_A, SUB_A, BPP_A, FMT_B, SUB_B, BPP_B, W1280, N, NEG, \ >+ OFF, FMT_C, BPP_C) \ >+ TEST_F(LibYUVConvertTest, FMT_A##To##FMT_B##_##FMT_C##N) { \ >+ const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ >+ const int kHeight = benchmark_height_; \ >+ const int kStrideA = SUBSAMPLE(kWidth, SUB_A) * BPP_A; \ >+ const int kStrideB = SUBSAMPLE(kWidth, SUB_B) * BPP_B; \ >+ align_buffer_page_end(src_argb_a, kStrideA* kHeight + OFF); \ >+ align_buffer_page_end(dst_argb_b, kStrideB* kHeight + OFF); \ >+ MemRandomize(src_argb_a + OFF, kStrideA * kHeight); \ >+ memset(dst_argb_b + OFF, 1, kStrideB * kHeight); \ >+ for (int i = 0; i < benchmark_iterations_; ++i) { \ >+ FMT_A##To##FMT_B(src_argb_a + OFF, kStrideA, dst_argb_b + OFF, kStrideB, \ >+ kWidth, NEG kHeight); \ >+ } \ >+ /* Convert to a 3rd format in 1 step and 2 steps and compare */ \ >+ const int kStrideC = kWidth * BPP_C; \ >+ align_buffer_page_end(dst_argb_c, kStrideC* kHeight + OFF); \ >+ align_buffer_page_end(dst_argb_bc, kStrideC* kHeight + OFF); \ >+ memset(dst_argb_c + OFF, 2, kStrideC * kHeight); \ >+ memset(dst_argb_bc + OFF, 3, kStrideC * kHeight); \ >+ FMT_A##To##FMT_C(src_argb_a + OFF, kStrideA, dst_argb_c + OFF, kStrideC, \ >+ kWidth, NEG kHeight); \ >+ /* Convert B to C */ \ >+ FMT_B##To##FMT_C(dst_argb_b + OFF, kStrideB, dst_argb_bc + OFF, kStrideC, \ >+ kWidth, kHeight); \ >+ for (int i = 0; i < kStrideC * kHeight; i += 4) { \ >+ EXPECT_EQ(dst_argb_c[i + OFF + 0], dst_argb_bc[i + OFF + 0]); \ >+ EXPECT_EQ(dst_argb_c[i + OFF + 1], dst_argb_bc[i + OFF + 1]); \ >+ EXPECT_EQ(dst_argb_c[i + OFF + 2], dst_argb_bc[i + OFF + 2]); \ >+ EXPECT_NEAR(dst_argb_c[i + OFF + 3], dst_argb_bc[i + OFF + 3], 64); \ >+ } \ >+ free_aligned_buffer_page_end(src_argb_a); \ >+ free_aligned_buffer_page_end(dst_argb_b); \ >+ free_aligned_buffer_page_end(dst_argb_c); \ >+ free_aligned_buffer_page_end(dst_argb_bc); \ >+ } >+ >+#define TESTPLANETOE(FMT_A, SUB_A, BPP_A, FMT_B, SUB_B, BPP_B, FMT_C, BPP_C) \ >+ TESTPLANETOEI(FMT_A, SUB_A, BPP_A, FMT_B, SUB_B, BPP_B, \ >+ benchmark_width_ - 4, _Any, +, 0, FMT_C, BPP_C) \ >+ TESTPLANETOEI(FMT_A, SUB_A, BPP_A, FMT_B, SUB_B, BPP_B, benchmark_width_, \ >+ _Unaligned, +, 1, FMT_C, BPP_C) \ >+ TESTPLANETOEI(FMT_A, SUB_A, BPP_A, FMT_B, SUB_B, BPP_B, benchmark_width_, \ >+ _Invert, -, 0, FMT_C, BPP_C) \ >+ TESTPLANETOEI(FMT_A, SUB_A, BPP_A, FMT_B, SUB_B, BPP_B, benchmark_width_, \ >+ _Opt, +, 0, FMT_C, BPP_C) >+ >+// Caveat: Destination needs to be 4 bytes >+TESTPLANETOE(ARGB, 1, 4, AR30, 1, 4, ARGB, 4) >+TESTPLANETOE(ABGR, 1, 4, AR30, 1, 4, ABGR, 4) >+TESTPLANETOE(AR30, 1, 4, ARGB, 1, 4, ABGR, 4) >+TESTPLANETOE(AR30, 1, 4, ABGR, 1, 4, ARGB, 4) >+TESTPLANETOE(ARGB, 1, 4, AB30, 1, 4, ARGB, 4) >+TESTPLANETOE(ABGR, 1, 4, AB30, 1, 4, ABGR, 4) >+TESTPLANETOE(AB30, 1, 4, ARGB, 1, 4, ABGR, 4) >+TESTPLANETOE(AB30, 1, 4, ABGR, 1, 4, ARGB, 4) >+ > TEST_F(LibYUVConvertTest, RotateWithARGBSource) { > // 2x2 frames > uint32_t src[4]; >@@ -1928,4 +1986,476 @@ TEST_F(LibYUVConvertTest, RotateWithARGBSource) { > EXPECT_EQ(dst[3], src[1]); > } > >+#ifdef HAS_ARGBTOAR30ROW_AVX2 >+TEST_F(LibYUVConvertTest, ARGBToAR30Row_Opt) { >+ // ARGBToAR30Row_AVX2 expects a multiple of 8 pixels. >+ const int kPixels = (benchmark_width_ * benchmark_height_ + 7) & ~7; >+ align_buffer_page_end(src, kPixels * 4); >+ align_buffer_page_end(dst_opt, kPixels * 4); >+ align_buffer_page_end(dst_c, kPixels * 4); >+ MemRandomize(src, kPixels * 4); >+ memset(dst_opt, 0, kPixels * 4); >+ memset(dst_c, 1, kPixels * 4); >+ >+ ARGBToAR30Row_C(src, dst_c, kPixels); >+ >+ int has_avx2 = TestCpuFlag(kCpuHasAVX2); >+ int has_ssse3 = TestCpuFlag(kCpuHasSSSE3); >+ for (int i = 0; i < benchmark_iterations_; ++i) { >+ if (has_avx2) { >+ ARGBToAR30Row_AVX2(src, dst_opt, kPixels); >+ } else if (has_ssse3) { >+ ARGBToAR30Row_SSSE3(src, dst_opt, kPixels); >+ } else { >+ ARGBToAR30Row_C(src, dst_opt, kPixels); >+ } >+ } >+ for (int i = 0; i < kPixels * 4; ++i) { >+ EXPECT_EQ(dst_opt[i], dst_c[i]); >+ } >+ >+ free_aligned_buffer_page_end(src); >+ free_aligned_buffer_page_end(dst_opt); >+ free_aligned_buffer_page_end(dst_c); >+} >+#endif // HAS_ARGBTOAR30ROW_AVX2 >+ >+#ifdef HAS_ABGRTOAR30ROW_AVX2 >+TEST_F(LibYUVConvertTest, ABGRToAR30Row_Opt) { >+ // ABGRToAR30Row_AVX2 expects a multiple of 8 pixels. >+ const int kPixels = (benchmark_width_ * benchmark_height_ + 7) & ~7; >+ align_buffer_page_end(src, kPixels * 4); >+ align_buffer_page_end(dst_opt, kPixels * 4); >+ align_buffer_page_end(dst_c, kPixels * 4); >+ MemRandomize(src, kPixels * 4); >+ memset(dst_opt, 0, kPixels * 4); >+ memset(dst_c, 1, kPixels * 4); >+ >+ ABGRToAR30Row_C(src, dst_c, kPixels); >+ >+ int has_avx2 = TestCpuFlag(kCpuHasAVX2); >+ int has_ssse3 = TestCpuFlag(kCpuHasSSSE3); >+ for (int i = 0; i < benchmark_iterations_; ++i) { >+ if (has_avx2) { >+ ABGRToAR30Row_AVX2(src, dst_opt, kPixels); >+ } else if (has_ssse3) { >+ ABGRToAR30Row_SSSE3(src, dst_opt, kPixels); >+ } else { >+ ABGRToAR30Row_C(src, dst_opt, kPixels); >+ } >+ } >+ for (int i = 0; i < kPixels * 4; ++i) { >+ EXPECT_EQ(dst_opt[i], dst_c[i]); >+ } >+ >+ free_aligned_buffer_page_end(src); >+ free_aligned_buffer_page_end(dst_opt); >+ free_aligned_buffer_page_end(dst_c); >+} >+#endif // HAS_ABGRTOAR30ROW_AVX2 >+ >+// TODO(fbarchard): Fix clamping issue affected by U channel. >+#define TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ >+ ALIGN, YALIGN, W1280, DIFF, N, NEG, SOFF, DOFF) \ >+ TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##N) { \ >+ const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ >+ const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \ >+ const int kStrideB = ALIGNINT(kWidth * BPP_B, ALIGN); \ >+ const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ >+ const int kSizeUV = kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y); \ >+ const int kBpc = 2; \ >+ align_buffer_page_end(src_y, kWidth* kHeight* kBpc + SOFF); \ >+ align_buffer_page_end(src_u, kSizeUV* kBpc + SOFF); \ >+ align_buffer_page_end(src_v, kSizeUV* kBpc + SOFF); \ >+ align_buffer_page_end(dst_argb_c, kStrideB* kHeight + DOFF); \ >+ align_buffer_page_end(dst_argb_opt, kStrideB* kHeight + DOFF); \ >+ for (int i = 0; i < kWidth * kHeight; ++i) { \ >+ reinterpret_cast<uint16_t*>(src_y + SOFF)[i] = (fastrand() & 0x3ff); \ >+ } \ >+ for (int i = 0; i < kSizeUV; ++i) { \ >+ reinterpret_cast<uint16_t*>(src_u + SOFF)[i] = (fastrand() & 0x3ff); \ >+ reinterpret_cast<uint16_t*>(src_v + SOFF)[i] = (fastrand() & 0x3ff); \ >+ } \ >+ memset(dst_argb_c + DOFF, 1, kStrideB * kHeight); \ >+ memset(dst_argb_opt + DOFF, 101, kStrideB * kHeight); \ >+ MaskCpuFlags(disable_cpu_flags_); \ >+ FMT_PLANAR##To##FMT_B( \ >+ reinterpret_cast<uint16_t*>(src_y + SOFF), kWidth, \ >+ reinterpret_cast<uint16_t*>(src_u + SOFF), kStrideUV, \ >+ reinterpret_cast<uint16_t*>(src_v + SOFF), kStrideUV, \ >+ dst_argb_c + DOFF, kStrideB, kWidth, NEG kHeight); \ >+ MaskCpuFlags(benchmark_cpu_info_); \ >+ for (int i = 0; i < benchmark_iterations_; ++i) { \ >+ FMT_PLANAR##To##FMT_B( \ >+ reinterpret_cast<uint16_t*>(src_y + SOFF), kWidth, \ >+ reinterpret_cast<uint16_t*>(src_u + SOFF), kStrideUV, \ >+ reinterpret_cast<uint16_t*>(src_v + SOFF), kStrideUV, \ >+ dst_argb_opt + DOFF, kStrideB, kWidth, NEG kHeight); \ >+ } \ >+ int max_diff = 0; \ >+ for (int i = 0; i < kWidth * BPP_B * kHeight; ++i) { \ >+ int abs_diff = abs(static_cast<int>(dst_argb_c[i + DOFF]) - \ >+ static_cast<int>(dst_argb_opt[i + DOFF])); \ >+ if (abs_diff > max_diff) { \ >+ max_diff = abs_diff; \ >+ } \ >+ } \ >+ EXPECT_LE(max_diff, DIFF); \ >+ free_aligned_buffer_page_end(src_y); \ >+ free_aligned_buffer_page_end(src_u); \ >+ free_aligned_buffer_page_end(src_v); \ >+ free_aligned_buffer_page_end(dst_argb_c); \ >+ free_aligned_buffer_page_end(dst_argb_opt); \ >+ } >+ >+#define TESTPLANAR16TOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN, DIFF) \ >+ TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, 0) \ >+ TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, 1) \ >+ TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN, benchmark_width_, DIFF, _Invert, -, 0, 0) \ >+ TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ >+ YALIGN, benchmark_width_, DIFF, _Opt, +, 0, 0) >+ >+TESTPLANAR16TOB(I010, 2, 2, ARGB, 4, 4, 1, 2) >+TESTPLANAR16TOB(I010, 2, 2, ABGR, 4, 4, 1, 2) >+TESTPLANAR16TOB(I010, 2, 2, AR30, 4, 4, 1, 2) >+TESTPLANAR16TOB(I010, 2, 2, AB30, 4, 4, 1, 2) >+TESTPLANAR16TOB(H010, 2, 2, ARGB, 4, 4, 1, 2) >+TESTPLANAR16TOB(H010, 2, 2, ABGR, 4, 4, 1, 2) >+TESTPLANAR16TOB(H010, 2, 2, AR30, 4, 4, 1, 2) >+TESTPLANAR16TOB(H010, 2, 2, AB30, 4, 4, 1, 2) >+ >+static int Clamp(int y) { >+ if (y < 0) { >+ y = 0; >+ } >+ if (y > 255) { >+ y = 255; >+ } >+ return y; >+} >+ >+static int Clamp10(int y) { >+ if (y < 0) { >+ y = 0; >+ } >+ if (y > 1023) { >+ y = 1023; >+ } >+ return y; >+} >+ >+// Test 8 bit YUV to 8 bit RGB >+TEST_F(LibYUVConvertTest, TestH420ToARGB) { >+ const int kSize = 256; >+ int histogram_b[256]; >+ int histogram_g[256]; >+ int histogram_r[256]; >+ memset(histogram_b, 0, sizeof(histogram_b)); >+ memset(histogram_g, 0, sizeof(histogram_g)); >+ memset(histogram_r, 0, sizeof(histogram_r)); >+ align_buffer_page_end(orig_yuv, kSize + kSize / 2 * 2); >+ align_buffer_page_end(argb_pixels, kSize * 4); >+ uint8_t* orig_y = orig_yuv; >+ uint8_t* orig_u = orig_y + kSize; >+ uint8_t* orig_v = orig_u + kSize / 2; >+ >+ // Test grey scale >+ for (int i = 0; i < kSize; ++i) { >+ orig_y[i] = i; >+ } >+ for (int i = 0; i < kSize / 2; ++i) { >+ orig_u[i] = 128; // 128 is 0. >+ orig_v[i] = 128; >+ } >+ >+ H420ToARGB(orig_y, 0, orig_u, 0, orig_v, 0, argb_pixels, 0, kSize, 1); >+ >+ for (int i = 0; i < kSize; ++i) { >+ int b = argb_pixels[i * 4 + 0]; >+ int g = argb_pixels[i * 4 + 1]; >+ int r = argb_pixels[i * 4 + 2]; >+ int a = argb_pixels[i * 4 + 3]; >+ ++histogram_b[b]; >+ ++histogram_g[g]; >+ ++histogram_r[r]; >+ int expected_y = Clamp(static_cast<int>((i - 16) * 1.164f)); >+ EXPECT_NEAR(b, expected_y, 1); >+ EXPECT_NEAR(g, expected_y, 1); >+ EXPECT_NEAR(r, expected_y, 1); >+ EXPECT_EQ(a, 255); >+ } >+ >+ int count_b = 0; >+ int count_g = 0; >+ int count_r = 0; >+ for (int i = 0; i < kSize; ++i) { >+ if (histogram_b[i]) { >+ ++count_b; >+ } >+ if (histogram_g[i]) { >+ ++count_g; >+ } >+ if (histogram_r[i]) { >+ ++count_r; >+ } >+ } >+ printf("uniques: B %d, G, %d, R %d\n", count_b, count_g, count_r); >+ >+ free_aligned_buffer_page_end(orig_yuv); >+ free_aligned_buffer_page_end(argb_pixels); >+} >+ >+// Test 10 bit YUV to 8 bit RGB >+TEST_F(LibYUVConvertTest, TestH010ToARGB) { >+ const int kSize = 1024; >+ int histogram_b[1024]; >+ int histogram_g[1024]; >+ int histogram_r[1024]; >+ memset(histogram_b, 0, sizeof(histogram_b)); >+ memset(histogram_g, 0, sizeof(histogram_g)); >+ memset(histogram_r, 0, sizeof(histogram_r)); >+ align_buffer_page_end(orig_yuv, kSize * 2 + kSize / 2 * 2 * 2); >+ align_buffer_page_end(argb_pixels, kSize * 4); >+ uint16_t* orig_y = reinterpret_cast<uint16_t*>(orig_yuv); >+ uint16_t* orig_u = orig_y + kSize; >+ uint16_t* orig_v = orig_u + kSize / 2; >+ >+ // Test grey scale >+ for (int i = 0; i < kSize; ++i) { >+ orig_y[i] = i; >+ } >+ for (int i = 0; i < kSize / 2; ++i) { >+ orig_u[i] = 512; // 512 is 0. >+ orig_v[i] = 512; >+ } >+ >+ H010ToARGB(orig_y, 0, orig_u, 0, orig_v, 0, argb_pixels, 0, kSize, 1); >+ >+ for (int i = 0; i < kSize; ++i) { >+ int b = argb_pixels[i * 4 + 0]; >+ int g = argb_pixels[i * 4 + 1]; >+ int r = argb_pixels[i * 4 + 2]; >+ int a = argb_pixels[i * 4 + 3]; >+ ++histogram_b[b]; >+ ++histogram_g[g]; >+ ++histogram_r[r]; >+ int expected_y = Clamp(static_cast<int>((i - 64) * 1.164f / 4)); >+ EXPECT_NEAR(b, expected_y, 1); >+ EXPECT_NEAR(g, expected_y, 1); >+ EXPECT_NEAR(r, expected_y, 1); >+ EXPECT_EQ(a, 255); >+ } >+ >+ int count_b = 0; >+ int count_g = 0; >+ int count_r = 0; >+ for (int i = 0; i < kSize; ++i) { >+ if (histogram_b[i]) { >+ ++count_b; >+ } >+ if (histogram_g[i]) { >+ ++count_g; >+ } >+ if (histogram_r[i]) { >+ ++count_r; >+ } >+ } >+ printf("uniques: B %d, G, %d, R %d\n", count_b, count_g, count_r); >+ >+ free_aligned_buffer_page_end(orig_yuv); >+ free_aligned_buffer_page_end(argb_pixels); >+} >+ >+// Test 10 bit YUV to 10 bit RGB >+// Caveat: Result is near due to float rounding in expected result. >+TEST_F(LibYUVConvertTest, TestH010ToAR30) { >+ const int kSize = 1024; >+ int histogram_b[1024]; >+ int histogram_g[1024]; >+ int histogram_r[1024]; >+ memset(histogram_b, 0, sizeof(histogram_b)); >+ memset(histogram_g, 0, sizeof(histogram_g)); >+ memset(histogram_r, 0, sizeof(histogram_r)); >+ >+ align_buffer_page_end(orig_yuv, kSize * 2 + kSize / 2 * 2 * 2); >+ align_buffer_page_end(ar30_pixels, kSize * 4); >+ uint16_t* orig_y = reinterpret_cast<uint16_t*>(orig_yuv); >+ uint16_t* orig_u = orig_y + kSize; >+ uint16_t* orig_v = orig_u + kSize / 2; >+ >+ // Test grey scale >+ for (int i = 0; i < kSize; ++i) { >+ orig_y[i] = i; >+ } >+ for (int i = 0; i < kSize / 2; ++i) { >+ orig_u[i] = 512; // 512 is 0. >+ orig_v[i] = 512; >+ } >+ >+ H010ToAR30(orig_y, 0, orig_u, 0, orig_v, 0, ar30_pixels, 0, kSize, 1); >+ >+ for (int i = 0; i < kSize; ++i) { >+ int b10 = reinterpret_cast<uint32_t*>(ar30_pixels)[i] & 1023; >+ int g10 = (reinterpret_cast<uint32_t*>(ar30_pixels)[i] >> 10) & 1023; >+ int r10 = (reinterpret_cast<uint32_t*>(ar30_pixels)[i] >> 20) & 1023; >+ int a2 = (reinterpret_cast<uint32_t*>(ar30_pixels)[i] >> 30) & 3; >+ ++histogram_b[b10]; >+ ++histogram_g[g10]; >+ ++histogram_r[r10]; >+ int expected_y = Clamp10(static_cast<int>((i - 64) * 1.164f)); >+ EXPECT_NEAR(b10, expected_y, 4); >+ EXPECT_NEAR(g10, expected_y, 4); >+ EXPECT_NEAR(r10, expected_y, 4); >+ EXPECT_EQ(a2, 3); >+ } >+ >+ int count_b = 0; >+ int count_g = 0; >+ int count_r = 0; >+ for (int i = 0; i < kSize; ++i) { >+ if (histogram_b[i]) { >+ ++count_b; >+ } >+ if (histogram_g[i]) { >+ ++count_g; >+ } >+ if (histogram_r[i]) { >+ ++count_r; >+ } >+ } >+ printf("uniques: B %d, G, %d, R %d\n", count_b, count_g, count_r); >+ >+ free_aligned_buffer_page_end(orig_yuv); >+ free_aligned_buffer_page_end(ar30_pixels); >+} >+ >+// Test 10 bit YUV to 10 bit RGB >+// Caveat: Result is near due to float rounding in expected result. >+TEST_F(LibYUVConvertTest, TestH010ToAB30) { >+ const int kSize = 1024; >+ int histogram_b[1024]; >+ int histogram_g[1024]; >+ int histogram_r[1024]; >+ memset(histogram_b, 0, sizeof(histogram_b)); >+ memset(histogram_g, 0, sizeof(histogram_g)); >+ memset(histogram_r, 0, sizeof(histogram_r)); >+ >+ align_buffer_page_end(orig_yuv, kSize * 2 + kSize / 2 * 2 * 2); >+ align_buffer_page_end(ab30_pixels, kSize * 4); >+ uint16_t* orig_y = reinterpret_cast<uint16_t*>(orig_yuv); >+ uint16_t* orig_u = orig_y + kSize; >+ uint16_t* orig_v = orig_u + kSize / 2; >+ >+ // Test grey scale >+ for (int i = 0; i < kSize; ++i) { >+ orig_y[i] = i; >+ } >+ for (int i = 0; i < kSize / 2; ++i) { >+ orig_u[i] = 512; // 512 is 0. >+ orig_v[i] = 512; >+ } >+ >+ H010ToAB30(orig_y, 0, orig_u, 0, orig_v, 0, ab30_pixels, 0, kSize, 1); >+ >+ for (int i = 0; i < kSize; ++i) { >+ int r10 = reinterpret_cast<uint32_t*>(ab30_pixels)[i] & 1023; >+ int g10 = (reinterpret_cast<uint32_t*>(ab30_pixels)[i] >> 10) & 1023; >+ int b10 = (reinterpret_cast<uint32_t*>(ab30_pixels)[i] >> 20) & 1023; >+ int a2 = (reinterpret_cast<uint32_t*>(ab30_pixels)[i] >> 30) & 3; >+ ++histogram_b[b10]; >+ ++histogram_g[g10]; >+ ++histogram_r[r10]; >+ int expected_y = Clamp10(static_cast<int>((i - 64) * 1.164f)); >+ EXPECT_NEAR(b10, expected_y, 4); >+ EXPECT_NEAR(g10, expected_y, 4); >+ EXPECT_NEAR(r10, expected_y, 4); >+ EXPECT_EQ(a2, 3); >+ } >+ >+ int count_b = 0; >+ int count_g = 0; >+ int count_r = 0; >+ for (int i = 0; i < kSize; ++i) { >+ if (histogram_b[i]) { >+ ++count_b; >+ } >+ if (histogram_g[i]) { >+ ++count_g; >+ } >+ if (histogram_r[i]) { >+ ++count_r; >+ } >+ } >+ printf("uniques: B %d, G, %d, R %d\n", count_b, count_g, count_r); >+ >+ free_aligned_buffer_page_end(orig_yuv); >+ free_aligned_buffer_page_end(ab30_pixels); >+} >+ >+// Test 8 bit YUV to 10 bit RGB >+TEST_F(LibYUVConvertTest, TestH420ToAR30) { >+ const int kSize = 256; >+ const int kHistSize = 1024; >+ int histogram_b[kHistSize]; >+ int histogram_g[kHistSize]; >+ int histogram_r[kHistSize]; >+ memset(histogram_b, 0, sizeof(histogram_b)); >+ memset(histogram_g, 0, sizeof(histogram_g)); >+ memset(histogram_r, 0, sizeof(histogram_r)); >+ align_buffer_page_end(orig_yuv, kSize + kSize / 2 * 2); >+ align_buffer_page_end(ar30_pixels, kSize * 4); >+ uint8_t* orig_y = orig_yuv; >+ uint8_t* orig_u = orig_y + kSize; >+ uint8_t* orig_v = orig_u + kSize / 2; >+ >+ // Test grey scale >+ for (int i = 0; i < kSize; ++i) { >+ orig_y[i] = i; >+ } >+ for (int i = 0; i < kSize / 2; ++i) { >+ orig_u[i] = 128; // 128 is 0. >+ orig_v[i] = 128; >+ } >+ >+ H420ToAR30(orig_y, 0, orig_u, 0, orig_v, 0, ar30_pixels, 0, kSize, 1); >+ >+ for (int i = 0; i < kSize; ++i) { >+ int b10 = reinterpret_cast<uint32_t*>(ar30_pixels)[i] & 1023; >+ int g10 = (reinterpret_cast<uint32_t*>(ar30_pixels)[i] >> 10) & 1023; >+ int r10 = (reinterpret_cast<uint32_t*>(ar30_pixels)[i] >> 20) & 1023; >+ int a2 = (reinterpret_cast<uint32_t*>(ar30_pixels)[i] >> 30) & 3; >+ ++histogram_b[b10]; >+ ++histogram_g[g10]; >+ ++histogram_r[r10]; >+ int expected_y = Clamp10(static_cast<int>((i - 16) * 1.164f * 4.f)); >+ EXPECT_NEAR(b10, expected_y, 4); >+ EXPECT_NEAR(g10, expected_y, 4); >+ EXPECT_NEAR(r10, expected_y, 4); >+ EXPECT_EQ(a2, 3); >+ } >+ >+ int count_b = 0; >+ int count_g = 0; >+ int count_r = 0; >+ for (int i = 0; i < kHistSize; ++i) { >+ if (histogram_b[i]) { >+ ++count_b; >+ } >+ if (histogram_g[i]) { >+ ++count_g; >+ } >+ if (histogram_r[i]) { >+ ++count_r; >+ } >+ } >+ printf("uniques: B %d, G, %d, R %d\n", count_b, count_g, count_r); >+ >+ free_aligned_buffer_page_end(orig_yuv); >+ free_aligned_buffer_page_end(ar30_pixels); >+} >+ > } // namespace libyuv >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/cpu_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/cpu_test.cc >index 4e694f55ce57f44b3b0e8e94d8a15eed554c1572..a8fb4b4ac01f16fc7525c39a20c66478ea0fccaa 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/cpu_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/cpu_test.cc >@@ -65,8 +65,6 @@ TEST_F(LibYUVBaseTest, TestCpuHas) { > #if defined(__mips__) > int has_mips = TestCpuFlag(kCpuHasMIPS); > printf("Has MIPS %x\n", has_mips); >- int has_dspr2 = TestCpuFlag(kCpuHasDSPR2); >- printf("Has DSPR2 %x\n", has_dspr2); > int has_msa = TestCpuFlag(kCpuHasMSA); > printf("Has MSA %x\n", has_msa); > #endif >@@ -147,6 +145,8 @@ static int FileExists(const char* file_name) { > > TEST_F(LibYUVBaseTest, TestLinuxNeon) { > if (FileExists("../../unit_test/testdata/arm_v7.txt")) { >+ printf("Note: testing to load \"../../unit_test/testdata/arm_v7.txt\"\n"); >+ > EXPECT_EQ(0, ArmCpuCaps("../../unit_test/testdata/arm_v7.txt")); > EXPECT_EQ(kCpuHasNEON, ArmCpuCaps("../../unit_test/testdata/tegra3.txt")); > EXPECT_EQ(kCpuHasNEON, ArmCpuCaps("../../unit_test/testdata/juno.txt")); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/math_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/math_test.cc >index 2b4b57b1cea4f634ebb896eb543708fd32d094a0..0abbad513210124ccc733512bcf7a7bec059a378 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/math_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/math_test.cc >@@ -65,8 +65,8 @@ TEST_F(LibYUVBaseTest, TestFixedDiv) { > } > EXPECT_EQ(123 * 65536, libyuv::FixedDiv(123, 1)); > >- MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num)); >- MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div)); >+ MemRandomize(reinterpret_cast<uint8_t*>(&num[0]), sizeof(num)); >+ MemRandomize(reinterpret_cast<uint8_t*>(&div[0]), sizeof(div)); > for (int j = 0; j < 1280; ++j) { > if (div[j] == 0) { > div[j] = 1280; >@@ -90,8 +90,8 @@ TEST_F(LibYUVBaseTest, TestFixedDiv_Opt) { > int result_opt[1280]; > int result_c[1280]; > >- MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num)); >- MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div)); >+ MemRandomize(reinterpret_cast<uint8_t*>(&num[0]), sizeof(num)); >+ MemRandomize(reinterpret_cast<uint8_t*>(&div[0]), sizeof(div)); > for (int j = 0; j < 1280; ++j) { > num[j] &= 4095; // Make numerator smaller. > div[j] &= 4095; // Make divisor smaller. >@@ -124,8 +124,8 @@ TEST_F(LibYUVBaseTest, TestFixedDiv1_Opt) { > int result_opt[1280]; > int result_c[1280]; > >- MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num)); >- MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div)); >+ MemRandomize(reinterpret_cast<uint8_t*>(&num[0]), sizeof(num)); >+ MemRandomize(reinterpret_cast<uint8_t*>(&div[0]), sizeof(div)); > for (int j = 0; j < 1280; ++j) { > num[j] &= 4095; // Make numerator smaller. > div[j] &= 4095; // Make divisor smaller. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/planar_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/planar_test.cc >index f9e6f8abb2fca5a3197ca3e9008f2c0818f1d535..756089558f792c529ad88d2a6e221e904eb2de5c 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/planar_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/planar_test.cc >@@ -252,8 +252,8 @@ TEST_F(LibYUVPlanarTest, ARGBUnattenuate_Opt) { > } > > TEST_F(LibYUVPlanarTest, TestARGBComputeCumulativeSum) { >- SIMD_ALIGNED(uint8 orig_pixels[16][16][4]); >- SIMD_ALIGNED(int32 added_pixels[16][16][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[16][16][4]); >+ SIMD_ALIGNED(int32_t added_pixels[16][16][4]); > > for (int y = 0; y < 16; ++y) { > for (int x = 0; x < 16; ++x) { >@@ -278,7 +278,7 @@ TEST_F(LibYUVPlanarTest, TestARGBComputeCumulativeSum) { > } > > TEST_F(LibYUVPlanarTest, TestARGBGray) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); > memset(orig_pixels, 0, sizeof(orig_pixels)); > > // Test blue >@@ -349,8 +349,8 @@ TEST_F(LibYUVPlanarTest, TestARGBGray) { > } > > TEST_F(LibYUVPlanarTest, TestARGBGrayTo) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >- SIMD_ALIGNED(uint8 gray_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t gray_pixels[1280][4]); > memset(orig_pixels, 0, sizeof(orig_pixels)); > > // Test blue >@@ -421,7 +421,7 @@ TEST_F(LibYUVPlanarTest, TestARGBGrayTo) { > } > > TEST_F(LibYUVPlanarTest, TestARGBSepia) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); > memset(orig_pixels, 0, sizeof(orig_pixels)); > > // Test blue >@@ -493,12 +493,12 @@ TEST_F(LibYUVPlanarTest, TestARGBSepia) { > } > > TEST_F(LibYUVPlanarTest, TestARGBColorMatrix) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >- SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]); >- SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t dst_pixels_opt[1280][4]); >+ SIMD_ALIGNED(uint8_t dst_pixels_c[1280][4]); > > // Matrix for Sepia. >- SIMD_ALIGNED(static const int8 kRGBToSepia[]) = { >+ SIMD_ALIGNED(static const int8_t kRGBToSepia[]) = { > 17 / 2, 68 / 2, 35 / 2, 0, 22 / 2, 88 / 2, 45 / 2, 0, > 24 / 2, 98 / 2, 50 / 2, 0, 0, 0, 0, 64, // Copy alpha. > }; >@@ -569,10 +569,10 @@ TEST_F(LibYUVPlanarTest, TestARGBColorMatrix) { > } > > TEST_F(LibYUVPlanarTest, TestRGBColorMatrix) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); > > // Matrix for Sepia. >- SIMD_ALIGNED(static const int8 kRGBToSepia[]) = { >+ SIMD_ALIGNED(static const int8_t kRGBToSepia[]) = { > 17, 68, 35, 0, 22, 88, 45, 0, > 24, 98, 50, 0, 0, 0, 0, 0, // Unused but makes matrix 16 bytes. > }; >@@ -629,11 +629,11 @@ TEST_F(LibYUVPlanarTest, TestRGBColorMatrix) { > } > > TEST_F(LibYUVPlanarTest, TestARGBColorTable) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); > memset(orig_pixels, 0, sizeof(orig_pixels)); > > // Matrix for Sepia. >- static const uint8 kARGBTable[256 * 4] = { >+ static const uint8_t kARGBTable[256 * 4] = { > 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u, 16u, > }; > >@@ -685,11 +685,11 @@ TEST_F(LibYUVPlanarTest, TestARGBColorTable) { > > // Same as TestARGBColorTable except alpha does not change. > TEST_F(LibYUVPlanarTest, TestRGBColorTable) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); > memset(orig_pixels, 0, sizeof(orig_pixels)); > > // Matrix for Sepia. >- static const uint8 kARGBTable[256 * 4] = { >+ static const uint8_t kARGBTable[256 * 4] = { > 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u, 16u, > }; > >@@ -740,7 +740,7 @@ TEST_F(LibYUVPlanarTest, TestRGBColorTable) { > } > > TEST_F(LibYUVPlanarTest, TestARGBQuantize) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); > > for (int i = 0; i < 1280; ++i) { > orig_pixels[i][0] = i; >@@ -764,8 +764,8 @@ TEST_F(LibYUVPlanarTest, TestARGBQuantize) { > } > > TEST_F(LibYUVPlanarTest, TestARGBMirror) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >- SIMD_ALIGNED(uint8 dst_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t dst_pixels[1280][4]); > > for (int i = 0; i < 1280; ++i) { > orig_pixels[i][0] = i; >@@ -787,8 +787,8 @@ TEST_F(LibYUVPlanarTest, TestARGBMirror) { > } > > TEST_F(LibYUVPlanarTest, TestShade) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >- SIMD_ALIGNED(uint8 shade_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t shade_pixels[1280][4]); > memset(orig_pixels, 0, sizeof(orig_pixels)); > > orig_pixels[0][0] = 10u; >@@ -845,9 +845,9 @@ TEST_F(LibYUVPlanarTest, TestShade) { > } > > TEST_F(LibYUVPlanarTest, TestARGBInterpolate) { >- SIMD_ALIGNED(uint8 orig_pixels_0[1280][4]); >- SIMD_ALIGNED(uint8 orig_pixels_1[1280][4]); >- SIMD_ALIGNED(uint8 interpolate_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels_0[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels_1[1280][4]); >+ SIMD_ALIGNED(uint8_t interpolate_pixels[1280][4]); > memset(orig_pixels_0, 0, sizeof(orig_pixels_0)); > memset(orig_pixels_1, 0, sizeof(orig_pixels_1)); > >@@ -926,9 +926,9 @@ TEST_F(LibYUVPlanarTest, TestARGBInterpolate) { > } > > TEST_F(LibYUVPlanarTest, TestInterpolatePlane) { >- SIMD_ALIGNED(uint8 orig_pixels_0[1280]); >- SIMD_ALIGNED(uint8 orig_pixels_1[1280]); >- SIMD_ALIGNED(uint8 interpolate_pixels[1280]); >+ SIMD_ALIGNED(uint8_t orig_pixels_0[1280]); >+ SIMD_ALIGNED(uint8_t orig_pixels_1[1280]); >+ SIMD_ALIGNED(uint8_t interpolate_pixels[1280]); > memset(orig_pixels_0, 0, sizeof(orig_pixels_0)); > memset(orig_pixels_1, 0, sizeof(orig_pixels_1)); > >@@ -1192,7 +1192,6 @@ static void TestBlendPlane(int width, > free_aligned_buffer_page_end(src_argb_alpha); > free_aligned_buffer_page_end(dst_argb_c); > free_aligned_buffer_page_end(dst_argb_opt); >- return; > } > > TEST_F(LibYUVPlanarTest, BlendPlane_Opt) { >@@ -1286,7 +1285,6 @@ static void TestI420Blend(int width, > free_aligned_buffer_page_end(dst_y_opt); > free_aligned_buffer_page_end(dst_u_opt); > free_aligned_buffer_page_end(dst_v_opt); >- return; > } > > TEST_F(LibYUVPlanarTest, I420Blend_Opt) { >@@ -1309,8 +1307,8 @@ TEST_F(LibYUVPlanarTest, I420Blend_Invert) { > } > > TEST_F(LibYUVPlanarTest, TestAffine) { >- SIMD_ALIGNED(uint8 orig_pixels_0[1280][4]); >- SIMD_ALIGNED(uint8 interpolate_pixels_C[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels_0[1280][4]); >+ SIMD_ALIGNED(uint8_t interpolate_pixels_C[1280][4]); > > for (int i = 0; i < 1280; ++i) { > for (int j = 0; j < 4; ++j) { >@@ -1327,7 +1325,7 @@ TEST_F(LibYUVPlanarTest, TestAffine) { > EXPECT_EQ(191u, interpolate_pixels_C[255][3]); > > #if defined(HAS_ARGBAFFINEROW_SSE2) >- SIMD_ALIGNED(uint8 interpolate_pixels_Opt[1280][4]); >+ SIMD_ALIGNED(uint8_t interpolate_pixels_Opt[1280][4]); > ARGBAffineRow_SSE2(&orig_pixels_0[0][0], 0, &interpolate_pixels_Opt[0][0], > uv_step, 1280); > EXPECT_EQ(0, memcmp(interpolate_pixels_Opt, interpolate_pixels_C, 1280 * 4)); >@@ -1367,7 +1365,7 @@ TEST_F(LibYUVPlanarTest, TestCopyPlane) { > > // Fill destination buffers with random data. > for (i = 0; i < y_plane_size; ++i) { >- uint8 random_number = fastrand() & 0x7f; >+ uint8_t random_number = fastrand() & 0x7f; > dst_c[i] = random_number; > dst_opt[i] = dst_c[i]; > } >@@ -1390,8 +1388,9 @@ TEST_F(LibYUVPlanarTest, TestCopyPlane) { > } > > for (i = 0; i < y_plane_size; ++i) { >- if (dst_c[i] != dst_opt[i]) >+ if (dst_c[i] != dst_opt[i]) { > ++err; >+ } > } > > free_aligned_buffer_page_end(orig_y); >@@ -1867,12 +1866,12 @@ static int TestBlur(int width, > > MaskCpuFlags(disable_cpu_flags); > ARGBBlur(src_argb_a + off, kStride, dst_argb_c, kStride, >- reinterpret_cast<int32*>(dst_cumsum), width * 4, width, >+ reinterpret_cast<int32_t*>(dst_cumsum), width * 4, width, > invert * height, radius); > MaskCpuFlags(benchmark_cpu_info); > for (int i = 0; i < benchmark_iterations; ++i) { > ARGBBlur(src_argb_a + off, kStride, dst_argb_opt, kStride, >- reinterpret_cast<int32*>(dst_cumsum), width * 4, width, >+ reinterpret_cast<int32_t*>(dst_cumsum), width * 4, width, > invert * height, radius); > } > int max_diff = 0; >@@ -1949,9 +1948,9 @@ TEST_F(LibYUVPlanarTest, ARGBBlurSmall_Opt) { > } > > TEST_F(LibYUVPlanarTest, TestARGBPolynomial) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >- SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]); >- SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t dst_pixels_opt[1280][4]); >+ SIMD_ALIGNED(uint8_t dst_pixels_c[1280][4]); > memset(orig_pixels, 0, sizeof(orig_pixels)); > > SIMD_ALIGNED(static const float kWarmifyPolynomial[16]) = { >@@ -2046,37 +2045,38 @@ int TestHalfFloatPlane(int benchmark_width, > const int y_plane_size = benchmark_width * benchmark_height * 2; > > align_buffer_page_end(orig_y, y_plane_size * 3); >- uint8* dst_opt = orig_y + y_plane_size; >- uint8* dst_c = orig_y + y_plane_size * 2; >+ uint8_t* dst_opt = orig_y + y_plane_size; >+ uint8_t* dst_c = orig_y + y_plane_size * 2; > > MemRandomize(orig_y, y_plane_size); > memset(dst_c, 0, y_plane_size); > memset(dst_opt, 1, y_plane_size); > > for (i = 0; i < y_plane_size / 2; ++i) { >- reinterpret_cast<uint16*>(orig_y)[i] &= mask; >+ reinterpret_cast<uint16_t*>(orig_y)[i] &= mask; > } > > // Disable all optimizations. > MaskCpuFlags(disable_cpu_flags); > for (j = 0; j < benchmark_iterations; j++) { >- HalfFloatPlane(reinterpret_cast<uint16*>(orig_y), benchmark_width * 2, >- reinterpret_cast<uint16*>(dst_c), benchmark_width * 2, scale, >- benchmark_width, benchmark_height); >+ HalfFloatPlane(reinterpret_cast<uint16_t*>(orig_y), benchmark_width * 2, >+ reinterpret_cast<uint16_t*>(dst_c), benchmark_width * 2, >+ scale, benchmark_width, benchmark_height); > } > > // Enable optimizations. > MaskCpuFlags(benchmark_cpu_info); > for (j = 0; j < benchmark_iterations; j++) { >- HalfFloatPlane(reinterpret_cast<uint16*>(orig_y), benchmark_width * 2, >- reinterpret_cast<uint16*>(dst_opt), benchmark_width * 2, >+ HalfFloatPlane(reinterpret_cast<uint16_t*>(orig_y), benchmark_width * 2, >+ reinterpret_cast<uint16_t*>(dst_opt), benchmark_width * 2, > scale, benchmark_width, benchmark_height); > } > > int max_diff = 0; > for (i = 0; i < y_plane_size / 2; ++i) { >- int abs_diff = abs(static_cast<int>(reinterpret_cast<uint16*>(dst_c)[i]) - >- static_cast<int>(reinterpret_cast<uint16*>(dst_opt)[i])); >+ int abs_diff = >+ abs(static_cast<int>(reinterpret_cast<uint16_t*>(dst_c)[i]) - >+ static_cast<int>(reinterpret_cast<uint16_t*>(dst_opt)[i])); > if (abs_diff > max_diff) { > max_diff = abs_diff; > } >@@ -2168,10 +2168,56 @@ TEST_F(LibYUVPlanarTest, TestHalfFloatPlane_12bit_One) { > EXPECT_LE(diff, 1); > } > >+float TestByteToFloat(int benchmark_width, >+ int benchmark_height, >+ int benchmark_iterations, >+ int disable_cpu_flags, >+ int benchmark_cpu_info, >+ float scale) { >+ int i, j; >+ const int y_plane_size = benchmark_width * benchmark_height; >+ >+ align_buffer_page_end(orig_y, y_plane_size * (1 + 4 + 4)); >+ float* dst_opt = reinterpret_cast<float*>(orig_y + y_plane_size); >+ float* dst_c = reinterpret_cast<float*>(orig_y + y_plane_size * 5); >+ >+ MemRandomize(orig_y, y_plane_size); >+ memset(dst_c, 0, y_plane_size * 4); >+ memset(dst_opt, 1, y_plane_size * 4); >+ >+ // Disable all optimizations. >+ MaskCpuFlags(disable_cpu_flags); >+ ByteToFloat(orig_y, dst_c, scale, y_plane_size); >+ >+ // Enable optimizations. >+ MaskCpuFlags(benchmark_cpu_info); >+ for (j = 0; j < benchmark_iterations; j++) { >+ ByteToFloat(orig_y, dst_opt, scale, y_plane_size); >+ } >+ >+ float max_diff = 0; >+ for (i = 0; i < y_plane_size; ++i) { >+ float abs_diff = fabs(dst_c[i] - dst_opt[i]); >+ if (abs_diff > max_diff) { >+ max_diff = abs_diff; >+ } >+ } >+ >+ free_aligned_buffer_page_end(orig_y); >+ return max_diff; >+} >+ >+TEST_F(LibYUVPlanarTest, TestByteToFloat) { >+ float diff = TestByteToFloat(benchmark_width_, benchmark_height_, >+ benchmark_iterations_, disable_cpu_flags_, >+ benchmark_cpu_info_, 1.0f); >+ EXPECT_EQ(0.f, diff); >+} >+ > TEST_F(LibYUVPlanarTest, TestARGBLumaColorTable) { >- SIMD_ALIGNED(uint8 orig_pixels[1280][4]); >- SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]); >- SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]); >+ SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); >+ SIMD_ALIGNED(uint8_t dst_pixels_opt[1280][4]); >+ SIMD_ALIGNED(uint8_t dst_pixels_c[1280][4]); > memset(orig_pixels, 0, sizeof(orig_pixels)); > > align_buffer_page_end(lumacolortable, 32768); >@@ -2343,7 +2389,7 @@ static int TestARGBRect(int width, > } > const int kStride = width * bpp; > const int kSize = kStride * height; >- const uint32 v32 = fastrand() & (bpp == 4 ? 0xffffffff : 0xff); >+ const uint32_t v32 = fastrand() & (bpp == 4 ? 0xffffffff : 0xff); > > align_buffer_page_end(dst_argb_c, kSize + off); > align_buffer_page_end(dst_argb_opt, kSize + off); >@@ -2631,21 +2677,21 @@ TEST_F(LibYUVPlanarTest, MergeUVRow_16_Opt) { > memset(dst_pixels_uv_opt, 0, kPixels * 2 * 2); > memset(dst_pixels_uv_c, 1, kPixels * 2 * 2); > >- MergeUVRow_16_C(reinterpret_cast<const uint16*>(src_pixels_u), >- reinterpret_cast<const uint16*>(src_pixels_v), >- reinterpret_cast<uint16*>(dst_pixels_uv_c), 64, kPixels); >+ MergeUVRow_16_C(reinterpret_cast<const uint16_t*>(src_pixels_u), >+ reinterpret_cast<const uint16_t*>(src_pixels_v), >+ reinterpret_cast<uint16_t*>(dst_pixels_uv_c), 64, kPixels); > > int has_avx2 = TestCpuFlag(kCpuHasAVX2); > for (int i = 0; i < benchmark_iterations_; ++i) { > if (has_avx2) { >- MergeUVRow_16_AVX2(reinterpret_cast<const uint16*>(src_pixels_u), >- reinterpret_cast<const uint16*>(src_pixels_v), >- reinterpret_cast<uint16*>(dst_pixels_uv_opt), 64, >+ MergeUVRow_16_AVX2(reinterpret_cast<const uint16_t*>(src_pixels_u), >+ reinterpret_cast<const uint16_t*>(src_pixels_v), >+ reinterpret_cast<uint16_t*>(dst_pixels_uv_opt), 64, > kPixels); > } else { >- MergeUVRow_16_C(reinterpret_cast<const uint16*>(src_pixels_u), >- reinterpret_cast<const uint16*>(src_pixels_v), >- reinterpret_cast<uint16*>(dst_pixels_uv_opt), 64, >+ MergeUVRow_16_C(reinterpret_cast<const uint16_t*>(src_pixels_u), >+ reinterpret_cast<const uint16_t*>(src_pixels_v), >+ reinterpret_cast<uint16_t*>(dst_pixels_uv_opt), 64, > kPixels); > } > } >@@ -2661,7 +2707,7 @@ TEST_F(LibYUVPlanarTest, MergeUVRow_16_Opt) { > } > #endif > >-// TODO(fbarchard): improve test for platforms and cpu detect >+// TODO(fbarchard): Improve test for more platforms. > #ifdef HAS_MULTIPLYROW_16_AVX2 > TEST_F(LibYUVPlanarTest, MultiplyRow_16_Opt) { > const int kPixels = benchmark_width_ * benchmark_height_; >@@ -2673,18 +2719,18 @@ TEST_F(LibYUVPlanarTest, MultiplyRow_16_Opt) { > memset(dst_pixels_y_opt, 0, kPixels * 2); > memset(dst_pixels_y_c, 1, kPixels * 2); > >- MultiplyRow_16_C(reinterpret_cast<const uint16*>(src_pixels_y), >- reinterpret_cast<uint16*>(dst_pixels_y_c), 64, kPixels); >+ MultiplyRow_16_C(reinterpret_cast<const uint16_t*>(src_pixels_y), >+ reinterpret_cast<uint16_t*>(dst_pixels_y_c), 64, kPixels); > > int has_avx2 = TestCpuFlag(kCpuHasAVX2); > for (int i = 0; i < benchmark_iterations_; ++i) { > if (has_avx2) { >- MultiplyRow_16_AVX2(reinterpret_cast<const uint16*>(src_pixels_y), >- reinterpret_cast<uint16*>(dst_pixels_y_opt), 64, >+ MultiplyRow_16_AVX2(reinterpret_cast<const uint16_t*>(src_pixels_y), >+ reinterpret_cast<uint16_t*>(dst_pixels_y_opt), 64, > kPixels); > } else { >- MultiplyRow_16_C(reinterpret_cast<const uint16*>(src_pixels_y), >- reinterpret_cast<uint16*>(dst_pixels_y_opt), 64, >+ MultiplyRow_16_C(reinterpret_cast<const uint16_t*>(src_pixels_y), >+ reinterpret_cast<uint16_t*>(dst_pixels_y_opt), 64, > kPixels); > } > } >@@ -2697,7 +2743,160 @@ TEST_F(LibYUVPlanarTest, MultiplyRow_16_Opt) { > free_aligned_buffer_page_end(dst_pixels_y_opt); > free_aligned_buffer_page_end(dst_pixels_y_c); > } >-#endif >+#endif // HAS_MULTIPLYROW_16_AVX2 >+ >+TEST_F(LibYUVPlanarTest, Convert16To8Plane) { >+ const int kPixels = benchmark_width_ * benchmark_height_; >+ align_buffer_page_end(src_pixels_y, kPixels * 2); >+ align_buffer_page_end(dst_pixels_y_opt, kPixels); >+ align_buffer_page_end(dst_pixels_y_c, kPixels); >+ >+ MemRandomize(src_pixels_y, kPixels * 2); >+ memset(dst_pixels_y_opt, 0, kPixels); >+ memset(dst_pixels_y_c, 1, kPixels); >+ >+ MaskCpuFlags(disable_cpu_flags_); >+ Convert16To8Plane(reinterpret_cast<const uint16_t*>(src_pixels_y), >+ benchmark_width_, dst_pixels_y_c, benchmark_width_, 16384, >+ benchmark_width_, benchmark_height_); >+ MaskCpuFlags(benchmark_cpu_info_); >+ >+ for (int i = 0; i < benchmark_iterations_; ++i) { >+ Convert16To8Plane(reinterpret_cast<const uint16_t*>(src_pixels_y), >+ benchmark_width_, dst_pixels_y_opt, benchmark_width_, >+ 16384, benchmark_width_, benchmark_height_); >+ } >+ >+ for (int i = 0; i < kPixels; ++i) { >+ EXPECT_EQ(dst_pixels_y_opt[i], dst_pixels_y_c[i]); >+ } >+ >+ free_aligned_buffer_page_end(src_pixels_y); >+ free_aligned_buffer_page_end(dst_pixels_y_opt); >+ free_aligned_buffer_page_end(dst_pixels_y_c); >+} >+ >+// TODO(fbarchard): Improve test for more platforms. >+#ifdef HAS_CONVERT16TO8ROW_AVX2 >+TEST_F(LibYUVPlanarTest, Convert16To8Row_Opt) { >+ // AVX2 does multiple of 32, so round count up >+ const int kPixels = (benchmark_width_ * benchmark_height_ + 31) & ~31; >+ align_buffer_page_end(src_pixels_y, kPixels * 2); >+ align_buffer_page_end(dst_pixels_y_opt, kPixels); >+ align_buffer_page_end(dst_pixels_y_c, kPixels); >+ >+ MemRandomize(src_pixels_y, kPixels * 2); >+ // clamp source range to 10 bits. >+ for (int i = 0; i < kPixels; ++i) { >+ reinterpret_cast<uint16_t*>(src_pixels_y)[i] &= 1023; >+ } >+ >+ memset(dst_pixels_y_opt, 0, kPixels); >+ memset(dst_pixels_y_c, 1, kPixels); >+ >+ Convert16To8Row_C(reinterpret_cast<const uint16_t*>(src_pixels_y), >+ dst_pixels_y_c, 16384, kPixels); >+ >+ int has_avx2 = TestCpuFlag(kCpuHasAVX2); >+ int has_ssse3 = TestCpuFlag(kCpuHasSSSE3); >+ for (int i = 0; i < benchmark_iterations_; ++i) { >+ if (has_avx2) { >+ Convert16To8Row_AVX2(reinterpret_cast<const uint16_t*>(src_pixels_y), >+ dst_pixels_y_opt, 16384, kPixels); >+ } else if (has_ssse3) { >+ Convert16To8Row_SSSE3(reinterpret_cast<const uint16_t*>(src_pixels_y), >+ dst_pixels_y_opt, 16384, kPixels); >+ } else { >+ Convert16To8Row_C(reinterpret_cast<const uint16_t*>(src_pixels_y), >+ dst_pixels_y_opt, 16384, kPixels); >+ } >+ } >+ >+ for (int i = 0; i < kPixels; ++i) { >+ EXPECT_EQ(dst_pixels_y_opt[i], dst_pixels_y_c[i]); >+ } >+ >+ free_aligned_buffer_page_end(src_pixels_y); >+ free_aligned_buffer_page_end(dst_pixels_y_opt); >+ free_aligned_buffer_page_end(dst_pixels_y_c); >+} >+#endif // HAS_CONVERT16TO8ROW_AVX2 >+ >+TEST_F(LibYUVPlanarTest, Convert8To16Plane) { >+ const int kPixels = benchmark_width_ * benchmark_height_; >+ align_buffer_page_end(src_pixels_y, kPixels); >+ align_buffer_page_end(dst_pixels_y_opt, kPixels * 2); >+ align_buffer_page_end(dst_pixels_y_c, kPixels * 2); >+ >+ MemRandomize(src_pixels_y, kPixels); >+ memset(dst_pixels_y_opt, 0, kPixels * 2); >+ memset(dst_pixels_y_c, 1, kPixels * 2); >+ >+ MaskCpuFlags(disable_cpu_flags_); >+ Convert8To16Plane(src_pixels_y, benchmark_width_, >+ reinterpret_cast<uint16_t*>(dst_pixels_y_c), >+ benchmark_width_, 1024, benchmark_width_, >+ benchmark_height_); >+ MaskCpuFlags(benchmark_cpu_info_); >+ >+ for (int i = 0; i < benchmark_iterations_; ++i) { >+ Convert8To16Plane(src_pixels_y, benchmark_width_, >+ reinterpret_cast<uint16_t*>(dst_pixels_y_opt), >+ benchmark_width_, 1024, benchmark_width_, >+ benchmark_height_); >+ } >+ >+ for (int i = 0; i < kPixels * 2; ++i) { >+ EXPECT_EQ(dst_pixels_y_opt[i], dst_pixels_y_c[i]); >+ } >+ >+ free_aligned_buffer_page_end(src_pixels_y); >+ free_aligned_buffer_page_end(dst_pixels_y_opt); >+ free_aligned_buffer_page_end(dst_pixels_y_c); >+} >+ >+// TODO(fbarchard): Improve test for more platforms. >+#ifdef HAS_CONVERT8TO16ROW_AVX2 >+TEST_F(LibYUVPlanarTest, Convert8To16Row_Opt) { >+ const int kPixels = (benchmark_width_ * benchmark_height_ + 31) & ~31; >+ align_buffer_page_end(src_pixels_y, kPixels); >+ align_buffer_page_end(dst_pixels_y_opt, kPixels * 2); >+ align_buffer_page_end(dst_pixels_y_c, kPixels * 2); >+ >+ MemRandomize(src_pixels_y, kPixels); >+ memset(dst_pixels_y_opt, 0, kPixels * 2); >+ memset(dst_pixels_y_c, 1, kPixels * 2); >+ >+ Convert8To16Row_C(src_pixels_y, reinterpret_cast<uint16_t*>(dst_pixels_y_c), >+ 1024, kPixels); >+ >+ int has_avx2 = TestCpuFlag(kCpuHasAVX2); >+ int has_sse2 = TestCpuFlag(kCpuHasSSE2); >+ for (int i = 0; i < benchmark_iterations_; ++i) { >+ if (has_avx2) { >+ Convert8To16Row_AVX2(src_pixels_y, >+ reinterpret_cast<uint16_t*>(dst_pixels_y_opt), 1024, >+ kPixels); >+ } else if (has_sse2) { >+ Convert8To16Row_SSE2(src_pixels_y, >+ reinterpret_cast<uint16_t*>(dst_pixels_y_opt), 1024, >+ kPixels); >+ } else { >+ Convert8To16Row_C(src_pixels_y, >+ reinterpret_cast<uint16_t*>(dst_pixels_y_opt), 1024, >+ kPixels); >+ } >+ } >+ >+ for (int i = 0; i < kPixels * 2; ++i) { >+ EXPECT_EQ(dst_pixels_y_opt[i], dst_pixels_y_c[i]); >+ } >+ >+ free_aligned_buffer_page_end(src_pixels_y); >+ free_aligned_buffer_page_end(dst_pixels_y_opt); >+ free_aligned_buffer_page_end(dst_pixels_y_c); >+} >+#endif // HAS_CONVERT8TO16ROW_AVX2 > > float TestScaleMaxSamples(int benchmark_width, > int benchmark_height, >@@ -2709,8 +2908,8 @@ float TestScaleMaxSamples(int benchmark_width, > // NEON does multiple of 8, so round count up > const int kPixels = (benchmark_width * benchmark_height + 7) & ~7; > align_buffer_page_end(orig_y, kPixels * 4 * 3 + 48); >- uint8* dst_c = orig_y + kPixels * 4 + 16; >- uint8* dst_opt = orig_y + kPixels * 4 * 2 + 32; >+ uint8_t* dst_c = orig_y + kPixels * 4 + 16; >+ uint8_t* dst_opt = orig_y + kPixels * 4 * 2 + 32; > > // Randomize works but may contain some denormals affecting performance. > // MemRandomize(orig_y, kPixels * 4); >@@ -2777,8 +2976,8 @@ float TestScaleSumSamples(int benchmark_width, > // NEON does multiple of 8, so round count up > const int kPixels = (benchmark_width * benchmark_height + 7) & ~7; > align_buffer_page_end(orig_y, kPixels * 4 * 3); >- uint8* dst_c = orig_y + kPixels * 4; >- uint8* dst_opt = orig_y + kPixels * 4 * 2; >+ uint8_t* dst_c = orig_y + kPixels * 4; >+ uint8_t* dst_opt = orig_y + kPixels * 4 * 2; > > // Randomize works but may contain some denormals affecting performance. > // MemRandomize(orig_y, kPixels * 4); >@@ -2855,8 +3054,8 @@ float TestScaleSamples(int benchmark_width, > // NEON does multiple of 8, so round count up > const int kPixels = (benchmark_width * benchmark_height + 7) & ~7; > align_buffer_page_end(orig_y, kPixels * 4 * 3); >- uint8* dst_c = orig_y + kPixels * 4; >- uint8* dst_opt = orig_y + kPixels * 4 * 2; >+ uint8_t* dst_c = orig_y + kPixels * 4; >+ uint8_t* dst_opt = orig_y + kPixels * 4 * 2; > > // Randomize works but may contain some denormals affecting performance. > // MemRandomize(orig_y, kPixels * 4); >@@ -2918,8 +3117,8 @@ float TestCopySamples(int benchmark_width, > // NEON does multiple of 16 floats, so round count up > const int kPixels = (benchmark_width * benchmark_height + 15) & ~15; > align_buffer_page_end(orig_y, kPixels * 4 * 3); >- uint8* dst_c = orig_y + kPixels * 4; >- uint8* dst_opt = orig_y + kPixels * 4 * 2; >+ uint8_t* dst_c = orig_y + kPixels * 4; >+ uint8_t* dst_opt = orig_y + kPixels * 4 * 2; > > // Randomize works but may contain some denormals affecting performance. > // MemRandomize(orig_y, kPixels * 4); >@@ -2970,13 +3169,13 @@ TEST_F(LibYUVPlanarTest, TestCopySamples_Opt) { > EXPECT_EQ(0, diff); > } > >-extern "C" void GaussRow_NEON(const uint32* src, uint16* dst, int width); >-extern "C" void GaussRow_C(const uint32* src, uint16* dst, int width); >+extern "C" void GaussRow_NEON(const uint32_t* src, uint16_t* dst, int width); >+extern "C" void GaussRow_C(const uint32_t* src, uint16_t* dst, int width); > > TEST_F(LibYUVPlanarTest, TestGaussRow_Opt) { >- SIMD_ALIGNED(uint32 orig_pixels[640 + 4]); >- SIMD_ALIGNED(uint16 dst_pixels_c[640]); >- SIMD_ALIGNED(uint16 dst_pixels_opt[640]); >+ SIMD_ALIGNED(uint32_t orig_pixels[640 + 4]); >+ SIMD_ALIGNED(uint16_t dst_pixels_c[640]); >+ SIMD_ALIGNED(uint16_t dst_pixels_opt[640]); > > memset(orig_pixels, 0, sizeof(orig_pixels)); > memset(dst_pixels_c, 1, sizeof(dst_pixels_c)); >@@ -3004,30 +3203,30 @@ TEST_F(LibYUVPlanarTest, TestGaussRow_Opt) { > } > > EXPECT_EQ(dst_pixels_c[0], >- static_cast<uint16>(0 * 1 + 1 * 4 + 2 * 6 + 3 * 4 + 4 * 1)); >- EXPECT_EQ(dst_pixels_c[639], static_cast<uint16>(10256)); >+ static_cast<uint16_t>(0 * 1 + 1 * 4 + 2 * 6 + 3 * 4 + 4 * 1)); >+ EXPECT_EQ(dst_pixels_c[639], static_cast<uint16_t>(10256)); > } > >-extern "C" void GaussCol_NEON(const uint16* src0, >- const uint16* src1, >- const uint16* src2, >- const uint16* src3, >- const uint16* src4, >- uint32* dst, >+extern "C" void GaussCol_NEON(const uint16_t* src0, >+ const uint16_t* src1, >+ const uint16_t* src2, >+ const uint16_t* src3, >+ const uint16_t* src4, >+ uint32_t* dst, > int width); > >-extern "C" void GaussCol_C(const uint16* src0, >- const uint16* src1, >- const uint16* src2, >- const uint16* src3, >- const uint16* src4, >- uint32* dst, >+extern "C" void GaussCol_C(const uint16_t* src0, >+ const uint16_t* src1, >+ const uint16_t* src2, >+ const uint16_t* src3, >+ const uint16_t* src4, >+ uint32_t* dst, > int width); > > TEST_F(LibYUVPlanarTest, TestGaussCol_Opt) { >- SIMD_ALIGNED(uint16 orig_pixels[640 * 5]); >- SIMD_ALIGNED(uint32 dst_pixels_c[640]); >- SIMD_ALIGNED(uint32 dst_pixels_opt[640]); >+ SIMD_ALIGNED(uint16_t orig_pixels[640 * 5]); >+ SIMD_ALIGNED(uint32_t dst_pixels_c[640]); >+ SIMD_ALIGNED(uint32_t dst_pixels_opt[640]); > > memset(orig_pixels, 0, sizeof(orig_pixels)); > memset(dst_pixels_c, 1, sizeof(dst_pixels_c)); >@@ -3062,9 +3261,10 @@ TEST_F(LibYUVPlanarTest, TestGaussCol_Opt) { > EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]); > } > >- EXPECT_EQ(dst_pixels_c[0], static_cast<uint32>(0 * 1 + 640 * 4 + 640 * 2 * 6 + >- 640 * 3 * 4 + 640 * 4 * 1)); >- EXPECT_EQ(dst_pixels_c[639], static_cast<uint32>(30704)); >+ EXPECT_EQ(dst_pixels_c[0], >+ static_cast<uint32_t>(0 * 1 + 640 * 4 + 640 * 2 * 6 + 640 * 3 * 4 + >+ 640 * 4 * 1)); >+ EXPECT_EQ(dst_pixels_c[639], static_cast<uint32_t>(30704)); > } > > } // namespace libyuv >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/scale_argb_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/scale_argb_test.cc >index d11aec2047603cfa3dc37a6a3399d75f68cbb8e2..a1be85b8d8ab49807ec4e9270a7f2d5156671ac7 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/scale_argb_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/scale_argb_test.cc >@@ -37,7 +37,7 @@ static int ARGBTestFilter(int src_width, > > int i, j; > const int b = 0; // 128 to test for padding/stride. >- int64 src_argb_plane_size = >+ int64_t src_argb_plane_size = > (Abs(src_width) + b * 2) * (Abs(src_height) + b * 2) * 4LL; > int src_stride_argb = (b * 2 + Abs(src_width)) * 4; > >@@ -48,7 +48,8 @@ static int ARGBTestFilter(int src_width, > } > MemRandomize(src_argb, src_argb_plane_size); > >- int64 dst_argb_plane_size = (dst_width + b * 2) * (dst_height + b * 2) * 4LL; >+ int64_t dst_argb_plane_size = >+ (dst_width + b * 2) * (dst_height + b * 2) * 4LL; > int dst_stride_argb = (b * 2 + dst_width) * 4; > > align_buffer_page_end(dst_argb_c, dst_argb_plane_size); >@@ -116,11 +117,11 @@ static int ARGBTestFilter(int src_width, > static const int kTileX = 8; > static const int kTileY = 8; > >-static int TileARGBScale(const uint8* src_argb, >+static int TileARGBScale(const uint8_t* src_argb, > int src_stride_argb, > int src_width, > int src_height, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int dst_width, > int dst_height, >@@ -157,7 +158,7 @@ static int ARGBClipTestFilter(int src_width, > } > > const int b = 128; >- int64 src_argb_plane_size = >+ int64_t src_argb_plane_size = > (Abs(src_width) + b * 2) * (Abs(src_height) + b * 2) * 4; > int src_stride_argb = (b * 2 + Abs(src_width)) * 4; > >@@ -168,7 +169,7 @@ static int ARGBClipTestFilter(int src_width, > } > memset(src_argb, 1, src_argb_plane_size); > >- int64 dst_argb_plane_size = (dst_width + b * 2) * (dst_height + b * 2) * 4; >+ int64_t dst_argb_plane_size = (dst_width + b * 2) * (dst_height + b * 2) * 4; > int dst_stride_argb = (b * 2 + dst_width) * 4; > > int i, j; >@@ -310,19 +311,20 @@ TEST_SCALETO(ARGBScale, 1280, 720) > #undef TEST_SCALETO > > // Scale with YUV conversion to ARGB and clipping. >+// TODO(fbarchard): Add fourcc support. All 4 ARGB formats is easy to support. > LIBYUV_API >-int YUVToARGBScaleReference2(const uint8* src_y, >+int YUVToARGBScaleReference2(const uint8_t* src_y, > int src_stride_y, >- const uint8* src_u, >+ const uint8_t* src_u, > int src_stride_u, >- const uint8* src_v, >+ const uint8_t* src_v, > int src_stride_v, >- uint32 /* src_fourcc */, // TODO: Add support. >+ uint32 /* src_fourcc */, > int src_width, > int src_height, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, >- uint32 /* dst_fourcc */, // TODO: Add support. >+ uint32 /* dst_fourcc */, > int dst_width, > int dst_height, > int clip_x, >@@ -330,7 +332,8 @@ int YUVToARGBScaleReference2(const uint8* src_y, > int clip_width, > int clip_height, > enum FilterMode filtering) { >- uint8* argb_buffer = static_cast<uint8*>(malloc(src_width * src_height * 4)); >+ uint8_t* argb_buffer = >+ static_cast<uint8_t*>(malloc(src_width * src_height * 4)); > int r; > I420ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, > argb_buffer, src_width * 4, src_width, src_height); >@@ -342,7 +345,12 @@ int YUVToARGBScaleReference2(const uint8* src_y, > return r; > } > >-static void FillRamp(uint8* buf, int width, int height, int v, int dx, int dy) { >+static void FillRamp(uint8_t* buf, >+ int width, >+ int height, >+ int v, >+ int dx, >+ int dy) { > int rv = v; > for (int y = 0; y < height; ++y) { > for (int x = 0; x < width; ++x) { >@@ -369,8 +377,8 @@ static int YUVToARGBTestFilter(int src_width, > int dst_height, > FilterMode f, > int benchmark_iterations) { >- int64 src_y_plane_size = Abs(src_width) * Abs(src_height); >- int64 src_uv_plane_size = >+ int64_t src_y_plane_size = Abs(src_width) * Abs(src_height); >+ int64_t src_uv_plane_size = > ((Abs(src_width) + 1) / 2) * ((Abs(src_height) + 1) / 2); > int src_stride_y = Abs(src_width); > int src_stride_uv = (Abs(src_width) + 1) / 2; >@@ -379,7 +387,7 @@ static int YUVToARGBTestFilter(int src_width, > align_buffer_page_end(src_u, src_uv_plane_size); > align_buffer_page_end(src_v, src_uv_plane_size); > >- int64 dst_argb_plane_size = (dst_width) * (dst_height)*4LL; >+ int64_t dst_argb_plane_size = (dst_width) * (dst_height)*4LL; > int dst_stride_argb = (dst_width)*4; > align_buffer_page_end(dst_argb_c, dst_argb_plane_size); > align_buffer_page_end(dst_argb_opt, dst_argb_plane_size); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/scale_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/scale_test.cc >index c39211a161b5bb1a326bac12dceda3a4fe73a41e..08b6cffaa26b7863371e691df89f8be135c7470b 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/scale_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/scale_test.cc >@@ -38,8 +38,8 @@ static int TestFilter(int src_width, > int src_width_uv = (Abs(src_width) + 1) >> 1; > int src_height_uv = (Abs(src_height) + 1) >> 1; > >- int64 src_y_plane_size = (Abs(src_width)) * (Abs(src_height)); >- int64 src_uv_plane_size = (src_width_uv) * (src_height_uv); >+ int64_t src_y_plane_size = (Abs(src_width)) * (Abs(src_height)); >+ int64_t src_uv_plane_size = (src_width_uv) * (src_height_uv); > > int src_stride_y = Abs(src_width); > int src_stride_uv = src_width_uv; >@@ -58,8 +58,8 @@ static int TestFilter(int src_width, > int dst_width_uv = (dst_width + 1) >> 1; > int dst_height_uv = (dst_height + 1) >> 1; > >- int64 dst_y_plane_size = (dst_width) * (dst_height); >- int64 dst_uv_plane_size = (dst_width_uv) * (dst_height_uv); >+ int64_t dst_y_plane_size = (dst_width) * (dst_height); >+ int64_t dst_uv_plane_size = (dst_width_uv) * (dst_height_uv); > > int dst_stride_y = dst_width; > int dst_stride_uv = dst_width_uv; >@@ -157,8 +157,8 @@ static int TestFilter_16(int src_width, > int src_width_uv = (Abs(src_width) + 1) >> 1; > int src_height_uv = (Abs(src_height) + 1) >> 1; > >- int64 src_y_plane_size = (Abs(src_width)) * (Abs(src_height)); >- int64 src_uv_plane_size = (src_width_uv) * (src_height_uv); >+ int64_t src_y_plane_size = (Abs(src_width)) * (Abs(src_height)); >+ int64_t src_uv_plane_size = (src_width_uv) * (src_height_uv); > > int src_stride_y = Abs(src_width); > int src_stride_uv = src_width_uv; >@@ -173,9 +173,9 @@ static int TestFilter_16(int src_width, > printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n"); > return 0; > } >- uint16* p_src_y_16 = reinterpret_cast<uint16*>(src_y_16); >- uint16* p_src_u_16 = reinterpret_cast<uint16*>(src_u_16); >- uint16* p_src_v_16 = reinterpret_cast<uint16*>(src_v_16); >+ uint16_t* p_src_y_16 = reinterpret_cast<uint16_t*>(src_y_16); >+ uint16_t* p_src_u_16 = reinterpret_cast<uint16_t*>(src_u_16); >+ uint16_t* p_src_v_16 = reinterpret_cast<uint16_t*>(src_v_16); > > MemRandomize(src_y, src_y_plane_size); > MemRandomize(src_u, src_uv_plane_size); >@@ -205,9 +205,9 @@ static int TestFilter_16(int src_width, > align_buffer_page_end(dst_u_16, dst_uv_plane_size * 2); > align_buffer_page_end(dst_v_16, dst_uv_plane_size * 2); > >- uint16* p_dst_y_16 = reinterpret_cast<uint16*>(dst_y_16); >- uint16* p_dst_u_16 = reinterpret_cast<uint16*>(dst_u_16); >- uint16* p_dst_v_16 = reinterpret_cast<uint16*>(dst_v_16); >+ uint16_t* p_dst_y_16 = reinterpret_cast<uint16_t*>(dst_y_16); >+ uint16_t* p_dst_u_16 = reinterpret_cast<uint16_t*>(dst_u_16); >+ uint16_t* p_dst_v_16 = reinterpret_cast<uint16_t*>(dst_v_16); > > MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization. > I420Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv, >@@ -345,9 +345,9 @@ TEST_SCALETO(Scale, 1280, 720) > > #ifdef HAS_SCALEROWDOWN2_SSSE3 > TEST_F(LibYUVScaleTest, TestScaleRowDown2Box_Odd_SSSE3) { >- SIMD_ALIGNED(uint8 orig_pixels[128 * 2]); >- SIMD_ALIGNED(uint8 dst_pixels_opt[64]); >- SIMD_ALIGNED(uint8 dst_pixels_c[64]); >+ SIMD_ALIGNED(uint8_t orig_pixels[128 * 2]); >+ SIMD_ALIGNED(uint8_t dst_pixels_opt[64]); >+ SIMD_ALIGNED(uint8_t dst_pixels_c[64]); > memset(orig_pixels, 0, sizeof(orig_pixels)); > memset(dst_pixels_opt, 0, sizeof(dst_pixels_opt)); > memset(dst_pixels_c, 0, sizeof(dst_pixels_c)); >@@ -433,19 +433,19 @@ TEST_F(LibYUVScaleTest, TestScaleRowDown2Box_Odd_SSSE3) { > } > #endif // HAS_SCALEROWDOWN2_SSSE3 > >-extern "C" void ScaleRowUp2_16_NEON(const uint16* src_ptr, >+extern "C" void ScaleRowUp2_16_NEON(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width); >-extern "C" void ScaleRowUp2_16_C(const uint16* src_ptr, >+extern "C" void ScaleRowUp2_16_C(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width); > > TEST_F(LibYUVScaleTest, TestScaleRowUp2_16) { >- SIMD_ALIGNED(uint16 orig_pixels[640 * 2 + 1]); // 2 rows + 1 pixel overrun. >- SIMD_ALIGNED(uint16 dst_pixels_opt[1280]); >- SIMD_ALIGNED(uint16 dst_pixels_c[1280]); >+ SIMD_ALIGNED(uint16_t orig_pixels[640 * 2 + 1]); // 2 rows + 1 pixel overrun. >+ SIMD_ALIGNED(uint16_t dst_pixels_opt[1280]); >+ SIMD_ALIGNED(uint16_t dst_pixels_c[1280]); > > memset(orig_pixels, 0, sizeof(orig_pixels)); > memset(dst_pixels_opt, 1, sizeof(dst_pixels_opt)); >@@ -475,15 +475,15 @@ TEST_F(LibYUVScaleTest, TestScaleRowUp2_16) { > EXPECT_EQ(dst_pixels_c[1279], 800); > } > >-extern "C" void ScaleRowDown2Box_16_NEON(const uint16* src_ptr, >+extern "C" void ScaleRowDown2Box_16_NEON(const uint16_t* src_ptr, > ptrdiff_t src_stride, >- uint16* dst, >+ uint16_t* dst, > int dst_width); > > TEST_F(LibYUVScaleTest, TestScaleRowDown2Box_16) { >- SIMD_ALIGNED(uint16 orig_pixels[2560 * 2]); >- SIMD_ALIGNED(uint16 dst_pixels_c[1280]); >- SIMD_ALIGNED(uint16 dst_pixels_opt[1280]); >+ SIMD_ALIGNED(uint16_t orig_pixels[2560 * 2]); >+ SIMD_ALIGNED(uint16_t dst_pixels_c[1280]); >+ SIMD_ALIGNED(uint16_t dst_pixels_opt[1280]); > > memset(orig_pixels, 0, sizeof(orig_pixels)); > memset(dst_pixels_c, 1, sizeof(dst_pixels_c)); >@@ -530,7 +530,7 @@ static int TestPlaneFilter_16(int src_width, > } > > int i; >- int64 src_y_plane_size = (Abs(src_width)) * (Abs(src_height)); >+ int64_t src_y_plane_size = (Abs(src_width)) * (Abs(src_height)); > int src_stride_y = Abs(src_width); > int dst_y_plane_size = dst_width * dst_height; > int dst_stride_y = dst_width; >@@ -539,8 +539,8 @@ static int TestPlaneFilter_16(int src_width, > align_buffer_page_end(src_y_16, src_y_plane_size * 2); > align_buffer_page_end(dst_y_8, dst_y_plane_size); > align_buffer_page_end(dst_y_16, dst_y_plane_size * 2); >- uint16* p_src_y_16 = reinterpret_cast<uint16*>(src_y_16); >- uint16* p_dst_y_16 = reinterpret_cast<uint16*>(dst_y_16); >+ uint16_t* p_src_y_16 = reinterpret_cast<uint16_t*>(src_y_16); >+ uint16_t* p_dst_y_16 = reinterpret_cast<uint16_t*>(dst_y_16); > > MemRandomize(src_y, src_y_plane_size); > memset(dst_y_8, 0, dst_y_plane_size); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/unit_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/unit_test.cc >index 1ad4dece861e74a80ad8c54bd30bae8574844550..20aadb44e2faf809f938515b538f6868ed14a108 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/unit_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/unit_test.cc >@@ -19,10 +19,6 @@ > #endif > #include "libyuv/cpu_id.h" > >-// Change this to 1000 for benchmarking. >-// TODO(fbarchard): Add command line parsing to pass this as option. >-#define BENCHMARK_ITERATIONS 1 >- > unsigned int fastrand_seed = 0xfb; > > #ifdef LIBYUV_USE_GFLAGS >@@ -35,11 +31,11 @@ DEFINE_int32(libyuv_cpu_info, > "cpu flags for benchmark code. 1 = C, -1 = SIMD"); > #else > // Disable command line parameters if gflags disabled. >-static const int32 FLAGS_libyuv_width = 0; >-static const int32 FLAGS_libyuv_height = 0; >-static const int32 FLAGS_libyuv_repeat = 0; >-static const int32 FLAGS_libyuv_flags = 0; >-static const int32 FLAGS_libyuv_cpu_info = 0; >+static const int32_t FLAGS_libyuv_width = 0; >+static const int32_t FLAGS_libyuv_height = 0; >+static const int32_t FLAGS_libyuv_repeat = 0; >+static const int32_t FLAGS_libyuv_flags = 0; >+static const int32_t FLAGS_libyuv_cpu_info = 0; > #endif > > // For quicker unittests, default is 128 x 72. But when benchmarking, >@@ -47,7 +43,7 @@ static const int32 FLAGS_libyuv_cpu_info = 0; > // Set flags to -1 for benchmarking to avoid slower C code. > > LibYUVConvertTest::LibYUVConvertTest() >- : benchmark_iterations_(BENCHMARK_ITERATIONS), >+ : benchmark_iterations_(1), > benchmark_width_(128), > benchmark_height_(72), > disable_cpu_flags_(1), >@@ -92,12 +88,6 @@ LibYUVConvertTest::LibYUVConvertTest() > benchmark_cpu_info_ = FLAGS_libyuv_cpu_info; > } > libyuv::MaskCpuFlags(benchmark_cpu_info_); >- benchmark_pixels_div256_ = >- static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * >- static_cast<double>(Abs(benchmark_height_)) * >- static_cast<double>(benchmark_iterations_) + >- 255.0) / >- 256.0); > benchmark_pixels_div1280_ = > static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * > static_cast<double>(Abs(benchmark_height_)) * >@@ -107,7 +97,7 @@ LibYUVConvertTest::LibYUVConvertTest() > } > > LibYUVColorTest::LibYUVColorTest() >- : benchmark_iterations_(BENCHMARK_ITERATIONS), >+ : benchmark_iterations_(1), > benchmark_width_(128), > benchmark_height_(72), > disable_cpu_flags_(1), >@@ -152,12 +142,6 @@ LibYUVColorTest::LibYUVColorTest() > benchmark_cpu_info_ = FLAGS_libyuv_cpu_info; > } > libyuv::MaskCpuFlags(benchmark_cpu_info_); >- benchmark_pixels_div256_ = >- static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * >- static_cast<double>(Abs(benchmark_height_)) * >- static_cast<double>(benchmark_iterations_) + >- 255.0) / >- 256.0); > benchmark_pixels_div1280_ = > static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * > static_cast<double>(Abs(benchmark_height_)) * >@@ -167,7 +151,7 @@ LibYUVColorTest::LibYUVColorTest() > } > > LibYUVScaleTest::LibYUVScaleTest() >- : benchmark_iterations_(BENCHMARK_ITERATIONS), >+ : benchmark_iterations_(1), > benchmark_width_(128), > benchmark_height_(72), > disable_cpu_flags_(1), >@@ -212,12 +196,6 @@ LibYUVScaleTest::LibYUVScaleTest() > benchmark_cpu_info_ = FLAGS_libyuv_cpu_info; > } > libyuv::MaskCpuFlags(benchmark_cpu_info_); >- benchmark_pixels_div256_ = >- static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * >- static_cast<double>(Abs(benchmark_height_)) * >- static_cast<double>(benchmark_iterations_) + >- 255.0) / >- 256.0); > benchmark_pixels_div1280_ = > static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * > static_cast<double>(Abs(benchmark_height_)) * >@@ -227,7 +205,7 @@ LibYUVScaleTest::LibYUVScaleTest() > } > > LibYUVRotateTest::LibYUVRotateTest() >- : benchmark_iterations_(BENCHMARK_ITERATIONS), >+ : benchmark_iterations_(1), > benchmark_width_(128), > benchmark_height_(72), > disable_cpu_flags_(1), >@@ -272,12 +250,6 @@ LibYUVRotateTest::LibYUVRotateTest() > benchmark_cpu_info_ = FLAGS_libyuv_cpu_info; > } > libyuv::MaskCpuFlags(benchmark_cpu_info_); >- benchmark_pixels_div256_ = >- static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * >- static_cast<double>(Abs(benchmark_height_)) * >- static_cast<double>(benchmark_iterations_) + >- 255.0) / >- 256.0); > benchmark_pixels_div1280_ = > static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * > static_cast<double>(Abs(benchmark_height_)) * >@@ -287,7 +259,7 @@ LibYUVRotateTest::LibYUVRotateTest() > } > > LibYUVPlanarTest::LibYUVPlanarTest() >- : benchmark_iterations_(BENCHMARK_ITERATIONS), >+ : benchmark_iterations_(1), > benchmark_width_(128), > benchmark_height_(72), > disable_cpu_flags_(1), >@@ -332,12 +304,6 @@ LibYUVPlanarTest::LibYUVPlanarTest() > benchmark_cpu_info_ = FLAGS_libyuv_cpu_info; > } > libyuv::MaskCpuFlags(benchmark_cpu_info_); >- benchmark_pixels_div256_ = >- static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * >- static_cast<double>(Abs(benchmark_height_)) * >- static_cast<double>(benchmark_iterations_) + >- 255.0) / >- 256.0); > benchmark_pixels_div1280_ = > static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * > static_cast<double>(Abs(benchmark_height_)) * >@@ -347,7 +313,7 @@ LibYUVPlanarTest::LibYUVPlanarTest() > } > > LibYUVBaseTest::LibYUVBaseTest() >- : benchmark_iterations_(BENCHMARK_ITERATIONS), >+ : benchmark_iterations_(1), > benchmark_width_(128), > benchmark_height_(72), > disable_cpu_flags_(1), >@@ -392,12 +358,6 @@ LibYUVBaseTest::LibYUVBaseTest() > benchmark_cpu_info_ = FLAGS_libyuv_cpu_info; > } > libyuv::MaskCpuFlags(benchmark_cpu_info_); >- benchmark_pixels_div256_ = >- static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * >- static_cast<double>(Abs(benchmark_height_)) * >- static_cast<double>(benchmark_iterations_) + >- 255.0) / >- 256.0); > benchmark_pixels_div1280_ = > static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * > static_cast<double>(Abs(benchmark_height_)) * >@@ -407,7 +367,7 @@ LibYUVBaseTest::LibYUVBaseTest() > } > > LibYUVCompareTest::LibYUVCompareTest() >- : benchmark_iterations_(BENCHMARK_ITERATIONS), >+ : benchmark_iterations_(1), > benchmark_width_(128), > benchmark_height_(72), > disable_cpu_flags_(1), >@@ -452,12 +412,6 @@ LibYUVCompareTest::LibYUVCompareTest() > benchmark_cpu_info_ = FLAGS_libyuv_cpu_info; > } > libyuv::MaskCpuFlags(benchmark_cpu_info_); >- benchmark_pixels_div256_ = >- static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * >- static_cast<double>(Abs(benchmark_height_)) * >- static_cast<double>(benchmark_iterations_) + >- 255.0) / >- 256.0); > benchmark_pixels_div1280_ = > static_cast<int>((static_cast<double>(Abs(benchmark_width_)) * > static_cast<double>(Abs(benchmark_height_)) * >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/unit_test.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/unit_test.h >index 6454389d52d1a78591c7d9ac6885ef11b1f0f9ee..87907fa1603922f7f518e94719973e463cd1f8ee 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/unit_test.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/unit_test.h >@@ -69,10 +69,10 @@ static inline bool SizeValid(int src_width, > return true; > } > >-#define align_buffer_page_end(var, size) \ >- uint8* var##_mem = \ >- reinterpret_cast<uint8*>(malloc(((size) + 4095 + 63) & ~4095)); \ >- uint8* var = reinterpret_cast<uint8*>( \ >+#define align_buffer_page_end(var, size) \ >+ uint8_t* var##_mem = \ >+ reinterpret_cast<uint8_t*>(malloc(((size) + 4095 + 63) & ~4095)); \ >+ uint8_t* var = reinterpret_cast<uint8_t*>( \ > (intptr_t)(var##_mem + (((size) + 4095 + 63) & ~4095) - (size)) & ~63) > > #define free_aligned_buffer_page_end(var) \ >@@ -111,10 +111,10 @@ inline int fastrand() { > return static_cast<int>((fastrand_seed >> 16) & 0xffff); > } > >-static inline void MemRandomize(uint8* dst, int64 len) { >- int64 i; >+static inline void MemRandomize(uint8_t* dst, int64_t len) { >+ int64_t i; > for (i = 0; i < len - 1; i += 2) { >- *reinterpret_cast<uint16*>(dst) = fastrand(); >+ *reinterpret_cast<uint16_t*>(dst) = fastrand(); > dst += 2; > } > for (; i < len; ++i) { >@@ -126,10 +126,9 @@ class LibYUVColorTest : public ::testing::Test { > protected: > LibYUVColorTest(); > >- int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >- int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >- int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. >- int benchmark_pixels_div256_; // Total pixels to benchmark / 256. >+ int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >+ int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >+ int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. > int benchmark_pixels_div1280_; // Total pixels to benchmark / 1280. > int disable_cpu_flags_; // Default 1. Use -1 for benchmarking. > int benchmark_cpu_info_; // Default -1. Use 1 to disable SIMD. >@@ -139,10 +138,9 @@ class LibYUVConvertTest : public ::testing::Test { > protected: > LibYUVConvertTest(); > >- int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >- int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >- int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. >- int benchmark_pixels_div256_; // Total pixels to benchmark / 256. >+ int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >+ int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >+ int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. > int benchmark_pixels_div1280_; // Total pixels to benchmark / 1280. > int disable_cpu_flags_; // Default 1. Use -1 for benchmarking. > int benchmark_cpu_info_; // Default -1. Use 1 to disable SIMD. >@@ -152,10 +150,9 @@ class LibYUVScaleTest : public ::testing::Test { > protected: > LibYUVScaleTest(); > >- int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >- int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >- int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. >- int benchmark_pixels_div256_; // Total pixels to benchmark / 256. >+ int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >+ int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >+ int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. > int benchmark_pixels_div1280_; // Total pixels to benchmark / 1280. > int disable_cpu_flags_; // Default 1. Use -1 for benchmarking. > int benchmark_cpu_info_; // Default -1. Use 1 to disable SIMD. >@@ -165,10 +162,9 @@ class LibYUVRotateTest : public ::testing::Test { > protected: > LibYUVRotateTest(); > >- int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >- int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >- int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. >- int benchmark_pixels_div256_; // Total pixels to benchmark / 256. >+ int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >+ int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >+ int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. > int benchmark_pixels_div1280_; // Total pixels to benchmark / 1280. > int disable_cpu_flags_; // Default 1. Use -1 for benchmarking. > int benchmark_cpu_info_; // Default -1. Use 1 to disable SIMD. >@@ -178,10 +174,9 @@ class LibYUVPlanarTest : public ::testing::Test { > protected: > LibYUVPlanarTest(); > >- int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >- int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >- int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. >- int benchmark_pixels_div256_; // Total pixels to benchmark / 256. >+ int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >+ int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >+ int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. > int benchmark_pixels_div1280_; // Total pixels to benchmark / 1280. > int disable_cpu_flags_; // Default 1. Use -1 for benchmarking. > int benchmark_cpu_info_; // Default -1. Use 1 to disable SIMD. >@@ -191,10 +186,9 @@ class LibYUVBaseTest : public ::testing::Test { > protected: > LibYUVBaseTest(); > >- int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >- int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >- int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. >- int benchmark_pixels_div256_; // Total pixels to benchmark / 256. >+ int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >+ int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >+ int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. > int benchmark_pixels_div1280_; // Total pixels to benchmark / 1280. > int disable_cpu_flags_; // Default 1. Use -1 for benchmarking. > int benchmark_cpu_info_; // Default -1. Use 1 to disable SIMD. >@@ -204,10 +198,9 @@ class LibYUVCompareTest : public ::testing::Test { > protected: > LibYUVCompareTest(); > >- int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >- int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >- int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. >- int benchmark_pixels_div256_; // Total pixels to benchmark / 256. >+ int benchmark_iterations_; // Default 1. Use 1000 for benchmarking. >+ int benchmark_width_; // Default 1280. Use 640 for benchmarking VGA. >+ int benchmark_height_; // Default 720. Use 360 for benchmarking VGA. > int benchmark_pixels_div1280_; // Total pixels to benchmark / 1280. > int disable_cpu_flags_; // Default 1. Use -1 for benchmarking. > int benchmark_cpu_info_; // Default -1. Use 1 to disable SIMD. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/video_common_test.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/video_common_test.cc >index f16b6772f95bad552a316609494f93b5804b1d87..4d89586e76f225c04736d27964b49152130b104f 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/video_common_test.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/unit_test/video_common_test.cc >@@ -18,15 +18,12 @@ namespace libyuv { > > // Tests FourCC codes in video common, which are used for ConvertToI420(). > >-static bool TestValidChar(uint32 onecc) { >- if ((onecc >= '0' && onecc <= '9') || (onecc >= 'A' && onecc <= 'Z') || >- (onecc >= 'a' && onecc <= 'z') || (onecc == ' ') || (onecc == 0xff)) { >- return true; >- } >- return false; >+static bool TestValidChar(uint32_t onecc) { >+ return (onecc >= '0' && onecc <= '9') || (onecc >= 'A' && onecc <= 'Z') || >+ (onecc >= 'a' && onecc <= 'z') || (onecc == ' ') || (onecc == 0xff); > } > >-static bool TestValidFourCC(uint32 fourcc, int bpp) { >+static bool TestValidFourCC(uint32_t fourcc, int bpp) { > if (!TestValidChar(fourcc & 0xff) || !TestValidChar((fourcc >> 8) & 0xff) || > !TestValidChar((fourcc >> 16) & 0xff) || > !TestValidChar((fourcc >> 24) & 0xff)) { >@@ -39,23 +36,23 @@ static bool TestValidFourCC(uint32 fourcc, int bpp) { > } > > TEST_F(LibYUVBaseTest, TestCanonicalFourCC) { >- EXPECT_EQ(static_cast<uint32>(FOURCC_I420), CanonicalFourCC(FOURCC_IYUV)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_I420), CanonicalFourCC(FOURCC_YU12)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_I422), CanonicalFourCC(FOURCC_YU16)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_I444), CanonicalFourCC(FOURCC_YU24)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_YUY2), CanonicalFourCC(FOURCC_YUYV)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_YUY2), CanonicalFourCC(FOURCC_YUVS)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_UYVY), CanonicalFourCC(FOURCC_HDYC)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_UYVY), CanonicalFourCC(FOURCC_2VUY)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_MJPG), CanonicalFourCC(FOURCC_JPEG)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_MJPG), CanonicalFourCC(FOURCC_DMB1)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_RAW), CanonicalFourCC(FOURCC_RGB3)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_24BG), CanonicalFourCC(FOURCC_BGR3)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_BGRA), CanonicalFourCC(FOURCC_CM32)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_RAW), CanonicalFourCC(FOURCC_CM24)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_RGBO), CanonicalFourCC(FOURCC_L555)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_RGBP), CanonicalFourCC(FOURCC_L565)); >- EXPECT_EQ(static_cast<uint32>(FOURCC_RGBO), CanonicalFourCC(FOURCC_5551)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_I420), CanonicalFourCC(FOURCC_IYUV)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_I420), CanonicalFourCC(FOURCC_YU12)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_I422), CanonicalFourCC(FOURCC_YU16)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_I444), CanonicalFourCC(FOURCC_YU24)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_YUY2), CanonicalFourCC(FOURCC_YUYV)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_YUY2), CanonicalFourCC(FOURCC_YUVS)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_UYVY), CanonicalFourCC(FOURCC_HDYC)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_UYVY), CanonicalFourCC(FOURCC_2VUY)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_MJPG), CanonicalFourCC(FOURCC_JPEG)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_MJPG), CanonicalFourCC(FOURCC_DMB1)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_RAW), CanonicalFourCC(FOURCC_RGB3)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_24BG), CanonicalFourCC(FOURCC_BGR3)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_BGRA), CanonicalFourCC(FOURCC_CM32)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_RAW), CanonicalFourCC(FOURCC_CM24)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_RGBO), CanonicalFourCC(FOURCC_L555)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_RGBP), CanonicalFourCC(FOURCC_L565)); >+ EXPECT_EQ(static_cast<uint32_t>(FOURCC_RGBO), CanonicalFourCC(FOURCC_5551)); > } > > TEST_F(LibYUVBaseTest, TestFourCC) { >@@ -73,12 +70,16 @@ TEST_F(LibYUVBaseTest, TestFourCC) { > EXPECT_TRUE(TestValidFourCC(FOURCC_ARGB, FOURCC_BPP_ARGB)); > EXPECT_TRUE(TestValidFourCC(FOURCC_BGRA, FOURCC_BPP_BGRA)); > EXPECT_TRUE(TestValidFourCC(FOURCC_ABGR, FOURCC_BPP_ABGR)); >+ EXPECT_TRUE(TestValidFourCC(FOURCC_AR30, FOURCC_BPP_AR30)); >+ EXPECT_TRUE(TestValidFourCC(FOURCC_AB30, FOURCC_BPP_AB30)); > EXPECT_TRUE(TestValidFourCC(FOURCC_24BG, FOURCC_BPP_24BG)); > EXPECT_TRUE(TestValidFourCC(FOURCC_RAW, FOURCC_BPP_RAW)); > EXPECT_TRUE(TestValidFourCC(FOURCC_RGBA, FOURCC_BPP_RGBA)); > EXPECT_TRUE(TestValidFourCC(FOURCC_RGBP, FOURCC_BPP_RGBP)); > EXPECT_TRUE(TestValidFourCC(FOURCC_RGBO, FOURCC_BPP_RGBO)); > EXPECT_TRUE(TestValidFourCC(FOURCC_R444, FOURCC_BPP_R444)); >+ EXPECT_TRUE(TestValidFourCC(FOURCC_H420, FOURCC_BPP_H420)); >+ EXPECT_TRUE(TestValidFourCC(FOURCC_H010, FOURCC_BPP_H010)); > EXPECT_TRUE(TestValidFourCC(FOURCC_MJPG, FOURCC_BPP_MJPG)); > EXPECT_TRUE(TestValidFourCC(FOURCC_YV12, FOURCC_BPP_YV12)); > EXPECT_TRUE(TestValidFourCC(FOURCC_YV16, FOURCC_BPP_YV16)); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/Makefile b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/Makefile >index 6044d2adf6384cee48ad6bcd2b562c9024367672..40e74b6509c6337983fcb9d8db9eefa6c6525427 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/Makefile >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/Makefile >@@ -4,3 +4,6 @@ ifeq ($(CXX),icl) > else > $(CXX) -msse2 -O3 -fopenmp -static -o psnr psnr.cc ssim.cc psnr_main.cc -Wl,--strip-all > endif >+ >+# for MacOS >+# /usr/local/bin/g++-7 -msse2 -O3 -fopenmp -Bstatic -o psnr psnr.cc ssim.cc psnr_main.cc >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/compare.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/compare.cc >index ef0beefafee5ed25759f5504e3c1246db0b9bad1..a16613ee2f98cbb7e454d501d5c7607a4712cc6e 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/compare.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/compare.cc >@@ -29,22 +29,24 @@ int main(int argc, char** argv) { > FILE* fin2 = name2 ? fopen(name2, "rb") : NULL; > > const int kBlockSize = 32768; >- uint8 buf1[kBlockSize]; >- uint8 buf2[kBlockSize]; >- uint32 hash1 = 5381; >- uint32 hash2 = 5381; >- uint64 sum_square_err = 0; >- uint64 size_min = 0; >+ uint8_t buf1[kBlockSize]; >+ uint8_t buf2[kBlockSize]; >+ uint32_t hash1 = 5381; >+ uint32_t hash2 = 5381; >+ uint64_t sum_square_err = 0; >+ uint64_t size_min = 0; > int amt1 = 0; > int amt2 = 0; > do { > amt1 = static_cast<int>(fread(buf1, 1, kBlockSize, fin1)); >- if (amt1 > 0) >+ if (amt1 > 0) { > hash1 = libyuv::HashDjb2(buf1, amt1, hash1); >+ } > if (fin2) { > amt2 = static_cast<int>(fread(buf2, 1, kBlockSize, fin2)); >- if (amt2 > 0) >+ if (amt2 > 0) { > hash2 = libyuv::HashDjb2(buf2, amt2, hash2); >+ } > int amt_min = (amt1 < amt2) ? amt1 : amt2; > size_min += amt_min; > sum_square_err += libyuv::ComputeSumSquareError(buf1, buf2, amt_min); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/cpuid.c b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/cpuid.c >index 9ff618e0d28e329a0add99da4f6bf212c8d34c37..59c65d60e0fe46d42c2fdb7554b1efc77f03315a 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/cpuid.c >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/cpuid.c >@@ -69,8 +69,8 @@ int main(int argc, const char* argv[]) { > printf("Has NEON %x\n", has_neon); > } > if (has_mips) { >- int has_dspr2 = TestCpuFlag(kCpuHasDSPR2); >- printf("Has DSPR2 %x\n", has_dspr2); >+ int has_msa = TestCpuFlag(kCpuHasMSA); >+ printf("Has MSA %x\n", has_msa); > } > if (has_x86) { > int has_sse2 = TestCpuFlag(kCpuHasSSE2); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr.cc >index 27f876c0b4aee7e277555cfa3d3e386be62dbf4d..f54015bab8299d5fae883a2f193d1b4c5c724a14 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr.cc >@@ -21,14 +21,14 @@ > extern "C" { > #endif > >-typedef unsigned int uint32; // NOLINT >+typedef unsigned int uint32_t; // NOLINT > #ifdef _MSC_VER >-typedef unsigned __int64 uint64; >+typedef unsigned __int64 uint64_t; > #else // COMPILER_MSVC > #if defined(__LP64__) && !defined(__OpenBSD__) && !defined(__APPLE__) >-typedef unsigned long uint64; // NOLINT >+typedef unsigned long uint64_t; // NOLINT > #else // defined(__LP64__) && !defined(__OpenBSD__) && !defined(__APPLE__) >-typedef unsigned long long uint64; // NOLINT >+typedef unsigned long long uint64_t; // NOLINT > #endif // __LP64__ > #endif // _MSC_VER > >@@ -38,10 +38,10 @@ typedef unsigned long long uint64; // NOLINT > #if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__) && \ > !defined(__aarch64__) > #define HAS_SUMSQUAREERROR_NEON >-static uint32 SumSquareError_NEON(const uint8* src_a, >- const uint8* src_b, >- int count) { >- volatile uint32 sse; >+static uint32_t SumSquareError_NEON(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ volatile uint32_t sse; > asm volatile( > "vmov.u8 q7, #0 \n" > "vmov.u8 q9, #0 \n" >@@ -73,10 +73,10 @@ static uint32 SumSquareError_NEON(const uint8* src_a, > } > #elif !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) > #define HAS_SUMSQUAREERROR_NEON >-static uint32 SumSquareError_NEON(const uint8* src_a, >- const uint8* src_b, >- int count) { >- volatile uint32 sse; >+static uint32_t SumSquareError_NEON(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ volatile uint32_t sse; > asm volatile( > "eor v16.16b, v16.16b, v16.16b \n" > "eor v18.16b, v18.16b, v18.16b \n" >@@ -107,9 +107,9 @@ static uint32 SumSquareError_NEON(const uint8* src_a, > } > #elif !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) > #define HAS_SUMSQUAREERROR_SSE2 >-__declspec(naked) static uint32 SumSquareError_SSE2(const uint8* /*src_a*/, >- const uint8* /*src_b*/, >- int /*count*/) { >+__declspec(naked) static uint32_t SumSquareError_SSE2(const uint8_t* /*src_a*/, >+ const uint8_t* /*src_b*/, >+ int /*count*/) { > __asm { > mov eax, [esp + 4] // src_a > mov edx, [esp + 8] // src_b >@@ -146,10 +146,10 @@ __declspec(naked) static uint32 SumSquareError_SSE2(const uint8* /*src_a*/, > } > #elif !defined(LIBYUV_DISABLE_X86) && (defined(__x86_64__) || defined(__i386__)) > #define HAS_SUMSQUAREERROR_SSE2 >-static uint32 SumSquareError_SSE2(const uint8* src_a, >- const uint8* src_b, >- int count) { >- uint32 sse; >+static uint32_t SumSquareError_SSE2(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t sse; > asm volatile( // NOLINT > "pxor %%xmm0,%%xmm0 \n" > "pxor %%xmm5,%%xmm5 \n" >@@ -228,22 +228,22 @@ static int CpuHasSSE2() { > } > #endif // HAS_SUMSQUAREERROR_SSE2 > >-static uint32 SumSquareError_C(const uint8* src_a, >- const uint8* src_b, >- int count) { >- uint32 sse = 0u; >+static uint32_t SumSquareError_C(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count) { >+ uint32_t sse = 0u; > for (int x = 0; x < count; ++x) { > int diff = src_a[x] - src_b[x]; >- sse += static_cast<uint32>(diff * diff); >+ sse += static_cast<uint32_t>(diff * diff); > } > return sse; > } > >-double ComputeSumSquareError(const uint8* src_a, >- const uint8* src_b, >+double ComputeSumSquareError(const uint8_t* src_a, >+ const uint8_t* src_b, > int count) { >- uint32 (*SumSquareError)(const uint8* src_a, const uint8* src_b, int count) = >- SumSquareError_C; >+ uint32_t (*SumSquareError)(const uint8_t* src_a, const uint8_t* src_b, >+ int count) = SumSquareError_C; > #if defined(HAS_SUMSQUAREERROR_NEON) > SumSquareError = SumSquareError_NEON; > #endif >@@ -253,7 +253,7 @@ double ComputeSumSquareError(const uint8* src_a, > } > #endif > const int kBlockSize = 1 << 15; >- uint64 sse = 0; >+ uint64_t sse = 0; > #ifdef _OPENMP > #pragma omp parallel for reduction(+ : sse) > #endif >@@ -280,8 +280,9 @@ double ComputeSumSquareError(const uint8* src_a, > // Returns 128.0 (kMaxPSNR) if sse is 0 (perfect match). > double ComputePSNR(double sse, double size) { > const double kMINSSE = 255.0 * 255.0 * size / pow(10.0, kMaxPSNR / 10.0); >- if (sse <= kMINSSE) >+ if (sse <= kMINSSE) { > sse = kMINSSE; // Produces max PSNR of 128 >+ } > return 10.0 * log10(255.0 * 255.0 * size / sse); > } > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr.h >index 0816b976001187b4b19099d6d4b70d33e4934a1e..aac128cbca800695a3001dc5fbf098a200791b6d 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr.h >@@ -20,7 +20,7 @@ extern "C" { > #endif > > #if !defined(INT_TYPES_DEFINED) && !defined(UINT8_TYPE_DEFINED) >-typedef unsigned char uint8; >+typedef unsigned char uint8_t; > #define UINT8_TYPE_DEFINED > #endif > >@@ -31,7 +31,9 @@ static const double kMaxPSNR = 128.0; > #if !defined(HAVE_JPEG) > // Computer Sum of Squared Error (SSE). > // Pass this to ComputePSNR for final result. >-double ComputeSumSquareError(const uint8* org, const uint8* rec, int size); >+double ComputeSumSquareError(const uint8_t* src_a, >+ const uint8_t* src_b, >+ int count); > #endif > > // PSNR formula: psnr = 10 * log10 (Peak Signal^2 * size / sse) >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr_main.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr_main.cc >index 4d930be4aedfc090d1c302f35b26c3c25c89ca7e..a930b202ecf094b83fdeb1df22062871cf24604f 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr_main.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/psnr_main.cc >@@ -90,9 +90,9 @@ bool ExtractResolutionFromFilename(const char* name, > fseek(file_org, 0, SEEK_END); > size_t total_size = ftell(file_org); > fseek(file_org, 0, SEEK_SET); >- uint8* const ch_org = new uint8[total_size]; >+ uint8_t* const ch_org = new uint8_t[total_size]; > memset(ch_org, 0, total_size); >- size_t bytes_org = fread(ch_org, sizeof(uint8), total_size, file_org); >+ size_t bytes_org = fread(ch_org, sizeof(uint8_t), total_size, file_org); > fclose(file_org); > if (bytes_org == total_size) { > if (0 == libyuv::MJPGSize(ch_org, total_size, width_ptr, height_ptr)) { >@@ -107,13 +107,15 @@ bool ExtractResolutionFromFilename(const char* name, > > // Scale Y channel from 16..240 to 0..255. > // This can be useful when comparing codecs that are inconsistant about Y >-uint8 ScaleY(uint8 y) { >+uint8_t ScaleY(uint8_t y) { > int ny = (y - 16) * 256 / 224; >- if (ny < 0) >+ if (ny < 0) { > ny = 0; >- if (ny > 255) >+ } >+ if (ny > 255) { > ny = 255; >- return static_cast<uint8>(ny); >+ } >+ return static_cast<uint8_t>(ny); > } > > // MSE = Mean Square Error >@@ -150,8 +152,9 @@ void PrintHelp(const char* program) { > } > > void ParseOptions(int argc, const char* argv[]) { >- if (argc <= 1) >+ if (argc <= 1) { > PrintHelp(argv[0]); >+ } > for (int c = 1; c < argc; ++c) { > if (!strcmp(argv[c], "-v")) { > verbose = true; >@@ -237,8 +240,8 @@ void ParseOptions(int argc, const char* argv[]) { > } > } > >-bool UpdateMetrics(uint8* ch_org, >- uint8* ch_rec, >+bool UpdateMetrics(uint8_t* ch_org, >+ uint8_t* ch_rec, > const int y_size, > const int uv_size, > const size_t total_size, >@@ -247,10 +250,10 @@ bool UpdateMetrics(uint8* ch_org, > metric* distorted_frame, > bool do_psnr) { > const int uv_offset = (do_swap_uv ? uv_size : 0); >- const uint8* const u_org = ch_org + y_size + uv_offset; >- const uint8* const u_rec = ch_rec + y_size; >- const uint8* const v_org = ch_org + y_size + (uv_size - uv_offset); >- const uint8* const v_rec = ch_rec + y_size + uv_size; >+ const uint8_t* const u_org = ch_org + y_size + uv_offset; >+ const uint8_t* const u_rec = ch_rec + y_size; >+ const uint8_t* const v_org = ch_org + y_size + (uv_size - uv_offset); >+ const uint8_t* const v_rec = ch_rec + y_size + uv_size; > if (do_psnr) { > #ifdef HAVE_JPEG > double y_err = static_cast<double>( >@@ -301,12 +304,15 @@ bool UpdateMetrics(uint8* ch_org, > cur_distortion_psnr->all += distorted_frame->all; > > bool ismin = false; >- if (distorted_frame->y < cur_distortion_psnr->min_y) >+ if (distorted_frame->y < cur_distortion_psnr->min_y) { > cur_distortion_psnr->min_y = distorted_frame->y; >- if (distorted_frame->u < cur_distortion_psnr->min_u) >+ } >+ if (distorted_frame->u < cur_distortion_psnr->min_u) { > cur_distortion_psnr->min_u = distorted_frame->u; >- if (distorted_frame->v < cur_distortion_psnr->min_v) >+ } >+ if (distorted_frame->v < cur_distortion_psnr->min_v) { > cur_distortion_psnr->min_v = distorted_frame->v; >+ } > if (distorted_frame->all < cur_distortion_psnr->min_all) { > cur_distortion_psnr->min_all = distorted_frame->all; > cur_distortion_psnr->min_frame = number_of_frames; >@@ -374,8 +380,8 @@ int main(int argc, const char* argv[]) { > #endif > } > >- uint8* const ch_org = new uint8[total_size]; >- uint8* const ch_rec = new uint8[total_size]; >+ uint8_t* const ch_org = new uint8_t[total_size]; >+ uint8_t* const ch_rec = new uint8_t[total_size]; > if (ch_org == NULL || ch_rec == NULL) { > fprintf(stderr, "No memory available\n"); > fclose(file_org); >@@ -429,14 +435,15 @@ int main(int argc, const char* argv[]) { > > int number_of_frames; > for (number_of_frames = 0;; ++number_of_frames) { >- if (num_frames && number_of_frames >= num_frames) >+ if (num_frames && number_of_frames >= num_frames) { > break; >+ } > >- size_t bytes_org = fread(ch_org, sizeof(uint8), total_size, file_org); >+ size_t bytes_org = fread(ch_org, sizeof(uint8_t), total_size, file_org); > if (bytes_org < total_size) { > #ifdef HAVE_JPEG > // Try parsing file as a jpeg. >- uint8* const ch_jpeg = new uint8[bytes_org]; >+ uint8_t* const ch_jpeg = new uint8_t[bytes_org]; > memcpy(ch_jpeg, ch_org, bytes_org); > memset(ch_org, 0, total_size); > >@@ -456,11 +463,11 @@ int main(int argc, const char* argv[]) { > > for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { > size_t bytes_rec = >- fread(ch_rec, sizeof(uint8), total_size, file_rec[cur_rec]); >+ fread(ch_rec, sizeof(uint8_t), total_size, file_rec[cur_rec]); > if (bytes_rec < total_size) { > #ifdef HAVE_JPEG > // Try parsing file as a jpeg. >- uint8* const ch_jpeg = new uint8[bytes_rec]; >+ uint8_t* const ch_jpeg = new uint8_t[bytes_rec]; > memcpy(ch_jpeg, ch_rec, bytes_rec); > memset(ch_rec, 0, total_size); > >@@ -482,7 +489,7 @@ int main(int argc, const char* argv[]) { > printf("%5d", number_of_frames); > } > if (do_psnr) { >- metric distorted_frame; >+ metric distorted_frame = {}; > metric* cur_distortion_psnr = &distortion_psnr[cur_rec]; > bool ismin = UpdateMetrics(ch_org, ch_rec, y_size, uv_size, total_size, > number_of_frames, cur_distortion_psnr, >@@ -496,7 +503,7 @@ int main(int argc, const char* argv[]) { > } > } > if (do_ssim) { >- metric distorted_frame; >+ metric distorted_frame = {}; > metric* cur_distortion_ssim = &distortion_ssim[cur_rec]; > bool ismin = UpdateMetrics(ch_org, ch_rec, y_size, uv_size, total_size, > number_of_frames, cur_distortion_ssim, >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/ssim.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/ssim.cc >index 43e725d82104f683a1131e4ac0a7aed2879bfe80..096fbcf0610c81c26e0821fd9c7167885dc37db7 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/ssim.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/ssim.cc >@@ -16,8 +16,8 @@ > extern "C" { > #endif > >-typedef unsigned int uint32; // NOLINT >-typedef unsigned short uint16; // NOLINT >+typedef unsigned int uint32_t; // NOLINT >+typedef unsigned short uint16_t; // NOLINT > > #if !defined(LIBYUV_DISABLE_X86) && !defined(__SSE2__) && \ > (defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))) >@@ -50,7 +50,7 @@ static const double kiW[KERNEL + 1 + 1] = { > > #if !defined(LIBYUV_DISABLE_X86) && defined(__SSE2__) > >-#define PWEIGHT(A, B) static_cast<uint16>(K[(A)] * K[(B)]) // weight product >+#define PWEIGHT(A, B) static_cast<uint16_t>(K[(A)] * K[(B)]) // weight product > #define MAKE_WEIGHT(L) \ > { \ > { \ >@@ -66,7 +66,7 @@ static const double kiW[KERNEL + 1 + 1] = { > // values. We can't call _mm_set_epi16() for static compile-time initialization. > static const struct { > union { >- uint16 i16_[8]; >+ uint16_t i16_[8]; > __m128i m_; > } values_; > } W0 = MAKE_WEIGHT(0), W1 = MAKE_WEIGHT(1), W2 = MAKE_WEIGHT(2), >@@ -88,10 +88,12 @@ static double FinalizeSSIM(double iw, > double sxx = xxm * iw - iwx * iwx; > double syy = yym * iw - iwy * iwy; > // small errors are possible, due to rounding. Clamp to zero. >- if (sxx < 0.) >+ if (sxx < 0.) { > sxx = 0.; >- if (syy < 0.) >+ } >+ if (syy < 0.) { > syy = 0.; >+ } > const double sxsy = sqrt(sxx * syy); > const double sxy = xym * iw - iwx * iwy; > static const double C11 = (0.01 * 0.01) * (255 * 255); >@@ -109,21 +111,22 @@ static double FinalizeSSIM(double iw, > // Note: worst case of accumulation is a weight of 33 = 11 + 2 * (7 + 3 + 1) > // with a diff of 255, squared. The maximum error is thus 0x4388241, > // which fits into 32 bits integers. >-double GetSSIM(const uint8* org, >- const uint8* rec, >+double GetSSIM(const uint8_t* org, >+ const uint8_t* rec, > int xo, > int yo, > int W, > int H, > int stride) { >- uint32 ws = 0, xm = 0, ym = 0, xxm = 0, xym = 0, yym = 0; >+ uint32_t ws = 0, xm = 0, ym = 0, xxm = 0, xym = 0, yym = 0; > org += (yo - KERNEL) * stride; > org += (xo - KERNEL); > rec += (yo - KERNEL) * stride; > rec += (xo - KERNEL); > for (int y_ = 0; y_ < KERNEL_SIZE; ++y_, org += stride, rec += stride) { >- if (((yo - KERNEL + y_) < 0) || ((yo - KERNEL + y_) >= H)) >+ if (((yo - KERNEL + y_) < 0) || ((yo - KERNEL + y_) >= H)) { > continue; >+ } > const int Wy = K[y_]; > for (int x_ = 0; x_ < KERNEL_SIZE; ++x_) { > const int Wxy = Wy * K[x_]; >@@ -142,13 +145,13 @@ double GetSSIM(const uint8* org, > return FinalizeSSIM(1. / ws, xm, ym, xxm, xym, yym); > } > >-double GetSSIMFullKernel(const uint8* org, >- const uint8* rec, >+double GetSSIMFullKernel(const uint8_t* org, >+ const uint8_t* rec, > int xo, > int yo, > int stride, > double area_weight) { >- uint32 xm = 0, ym = 0, xxm = 0, xym = 0, yym = 0; >+ uint32_t xm = 0, ym = 0, xxm = 0, xym = 0, yym = 0; > > #if defined(LIBYUV_DISABLE_X86) || !defined(__SSE2__) > >@@ -262,7 +265,7 @@ double GetSSIMFullKernel(const uint8* org, > > #define ADD_AND_STORE_FOUR_EPI32(M, OUT) \ > do { \ >- uint32 tmp[4]; \ >+ uint32_t tmp[4]; \ > _mm_storeu_si128(reinterpret_cast<__m128i*>(tmp), (M)); \ > (OUT) = tmp[3] + tmp[2] + tmp[1] + tmp[0]; \ > } while (0) >@@ -292,8 +295,8 @@ static int start_max(int x, int y) { > return (x > y) ? x : y; > } > >-double CalcSSIM(const uint8* org, >- const uint8* rec, >+double CalcSSIM(const uint8_t* org, >+ const uint8_t* rec, > const int image_width, > const int image_height) { > double SSIM = 0.; >@@ -328,8 +331,8 @@ double CalcSSIM(const uint8* org, > // NOTE: we could use similar method for the left-most pixels too. > const int kScratchWidth = 8; > const int kScratchStride = kScratchWidth + KERNEL + 1; >- uint8 scratch_org[KERNEL_SIZE * kScratchStride] = {0}; >- uint8 scratch_rec[KERNEL_SIZE * kScratchStride] = {0}; >+ uint8_t scratch_org[KERNEL_SIZE * kScratchStride] = {0}; >+ uint8_t scratch_rec[KERNEL_SIZE * kScratchStride] = {0}; > > for (int k = 0; k < KERNEL_SIZE; ++k) { > const int offset = >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/ssim.h b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/ssim.h >index 4647f45de14ea3192576e04c24b92ea1d286c813..a855f1d12331d599c896dabda59e9e8bd3759977 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/ssim.h >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/ssim.h >@@ -20,12 +20,12 @@ extern "C" { > #endif > > #if !defined(INT_TYPES_DEFINED) && !defined(UINT8_TYPE_DEFINED) >-typedef unsigned char uint8; >+typedef unsigned char uint8_t; > #define UINT8_TYPE_DEFINED > #endif > >-double CalcSSIM(const uint8* org, >- const uint8* rec, >+double CalcSSIM(const uint8_t* org, >+ const uint8_t* rec, > const int image_width, > const int image_height); > >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/yuvconvert.cc b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/yuvconvert.cc >index bc01d9ff503e74886eff48bd8b88c0c4a0ba7e19..27cdfe9e375631ec3bec41ebdb7b096922c2764b 100644 >--- a/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/yuvconvert.cc >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/libyuv/util/yuvconvert.cc >@@ -37,7 +37,7 @@ int num_skip_org = 0; // Number of frames to skip in original. > int num_frames = 0; // Number of frames to convert. > int filter = 1; // Bilinear filter for scaling. > >-static __inline uint32 Abs(int32 v) { >+static __inline uint32_t Abs(int32_t v) { > return v >= 0 ? v : -v; > } > >@@ -79,8 +79,9 @@ void PrintHelp(const char* program) { > } > > void ParseOptions(int argc, const char* argv[]) { >- if (argc <= 1) >+ if (argc <= 1) { > PrintHelp(argv[0]); >+ } > for (int c = 1; c < argc; ++c) { > if (!strcmp(argv[c], "-v")) { > verbose = true; >@@ -158,11 +159,11 @@ void ParseOptions(int argc, const char* argv[]) { > static const int kTileX = 32; > static const int kTileY = 32; > >-static int TileARGBScale(const uint8* src_argb, >+static int TileARGBScale(const uint8_t* src_argb, > int src_stride_argb, > int src_width, > int src_height, >- uint8* dst_argb, >+ uint8_t* dst_argb, > int dst_stride_argb, > int dst_width, > int dst_height, >@@ -242,9 +243,9 @@ int main(int argc, const char* argv[]) { > fseek(file_org, num_skip_org * total_size, SEEK_SET); > #endif > >- uint8* const ch_org = new uint8[org_size]; >- uint8* const ch_dst = new uint8[dst_size]; >- uint8* const ch_rec = new uint8[total_size]; >+ uint8_t* const ch_org = new uint8_t[org_size]; >+ uint8_t* const ch_dst = new uint8_t[dst_size]; >+ uint8_t* const ch_rec = new uint8_t[total_size]; > if (ch_org == NULL || ch_rec == NULL) { > fprintf(stderr, "No memory available\n"); > fclose(file_org); >@@ -265,14 +266,16 @@ int main(int argc, const char* argv[]) { > > int number_of_frames; > for (number_of_frames = 0;; ++number_of_frames) { >- if (num_frames && number_of_frames >= num_frames) >+ if (num_frames && number_of_frames >= num_frames) { > break; >+ } > > // Load original YUV or ARGB frame. > size_t bytes_org = >- fread(ch_org, sizeof(uint8), static_cast<size_t>(org_size), file_org); >- if (bytes_org < static_cast<size_t>(org_size)) >+ fread(ch_org, sizeof(uint8_t), static_cast<size_t>(org_size), file_org); >+ if (bytes_org < static_cast<size_t>(org_size)) { > break; >+ } > > // TODO(fbarchard): Attenuate doesnt need to know dimensions. > // ARGB attenuate frame >@@ -329,16 +332,18 @@ int main(int argc, const char* argv[]) { > // Output YUV or ARGB frame. > if (rec_is_yuv) { > size_t bytes_rec = >- fwrite(ch_rec, sizeof(uint8), static_cast<size_t>(total_size), >+ fwrite(ch_rec, sizeof(uint8_t), static_cast<size_t>(total_size), > file_rec[cur_rec]); >- if (bytes_rec < static_cast<size_t>(total_size)) >+ if (bytes_rec < static_cast<size_t>(total_size)) { > break; >+ } > } else { > size_t bytes_rec = >- fwrite(ch_dst, sizeof(uint8), static_cast<size_t>(dst_size), >+ fwrite(ch_dst, sizeof(uint8_t), static_cast<size_t>(dst_size), > file_rec[cur_rec]); >- if (bytes_rec < static_cast<size_t>(dst_size)) >+ if (bytes_rec < static_cast<size_t>(dst_size)) { > break; >+ } > } > if (verbose) { > printf("%5d", number_of_frames); >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/BUILD.gn >new file mode 100644 >index 0000000000000000000000000000000000000000..c669179a5f0e21112ae398827a88ced309fd3dfe >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/BUILD.gn >@@ -0,0 +1,38 @@ >+# Copyright 2018 The Chromium Authors. All rights reserved. >+# Use of this source code is governed by a BSD-style license that can be >+# found in the LICENSE file. >+ >+import("//testing/test.gni") >+ >+group("rnnoise") { >+ deps = [ >+ ":kiss_fft", >+ ":rnn_vad", >+ ] >+} >+ >+source_set("kiss_fft") { >+ sources = [ >+ "src/kiss_fft.cc", >+ "src/kiss_fft.h", >+ ] >+} >+ >+source_set("rnn_vad") { >+ sources = [ >+ "src/rnn_activations.h", >+ "src/rnn_vad_weights.cc", >+ "src/rnn_vad_weights.h", >+ ] >+} >+ >+test("kiss_fft_unittest") { >+ sources = [ >+ "src/kiss_fft_unittest.cc", >+ ] >+ deps = [ >+ ":kiss_fft", >+ "//testing/gtest", >+ "//testing/gtest:gtest_main", >+ ] >+} >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/COPYING b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/COPYING >new file mode 100644 >index 0000000000000000000000000000000000000000..01ea4b1a2ac025fd9daa73a031b06c01fc57ed81 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/COPYING >@@ -0,0 +1,31 @@ >+Copyright (c) 2017, Mozilla >+Copyright (c) 2007-2017, Jean-Marc Valin >+Copyright (c) 2005-2017, Xiph.Org Foundation >+Copyright (c) 2003-2004, Mark Borgerding >+ >+Redistribution and use in source and binary forms, with or without >+modification, are permitted provided that the following conditions >+are met: >+ >+- Redistributions of source code must retain the above copyright >+notice, this list of conditions and the following disclaimer. >+ >+- Redistributions in binary form must reproduce the above copyright >+notice, this list of conditions and the following disclaimer in the >+documentation and/or other materials provided with the distribution. >+ >+- Neither the name of the Xiph.Org Foundation nor the names of its >+contributors may be used to endorse or promote products derived from >+this software without specific prior written permission. >+ >+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT >+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR >+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION >+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, >+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT >+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/DEPS b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/DEPS >new file mode 100644 >index 0000000000000000000000000000000000000000..fca61fcf64b71f2176b3f81050278405df2a3c6a >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/DEPS >@@ -0,0 +1,3 @@ >+include_rules = [ >+ "+testing/gtest/include/gtest", >+] >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/OWNERS b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/OWNERS >new file mode 100644 >index 0000000000000000000000000000000000000000..b3f35ec172b31c34a7378ebda50b2226c81520b2 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/OWNERS >@@ -0,0 +1,2 @@ >+alessiob@chromium.org >+aleloi@chromium.org >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/README.chromium b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/README.chromium >new file mode 100644 >index 0000000000000000000000000000000000000000..8efe059ca6b2de964c94f19d661456e45af8b029 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/README.chromium >@@ -0,0 +1,28 @@ >+Name: Recurrent neural network for audio noise reduction >+Short Name: rnnoise >+URL: https://github.com/xiph/rnnoise >+Version: 91ef401 >+Date: Oct 10, 2017 >+Revision: >+License: BSD 3-Clause >+License File: COPYING >+Security Critical: no >+License Android Compatible: >+ >+Description: >+RNNoise is a noise suppression library based on a recurrent neural network. >+The library is used for speech processing in WebRTC. >+ >+Local Modifications: >+* Only retaining COPYING and from src/ the following files: >+ - kiss_fft.c, kiss_fft.h >+ - rnn.c >+ - rnn_data.c >+ - tansig_table.h >+* KissFFT: non-floating point parts removed, code clean, from C to C++, >+ class wrapper added >+* BUILD targets and KissFFT unit tests added >+* rnn_vad_weights.h: output layer sizes + weights scaling factor >+* removing unwanted extern from constants in rnn_vad_weights.h and using >+ constants to declare array sizes >+* Add braces around arrays in unit test. >\ No newline at end of file >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/kiss_fft.cc b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/kiss_fft.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..27b4900b918b9d324d98f3c89f8204a236997873 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/kiss_fft.cc >@@ -0,0 +1,443 @@ >+/*Copyright (c) 2003-2004, Mark Borgerding >+ Lots of modifications by Jean-Marc Valin >+ Copyright (c) 2005-2007, Xiph.Org Foundation >+ Copyright (c) 2008, Xiph.Org Foundation, CSIRO >+ Copyright (c) 2018, The WebRTC project authors >+ >+ All rights reserved. >+ >+ Redistribution and use in source and binary forms, with or without >+ modification, are permitted provided that the following conditions are met: >+ >+ * Redistributions of source code must retain the above copyright notice, >+ this list of conditions and the following disclaimer. >+ * Redistributions in binary form must reproduce the above copyright notice, >+ this list of conditions and the following disclaimer in the >+ documentation and/or other materials provided with the distribution. >+ >+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" >+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE >+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE >+ POSSIBILITY OF SUCH DAMAGE.*/ >+ >+#include "third_party/rnnoise/src/kiss_fft.h" >+ >+#include <cassert> >+#include <cmath> >+#include <utility> >+ >+namespace rnnoise { >+namespace { >+ >+void kf_bfly2(std::complex<float>* Fout, int m, int N) { >+ if (m == 1) { >+ for (int i = 0; i < N; i++) { >+ const std::complex<float> t = Fout[1]; >+ Fout[1] = Fout[0] - t; >+ Fout[0] += t; >+ Fout += 2; >+ } >+ } else { >+ constexpr float tw = 0.7071067812f; >+ // We know that m==4 here because the radix-2 is just after a radix-4. >+ assert(m == 4); >+ for (int i = 0; i < N; i++) { >+ std::complex<float>* Fout2 = Fout + 4; >+ std::complex<float> t = Fout2[0]; >+ >+ *Fout2 = Fout[0] - t; >+ Fout[0] += t; >+ >+ t.real((Fout2[1].real() + Fout2[1].imag()) * tw); >+ t.imag((Fout2[1].imag() - Fout2[1].real()) * tw); >+ Fout2[1] = Fout[1] - t; >+ Fout[1] += t; >+ >+ t.real(Fout2[2].imag()); >+ t.imag(-Fout2[2].real()); >+ Fout2[2] = Fout[2] - t; >+ Fout[2] += t; >+ >+ t.real((Fout2[3].imag() - Fout2[3].real()) * tw); >+ t.imag(-(Fout2[3].imag() + Fout2[3].real()) * tw); >+ Fout2[3] = Fout[3] - t; >+ Fout[3] += t; >+ Fout += 8; >+ } >+ } >+} >+ >+void kf_bfly4(std::complex<float>* Fout, >+ const size_t fstride, >+ const KissFft::KissFftState* st, >+ int m, >+ int N, >+ int mm) { >+ assert(Fout); >+ assert(st); >+ if (m == 1) { >+ // Degenerate case where all the twiddles are 1. >+ for (int i = 0; i < N; i++) { >+ std::complex<float> scratch0 = Fout[0] - Fout[2]; >+ Fout[0] += Fout[2]; >+ std::complex<float> scratch1 = Fout[1] + Fout[3]; >+ Fout[2] = Fout[0] - scratch1; >+ Fout[0] += scratch1; >+ scratch1 = Fout[1] - Fout[3]; >+ >+ Fout[1].real(scratch0.real() + scratch1.imag()); >+ Fout[1].imag(scratch0.imag() - scratch1.real()); >+ Fout[3].real(scratch0.real() - scratch1.imag()); >+ Fout[3].imag(scratch0.imag() + scratch1.real()); >+ Fout += 4; >+ } >+ } else { >+ std::complex<float> scratch[6]; >+ const int m2 = 2 * m; >+ const int m3 = 3 * m; >+ std::complex<float>* Fout_beg = Fout; >+ for (int i = 0; i < N; i++) { >+ Fout = Fout_beg + i * mm; >+ const std::complex<float>* tw1; >+ const std::complex<float>* tw2; >+ const std::complex<float>* tw3; >+ tw3 = tw2 = tw1 = &st->twiddles[0]; >+ assert(m % 4 == 0); // |m| is guaranteed to be a multiple of 4. >+ for (int j = 0; j < m; j++) { >+ scratch[0] = Fout[m] * *tw1; >+ scratch[1] = Fout[m2] * *tw2; >+ scratch[2] = Fout[m3] * *tw3; >+ >+ scratch[5] = Fout[0] - scratch[1]; >+ Fout[0] += scratch[1]; >+ scratch[3] = scratch[0] + scratch[2]; >+ scratch[4] = scratch[0] - scratch[2]; >+ Fout[m2] = Fout[0] - scratch[3]; >+ >+ tw1 += fstride; >+ tw2 += fstride * 2; >+ tw3 += fstride * 3; >+ Fout[0] += scratch[3]; >+ >+ Fout[m].real(scratch[5].real() + scratch[4].imag()); >+ Fout[m].imag(scratch[5].imag() - scratch[4].real()); >+ Fout[m3].real(scratch[5].real() - scratch[4].imag()); >+ Fout[m3].imag(scratch[5].imag() + scratch[4].real()); >+ ++Fout; >+ } >+ } >+ } >+} >+ >+void kf_bfly3(std::complex<float>* Fout, >+ const size_t fstride, >+ const KissFft::KissFftState* st, >+ int m, >+ int N, >+ int mm) { >+ assert(Fout); >+ assert(st); >+ const size_t m2 = 2 * m; >+ const std::complex<float>*tw1, *tw2; >+ std::complex<float> scratch[5]; >+ std::complex<float> epi3; >+ >+ std::complex<float>* Fout_beg = Fout; >+ epi3 = st->twiddles[fstride * m]; >+ for (int i = 0; i < N; i++) { >+ Fout = Fout_beg + i * mm; >+ tw1 = tw2 = &st->twiddles[0]; >+ size_t k = m; >+ do { >+ scratch[1] = Fout[m] * *tw1; >+ scratch[2] = Fout[m2] * *tw2; >+ >+ scratch[3] = scratch[1] + scratch[2]; >+ scratch[0] = scratch[1] - scratch[2]; >+ tw1 += fstride; >+ tw2 += fstride * 2; >+ >+ Fout[m] = Fout[0] - 0.5f * scratch[3]; >+ >+ scratch[0] *= epi3.imag(); >+ >+ Fout[0] += scratch[3]; >+ >+ Fout[m2].real(Fout[m].real() + scratch[0].imag()); >+ Fout[m2].imag(Fout[m].imag() - scratch[0].real()); >+ >+ Fout[m].real(Fout[m].real() - scratch[0].imag()); >+ Fout[m].imag(Fout[m].imag() + scratch[0].real()); >+ >+ ++Fout; >+ } while (--k); >+ } >+} >+ >+void kf_bfly5(std::complex<float>* Fout, >+ const size_t fstride, >+ const KissFft::KissFftState* st, >+ int m, >+ int N, >+ int mm) { >+ assert(Fout); >+ assert(st); >+ std::complex<float> scratch[13]; >+ const std::complex<float>* tw; >+ std::complex<float> ya, yb; >+ std::complex<float>* const Fout_beg = Fout; >+ >+ ya = st->twiddles[fstride * m]; >+ yb = st->twiddles[fstride * 2 * m]; >+ tw = &st->twiddles[0]; >+ >+ for (int i = 0; i < N; i++) { >+ Fout = Fout_beg + i * mm; >+ std::complex<float>* Fout0 = Fout; >+ std::complex<float>* Fout1 = Fout0 + m; >+ std::complex<float>* Fout2 = Fout0 + 2 * m; >+ std::complex<float>* Fout3 = Fout0 + 3 * m; >+ std::complex<float>* Fout4 = Fout0 + 4 * m; >+ >+ // For non-custom modes, m is guaranteed to be a multiple of 4. >+ for (int u = 0; u < m; ++u) { >+ scratch[0] = *Fout0; >+ >+ scratch[1] = *Fout1 * tw[u * fstride]; >+ scratch[2] = *Fout2 * tw[2 * u * fstride]; >+ scratch[3] = *Fout3 * tw[3 * u * fstride]; >+ scratch[4] = *Fout4 * tw[4 * u * fstride]; >+ >+ scratch[7] = scratch[1] + scratch[4]; >+ scratch[10] = scratch[1] - scratch[4]; >+ scratch[8] = scratch[2] + scratch[3]; >+ scratch[9] = scratch[2] - scratch[3]; >+ >+ Fout0->real(Fout0->real() + scratch[7].real() + scratch[8].real()); >+ Fout0->imag(Fout0->imag() + scratch[7].imag() + scratch[8].imag()); >+ >+ scratch[5].real(scratch[0].real() + scratch[7].real() * ya.real() + >+ scratch[8].real() * yb.real()); >+ scratch[5].imag(scratch[0].imag() + scratch[7].imag() * ya.real() + >+ scratch[8].imag() * yb.real()); >+ >+ scratch[6].real(scratch[10].imag() * ya.imag() + >+ scratch[9].imag() * yb.imag()); >+ scratch[6].imag( >+ -(scratch[10].real() * ya.imag() + scratch[9].real() * yb.imag())); >+ >+ *Fout1 = scratch[5] - scratch[6]; >+ *Fout4 = scratch[5] + scratch[6]; >+ >+ scratch[11].real(scratch[0].real() + scratch[7].real() * yb.real() + >+ scratch[8].real() * ya.real()); >+ scratch[11].imag(scratch[0].imag() + scratch[7].imag() * yb.real() + >+ scratch[8].imag() * ya.real()); >+ scratch[12].real(scratch[9].imag() * ya.imag() - >+ scratch[10].imag() * yb.imag()); >+ scratch[12].imag(scratch[10].real() * yb.imag() - >+ scratch[9].real() * ya.imag()); >+ >+ *Fout2 = scratch[11] + scratch[12]; >+ *Fout3 = scratch[11] - scratch[12]; >+ >+ ++Fout0; >+ ++Fout1; >+ ++Fout2; >+ ++Fout3; >+ ++Fout4; >+ } >+ } >+} >+ >+void compute_bitrev_table(int base_index, >+ const size_t stride, >+ const int16_t* factors, >+ const KissFft::KissFftState* st, >+ const int16_t* bitrev_table_last, >+ int16_t* bitrev_table) { >+ const int p = *factors++; // The radix. >+ const int m = *factors++; // Stage's fft length/p. >+ if (m == 1) { >+ for (int j = 0; j < p; j++) { >+ assert(bitrev_table <= bitrev_table_last); >+ *bitrev_table = base_index + j; >+ bitrev_table += stride; >+ } >+ } else { >+ for (int j = 0; j < p; j++) { >+ compute_bitrev_table(base_index, stride * p, factors, st, >+ bitrev_table_last, bitrev_table); >+ bitrev_table += stride; >+ base_index += m; >+ } >+ } >+} >+ >+// Populates |facbuf| with p1, m1, p2, m2, ... where p[i] * m[i] = m[i-1] and >+// m0 = n. >+bool kf_factor(int n, int16_t* facbuf) { >+ assert(facbuf); >+ int p = 4; >+ int stages = 0; >+ int nbak = n; >+ >+ // Factor out powers of 4, powers of 2, then any remaining primes. >+ do { >+ while (n % p) { >+ switch (p) { >+ case 4: >+ p = 2; >+ break; >+ case 2: >+ p = 3; >+ break; >+ default: >+ p += 2; >+ break; >+ } >+ if (p > 32000 || p * p > n) >+ p = n; // No more factors, skip to end. >+ } >+ n /= p; >+ if (p > 5) >+ return false; >+ facbuf[2 * stages] = p; >+ if (p == 2 && stages > 1) { >+ facbuf[2 * stages] = 4; >+ facbuf[2] = 2; >+ } >+ stages++; >+ } while (n > 1); >+ n = nbak; >+ // Reverse the order to get the radix 4 at the end, so we can use the >+ // fast degenerate case. It turns out that reversing the order also >+ // improves the noise behavior. >+ for (int i = 0; i < stages / 2; i++) >+ std::swap(facbuf[2 * i], facbuf[2 * (stages - i - 1)]); >+ for (int i = 0; i < stages; i++) { >+ n /= facbuf[2 * i]; >+ facbuf[2 * i + 1] = n; >+ } >+ return true; >+} >+ >+void compute_twiddles(const int nfft, std::complex<float>* twiddles) { >+ constexpr double pi = 3.14159265358979323846264338327; >+ assert(twiddles); >+ for (int i = 0; i < nfft; ++i) { >+ const double phase = (-2 * pi / nfft) * i; >+ twiddles[i].real(std::cos(phase)); >+ twiddles[i].imag(std::sin(phase)); >+ } >+} >+ >+void fft_impl(const KissFft::KissFftState* st, std::complex<float>* fout) { >+ assert(st); >+ assert(fout); >+ int m2, m; >+ int p; >+ int L; >+ int fstride[KissFft::kMaxFactors]; >+ >+ fstride[0] = 1; >+ L = 0; >+ do { >+ p = st->factors[2 * L]; >+ m = st->factors[2 * L + 1]; >+ assert(static_cast<size_t>(L + 1) < KissFft::kMaxFactors); >+ fstride[L + 1] = fstride[L] * p; >+ L++; >+ } while (m != 1); >+ m = st->factors[2 * L - 1]; >+ for (int i = L - 1; i >= 0; i--) { >+ if (i != 0) >+ m2 = st->factors[2 * i - 1]; >+ else >+ m2 = 1; >+ switch (st->factors[2 * i]) { >+ case 2: >+ kf_bfly2(fout, m, fstride[i]); >+ break; >+ case 4: >+ kf_bfly4(fout, fstride[i], st, m, fstride[i], m2); >+ break; >+ case 3: >+ kf_bfly3(fout, fstride[i], st, m, fstride[i], m2); >+ break; >+ case 5: >+ kf_bfly5(fout, fstride[i], st, m, fstride[i], m2); >+ break; >+ default: >+ assert(0); >+ break; >+ } >+ m = m2; >+ } >+} >+ >+} // namespace >+ >+KissFft::KissFftState::KissFftState(int num_fft_points) >+ : nfft(num_fft_points), scale(1.f / nfft) { >+ // Factorize |nfft|. >+ // TODO(alessiob): Handle kf_factor fails (invalid nfft). >+ if (!kf_factor(nfft, factors.data())) >+ assert(0); >+ // Twiddles. >+ twiddles.resize(nfft); >+ compute_twiddles(nfft, twiddles.data()); >+ // Bit-reverse table. >+ bitrev.resize(nfft); >+ compute_bitrev_table(0, 1, factors.data(), this, &bitrev.back(), >+ bitrev.data()); >+} >+ >+KissFft::KissFftState::~KissFftState() = default; >+ >+KissFft::KissFft(const int nfft) : state_(nfft) {} >+ >+KissFft::~KissFft() = default; >+ >+void KissFft::ForwardFft(const size_t in_size, >+ const std::complex<float>* in, >+ const size_t out_size, >+ std::complex<float>* out) { >+ assert(in); >+ assert(out); >+ assert(in != out); // In-place FFT not supported. >+ assert(state_.nfft == static_cast<int>(in_size)); >+ assert(state_.nfft == static_cast<int>(out_size)); >+ // Bit-reverse the input. >+ for (int i = 0; i < state_.nfft; i++) >+ out[state_.bitrev[i]] = state_.scale * in[i]; >+ fft_impl(&state_, out); >+} >+ >+void KissFft::ReverseFft(const size_t in_size, >+ const std::complex<float>* in, >+ const size_t out_size, >+ std::complex<float>* out) { >+ assert(in); >+ assert(out); >+ assert(in != out); // In-place IFFT not supported. >+ assert(state_.nfft == static_cast<int>(in_size)); >+ assert(state_.nfft == static_cast<int>(out_size)); >+ // Bit-reverse the input. >+ for (int i = 0; i < state_.nfft; i++) >+ out[state_.bitrev[i]] = in[i]; >+ for (int i = 0; i < state_.nfft; i++) >+ out[i].imag(-out[i].imag()); >+ fft_impl(&state_, out); >+ for (int i = 0; i < state_.nfft; i++) >+ out[i].imag(-out[i].imag()); >+} >+ >+} // namespace rnnoise >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/kiss_fft.h b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/kiss_fft.h >new file mode 100644 >index 0000000000000000000000000000000000000000..b90f77d1ae3c420075b99b314030be3cb586da7d >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/kiss_fft.h >@@ -0,0 +1,78 @@ >+/*Copyright (c) 2003-2004, Mark Borgerding >+ Lots of modifications by Jean-Marc Valin >+ Copyright (c) 2005-2007, Xiph.Org Foundation >+ Copyright (c) 2008, Xiph.Org Foundation, CSIRO >+ Copyright (c) 2018, The WebRTC project authors >+ >+ All rights reserved. >+ >+ Redistribution and use in source and binary forms, with or without >+ modification, are permitted provided that the following conditions are met: >+ >+ * Redistributions of source code must retain the above copyright notice, >+ this list of conditions and the following disclaimer. >+ * Redistributions in binary form must reproduce the above copyright notice, >+ this list of conditions and the following disclaimer in the >+ documentation and/or other materials provided with the distribution. >+ >+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" >+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE >+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE >+ POSSIBILITY OF SUCH DAMAGE.*/ >+ >+#ifndef THIRD_PARTY_RNNOISE_SRC_KISS_FFT_H_ >+#define THIRD_PARTY_RNNOISE_SRC_KISS_FFT_H_ >+ >+#include <array> >+#include <complex> >+#include <vector> >+ >+namespace rnnoise { >+ >+class KissFft { >+ public: >+ // Example: an FFT of length 128 has 4 factors as far as kissfft is concerned >+ // (namely, 4*4*4*2). >+ static const size_t kMaxFactors = 8; >+ >+ class KissFftState { >+ public: >+ KissFftState(int num_fft_points); >+ KissFftState(const KissFftState&) = delete; >+ KissFftState& operator=(const KissFftState&) = delete; >+ ~KissFftState(); >+ >+ const int nfft; >+ const float scale; >+ std::array<int16_t, 2 * kMaxFactors> factors; >+ std::vector<int16_t> bitrev; >+ std::vector<std::complex<float>> twiddles; >+ }; >+ >+ explicit KissFft(const int nfft); >+ KissFft(const KissFft&) = delete; >+ KissFft& operator=(const KissFft&) = delete; >+ ~KissFft(); >+ void ForwardFft(const size_t in_size, >+ const std::complex<float>* in, >+ const size_t out_size, >+ std::complex<float>* out); >+ void ReverseFft(const size_t in_size, >+ const std::complex<float>* in, >+ const size_t out_size, >+ std::complex<float>* out); >+ >+ private: >+ KissFftState state_; >+}; >+ >+} // namespace rnnoise >+ >+#endif // THIRD_PARTY_RNNOISE_SRC_KISS_FFT_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/kiss_fft_unittest.cc b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/kiss_fft_unittest.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..31324453886f4a00f7a1eb92f6fb4ef90e49404c >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/kiss_fft_unittest.cc >@@ -0,0 +1,145 @@ >+// Copyright 2018 The Chromium Authors. All rights reserved. >+// Use of this source code is governed by a BSD-style license that can be >+// found in the LICENSE file. >+ >+#include <array> >+#include <cmath> >+#include <limits> >+#include <tuple> >+#include <vector> >+ >+#include "testing/gtest/include/gtest/gtest.h" >+#include "third_party/rnnoise/src/kiss_fft.h" >+ >+namespace rnnoise { >+namespace test { >+namespace { >+ >+const double kPi = std::acos(-1.0); >+ >+void FillFftInputBuffer(const size_t num_samples, >+ const float* samples, >+ std::complex<float>* input_buf) { >+ for (size_t i = 0; i < num_samples; ++i) >+ input_buf[i].real(samples[i]); >+} >+ >+void CheckFftResult(const size_t num_fft_points, >+ const float* expected_real, >+ const float* expected_imag, >+ const std::complex<float>* computed, >+ const float tolerance) { >+ for (size_t i = 0; i < num_fft_points; ++i) { >+ SCOPED_TRACE(i); >+ EXPECT_NEAR(expected_real[i], computed[i].real(), tolerance); >+ EXPECT_NEAR(expected_imag[i], computed[i].imag(), tolerance); >+ } >+} >+ >+} // namespace >+ >+class RnnVadTest >+ : public testing::Test, >+ public ::testing::WithParamInterface<std::tuple<size_t, float, float>> {}; >+ >+// Check that IFFT(FFT(x)) == x (tolerating round-off errors). >+TEST_P(RnnVadTest, KissFftForwardReverseCheckIdentity) { >+ const auto params = GetParam(); >+ const float amplitude = std::get<0>(params); >+ const size_t num_fft = std::get<1>(params); >+ const float tolerance = std::get<2>(params); >+ std::vector<float> samples; >+ std::vector<float> zeros; >+ samples.resize(num_fft); >+ zeros.resize(num_fft); >+ for (size_t i = 0; i < num_fft; ++i) { >+ samples[i] = amplitude * std::sin(2.f * kPi * 10 * i / num_fft); >+ zeros[i] = 0.f; >+ } >+ >+ KissFft fft(num_fft); >+ std::vector<std::complex<float>> fft_buf_1; >+ fft_buf_1.resize(num_fft); >+ std::vector<std::complex<float>> fft_buf_2; >+ fft_buf_2.resize(num_fft); >+ >+ FillFftInputBuffer(samples.size(), samples.data(), fft_buf_1.data()); >+ { >+ // TODO(alessiob): Underflow with non power of 2 frame sizes. >+ // FloatingPointExceptionObserver fpe_observer; >+ >+ fft.ForwardFft(fft_buf_1.size(), fft_buf_1.data(), fft_buf_2.size(), >+ fft_buf_2.data()); >+ fft.ReverseFft(fft_buf_2.size(), fft_buf_2.data(), fft_buf_1.size(), >+ fft_buf_1.data()); >+ } >+ CheckFftResult(samples.size(), samples.data(), zeros.data(), fft_buf_1.data(), >+ tolerance); >+} >+ >+INSTANTIATE_TEST_CASE_P(FftPoints, >+ RnnVadTest, >+ ::testing::Values(std::make_tuple(1.f, 240, 3e-7f), >+ std::make_tuple(1.f, 256, 3e-7f), >+ std::make_tuple(1.f, 480, 3e-7f), >+ std::make_tuple(1.f, 512, 3e-7f), >+ std::make_tuple(1.f, 960, 4e-7f), >+ std::make_tuple(1.f, 1024, 3e-7f), >+ std::make_tuple(30.f, 240, 5e-6f), >+ std::make_tuple(30.f, 256, 5e-6f), >+ std::make_tuple(30.f, 480, 6e-6f), >+ std::make_tuple(30.f, 512, 6e-6f), >+ std::make_tuple(30.f, 960, 8e-6f), >+ std::make_tuple(30.f, 1024, 6e-6f))); >+ >+TEST(RnnVadTest, KissFftBitExactness) { >+ constexpr std::array<float, 32> samples = { >+ {0.3524301946163177490234375f, 0.891803801059722900390625f, >+ 0.07706542313098907470703125f, 0.699530780315399169921875f, >+ 0.3789891898632049560546875f, 0.5438187122344970703125f, >+ 0.332781612873077392578125f, 0.449340641498565673828125f, >+ 0.105229437351226806640625f, 0.722373783588409423828125f, >+ 0.13155306875705718994140625f, 0.340857982635498046875f, >+ 0.970204889774322509765625f, 0.53061950206756591796875f, >+ 0.91507828235626220703125f, 0.830274522304534912109375f, >+ 0.74468600749969482421875f, 0.24320767819881439208984375f, >+ 0.743998110294342041015625f, 0.17574800550937652587890625f, >+ 0.1834825575351715087890625f, 0.63317775726318359375f, >+ 0.11414264142513275146484375f, 0.1612723171710968017578125f, >+ 0.80316197872161865234375f, 0.4979794919490814208984375f, >+ 0.554282128810882568359375f, 0.67189347743988037109375f, >+ 0.06660757958889007568359375f, 0.89568817615509033203125f, >+ 0.29327380657196044921875f, 0.3472573757171630859375f}}; >+ constexpr std::array<float, 17> expected_real = { >+ {0.4813065826892852783203125f, -0.0246877372264862060546875f, >+ 0.04095232486724853515625f, -0.0401695556938648223876953125f, >+ 0.00500857271254062652587890625f, 0.0160773508250713348388671875f, >+ -0.011385642923414707183837890625f, -0.008461721241474151611328125f, >+ 0.01383177936077117919921875f, 0.0117270611226558685302734375f, >+ -0.0164460353553295135498046875f, 0.0585579685866832733154296875f, >+ 0.02038039825856685638427734375f, -0.0209107734262943267822265625f, >+ 0.01046995259821414947509765625f, -0.09019653499126434326171875f, >+ -0.0583711564540863037109375f}}; >+ constexpr std::array<float, 17> expected_imag = { >+ {0.f, -0.010482530109584331512451171875f, 0.04762755334377288818359375f, >+ -0.0558677613735198974609375f, 0.007908363826572895050048828125f, >+ -0.0071932487189769744873046875f, 0.01322011835873126983642578125f, >+ -0.011227893643081188201904296875f, -0.0400779247283935546875f, >+ -0.0290451310575008392333984375f, 0.01519204117357730865478515625f, >+ -0.09711246192455291748046875f, -0.00136523949913680553436279296875f, >+ 0.038602568209171295166015625f, -0.009693108499050140380859375f, >+ -0.0183933563530445098876953125f, 0.f}}; >+ >+ KissFft fft(32); >+ std::array<std::complex<float>, 32> fft_buf_in; >+ std::array<std::complex<float>, 32> fft_buf_out; >+ FillFftInputBuffer(samples.size(), samples.data(), fft_buf_in.data()); >+ fft.ForwardFft(fft_buf_in.size(), fft_buf_in.data(), fft_buf_out.size(), >+ fft_buf_out.data()); >+ CheckFftResult(expected_real.size(), expected_real.data(), >+ expected_imag.data(), fft_buf_out.data(), >+ std::numeric_limits<float>::min()); >+} >+ >+} // namespace test >+} // namespace rnnoise >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/rnn_activations.h b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/rnn_activations.h >new file mode 100644 >index 0000000000000000000000000000000000000000..af810319962e7a2aa333444b64c5aabae837b271 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/rnn_activations.h >@@ -0,0 +1,102 @@ >+/* Copyright (c) 2008-2011 Octasic Inc. >+ 2012-2017 Jean-Marc Valin */ >+/* >+ Redistribution and use in source and binary forms, with or without >+ modification, are permitted provided that the following conditions >+ are met: >+ >+ - Redistributions of source code must retain the above copyright >+ notice, this list of conditions and the following disclaimer. >+ >+ - Redistributions in binary form must reproduce the above copyright >+ notice, this list of conditions and the following disclaimer in the >+ documentation and/or other materials provided with the distribution. >+ >+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT >+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR >+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR >+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF >+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING >+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+*/ >+ >+#ifndef THIRD_PARTY_RNNOISE_SRC_RNN_ACTIVATIONS_H_ >+#define THIRD_PARTY_RNNOISE_SRC_RNN_ACTIVATIONS_H_ >+ >+#include <cmath> >+ >+namespace rnnoise { >+ >+inline float TansigApproximated(float x) { >+ static constexpr float kTansigTable[201] = { >+ 0.000000f, 0.039979f, 0.079830f, 0.119427f, 0.158649f, 0.197375f, >+ 0.235496f, 0.272905f, 0.309507f, 0.345214f, 0.379949f, 0.413644f, >+ 0.446244f, 0.477700f, 0.507977f, 0.537050f, 0.564900f, 0.591519f, >+ 0.616909f, 0.641077f, 0.664037f, 0.685809f, 0.706419f, 0.725897f, >+ 0.744277f, 0.761594f, 0.777888f, 0.793199f, 0.807569f, 0.821040f, >+ 0.833655f, 0.845456f, 0.856485f, 0.866784f, 0.876393f, 0.885352f, >+ 0.893698f, 0.901468f, 0.908698f, 0.915420f, 0.921669f, 0.927473f, >+ 0.932862f, 0.937863f, 0.942503f, 0.946806f, 0.950795f, 0.954492f, >+ 0.957917f, 0.961090f, 0.964028f, 0.966747f, 0.969265f, 0.971594f, >+ 0.973749f, 0.975743f, 0.977587f, 0.979293f, 0.980869f, 0.982327f, >+ 0.983675f, 0.984921f, 0.986072f, 0.987136f, 0.988119f, 0.989027f, >+ 0.989867f, 0.990642f, 0.991359f, 0.992020f, 0.992631f, 0.993196f, >+ 0.993718f, 0.994199f, 0.994644f, 0.995055f, 0.995434f, 0.995784f, >+ 0.996108f, 0.996407f, 0.996682f, 0.996937f, 0.997172f, 0.997389f, >+ 0.997590f, 0.997775f, 0.997946f, 0.998104f, 0.998249f, 0.998384f, >+ 0.998508f, 0.998623f, 0.998728f, 0.998826f, 0.998916f, 0.999000f, >+ 0.999076f, 0.999147f, 0.999213f, 0.999273f, 0.999329f, 0.999381f, >+ 0.999428f, 0.999472f, 0.999513f, 0.999550f, 0.999585f, 0.999617f, >+ 0.999646f, 0.999673f, 0.999699f, 0.999722f, 0.999743f, 0.999763f, >+ 0.999781f, 0.999798f, 0.999813f, 0.999828f, 0.999841f, 0.999853f, >+ 0.999865f, 0.999875f, 0.999885f, 0.999893f, 0.999902f, 0.999909f, >+ 0.999916f, 0.999923f, 0.999929f, 0.999934f, 0.999939f, 0.999944f, >+ 0.999948f, 0.999952f, 0.999956f, 0.999959f, 0.999962f, 0.999965f, >+ 0.999968f, 0.999970f, 0.999973f, 0.999975f, 0.999977f, 0.999978f, >+ 0.999980f, 0.999982f, 0.999983f, 0.999984f, 0.999986f, 0.999987f, >+ 0.999988f, 0.999989f, 0.999990f, 0.999990f, 0.999991f, 0.999992f, >+ 0.999992f, 0.999993f, 0.999994f, 0.999994f, 0.999994f, 0.999995f, >+ 0.999995f, 0.999996f, 0.999996f, 0.999996f, 0.999997f, 0.999997f, >+ 0.999997f, 0.999997f, 0.999997f, 0.999998f, 0.999998f, 0.999998f, >+ 0.999998f, 0.999998f, 0.999998f, 0.999999f, 0.999999f, 0.999999f, >+ 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, >+ 0.999999f, 0.999999f, 0.999999f, 0.999999f, 1.000000f, 1.000000f, >+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, >+ 1.000000f, 1.000000f, 1.000000f, >+ }; >+ >+ // Tests are reversed to catch NaNs. >+ if (!(x < 8.f)) >+ return 1.f; >+ if (!(x > -8.f)) >+ return -1.f; >+ float sign = 1.f; >+ if (x < 0.f) { >+ x = -x; >+ sign = -1.f; >+ } >+ // Look-up. >+ int i = static_cast<int>(std::floor(0.5f + 25 * x)); >+ float y = kTansigTable[i]; >+ // Map i back to x's scale (undo 25 factor). >+ x -= 0.04f * i; >+ y = y + x * (1.f - y * y) * (1.f - y * x); >+ return sign * y; >+} >+ >+inline float SigmoidApproximated(const float x) { >+ return 0.5f + 0.5f * TansigApproximated(0.5f * x); >+} >+ >+inline float RectifiedLinearUnit(const float x) { >+ return x < 0.f ? 0.f : x; >+} >+ >+} // namespace rnnoise >+ >+#endif // THIRD_PARTY_RNNOISE_SRC_RNN_ACTIVATIONS_H_ >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/rnn_vad_weights.cc b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/rnn_vad_weights.cc >new file mode 100644 >index 0000000000000000000000000000000000000000..40c184b98b0dcf23d2e20ed101d1c384b53bcad2 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/rnn_vad_weights.cc >@@ -0,0 +1,401 @@ >+#include "third_party/rnnoise/src/rnn_vad_weights.h" >+ >+namespace rnnoise { >+ >+const int8_t kInputDenseWeights[kInputLayerWeights] = { >+ -10, 0, -3, 1, -8, -6, 3, -13, 1, 0, -3, -7, >+ -5, -3, 6, -1, -6, 0, -6, -4, -1, -2, 1, 1, >+ -7, 2, 21, 10, -5, -20, 24, 23, 37, 8, -2, 33, >+ -6, 22, 13, -2, 50, 8, 13, 1, -15, 30, -10, 30, >+ 0, 3, 5, 27, 1, 4, -3, 41, 56, 35, -2, 49, >+ -13, 11, 13, -2, -47, 5, -16, -60, -15, 77, -17, 26, >+ -3, 14, -21, 19, -5, -19, -13, 0, 10, 14, 9, 31, >+ -13, -41, -10, 4, 22, 18, -48, -6, -10, 62, -3, -18, >+ -14, 12, 26, -28, 3, 14, 25, -13, -19, 6, 5, 36, >+ -3, -65, -12, 0, 31, -7, -9, 101, -4, 26, 16, 17, >+ -12, -12, 14, -36, -3, 5, -15, 21, 2, 30, -3, 38, >+ -4, 1, -6, 7, -7, 14, 38, -22, -30, -3, -7, 3, >+ -39, -70, -126, 25, 34, 94, -67, -22, -33, 83, -47, -118, >+ 4, 70, 33, 25, 62, -128, -76, -118, -113, 49, -12, -100, >+ -18, -114, -33, 43, 32, 61, 40, -9, -106, 2, 36, -100, >+ -40, -5, 20, -75, 61, -51, -9, 126, -27, -52, 5, -24, >+ -21, -126, -114, -12, 15, 106, -2, 73, -125, 50, 13, -120, >+ 35, 35, 4, -61, 29, -124, 6, -53, -69, -125, 64, -89, >+ 36, -107, -103, -7, 27, 121, 69, 77, -35, 35, 95, -125, >+ -49, 97, -45, -43, -23, 23, -28, -65, -118, 2, 8, -126, >+ 27, -97, 92, 5, 55, 82, 17, -57, -115, 37, 8, -106, >+ -46, 41, -2, 21, -44, 8, -73, -58, -39, 34, 89, -95, >+ 95, -117, 120, -58, 31, 123, 1, -32, -109, -110, 60, -120, >+ -43, -74, 5, 91, 26, 21, 114, 82, -83, -126, 123, 22, >+ -16, -67, 25, -83, 46, 48, -34, -121, -124, -63, -35, -9, >+ 31, 82, 123, 6, -3, 117, 93, -2, -13, -36, 124, -112, >+ -6, -102, -5, -33, -15, 44, -69, -127, -23, -40, -34, -85, >+ 68, 83, -1, 40, 8, 84, 118, -58, -55, -102, 123, -55, >+ -14, -123, 44, -63, -14, 21, 35, 16, 24, -126, -13, -114, >+ 35, 20, -36, 61, -9, 97, 34, 19, -32, -109, 76, -104, >+ 99, -119, 45, -125, -51, -28, -8, -69, -8, 125, -45, -93, >+ 113, 103, -41, -82, 52, 7, 126, 0, -40, 104, 55, -58, >+ 17, -124, -93, -58, 8, -45, 1, 56, -123, 108, -47, -23, >+ 115, 127, 17, -68, -13, 116, -82, -44, 45, 67, -120, -101, >+ -15, -125, 120, -113, 17, -48, -73, 126, -64, -86, -118, -19, >+ 112, -1, -66, -27, -62, 121, -86, -58, 50, 89, -38, -75, >+ 95, -111, 12, -113, 2, -68, 2, -94, -121, 91, -5, 0, >+ 79, 43, -7, -18, 79, 35, -38, 47, 1, -45, 83, -50, >+ 102, 32, 55, -96, 15, -122, -69, 45, -27, 91, -62, -30, >+ 46, -95, 22, -72, -97, -1, 14, -122, 28, 127, 61, -126, >+ 121, 9, 68, -120, 49, -60, 90, 3, 43, 68, 54, 34, >+ -10, 28, 21, -24, -54, 22, -113, -12, 82, -2, -17, -9, >+ 127, 8, 116, -92, 0, -70, -33, 123, 66, 116, -74, -4, >+ 74, -72, -22, -47, 1, -83, -60, -124, 1, 122, -57, -43, >+ 49, 40, -126, -128, -8, -29, 28, -24, -123, -121, -70, -93, >+ -37, -126, 11, -125, -37, 11, -31, -51, -124, 116, -128, 8, >+ -25, 109, 75, -12, 7, 8, 10, 117, 124, -128, -128, 29, >+ -26, 101, 21, -128, 87, 8, -39, 23, -128, 127, -127, 74, >+ -55, 74, 112, 127, 4, 55, 44, -92, 123, 34, -93, 47, >+ -21, -92, 17, 49, -121, 92, 7, -126, -125, 124, -74, 3, >+ -59, 18, -91, 3, -9, 9, 56, 116, 7, -29, 33, 87, >+ -21, -128, -13, 57, 74, 9, -29, -61, -97, -21, -95, -12, >+ -114, 16, 82, 125, -7, 10, -24, 9, 77, -128, -102, -25, >+ 3, -126, 10, 13, -18, 51, 26, 127, -79, 35, 51, 12, >+ -50, -24, 1, -7, 22, 81, 65, 120, -30, -38, 85, 122, >+ -4, -106, -11, 27, 53, 41, 8, -104, -66, -38, -124, 10, >+ 12, 76, 117, -109, 9, 11, 2, -18, 3, 113, -16, -79, >+ -39, -123, -20, -128, 2, 13, -33, -58, 10, 84, -104, 13, >+ 64, 109, 1, 54, -12, 28, 24, 63, -126, 118, -82, 46, >+ -12, -15, 14, -43, 60, 22, -32, -19, -46, 91, -107, 24, >+ -94, 26, -47, 125, 6, 58, -15, -75, -26, -38, -35, 103, >+ -16, -17, -13, 63, -2, 45, -45, -73, -23, 70, -87, 51, >+ -17, 53, 76, 14, -18, -31, -14, 103, 8, 21, -28, -33, >+ -20, -47, 6, 39, 40, -30, 7, -76, 55, 31, -20, -21, >+ -59, 1, 25, -11, 17, 5, -13, -39, 0, -76, 50, -33, >+ -29, -50, -16, -11, -12, -1, -46, 40, -10, 65, -19, 21, >+ -41, -32, -83, -19, -4, 49, -60, 118, -24, -46, 9, 102, >+ -20, 8, -19, 25, 31, -3, -37, 0, 25, 7, 29, 2, >+ -39, 127, -64, -20, 64, 115, -30, 36, 100, 35, 122, 127, >+ 127, -127, 127, -127, 19, 127, -89, -79, -32, 39, -127, 125, >+ -80, 126, -127, 26, 8, 98, -8, -57, -90, -50, 126, 61, >+ 127, -126, 40, -106, -68, 104, -125, -119, 11, 10, -127, 66, >+ -56, -12, -126, -104, 27, 75, 38, -124, -126, -125, 84, -123, >+ -45, -114, -128, 127, 103, -101, -124, 127, -11, -23, -123, 92, >+ -123, 24, 126, 41, -2, -39, -27, -94, 40, -112, -48, 127, >+ 58, 14, 38, -75, -64, 73, 117, 100, -119, -11, 6, 32, >+ -126, -14, 35, 121, -10, 54, -60, 89, -3, 69, -25, -20, >+ 43, -86, -34, 24, 27, 7, -81, -99, -23, -16, -26, 13, >+ 35, -97, 80, -29, -13, -121, -12, -65, -94, 70, -89, -126, >+ -95, 88, 33, 96, 29, -90, 69, 114, -78, 65, 90, -47, >+ -47, 89, 1, -12, 3, 8, 30, 5, 2, -30, -1, 6, >+ -7, 10, -4, 46, -27, -40, 22, -6, -17, 45, 24, -9, >+ 23, -14, -63, -26, -12, -57, 27, 25, 55, -76, -47, 21, >+ 34, 33, 26, 17, 14, 6, 9, 26, 25, -25, -25, -18}; >+ >+const int8_t kInputDenseBias[kInputLayerOutputSize] = { >+ 38, -6, 127, 127, 127, -43, -127, 78, 127, 5, 127, 123, >+ 127, 127, -128, -76, -126, 28, 127, 125, -30, 127, -89, -20}; >+ >+const int8_t kHiddenGruWeights[kHiddenLayerWeights] = { >+ -124, 23, -123, -33, -95, -4, 8, -84, 4, 101, -119, 116, >+ -4, 123, 103, -51, 29, -124, -114, -49, 31, 9, 75, -128, >+ 0, -49, 37, -50, 46, -21, -63, -104, 54, 82, 33, 21, >+ 70, 127, -9, -79, -39, -23, -127, 107, 122, -96, -46, -18, >+ -39, 13, -28, -48, 14, 56, -52, 49, -1, -121, 25, -18, >+ -36, -52, -57, -30, 54, -124, -26, -47, 10, 39, 12, 2, >+ 9, -127, -128, 102, 21, 11, -64, -71, 89, -113, -111, 54, >+ 31, 94, 121, -40, 30, 40, -109, 73, -9, 108, -92, 2, >+ -127, 116, 127, 127, -122, 95, 127, -37, -127, 28, 89, 10, >+ 24, -104, -62, -67, -14, 38, 14, -71, 22, -41, 20, -50, >+ 39, 63, 86, 127, -18, 79, 4, -51, 2, 33, 117, -113, >+ -78, 56, -91, 37, 34, -45, -44, -22, 21, -16, 56, 30, >+ -84, -79, 38, -74, 127, 9, -25, 2, 82, 61, 25, -26, >+ 26, 11, 117, -65, 12, -58, 42, -62, -93, 11, 11, 124, >+ -123, 80, -125, 11, -90, 42, 94, 4, -109, -1, 85, -52, >+ 45, -26, -27, 77, -5, 30, 90, 0, 95, -7, 53, 29, >+ -82, 22, -9, 74, 2, -12, -73, 114, 97, -64, 122, -77, >+ 43, 91, 86, 126, 106, 72, 90, -43, 46, 96, -51, 21, >+ 22, 68, 22, 41, 79, 75, -46, -105, 23, -116, 127, -123, >+ 102, 57, 85, 10, -29, 34, 125, 126, 124, 81, -15, 54, >+ 96, -128, 39, -124, 103, 74, 126, 127, -50, -71, -122, -64, >+ 93, -75, 71, 105, 122, 123, 126, 122, -127, 33, -63, -74, >+ 124, -71, 33, 41, -56, 19, 6, 65, 41, 90, -116, -3, >+ -46, 75, -13, 98, -74, -42, 74, -95, -96, 81, 24, 32, >+ -19, -123, 74, 55, 109, 115, 0, 32, 33, 12, -20, 9, >+ 127, 127, -61, 79, -48, -54, -49, 101, -9, 27, -106, 74, >+ 119, 77, 87, -126, -24, 127, 124, 31, 34, 127, 40, 3, >+ -90, 127, 23, 57, -53, 127, -69, -88, -33, 127, 19, -46, >+ -9, -125, 13, -126, -113, 127, -41, 46, 106, -62, 3, -10, >+ 111, 49, -34, -24, -20, -112, 11, 101, -50, -34, 50, 65, >+ -64, -106, 70, -48, 60, 9, -122, -45, 15, -112, -26, -4, >+ 1, 39, 23, 58, -45, -80, 127, 82, 58, 30, -94, -119, >+ 51, -89, 95, -107, 30, 127, 125, 58, -52, -42, -38, -20, >+ -122, 115, 39, -26, 5, 73, 13, -39, 43, -23, -20, -125, >+ 23, 35, 53, -61, -66, 72, -20, 33, 8, 35, 4, 7, >+ 18, 19, 16, -45, -50, -71, 31, -29, -41, -27, 10, 14, >+ 27, 9, -23, 98, 6, -94, 92, 127, -114, 59, -26, -100, >+ -62, -127, -17, -85, -60, 126, -42, -6, 33, -120, -26, -126, >+ -127, -35, -114, -31, 25, -126, -100, -126, -64, -46, -31, 30, >+ 25, -74, -111, -97, -81, -104, -114, -19, -9, -116, -69, 22, >+ 30, 59, 8, -51, 16, -97, 18, -4, -89, 80, -50, 3, >+ 36, -67, 56, 69, -26, 107, -10, 58, -28, -4, -57, -72, >+ -111, 0, -75, -119, 14, -75, -49, -66, -49, 8, -121, 22, >+ -54, 121, 30, 54, -26, -126, -123, 56, 5, 48, 21, -127, >+ -11, 23, 25, -82, 6, -25, 119, 78, 4, -104, 27, 61, >+ -48, 37, -13, -52, 50, -50, 44, -1, -22, -43, -59, -78, >+ -67, -32, -26, 9, -3, 40, 16, 19, 3, -9, 20, -6, >+ -37, 28, 39, 17, -19, -10, 1, 6, -59, 74, 47, 3, >+ -119, 0, -128, -107, -25, -22, -69, -23, -111, -42, -93, -120, >+ 90, -85, -54, -118, 76, -79, 124, 101, -77, -75, -17, -71, >+ -114, 68, 55, 79, -1, -123, -20, 127, -65, -123, -128, -87, >+ 123, 9, -115, -14, 7, -4, 127, -79, -115, 125, -28, 89, >+ -83, 49, 89, 119, -69, -5, 12, -49, 60, 57, -24, -99, >+ -110, 76, -83, 125, 73, 81, 11, 8, -45, 1, 83, 13, >+ -70, -2, 97, 112, -97, 53, -9, -94, 124, 44, -49, -24, >+ 52, 76, -110, -70, -114, -12, 72, -4, -114, 43, -43, 81, >+ 102, -84, -27, 62, -40, 52, 58, 124, -35, -51, -123, -43, >+ 56, -75, -34, -35, -106, 93, -43, 14, -16, 46, 62, -97, >+ 21, 30, -53, 21, -11, -33, -20, -95, 4, -126, 12, 45, >+ 20, 108, 85, 11, 20, -40, 99, 4, -25, -18, -23, -12, >+ -126, -55, -20, -44, -51, 91, -127, 127, -44, 7, 127, 78, >+ 38, 125, -6, -94, -103, 73, 126, -126, 18, 59, -46, 106, >+ 76, 116, -31, 75, -4, 92, 102, 32, -31, 73, 42, -21, >+ -28, 57, 127, -8, -107, 115, 124, -94, -4, -128, 29, -57, >+ 70, -82, 50, -13, -44, 38, 67, -93, 6, -39, -46, 56, >+ 68, 27, 61, 26, 18, -72, 127, 22, 18, -31, 127, 61, >+ -65, -38, 1, -67, -1, 8, -73, 46, -116, -94, 58, -49, >+ 71, -40, -63, -82, -20, -60, 93, 76, 69, -106, 34, -31, >+ 4, -25, 107, -18, 45, 4, -61, 126, 54, -126, -125, 41, >+ 19, 44, 32, -98, 125, -24, 125, -96, -125, 15, 87, -4, >+ -90, 18, -40, 28, -69, 67, 22, 41, 39, 7, -48, -44, >+ 12, 69, -13, 2, 44, -38, 111, -7, -126, -22, -9, 74, >+ -128, -36, -7, -123, -15, -79, -91, -37, -127, -122, 104, 30, >+ 7, 98, -37, 111, -116, -47, 127, -45, 118, -111, -123, -120, >+ -77, -64, -125, 124, 77, 111, 77, 18, -113, 117, -9, 67, >+ -77, 126, 49, -20, -124, 39, 41, -124, -34, 114, -87, -126, >+ 98, -20, 59, -17, -24, 125, 107, 54, 35, 33, -44, 12, >+ -29, 125, -71, -28, -63, -114, 28, -17, 121, -36, 127, 89, >+ -122, -49, -18, -48, 17, 24, 19, -64, -128, 13, 86, 45, >+ 13, -49, 55, 84, 48, 80, -39, 99, -127, 70, -33, 30, >+ 50, 126, -65, -117, -13, -20, -24, 127, 115, -72, -104, 63, >+ 126, -42, 57, 17, 46, 21, 119, 110, -100, -60, -112, 62, >+ -33, 28, 26, -22, -60, -33, -54, 78, 25, 32, -114, 86, >+ 44, 26, 43, 76, 121, 19, 97, -2, -3, -73, -68, 6, >+ -116, 6, -43, -97, 46, -128, -120, -31, -119, -29, 16, 16, >+ -126, -128, -126, -46, -9, -3, 92, -31, -76, -126, -3, -107, >+ -12, -23, -69, 5, 51, 27, -42, 23, -70, -128, -29, 22, >+ 29, -126, -55, 50, -71, -3, 127, 44, -27, -70, -63, -66, >+ -70, 104, 86, 115, 29, -92, 41, -90, 44, -11, -28, 20, >+ -11, -63, -16, 43, 31, 17, -73, -31, -1, -17, -11, -39, >+ 56, 18, 124, 72, -14, 28, 69, -121, -125, 34, 127, 63, >+ 86, -80, -126, -125, -124, -47, 124, 77, 124, -19, 23, -7, >+ -50, 96, -128, -93, 102, -53, -36, -87, 119, -125, 92, -126, >+ 118, 102, 72, -2, 125, 10, 97, 124, -125, 125, 71, -20, >+ -47, -116, -121, -4, -9, -32, 79, -124, -36, 33, -128, -74, >+ 125, 23, 127, -29, -115, -32, 124, -89, 32, -107, 43, -17, >+ 24, 24, 18, 29, -13, -15, -36, 62, -91, 4, -41, 95, >+ 28, -23, 6, 46, 84, 66, 77, 68, -70, -1, -23, -6, >+ 65, 70, -21, 9, 77, -12, 2, -118, 4, 9, -108, 84, >+ 52, 2, 52, 13, -10, 58, -110, 18, 66, -95, -23, 70, >+ 31, -3, 56, 56, -3, -7, 1, -27, -48, -61, 41, -4, >+ 10, -62, 32, -7, -24, 9, -48, -60, -4, 79, -20, -38, >+ -76, 68, -49, -97, 0, -15, 5, -100, -49, -95, -99, -115, >+ -9, -40, 10, 104, 13, 56, 127, -27, -109, -94, -118, -102, >+ -44, -85, 52, 127, -4, 14, 62, 121, -122, -26, -79, -42, >+ -34, 1, 25, -38, -79, -58, -31, -31, -90, -30, -123, 32, >+ -56, 125, 66, 124, -1, 3, 91, -103, -7, 23, 78, -18, >+ 9, 69, -69, 76, -38, -33, -2, -98, 18, 106, 84, 55, >+ 87, -47, 35, -124, 64, 41, -14, 46, 25, -2, 120, -21, >+ 82, 19, -79, -37, -3, -8, -16, 21, 19, -5, -28, -112, >+ 39, -6, -30, 53, -69, 53, 46, 127, 123, 78, 20, 28, >+ -7, 73, 72, 17, -40, 41, 111, 57, 32, -95, 29, 28, >+ -39, -65, 54, -20, -63, 29, -67, 3, 44, -57, -47, 11, >+ 61, -22, -44, 61, 48, -100, 20, 125, 96, -24, -16, 3, >+ -69, -126, 74, -125, 9, 45, -67, -123, -59, -72, 118, 69, >+ 45, 50, -57, 67, 13, -66, -106, 47, 62, 22, -1, -22, >+ -25, -40, -125, 3, 125, 32, 102, -56, -25, -75, -30, 122, >+ 60, -13, 36, -73, 7, -84, 124, 40, -118, 17, -87, -118, >+ -8, 3, -27, 111, -40, 40, -51, 127, 125, -45, -30, -54, >+ 46, 80, -1, -30, 101, -17, 18, 26, 54, 7, -12, 1, >+ -127, 123, -122, -27, -75, 64, 10, 25, -15, -44, 127, -127, >+ 5, -84, -81, -7, 19, -26, 126, 15, 116, -126, 14, -76, >+ 44, 62, -110, -124, 125, -29, -87, -3, -69, 82, 90, 57, >+ -123, 123, 100, -19, -51, -32, 69, 37, -57, -128, -124, -72, >+ -13, 51, -7, -45, -73, 5, 99, -26, -117, -96, -109, 4, >+ -31, -12, 0, 31, -42, -27, 12, -81, 118, 39, 83, 14, >+ 41, -126, 107, -82, 94, -116, -122, -47, -109, -84, -128, -35, >+ -56, 66, 8, -65, 19, 42, -46, -72, -109, 41, 43, -127, >+ -113, 58, 127, 42, -75, -1, 65, 117, -55, -113, -123, 124, >+ 43, -96, -115, -19, 68, 15, 94, 3, 75, 0, 34, 9, >+ 42, 110, -48, 92, -76, 99, -17, 27, 32, 13, 125, 50, >+ -17, 56, 4, 53, 34, -8, 99, 80, -126, -21, -65, -11, >+ -46, 44, -81, -3, -121, 123, 66, -81, -84, 119, 127, 84, >+ 105, 45, -66, -42, -23, 32, -25, 12, 111, 127, 88, 125, >+ 30, 24, -127, -9, -54, 127, -116, -119, 88, 70, 94, -120, >+ 35, -93, 15, 22, -21, 25, -110, -123, -45, 8, -109, 125, >+ -122, -86, -126, 8, -14, -120, -45, -45, 69, -125, -122, 6, >+ 81, 86, 125, 95, 54, 77, 54, -123, 126, -85, -117, 56, >+ 11, 0, -61, -91, -12, -2, -113, -3, -15, -122, -63, -91, >+ 10, 84, -111, 125, 93, 21, 62, -78, -116, 13, -57, 28, >+ -124, 126, 110, 12, 15, 95, 15, -19, -125, -97, 52, -7, >+ 101, 9, 20, -125, -26, -56, 72, 77, 12, -126, 22, -29, >+ 47, 62, 95, 112, 69, 32, 97, -83, -8, -5, 67, -63, >+ -123, 79, 59, 0, -6, -17, 4, -111, -52, 27, 65, 0}; >+ >+const int8_t kHiddenGruRecurrentWeights[kHiddenLayerWeights] = { >+ 65, 83, 35, 56, 24, -34, -28, -2, 125, 19, 42, -9, >+ 124, -53, 24, -87, 11, 35, -81, -35, -125, -31, 123, -21, >+ 33, -91, 113, -93, 45, -6, 53, 38, -92, 8, -27, 87, >+ 4, 43, 43, 10, -128, -128, -46, 127, -38, -45, 25, -87, >+ 19, 5, 52, -96, -23, -29, 121, -126, -24, -20, -2, 69, >+ -50, 6, 71, -81, -125, 90, -94, 1, -38, 36, 89, 17, >+ -60, 71, -48, 18, -15, 44, -18, 59, 11, 114, -51, 32, >+ 110, 1, 4, 109, -24, 127, 27, 60, 88, 24, 45, -59, >+ 75, -36, 8, 57, -32, -25, 13, 126, -89, -61, -76, 127, >+ 18, -62, -68, 23, -113, 5, 126, 43, -88, 26, -78, 18, >+ 75, 21, 9, -74, 20, 41, 126, -118, -15, 9, 116, 126, >+ -127, 34, -6, 126, -128, -53, -54, -55, -121, 70, 127, -12, >+ -68, 82, -25, 104, -126, 126, -21, -26, 124, -75, -127, -120, >+ 13, 61, -64, -108, -63, -65, -44, -35, -61, -39, 109, -74, >+ 113, -3, 108, -30, 125, 120, 39, 125, -128, -95, -99, 111, >+ 9, 25, 114, -75, -92, -54, -12, -32, -38, 10, 31, 10, >+ 63, 51, 40, -99, 74, 4, 50, -128, -36, -35, -11, -28, >+ -126, -7, 66, -58, -126, -22, -83, -61, -127, 49, 126, -8, >+ 7, 62, 36, -11, -32, -44, 63, 116, 41, 65, -127, 126, >+ 63, -30, -96, 74, -92, 127, 38, -18, -128, 68, -5, 101, >+ -4, 85, 58, 79, 0, -58, 8, 119, -70, -1, -79, -68, >+ 114, -28, -90, -6, -112, 2, 127, -8, 10, 55, -59, -126, >+ 127, 125, 80, 72, 35, -54, 95, -124, -124, 79, 23, -46, >+ -61, -127, -100, 99, -77, 8, -87, 5, -2, 49, 85, 7, >+ -71, 82, 53, -41, 22, -22, -93, -103, 6, 52, -56, 14, >+ -8, -111, 85, 16, 54, 32, -118, -24, 61, -53, 96, -70, >+ -5, -17, -67, -84, -7, -82, -107, -96, 21, -83, -58, 50, >+ 12, -126, -1, -28, 34, -126, 115, 17, 91, 1, -127, 72, >+ 11, 126, -81, 6, 96, -8, 77, 15, -6, 63, -27, 20, >+ -123, -109, 85, -79, -17, 126, -92, 2, -61, 20, 14, 17, >+ 121, 123, 30, 57, 120, 127, 57, 42, 117, 98, 67, 39, >+ -20, -70, 100, 7, 125, 122, 40, 16, -79, 125, 83, 41, >+ -106, -57, 24, 55, 27, -66, -111, -44, -7, -43, -66, 121, >+ 42, -128, -45, 35, 15, -127, 34, -35, -34, -40, -18, -6, >+ 63, 111, 31, 116, 127, 19, 24, -71, -39, 34, 11, 19, >+ -40, 27, 12, 106, -10, 56, -82, -106, -2, -50, -52, 114, >+ -126, -34, -43, -68, 10, 76, 57, -118, -128, 37, -104, 76, >+ 125, 3, -76, 127, -29, 84, -94, -15, 55, 125, 79, 127, >+ -57, -125, 104, -68, 126, 126, -77, 51, 45, 33, -109, 115, >+ -11, 1, 95, -121, -5, -9, -126, -114, 39, 68, -126, -107, >+ -51, -42, 24, -8, 51, -27, -43, 66, -45, 62, -98, -109, >+ 69, 67, 0, -125, -128, 49, 31, 126, -122, 2, -55, -67, >+ -126, -70, -128, -125, -77, 25, 16, -8, -102, 11, -75, 82, >+ 38, -5, 5, 19, 34, 47, -127, -93, 21, 24, -97, -18, >+ 31, 39, 34, -20, 22, 123, 7, -77, -81, -46, -9, 1, >+ 23, 39, -127, -43, -8, -50, 10, -21, 59, -9, -4, -13, >+ -27, 44, 127, 52, -47, 70, -43, 52, 101, -49, 27, 45, >+ 49, 33, -125, 55, 114, 20, -1, 76, -24, -96, 105, 24, >+ 126, 75, -21, -105, 13, -42, 40, 126, -30, -39, -95, 125, >+ -63, 11, 6, 125, 125, -14, 5, 42, -61, -4, 49, 88, >+ 6, -107, -28, 19, -29, 47, 126, 6, -46, -89, -18, 91, >+ -20, -6, 118, -21, -22, 39, 115, 11, -42, 54, 73, -55, >+ -77, 62, -27, -59, -99, -12, -127, -40, 56, -3, -124, -91, >+ 71, -111, 6, -19, 82, -24, -35, 102, -42, 7, -126, -126, >+ -125, 18, 98, -52, 127, 105, -52, 40, -83, 126, -122, 109, >+ 5, 127, 48, 6, 5, -125, 100, -16, 29, 85, -89, 8, >+ 4, 41, 62, -127, 62, 122, 85, 122, -107, 8, -125, 93, >+ -127, 127, 102, 19, 19, -66, 41, -42, 114, 127, -48, -117, >+ -29, -6, -73, -102, -3, -19, 0, 88, 42, 87, -117, -20, >+ 2, 122, 28, 63, 71, 66, 120, 93, 124, -43, 49, 103, >+ 31, 90, -91, -22, -126, 26, -24, -21, 51, -126, 87, -103, >+ -69, -10, -66, -23, 20, 97, 36, 25, -127, 30, -20, -63, >+ 30, 51, -116, 23, 40, -39, 36, -83, -77, -25, -50, 110, >+ 14, 13, -109, 125, -65, -55, -87, 124, -126, -32, -72, -108, >+ 127, 127, -125, -124, 61, 121, 102, -128, -127, 16, 100, 127, >+ -124, -68, 72, -93, -128, 43, -93, -19, -125, -97, -113, -33, >+ 83, 127, -44, 127, -75, 127, 16, 44, 50, -122, 23, 118, >+ 46, 19, 26, -128, 10, 4, 99, -14, -82, -13, 30, 125, >+ 57, 65, 60, -71, 35, 98, 28, 7, 1, 43, 89, 70, >+ 75, 121, -59, 82, -126, -53, -16, -116, -65, 52, -52, 0, >+ 80, 35, 45, -61, 46, 8, 107, 27, -26, -118, 90, 57, >+ -10, 7, -15, 0, -39, -4, 12, 29, -1, 116, 84, 79, >+ 119, 125, -59, 28, -6, -25, -43, 2, 90, 79, 67, 103, >+ -82, 2, -6, 125, 19, 73, 0, -105, 112, -17, 104, 107, >+ 124, 106, 19, 56, -44, 55, -112, 6, -39, -83, 126, -93, >+ -98, 57, -120, -23, -38, 2, -31, -48, 106, 127, 127, 69, >+ 16, 110, 71, 104, 62, -12, -22, 42, -37, -94, 34, -1, >+ -32, -12, -124, -47, -13, 60, -75, -66, 58, -127, -2, 64, >+ 76, -106, 73, -49, -31, 127, 126, 31, 16, 127, -110, 107, >+ -16, -53, 20, 69, -14, -125, 59, -44, 15, 120, 125, 125, >+ 43, 6, 19, -58, 127, 127, 43, 16, 82, 97, -127, 127, >+ -93, -41, 88, 0, 77, -15, 116, 16, -124, -31, -3, 95, >+ -40, -126, -54, -126, -83, -8, -59, 6, 67, -29, 4, 124, >+ -10, 112, -28, -8, 85, -21, 45, 84, 6, -8, 11, 72, >+ 32, 84, -62, 77, 2, -36, 75, 31, -50, 116, 126, 119, >+ -88, -55, -14, -37, 126, 40, -108, -6, -6, 57, 64, -28, >+ -76, 30, -117, -93, 31, -92, -44, -64, 94, 58, 65, 114, >+ 41, 47, 71, 42, -26, 99, -126, 57, -5, 74, -19, -113, >+ -1, 67, -21, 126, 1, -3, 33, 60, -82, 37, -48, 89, >+ 114, -38, 127, -114, 35, 58, -5, 21, -46, 121, -123, -43, >+ 127, 115, 123, 122, -101, 126, 127, 81, 52, 89, -127, 102, >+ 42, 117, -9, -2, 125, 127, 110, 96, 120, 66, 70, 124, >+ 55, 84, -38, -58, 119, -127, -16, -79, 123, 18, -127, -50, >+ -38, 120, -85, 1, 7, -56, 108, -77, -2, 21, 37, 1, >+ 13, -105, -69, 28, -87, 33, -104, -51, 126, 41, 3, -121, >+ 28, 71, 58, 86, -8, 127, 94, -55, 125, 40, -19, 127, >+ -33, -87, -23, 7, -111, -68, 9, 84, -119, 55, -82, 78, >+ -37, -20, -9, -23, 53, -13, 15, -46, 116, 126, -127, 56, >+ -126, 125, -7, -1, 45, 26, 125, 121, 29, 47, -86, 30, >+ 10, 76, -125, -7, 23, 92, -12, -39, -18, 92, -97, -8, >+ -85, -41, 49, -50, 123, -37, -126, -30, 14, 79, -49, -65, >+ 9, -36, -38, -96, 85, -24, -13, 37, -25, -5, -64, -127, >+ 55, -60, -18, -61, -63, 127, 56, 67, 15, 124, 72, 120, >+ 127, 40, -10, 114, 24, -23, 46, 78, -53, 125, 86, 124, >+ 86, 0, 38, 93, 21, 127, 123, 75, -72, 13, 48, 33, >+ 83, -51, 15, -32, -49, -33, 120, 64, 7, 9, 65, 60, >+ 21, -21, -61, -53, -113, 84, -97, 101, 37, -114, -27, 41, >+ 73, 126, -10, 59, 61, -15, 70, -13, 82, -4, 69, 56, >+ 94, -91, -50, 92, -74, -48, 53, -7, -107, 127, 28, 30, >+ -26, -21, -61, 77, 82, 64, -91, -125, 122, -104, 127, 123, >+ 122, 123, 76, -126, 127, -6, -80, 7, 40, -66, -65, 54, >+ -2, 23, 96, -64, 74, 2, -53, -12, -123, 39, 60, -20, >+ 16, -17, -97, 23, -4, -53, -122, 32, -16, -54, -95, 43, >+ 71, -1, -67, -33, 41, 18, 72, 28, -83, 31, -100, -91, >+ -27, 10, -128, -106, 2, 76, -13, 42, 34, 112, -19, 44, >+ 40, -9, -11, 65, 92, -43, -125, 2, 47, -32, 25, 122, >+ -29, 12, 101, -8, -126, -23, 43, 7, 125, -20, -124, 82, >+ -2, 13, -73, -106, 115, 31, 116, -23, -44, -71, 84, 3, >+ 47, 91, 127, 127, -15, 95, 7, 93, 5, 113, -50, 54, >+ 11, 13, -127, 17, 72, 43, -23, 5, -70, 20, 15, -27, >+ 99, 69, -109, -122, -94, 16, 127, 0, 116, 104, 45, 108, >+ -34, 87, 72, -14, 118, 46, 42, 109, -26, 95, 93, 127, >+ 60, 127, -93, -54, -122, 34, -105, 56, 55, 103, 125, -71, >+ -50, 95, -72, 127, 107, 21, 73, 126, 61, 127, 127, 24, >+ -62, 90, 73, 90, -46, -78, -124, 72, 123, -42, 50, -107, >+ 17, -32, -62, -89, 124, 1, 80, -2, 117, 119, -65, -127, >+ -95, -121, -52, 103, 66, 75, -3, -62, -127, 127, -74, 124, >+ 79, 49, 40, 105, -67, -71, -70, 43, 127, 119, -4, 66, >+ 43, 23, 91, -126, 15, 63, -119, 112, 103, 15, -99, 31, >+ -127, 69, 116, -46, -67, 2, -126, -29, 30, 30, -69, -98, >+ -47, -87, -70, -127, 23, -73, 30, -7, 94, -52, -65, 98, >+ -45, 97, 53, 23, -9, -22, -52, -47, 6, -1, -85, -15, >+ -61, -14, 68, 110, -10, -121, -25, -35, -15, -94, -123, 27, >+ 75, 48, -66, -56, -44, 93, 109, 67, -36, 24, 70, -126, >+ 8, -127, 126, 52, 11, -32, 120, -13, -26, -28, -125, 127, >+ 106, -50, 124, 36, -126, -12, 0, -23, 76, -71, -126, -12, >+ -17, -82, 12, 124, 57, 33, 4, 77, -46, 71, -34, 72, >+ 125, -128, 124, -24, -128, 75, -120, 69, -45, 55, 33, 127, >+ -33, 4, -105, -41, -59, -91, 123, 44, -127, 127, -67, 52, >+ 25, -125, -65, 100, -25, 123, 6, 11, -123, -92, -33, 126, >+ -17, -4, 29, 33, 127, 96, 3, 87, -48, -18, -70, 123, >+ 58, -127, -3, -52, -1, -36, -41, 127, 51, -52, -27, 46, >+ -83, 57, 9, 126, 127, 94, 79, -37, -127, -40, 67, 52, >+ 82, -66, 122, -13, -73, 127, -8, -80, 46, -48, 4, -54}; >+ >+const int8_t kHiddenGruBias[kHiddenLayerBiases] = { >+ 124, 125, -57, -126, 53, 123, 127, -75, 68, 102, -2, 116, >+ 124, 127, 124, 125, 126, 123, -16, 48, 125, 126, 78, 85, >+ 11, 126, -30, -30, -64, -3, -105, -29, -17, 69, 63, 2, >+ -32, -10, -62, 113, -52, 112, -109, 112, 7, -40, 73, 53, >+ 62, 6, -2, 0, 0, 100, -16, 26, -24, 56, 26, -10, >+ -33, 41, 70, 109, -29, 127, 34, -66, 49, 53, 27, 62}; >+ >+const int8_t kOutputDenseWeights[kOutputLayerWeights] = { >+ 127, 127, 127, 127, 127, 20, 127, -126, -126, -54, 14, 125, >+ -126, -126, 127, -125, -126, 127, -127, -127, -57, -30, 127, 80}; >+ >+const int8_t kOutputDenseBias[kOutputLayerOutputSize] = {-50}; >+ >+} // namespace rnnoise >diff --git a/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/rnn_vad_weights.h b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/rnn_vad_weights.h >new file mode 100644 >index 0000000000000000000000000000000000000000..d55e33ddad7b5e51d7bb773e3458694443719815 >--- /dev/null >+++ b/Source/ThirdParty/libwebrtc/Source/third_party/rnnoise/src/rnn_vad_weights.h >@@ -0,0 +1,37 @@ >+#ifndef THIRD_PARTY_RNNOISE_SRC_RNN_VAD_WEIGHTS_H_ >+#define THIRD_PARTY_RNNOISE_SRC_RNN_VAD_WEIGHTS_H_ >+ >+#include <cstdint> >+#include <cstring> >+ >+namespace rnnoise { >+ >+// Weights scaling factor. >+const float kWeightsScale = 1.f / 256.f; >+ >+// Input layer (dense). >+const size_t kInputLayerInputSize = 42; >+const size_t kInputLayerOutputSize = 24; >+const size_t kInputLayerWeights = kInputLayerInputSize * kInputLayerOutputSize; >+extern const int8_t kInputDenseWeights[kInputLayerWeights]; >+extern const int8_t kInputDenseBias[kInputLayerOutputSize]; >+ >+// Hidden layer (GRU). >+const size_t kHiddenLayerOutputSize = 24; >+const size_t kHiddenLayerWeights = >+ 3 * kInputLayerOutputSize * kHiddenLayerOutputSize; >+const size_t kHiddenLayerBiases = 3 * kHiddenLayerOutputSize; >+extern const int8_t kHiddenGruWeights[kHiddenLayerWeights]; >+extern const int8_t kHiddenGruRecurrentWeights[kHiddenLayerWeights]; >+extern const int8_t kHiddenGruBias[kHiddenLayerBiases]; >+ >+// Output layer (dense). >+const size_t kOutputLayerOutputSize = 1; >+const size_t kOutputLayerWeights = >+ kHiddenLayerOutputSize * kOutputLayerOutputSize; >+extern const int8_t kOutputDenseWeights[kOutputLayerWeights]; >+extern const int8_t kOutputDenseBias[kOutputLayerOutputSize]; >+ >+} // namespace rnnoise >+ >+#endif // THIRD_PARTY_RNNOISE_SRC_RNN_VAD_WEIGHTS_H_
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188751
:
347534
|
347543
|
347615
|
347658