Add vendored dependencies & cleanup script

This commit is contained in:
Luke Street 2022-02-11 14:01:25 -05:00
parent ea5ad06289
commit f55d064a0d
4315 changed files with 1296565 additions and 18 deletions

18
.gitignore vendored
View File

@ -7,24 +7,6 @@
/build
/buildtools
/testing
/third_party/abseil-cpp/
/third_party/angle
/third_party/catapult
/third_party/clang-format
/third_party/glfw
/third_party/googletest
/third_party/gpuweb
/third_party/jinja2
/third_party/jsoncpp
/third_party/llvm-build
/third_party/markupsafe
/third_party/node-addon-api
/third_party/node-api-headers
/third_party/swiftshader
/third_party/tint
/third_party/vulkan-deps
/third_party/vulkan_memory_allocator
/third_party/zlib
/tools
/out

12
mach/README.md Normal file
View File

@ -0,0 +1,12 @@
add-dependencies.sh & README.md originally from https://github.com/hexops/dawn
## Updating
Process for updating Dawn:
1. `git remote add upstream https://dawn.googlesource.com/dawn`
2. `git checkout main && git checkout -B update-nov-30` (replace date with current date)
3. `git fetch upstream && git merge upstream/main`
4. `rm -rf out/ third_party/ build/ && git checkout upstream/main -- third_party/`
5. `gclient sync` At this point there will be quite a large diff as many `third_party/` dependencies we commit will have changed.
6. Stage and review the changes to the `third_party/` directory by running `./mach/add-dependencies.sh`. Alter the script to include/exclude files as needed, commit the result. Make sure test files, documentation, `.gitmodules`, etc. are not included.

48
mach/add-dependencies.sh Executable file
View File

@ -0,0 +1,48 @@
#!/usr/bin/env bash
set -exuo pipefail
echo "Note: You should run gclient sync before this script"
# Remove unneeded dependencies
rm -rf build
# rm -rf build_overrides
rm -rf buildtools
# rm -rf infra
rm -rf testing
rm -rf third_party/angle
rm -rf third_party/catapult
rm -rf third_party/googletest
rm -rf third_party/llvm-build
rm -rf third_party/markupsafe
rm -rf third_party/swiftshader
rm -rf third_party/vulkan_memory_allocator
rm -rf third_party/vulkan-deps/glslang
rm -rf third_party/vulkan-deps/spirv-cross
rm -rf third_party/vulkan-deps/vulkan-headers
rm -rf third_party/vulkan-deps/vulkan-loader
rm -rf third_party/vulkan-deps/vulkan-tools
rm -rf third_party/vulkan-deps/vulkan-validation-layers
rm -rf third_party/zlib
# Remove gitmodules, some third_party/ repositories contain these and leaving them around would
# cause any recursive submodule clones to fail because e.g. some reference internal Google
# repositories. We don't want them anyway.
find third_party -type f -name .gitmodules -delete
# Turn subrepositories into regular folders.
find third_party -depth -type d -name .git -exec rm -rf {} \;
# Remove files that are not needed.
find third_party -depth -type d -name tests -print -exec rm -rf {} \;
find third_party -depth -type d -name docs -print -exec rm -rf {} \;
find third_party -depth -type d -name samples -print -exec rm -rf {} \;
rm -rf third_party/tint/test/
rm -rf third_party/swiftshader/third_party/SPIRV-Tools # already in third_party/vulkan-deps/spirv-tools
rm -rf third_party/swiftshader/third_party/SPIRV-Headers # already in third_party/vulkan-deps/spirv-headers
# Remove gn/gni files
# find . -type f -name '*.gn' -delete
# find . -type f -name '*.gni' -delete
git add third_party/
echo "you may now 'git commit -s -m 'update dependencies' if you are happy with the staged changes"

View File

@ -0,0 +1,41 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'bug'
assignees: ''
---
**Describe the bug**
Include a clear and concise description of what the problem is, including what
you expected to happen, and what actually happened.
**Steps to reproduce the bug**
It's important that we are able to reproduce the problem that you are
experiencing. Please provide all code and relevant steps to reproduce the
problem, including your `BUILD`/`CMakeLists.txt` file and build commands. Links
to a GitHub branch or [godbolt.org](https://godbolt.org/) that demonstrate the
problem are also helpful.
**What version of Abseil are you using?**
**What operating system and version are you using**
If you are using a Linux distribution please include the name and version of the
distribution as well.
**What compiler and version are you using?**
Please include the output of `gcc -v` or `clang -v`, or the equivalent for your
compiler.
**What build system are you using?**
Please include the output of `bazel --version` or `cmake --version`, or the
equivalent for your build system.
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,7 @@
---
name: Question
about: Have a question? Ask us anything! :-)
title: ''
labels: 'question'
assignees: ''
---

View File

@ -0,0 +1 @@
blank_issues_enabled: true

View File

@ -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.]

6
third_party/abseil-cpp/AUTHORS vendored Normal file
View File

@ -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.

25
third_party/abseil-cpp/BUILD.bazel vendored Normal file
View File

@ -0,0 +1,25 @@
#
# Copyright 2020 The Abseil Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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
# Expose license for external usage through bazel.
exports_files([
"AUTHORS",
"LICENSE",
])

View File

@ -0,0 +1,545 @@
include(CMakeParseArguments)
include(GNUInstallDirs)
set(ABSL_INTERNAL_DLL_FILES
"algorithm/algorithm.h"
"algorithm/container.h"
"base/attributes.h"
"base/call_once.h"
"base/casts.h"
"base/config.h"
"base/const_init.h"
"base/dynamic_annotations.h"
"base/internal/atomic_hook.h"
"base/internal/cycleclock.cc"
"base/internal/cycleclock.h"
"base/internal/direct_mmap.h"
"base/internal/dynamic_annotations.h"
"base/internal/endian.h"
"base/internal/errno_saver.h"
"base/internal/exponential_biased.cc"
"base/internal/exponential_biased.h"
"base/internal/fast_type_id.h"
"base/internal/hide_ptr.h"
"base/internal/identity.h"
"base/internal/invoke.h"
"base/internal/inline_variable.h"
"base/internal/low_level_alloc.cc"
"base/internal/low_level_alloc.h"
"base/internal/low_level_scheduling.h"
"base/internal/per_thread_tls.h"
"base/internal/periodic_sampler.cc"
"base/internal/periodic_sampler.h"
"base/internal/pretty_function.h"
"base/internal/raw_logging.cc"
"base/internal/raw_logging.h"
"base/internal/scheduling_mode.h"
"base/internal/scoped_set_env.cc"
"base/internal/scoped_set_env.h"
"base/internal/strerror.h"
"base/internal/strerror.cc"
"base/internal/spinlock.cc"
"base/internal/spinlock.h"
"base/internal/spinlock_wait.cc"
"base/internal/spinlock_wait.h"
"base/internal/sysinfo.cc"
"base/internal/sysinfo.h"
"base/internal/thread_annotations.h"
"base/internal/thread_identity.cc"
"base/internal/thread_identity.h"
"base/internal/throw_delegate.cc"
"base/internal/throw_delegate.h"
"base/internal/tsan_mutex_interface.h"
"base/internal/unaligned_access.h"
"base/internal/unscaledcycleclock.cc"
"base/internal/unscaledcycleclock.h"
"base/log_severity.cc"
"base/log_severity.h"
"base/macros.h"
"base/optimization.h"
"base/options.h"
"base/policy_checks.h"
"base/port.h"
"base/thread_annotations.h"
"cleanup/cleanup.h"
"cleanup/internal/cleanup.h"
"container/btree_map.h"
"container/btree_set.h"
"container/fixed_array.h"
"container/flat_hash_map.h"
"container/flat_hash_set.h"
"container/inlined_vector.h"
"container/internal/btree.h"
"container/internal/btree_container.h"
"container/internal/common.h"
"container/internal/compressed_tuple.h"
"container/internal/container_memory.h"
"container/internal/counting_allocator.h"
"container/internal/hash_function_defaults.h"
"container/internal/hash_policy_traits.h"
"container/internal/hashtable_debug.h"
"container/internal/hashtable_debug_hooks.h"
"container/internal/hashtablez_sampler.cc"
"container/internal/hashtablez_sampler.h"
"container/internal/hashtablez_sampler_force_weak_definition.cc"
"container/internal/have_sse.h"
"container/internal/inlined_vector.h"
"container/internal/layout.h"
"container/internal/node_hash_policy.h"
"container/internal/raw_hash_map.h"
"container/internal/raw_hash_set.cc"
"container/internal/raw_hash_set.h"
"container/internal/tracked.h"
"container/node_hash_map.h"
"container/node_hash_set.h"
"debugging/failure_signal_handler.cc"
"debugging/failure_signal_handler.h"
"debugging/leak_check.h"
"debugging/leak_check_disable.cc"
"debugging/stacktrace.cc"
"debugging/stacktrace.h"
"debugging/symbolize.cc"
"debugging/symbolize.h"
"debugging/internal/address_is_readable.cc"
"debugging/internal/address_is_readable.h"
"debugging/internal/demangle.cc"
"debugging/internal/demangle.h"
"debugging/internal/elf_mem_image.cc"
"debugging/internal/elf_mem_image.h"
"debugging/internal/examine_stack.cc"
"debugging/internal/examine_stack.h"
"debugging/internal/stack_consumption.cc"
"debugging/internal/stack_consumption.h"
"debugging/internal/stacktrace_config.h"
"debugging/internal/symbolize.h"
"debugging/internal/vdso_support.cc"
"debugging/internal/vdso_support.h"
"functional/internal/front_binder.h"
"functional/bind_front.h"
"functional/function_ref.h"
"functional/internal/function_ref.h"
"hash/hash.h"
"hash/internal/city.h"
"hash/internal/city.cc"
"hash/internal/hash.h"
"hash/internal/hash.cc"
"hash/internal/spy_hash_state.h"
"hash/internal/low_level_hash.h"
"hash/internal/low_level_hash.cc"
"memory/memory.h"
"meta/type_traits.h"
"numeric/bits.h"
"numeric/int128.cc"
"numeric/int128.h"
"numeric/internal/bits.h"
"numeric/internal/representation.h"
"random/bernoulli_distribution.h"
"random/beta_distribution.h"
"random/bit_gen_ref.h"
"random/discrete_distribution.cc"
"random/discrete_distribution.h"
"random/distributions.h"
"random/exponential_distribution.h"
"random/gaussian_distribution.cc"
"random/gaussian_distribution.h"
"random/internal/distribution_caller.h"
"random/internal/fastmath.h"
"random/internal/fast_uniform_bits.h"
"random/internal/generate_real.h"
"random/internal/iostream_state_saver.h"
"random/internal/mock_helpers.h"
"random/internal/nonsecure_base.h"
"random/internal/pcg_engine.h"
"random/internal/platform.h"
"random/internal/pool_urbg.cc"
"random/internal/pool_urbg.h"
"random/internal/randen.cc"
"random/internal/randen.h"
"random/internal/randen_detect.cc"
"random/internal/randen_detect.h"
"random/internal/randen_engine.h"
"random/internal/randen_hwaes.cc"
"random/internal/randen_hwaes.h"
"random/internal/randen_round_keys.cc"
"random/internal/randen_slow.cc"
"random/internal/randen_slow.h"
"random/internal/randen_traits.h"
"random/internal/salted_seed_seq.h"
"random/internal/seed_material.cc"
"random/internal/seed_material.h"
"random/internal/sequence_urbg.h"
"random/internal/traits.h"
"random/internal/uniform_helper.h"
"random/internal/wide_multiply.h"
"random/log_uniform_int_distribution.h"
"random/poisson_distribution.h"
"random/random.h"
"random/seed_gen_exception.cc"
"random/seed_gen_exception.h"
"random/seed_sequences.cc"
"random/seed_sequences.h"
"random/uniform_int_distribution.h"
"random/uniform_real_distribution.h"
"random/zipf_distribution.h"
"status/internal/status_internal.h"
"status/internal/statusor_internal.h"
"status/status.h"
"status/status.cc"
"status/statusor.h"
"status/statusor.cc"
"status/status_payload_printer.h"
"status/status_payload_printer.cc"
"strings/ascii.cc"
"strings/ascii.h"
"strings/charconv.cc"
"strings/charconv.h"
"strings/cord.cc"
"strings/cord.h"
"strings/escaping.cc"
"strings/escaping.h"
"strings/internal/charconv_bigint.cc"
"strings/internal/charconv_bigint.h"
"strings/internal/charconv_parse.cc"
"strings/internal/charconv_parse.h"
"strings/internal/cord_internal.cc"
"strings/internal/cord_internal.h"
"strings/internal/cord_rep_consume.h"
"strings/internal/cord_rep_consume.cc"
"strings/internal/cord_rep_btree.cc"
"strings/internal/cord_rep_btree.h"
"strings/internal/cord_rep_btree_navigator.cc"
"strings/internal/cord_rep_btree_navigator.h"
"strings/internal/cord_rep_btree_reader.cc"
"strings/internal/cord_rep_btree_reader.h"
"strings/internal/cord_rep_flat.h"
"strings/internal/cord_rep_ring.cc"
"strings/internal/cord_rep_ring.h"
"strings/internal/cord_rep_ring_reader.h"
"strings/internal/cordz_functions.cc"
"strings/internal/cordz_functions.h"
"strings/internal/cordz_handle.cc"
"strings/internal/cordz_handle.h"
"strings/internal/cordz_info.cc"
"strings/internal/cordz_info.h"
"strings/internal/cordz_sample_token.cc"
"strings/internal/cordz_sample_token.h"
"strings/internal/cordz_statistics.h"
"strings/internal/cordz_update_scope.h"
"strings/internal/cordz_update_tracker.h"
"strings/internal/stl_type_traits.h"
"strings/internal/string_constant.h"
"strings/match.cc"
"strings/match.h"
"strings/numbers.cc"
"strings/numbers.h"
"strings/str_format.h"
"strings/str_cat.cc"
"strings/str_cat.h"
"strings/str_join.h"
"strings/str_replace.cc"
"strings/str_replace.h"
"strings/str_split.cc"
"strings/str_split.h"
"strings/string_view.cc"
"strings/string_view.h"
"strings/strip.h"
"strings/substitute.cc"
"strings/substitute.h"
"strings/internal/char_map.h"
"strings/internal/escaping.h"
"strings/internal/escaping.cc"
"strings/internal/memutil.cc"
"strings/internal/memutil.h"
"strings/internal/ostringstream.cc"
"strings/internal/ostringstream.h"
"strings/internal/pow10_helper.cc"
"strings/internal/pow10_helper.h"
"strings/internal/resize_uninitialized.h"
"strings/internal/str_format/arg.cc"
"strings/internal/str_format/arg.h"
"strings/internal/str_format/bind.cc"
"strings/internal/str_format/bind.h"
"strings/internal/str_format/checker.h"
"strings/internal/str_format/extension.cc"
"strings/internal/str_format/extension.h"
"strings/internal/str_format/float_conversion.cc"
"strings/internal/str_format/float_conversion.h"
"strings/internal/str_format/output.cc"
"strings/internal/str_format/output.h"
"strings/internal/str_format/parser.cc"
"strings/internal/str_format/parser.h"
"strings/internal/str_join_internal.h"
"strings/internal/str_split_internal.h"
"strings/internal/utf8.cc"
"strings/internal/utf8.h"
"synchronization/barrier.cc"
"synchronization/barrier.h"
"synchronization/blocking_counter.cc"
"synchronization/blocking_counter.h"
"synchronization/mutex.cc"
"synchronization/mutex.h"
"synchronization/notification.cc"
"synchronization/notification.h"
"synchronization/internal/create_thread_identity.cc"
"synchronization/internal/create_thread_identity.h"
"synchronization/internal/futex.h"
"synchronization/internal/graphcycles.cc"
"synchronization/internal/graphcycles.h"
"synchronization/internal/kernel_timeout.h"
"synchronization/internal/per_thread_sem.cc"
"synchronization/internal/per_thread_sem.h"
"synchronization/internal/thread_pool.h"
"synchronization/internal/waiter.cc"
"synchronization/internal/waiter.h"
"time/civil_time.cc"
"time/civil_time.h"
"time/clock.cc"
"time/clock.h"
"time/duration.cc"
"time/format.cc"
"time/time.cc"
"time/time.h"
"time/internal/cctz/include/cctz/civil_time.h"
"time/internal/cctz/include/cctz/civil_time_detail.h"
"time/internal/cctz/include/cctz/time_zone.h"
"time/internal/cctz/include/cctz/zone_info_source.h"
"time/internal/cctz/src/civil_time_detail.cc"
"time/internal/cctz/src/time_zone_fixed.cc"
"time/internal/cctz/src/time_zone_fixed.h"
"time/internal/cctz/src/time_zone_format.cc"
"time/internal/cctz/src/time_zone_if.cc"
"time/internal/cctz/src/time_zone_if.h"
"time/internal/cctz/src/time_zone_impl.cc"
"time/internal/cctz/src/time_zone_impl.h"
"time/internal/cctz/src/time_zone_info.cc"
"time/internal/cctz/src/time_zone_info.h"
"time/internal/cctz/src/time_zone_libc.cc"
"time/internal/cctz/src/time_zone_libc.h"
"time/internal/cctz/src/time_zone_lookup.cc"
"time/internal/cctz/src/time_zone_posix.cc"
"time/internal/cctz/src/time_zone_posix.h"
"time/internal/cctz/src/tzfile.h"
"time/internal/cctz/src/zone_info_source.cc"
"types/any.h"
"types/bad_any_cast.cc"
"types/bad_any_cast.h"
"types/bad_optional_access.cc"
"types/bad_optional_access.h"
"types/bad_variant_access.cc"
"types/bad_variant_access.h"
"types/compare.h"
"types/internal/conformance_aliases.h"
"types/internal/conformance_archetype.h"
"types/internal/conformance_profile.h"
"types/internal/parentheses.h"
"types/internal/transform_args.h"
"types/internal/variant.h"
"types/optional.h"
"types/internal/optional.h"
"types/span.h"
"types/internal/span.h"
"types/variant.h"
"utility/utility.h"
)
set(ABSL_INTERNAL_DLL_TARGETS
"stacktrace"
"symbolize"
"examine_stack"
"failure_signal_handler"
"debugging_internal"
"demangle_internal"
"leak_check"
"leak_check_disable"
"stack_consumption"
"debugging"
"hash"
"spy_hash_state"
"city"
"memory"
"strings"
"strings_internal"
"cord"
"str_format"
"str_format_internal"
"pow10_helper"
"int128"
"numeric"
"utility"
"any"
"bad_any_cast"
"bad_any_cast_impl"
"span"
"optional"
"bad_optional_access"
"bad_variant_access"
"variant"
"compare"
"algorithm"
"algorithm_container"
"graphcycles_internal"
"kernel_timeout_internal"
"synchronization"
"thread_pool"
"bind_front"
"function_ref"
"atomic_hook"
"log_severity"
"raw_logging_internal"
"spinlock_wait"
"config"
"dynamic_annotations"
"core_headers"
"malloc_internal"
"base_internal"
"base"
"throw_delegate"
"pretty_function"
"endian"
"bits"
"exponential_biased"
"periodic_sampler"
"scoped_set_env"
"type_traits"
"meta"
"random_random"
"random_bit_gen_ref"
"random_distributions"
"random_seed_gen_exception"
"random_seed_sequences"
"random_internal_traits"
"random_internal_distribution_caller"
"random_internal_distributions"
"random_internal_fast_uniform_bits"
"random_internal_seed_material"
"random_internal_pool_urbg"
"random_internal_explicit_seed_seq"
"random_internal_sequence_urbg"
"random_internal_salted_seed_seq"
"random_internal_iostream_state_saver"
"random_internal_generate_real"
"random_internal_wide_multiply"
"random_internal_fastmath"
"random_internal_nonsecure_base"
"random_internal_pcg_engine"
"random_internal_randen_engine"
"random_internal_platform"
"random_internal_randen"
"random_internal_randen_slow"
"random_internal_randen_hwaes"
"random_internal_randen_hwaes_impl"
"random_internal_uniform_helper"
"status"
"time"
"civil_time"
"time_zone"
"container"
"btree"
"compressed_tuple"
"fixed_array"
"inlined_vector_internal"
"inlined_vector"
"counting_allocator"
"flat_hash_map"
"flat_hash_set"
"node_hash_map"
"node_hash_set"
"container_memory"
"hash_function_defaults"
"hash_policy_traits"
"hashtablez_sampler"
"hashtable_debug"
"hashtable_debug_hooks"
"have_sse"
"node_hash_policy"
"raw_hash_map"
"container_common"
"raw_hash_set"
"layout"
"tracked"
)
function(absl_internal_dll_contains)
cmake_parse_arguments(ABSL_INTERNAL_DLL
""
"OUTPUT;TARGET"
""
${ARGN}
)
STRING(REGEX REPLACE "^absl::" "" _target ${ABSL_INTERNAL_DLL_TARGET})
list(FIND
ABSL_INTERNAL_DLL_TARGETS
"${_target}"
_index)
if (${_index} GREATER -1)
set(${ABSL_INTERNAL_DLL_OUTPUT} 1 PARENT_SCOPE)
else()
set(${ABSL_INTERNAL_DLL_OUTPUT} 0 PARENT_SCOPE)
endif()
endfunction()
function(absl_internal_dll_targets)
cmake_parse_arguments(ABSL_INTERNAL_DLL
""
"OUTPUT"
"DEPS"
${ARGN}
)
set(_deps "")
foreach(dep IN LISTS ABSL_INTERNAL_DLL_DEPS)
absl_internal_dll_contains(TARGET ${dep} OUTPUT _contains)
if (_contains)
list(APPEND _deps abseil_dll)
else()
list(APPEND _deps ${dep})
endif()
endforeach()
# Because we may have added the DLL multiple times
list(REMOVE_DUPLICATES _deps)
set(${ABSL_INTERNAL_DLL_OUTPUT} "${_deps}" PARENT_SCOPE)
endfunction()
function(absl_make_dll)
add_library(
abseil_dll
SHARED
"${ABSL_INTERNAL_DLL_FILES}"
)
target_link_libraries(
abseil_dll
PRIVATE
${ABSL_DEFAULT_LINKOPTS}
)
set_property(TARGET abseil_dll PROPERTY LINKER_LANGUAGE "CXX")
target_include_directories(
abseil_dll
PUBLIC
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_compile_options(
abseil_dll
PRIVATE
${ABSL_DEFAULT_COPTS}
)
target_compile_definitions(
abseil_dll
PRIVATE
ABSL_BUILD_DLL
NOMINMAX
INTERFACE
${ABSL_CC_LIB_DEFINES}
)
install(TARGETS abseil_dll EXPORT ${PROJECT_NAME}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endfunction()

View File

@ -0,0 +1,444 @@
#
# 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
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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)
include(AbseilConfigureCopts)
include(AbseilDll)
# 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.
if(NOT DEFINED ABSL_IDE_FOLDER)
set(ABSL_IDE_FOLDER Abseil)
endif()
# absl_cc_library()
#
# CMake function to imitate Bazel's cc_library rule.
#
# Parameters:
# NAME: name of target (see Note)
# HDRS: List of public header files for the library
# SRCS: List of source files for the library
# DEPS: List of other libraries to be linked in to the binary targets
# COPTS: List of private compile options
# DEFINES: List of public defines
# LINKOPTS: List of link options
# PUBLIC: Add this so that this library will be exported under absl::
# Also in IDE, target will appear in Abseil folder while non PUBLIC will be in Abseil/internal.
# TESTONLY: When added, this target will only be built if BUILD_TESTING=ON.
#
# Note:
# By default, absl_cc_library will always create a library named absl_${NAME},
# and alias target absl::${NAME}. The absl:: form should always be used.
# This is to reduce namespace pollution.
#
# absl_cc_library(
# NAME
# awesome
# HDRS
# "a.h"
# SRCS
# "a.cc"
# )
# absl_cc_library(
# NAME
# fantastic_lib
# SRCS
# "b.cc"
# DEPS
# absl::awesome # not "awesome" !
# PUBLIC
# )
#
# absl_cc_library(
# NAME
# main_lib
# ...
# DEPS
# absl::fantastic_lib
# )
#
# TODO: Implement "ALWAYSLINK"
function(absl_cc_library)
cmake_parse_arguments(ABSL_CC_LIB
"DISABLE_INSTALL;PUBLIC;TESTONLY"
"NAME"
"HDRS;SRCS;COPTS;DEFINES;LINKOPTS;DEPS"
${ARGN}
)
if(ABSL_CC_LIB_TESTONLY AND NOT BUILD_TESTING)
return()
endif()
if(ABSL_ENABLE_INSTALL)
set(_NAME "${ABSL_CC_LIB_NAME}")
else()
set(_NAME "absl_${ABSL_CC_LIB_NAME}")
endif()
# Check if this is a header-only library
# Note that as of February 2019, many popular OS's (for example, Ubuntu
# 16.04 LTS) only come with cmake 3.5 by default. For this reason, we can't
# use list(FILTER...)
set(ABSL_CC_SRCS "${ABSL_CC_LIB_SRCS}")
foreach(src_file IN LISTS ABSL_CC_SRCS)
if(${src_file} MATCHES ".*\\.(h|inc)")
list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}")
endif()
endforeach()
if(ABSL_CC_SRCS STREQUAL "")
set(ABSL_CC_LIB_IS_INTERFACE 1)
else()
set(ABSL_CC_LIB_IS_INTERFACE 0)
endif()
# Determine this build target's relationship to the DLL. It's one of four things:
# 1. "dll" -- This target is part of the DLL
# 2. "dll_dep" -- This target is not part of the DLL, but depends on the DLL.
# Note that we assume any target not in the DLL depends on the
# DLL. This is not a technical necessity but a convenience
# which happens to be true, because nearly every target is
# part of the DLL.
# 3. "shared" -- This is a shared library, perhaps on a non-windows platform
# where DLL doesn't make sense.
# 4. "static" -- This target does not depend on the DLL and should be built
# statically.
if (${ABSL_BUILD_DLL})
if(ABSL_ENABLE_INSTALL)
absl_internal_dll_contains(TARGET ${_NAME} OUTPUT _in_dll)
else()
absl_internal_dll_contains(TARGET ${ABSL_CC_LIB_NAME} OUTPUT _in_dll)
endif()
if (${_in_dll})
# This target should be replaced by the DLL
set(_build_type "dll")
set(ABSL_CC_LIB_IS_INTERFACE 1)
else()
# Building a DLL, but this target is not part of the DLL
set(_build_type "dll_dep")
endif()
elseif(BUILD_SHARED_LIBS)
set(_build_type "shared")
else()
set(_build_type "static")
endif()
# Generate a pkg-config file for every library:
if((_build_type STREQUAL "static" OR _build_type STREQUAL "shared")
AND ABSL_ENABLE_INSTALL)
if(NOT ABSL_CC_LIB_TESTONLY)
if(absl_VERSION)
set(PC_VERSION "${absl_VERSION}")
else()
set(PC_VERSION "head")
endif()
foreach(dep ${ABSL_CC_LIB_DEPS})
if(${dep} MATCHES "^absl::(.*)")
# Join deps with commas.
if(PC_DEPS)
set(PC_DEPS "${PC_DEPS},")
endif()
set(PC_DEPS "${PC_DEPS} absl_${CMAKE_MATCH_1} = ${PC_VERSION}")
endif()
endforeach()
foreach(cflag ${ABSL_CC_LIB_COPTS})
if(${cflag} MATCHES "^(-Wno|/wd)")
# These flags are needed to suppress warnings that might fire in our headers.
set(PC_CFLAGS "${PC_CFLAGS} ${cflag}")
elseif(${cflag} MATCHES "^(-W|/w[1234eo])")
# Don't impose our warnings on others.
else()
set(PC_CFLAGS "${PC_CFLAGS} ${cflag}")
endif()
endforeach()
FILE(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/lib/pkgconfig/absl_${_NAME}.pc" CONTENT "\
prefix=${CMAKE_INSTALL_PREFIX}\n\
exec_prefix=\${prefix}\n\
libdir=${CMAKE_INSTALL_FULL_LIBDIR}\n\
includedir=${CMAKE_INSTALL_FULL_INCLUDEDIR}\n\
\n\
Name: absl_${_NAME}\n\
Description: Abseil ${_NAME} library\n\
URL: https://abseil.io/\n\
Version: ${PC_VERSION}\n\
Requires:${PC_DEPS}\n\
Libs: -L\${libdir} $<JOIN:${ABSL_CC_LIB_LINKOPTS}, > $<$<NOT:$<BOOL:${ABSL_CC_LIB_IS_INTERFACE}>>:-labsl_${_NAME}>\n\
Cflags: -I\${includedir}${PC_CFLAGS}\n")
INSTALL(FILES "${CMAKE_BINARY_DIR}/lib/pkgconfig/absl_${_NAME}.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endif()
endif()
if(NOT ABSL_CC_LIB_IS_INTERFACE)
if(_build_type STREQUAL "dll_dep")
# This target depends on the DLL. When adding dependencies to this target,
# any depended-on-target which is contained inside the DLL is replaced
# with a dependency on the DLL.
add_library(${_NAME} STATIC "")
target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS})
absl_internal_dll_targets(
DEPS ${ABSL_CC_LIB_DEPS}
OUTPUT _dll_deps
)
target_link_libraries(${_NAME}
PUBLIC ${_dll_deps}
PRIVATE
${ABSL_CC_LIB_LINKOPTS}
${ABSL_DEFAULT_LINKOPTS}
)
if (ABSL_CC_LIB_TESTONLY)
set(_gtest_link_define "GTEST_LINKED_AS_SHARED_LIBRARY=1")
else()
set(_gtest_link_define)
endif()
target_compile_definitions(${_NAME}
PUBLIC
ABSL_CONSUME_DLL
"${_gtest_link_define}"
)
elseif(_build_type STREQUAL "static" OR _build_type STREQUAL "shared")
add_library(${_NAME} "")
target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS})
target_link_libraries(${_NAME}
PUBLIC ${ABSL_CC_LIB_DEPS}
PRIVATE
${ABSL_CC_LIB_LINKOPTS}
${ABSL_DEFAULT_LINKOPTS}
)
else()
message(FATAL_ERROR "Invalid build type: ${_build_type}")
endif()
# Linker language can be inferred from sources, but in the case of DLLs we
# don't have any .cc files so it would be ambiguous. We could set it
# explicitly only in the case of DLLs but, because "CXX" is always the
# correct linker language for static or for shared libraries, we set it
# unconditionally.
set_property(TARGET ${_NAME} PROPERTY LINKER_LANGUAGE "CXX")
target_include_directories(${_NAME}
PUBLIC
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_compile_options(${_NAME}
PRIVATE ${ABSL_CC_LIB_COPTS})
target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES})
# Add all Abseil targets to a a folder in the IDE for organization.
if(ABSL_CC_LIB_PUBLIC)
set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER})
elseif(ABSL_CC_LIB_TESTONLY)
set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test)
else()
set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/internal)
endif()
if(ABSL_PROPAGATE_CXX_STD)
# Abseil libraries require C++11 as the current minimum standard.
# Top-level application CMake projects should ensure a consistent C++
# standard for all compiled sources by setting CMAKE_CXX_STANDARD.
target_compile_features(${_NAME} PUBLIC cxx_std_11)
else()
# Note: This is legacy (before CMake 3.8) behavior. Setting the
# target-level CXX_STANDARD property to ABSL_CXX_STANDARD (which is
# initialized by CMAKE_CXX_STANDARD) should have no real effect, since
# that is the default value anyway.
#
# CXX_STANDARD_REQUIRED does guard against the top-level CMake project
# not having enabled CMAKE_CXX_STANDARD_REQUIRED (which prevents
# "decaying" to an older standard if the requested one isn't available).
set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD})
set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
endif()
# When being installed, we lose the absl_ prefix. We want to put it back
# to have properly named lib files. This is a no-op when we are not being
# installed.
if(ABSL_ENABLE_INSTALL)
set_target_properties(${_NAME} PROPERTIES
OUTPUT_NAME "absl_${_NAME}"
SOVERSION 0
)
endif()
else()
# Generating header-only library
add_library(${_NAME} INTERFACE)
target_include_directories(${_NAME}
INTERFACE
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
if (_build_type STREQUAL "dll")
set(ABSL_CC_LIB_DEPS abseil_dll)
endif()
target_link_libraries(${_NAME}
INTERFACE
${ABSL_CC_LIB_DEPS}
${ABSL_CC_LIB_LINKOPTS}
${ABSL_DEFAULT_LINKOPTS}
)
target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES})
if(ABSL_PROPAGATE_CXX_STD)
# Abseil libraries require C++11 as the current minimum standard.
# Top-level application CMake projects should ensure a consistent C++
# standard for all compiled sources by setting CMAKE_CXX_STANDARD.
target_compile_features(${_NAME} INTERFACE cxx_std_11)
# (INTERFACE libraries can't have the CXX_STANDARD property set, so there
# is no legacy behavior else case).
endif()
endif()
# TODO currently we don't install googletest alongside abseil sources, so
# installed abseil can't be tested.
if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL)
install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endif()
add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME})
endfunction()
# absl_cc_test()
#
# CMake function to imitate Bazel's cc_test rule.
#
# Parameters:
# NAME: name of target (see Usage below)
# SRCS: List of source files for the binary
# DEPS: List of other libraries to be linked in to the binary targets
# COPTS: List of private compile options
# DEFINES: List of public defines
# LINKOPTS: List of link options
#
# Note:
# By default, absl_cc_test will always create a binary named absl_${NAME}.
# This will also add it to ctest list as absl_${NAME}.
#
# Usage:
# absl_cc_library(
# NAME
# awesome
# HDRS
# "a.h"
# SRCS
# "a.cc"
# PUBLIC
# )
#
# absl_cc_test(
# NAME
# awesome_test
# SRCS
# "awesome_test.cc"
# DEPS
# absl::awesome
# GTest::gmock
# GTest::gtest_main
# )
function(absl_cc_test)
if(NOT BUILD_TESTING)
return()
endif()
cmake_parse_arguments(ABSL_CC_TEST
""
"NAME"
"SRCS;COPTS;DEFINES;LINKOPTS;DEPS"
${ARGN}
)
set(_NAME "absl_${ABSL_CC_TEST_NAME}")
add_executable(${_NAME} "")
target_sources(${_NAME} PRIVATE ${ABSL_CC_TEST_SRCS})
target_include_directories(${_NAME}
PUBLIC ${ABSL_COMMON_INCLUDE_DIRS}
PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS}
)
if (${ABSL_BUILD_DLL})
target_compile_definitions(${_NAME}
PUBLIC
${ABSL_CC_TEST_DEFINES}
ABSL_CONSUME_DLL
GTEST_LINKED_AS_SHARED_LIBRARY=1
)
# Replace dependencies on targets inside the DLL with abseil_dll itself.
absl_internal_dll_targets(
DEPS ${ABSL_CC_TEST_DEPS}
OUTPUT ABSL_CC_TEST_DEPS
)
else()
target_compile_definitions(${_NAME}
PUBLIC
${ABSL_CC_TEST_DEFINES}
)
endif()
target_compile_options(${_NAME}
PRIVATE ${ABSL_CC_TEST_COPTS}
)
target_link_libraries(${_NAME}
PUBLIC ${ABSL_CC_TEST_DEPS}
PRIVATE ${ABSL_CC_TEST_LINKOPTS}
)
# Add all Abseil targets to a folder in the IDE for organization.
set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test)
if(ABSL_PROPAGATE_CXX_STD)
# Abseil libraries require C++11 as the current minimum standard.
# Top-level application CMake projects should ensure a consistent C++
# standard for all compiled sources by setting CMAKE_CXX_STANDARD.
target_compile_features(${_NAME} PUBLIC cxx_std_11)
else()
# Note: This is legacy (before CMake 3.8) behavior. Setting the
# target-level CXX_STANDARD property to ABSL_CXX_STANDARD (which is
# initialized by CMAKE_CXX_STANDARD) should have no real effect, since
# that is the default value anyway.
#
# CXX_STANDARD_REQUIRED does guard against the top-level CMake project
# not having enabled CMAKE_CXX_STANDARD_REQUIRED (which prevents
# "decaying" to an older standard if the requested one isn't available).
set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD})
set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
endif()
add_test(NAME ${_NAME} COMMAND ${_NAME})
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()

View File

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 2.8.2)
project(googletest-external NONE)
include(ExternalProject)
ExternalProject_Add(googletest
URL "${absl_gtest_download_url}" # May be empty
SOURCE_DIR "${absl_gtest_src_dir}"
BINARY_DIR "${absl_gtest_build_dir}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

View File

@ -0,0 +1,41 @@
# Integrates googletest at configure time. Based on the instructions at
# https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project
# Set up the external googletest project, downloading the latest from Github
# master if requested.
configure_file(
${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt.in
${CMAKE_BINARY_DIR}/googletest-external/CMakeLists.txt
)
set(ABSL_SAVE_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
set(ABSL_SAVE_CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
if (BUILD_SHARED_LIBS)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_CREATE_SHARED_LIBRARY=1")
endif()
# Configure and build the googletest source.
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-external )
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-external)
if(result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
set(CMAKE_CXX_FLAGS ${ABSL_SAVE_CMAKE_CXX_FLAGS})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ABSL_SAVE_CMAKE_RUNTIME_OUTPUT_DIRECTORY})
# 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(${absl_gtest_src_dir} ${absl_gtest_build_dir} EXCLUDE_FROM_ALL)

185
third_party/abseil-cpp/CMake/README.md vendored Normal file
View File

@ -0,0 +1,185 @@
# 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
<https://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 an application project using Abseil.
```cmake
cmake_minimum_required(VERSION 3.8.2)
project(my_app_project)
# Pick the C++ standard to compile with.
# Abseil currently supports C++11, C++14, and C++17.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(abseil-cpp)
add_executable(my_exe source.cpp)
target_link_libraries(my_exe absl::base absl::synchronization absl::strings)
```
Note that if you are developing a library designed for use by other clients, you
should instead leave `CMAKE_CXX_STANDARD` unset (or only set if being built as
the current top-level CMake project) and configure the minimum required C++
standard at the target level. If you require a later minimum C++ standard than
Abseil does, it's a good idea to also enforce that `CMAKE_CXX_STANDARD` (which
will control Abseil library targets) is set to at least that minimum. For
example:
```cmake
cmake_minimum_required(VERSION 3.8.2)
project(my_lib_project)
# Leave C++ standard up to the root application, so set it only if this is the
# current top-level CMake project.
if(CMAKE_SOURCE_DIR STREQUAL my_lib_project_SOURCE_DIR)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
add_subdirectory(abseil-cpp)
add_library(my_lib source.cpp)
target_link_libraries(my_lib absl::base absl::synchronization absl::strings)
# Enforce that my_lib requires C++17. Important to document for clients that they
# must set CMAKE_CXX_STANDARD to 17 or higher for proper Abseil ABI compatibility
# (since otherwise, Abseil library targets could be compiled with a lower C++
# standard than my_lib).
target_compile_features(my_lib PUBLIC cxx_std_17)
if(CMAKE_CXX_STANDARD LESS 17)
message(FATAL_ERROR
"my_lib_project requires CMAKE_CXX_STANDARD >= 17 (got: ${CMAKE_CXX_STANDARD})")
endif()
```
Then the top-level application project that uses your library is responsible for
setting a consistent `CMAKE_CXX_STANDARD` that is sufficiently high.
### Running Abseil Tests with CMake
Use the `-DBUILD_TESTING=ON` flag to run Abseil tests.
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 -DBUILD_TESTING=ON -DABSL_USE_GOOGLETEST_HEAD=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::algorithm
absl::base
absl::debugging
absl::flat_hash_map
absl::flags
absl::memory
absl::meta
absl::numeric
absl::random_random
absl::strings
absl::synchronization
absl::time
absl::utility
```
## Traditional CMake Set-Up
For larger projects, it may make sense to use the traditional CMake set-up where you build and install projects separately.
First, you'd need to build and install Google Test:
```
cmake -S /source/googletest -B /build/googletest -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/installation/dir -DBUILD_GMOCK=ON
cmake --build /build/googletest --target install
```
Then you need to configure and build Abseil. Make sure you enable `ABSL_USE_EXTERNAL_GOOGLETEST` and `ABSL_FIND_GOOGLETEST`. You also need to enable `ABSL_ENABLE_INSTALL` so that you can install Abseil itself.
```
cmake -S /source/abseil-cpp -B /build/abseil-cpp -DCMAKE_PREFIX_PATH=/installation/dir -DCMAKE_INSTALL_PREFIX=/installation/dir -DABSL_ENABLE_INSTALL=ON -DABSL_USE_EXTERNAL_GOOGLETEST=ON -DABSL_FIND_GOOGLETEST=ON
cmake --build /temporary/build/abseil-cpp
```
(`CMAKE_PREFIX_PATH` is where you already have Google Test installed; `CMAKE_INSTALL_PREFIX` is where you want to have Abseil installed; they can be different.)
Run the tests:
```
ctest --test-dir /temporary/build/abseil-cpp
```
And finally install:
```
cmake --build /temporary/build/abseil-cpp --target install
```
# CMake Option Synposis
## Enable Standard CMake Installation
`-DABSL_ENABLE_INSTALL=ON`
## Google Test Options
`-DBUILD_TESTING=ON` must be set to enable testing
- Have Abseil download and build Google Test for you: `-DABSL_USE_EXTERNAL_GOOGLETEST=OFF` (default)
- Download and build latest Google Test: `-DABSL_USE_GOOGLETEST_HEAD=ON`
- Download specific Google Test version (ZIP archive): `-DABSL_GOOGLETEST_DOWNLOAD_URL=https://.../version.zip`
- Use Google Test from specific local directory: `-DABSL_LOCAL_GOOGLETEST_DIR=/path/to/googletest`
- Use Google Test included elsewhere in your project: `-DABSL_USE_EXTERNAL_GOOGLETEST=ON`
- Use standard CMake `find_package(CTest)` to find installed Google Test: `-DABSL_USE_EXTERNAL_GOOGLETEST=ON -DABSL_FIND_GOOGLETEST=ON`

View File

@ -0,0 +1,8 @@
# absl CMake configuration file.
include(CMakeFindDependencyMacro)
find_dependency(Threads)
@PACKAGE_INIT@
include ("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")

View File

@ -0,0 +1,25 @@
#
# Copyright 2019 The Abseil Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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 simple CMakeLists.txt for testing cmake installation
cmake_minimum_required(VERSION 3.5)
project(absl_cmake_testing CXX)
add_executable(simple simple.cc)
find_package(absl REQUIRED)
target_link_libraries(simple absl::strings)

View File

@ -0,0 +1,23 @@
//
// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT 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 <iostream>
#include "absl/strings/substitute.h"
int main(int argc, char** argv) {
for (int i = 0; i < argc; ++i) {
std::cout << absl::Substitute("Arg $0: $1\n", i, argv[i]);
}
}

View File

@ -0,0 +1,112 @@
#!/bin/bash
#
# Copyright 2019 The Abseil Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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 and integration tests for Abseil LTS CMake installation
# Fail on any error. Treat unset variables an error. Print commands as executed.
set -euox pipefail
absl_dir=/abseil-cpp
absl_build_dir=/buildfs
googletest_builddir=/googletest_builddir
project_dir="${absl_dir}"/CMake/install_test_project
project_build_dir=/buildfs/project-build
build_shared_libs="OFF"
if [ "${LINK_TYPE:-}" = "DYNAMIC" ]; then
build_shared_libs="ON"
fi
# Build and install GoogleTest
mkdir "${googletest_builddir}"
pushd "${googletest_builddir}"
curl -L "${ABSL_GOOGLETEST_DOWNLOAD_URL}" --output "${ABSL_GOOGLETEST_COMMIT}".zip
unzip "${ABSL_GOOGLETEST_COMMIT}".zip
pushd "googletest-${ABSL_GOOGLETEST_COMMIT}"
mkdir build
pushd build
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS="${build_shared_libs}" ..
make -j $(nproc)
make install
ldconfig
popd
popd
popd
# Run the LTS transformations
./create_lts.py 99998877
# Build and install Abseil
pushd "${absl_build_dir}"
cmake "${absl_dir}" \
-DABSL_USE_EXTERNAL_GOOGLETEST=ON \
-DABSL_FIND_GOOGLETEST=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTING=ON \
-DBUILD_SHARED_LIBS="${build_shared_libs}"
make -j $(nproc)
ctest -j $(nproc)
make install
ldconfig
popd
# Test the project against the installed Abseil
mkdir -p "${project_build_dir}"
pushd "${project_build_dir}"
cmake "${project_dir}"
cmake --build . --target simple
output="$(${project_build_dir}/simple "printme" 2>&1)"
if [[ "${output}" != *"Arg 1: printme"* ]]; then
echo "Faulty output on simple project:"
echo "${output}"
exit 1
fi
popd
if ! grep absl::strings "/usr/local/lib/cmake/absl/abslTargets.cmake"; then
cat "/usr/local/lib/cmake/absl/abslTargets.cmake"
echo "CMake targets named incorrectly"
exit 1
fi
pushd "${HOME}"
cat > hello-abseil.cc << EOF
#include <cstdlib>
#include "absl/strings/str_format.h"
int main(int argc, char **argv) {
absl::PrintF("Hello Abseil!\n");
return EXIT_SUCCESS;
}
EOF
if [ "${LINK_TYPE:-}" != "DYNAMIC" ]; then
pc_args=($(pkg-config --cflags --libs --static absl_str_format))
g++ -static -o hello-abseil hello-abseil.cc "${pc_args[@]}"
else
pc_args=($(pkg-config --cflags --libs absl_str_format))
g++ -o hello-abseil hello-abseil.cc "${pc_args[@]}"
fi
hello="$(./hello-abseil)"
[[ "${hello}" == "Hello Abseil!" ]]
popd
echo "Install test complete!"
exit 0

233
third_party/abseil-cpp/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,233 @@
#
# 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
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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 widely used distributions have cmake 3.5 or greater available as of March
# 2019. A notable exception is RHEL-7 (CentOS7). You can install a current
# version of CMake by first installing Extra Packages for Enterprise Linux
# (https://fedoraproject.org/wiki/EPEL#Extra_Packages_for_Enterprise_Linux_.28EPEL.29)
# and then issuing `yum install cmake3` on the command line.
cmake_minimum_required(VERSION 3.5)
# Compiler id for Apple Clang is now AppleClang.
if (POLICY CMP0025)
cmake_policy(SET CMP0025 NEW)
endif (POLICY CMP0025)
# if command can use IN_LIST
if (POLICY CMP0057)
cmake_policy(SET CMP0057 NEW)
endif (POLICY CMP0057)
# Project version variables are the empty string if version is unspecified
if (POLICY CMP0048)
cmake_policy(SET CMP0048 NEW)
endif (POLICY CMP0048)
# option() honor variables
if (POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)
endif (POLICY CMP0077)
# Allow the user to specify the MSVC runtime
if (POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif (POLICY CMP0091)
# Set BUILD_TESTING to OFF by default.
# This must come before the project() and include(CTest) lines.
OPTION(BUILD_TESTING "Build tests" OFF)
project(absl LANGUAGES CXX)
include(CTest)
# Output directory is correct by default for most build setups. However, when
# building Abseil as a DLL, it is important to have the DLL in the same
# directory as the executable using it. Thus, we put all executables in a single
# /bin directory.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# when absl is included as subproject (i.e. using add_subdirectory(abseil-cpp))
# in the source tree of a project that uses it, install rules are disabled.
if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
option(ABSL_ENABLE_INSTALL "Enable install rule" OFF)
else()
option(ABSL_ENABLE_INSTALL "Enable install rule" ON)
endif()
option(ABSL_PROPAGATE_CXX_STD
"Use CMake C++ standard meta features (e.g. cxx_std_11) that propagate to targets that link to Abseil"
OFF) # TODO: Default to ON for CMake 3.8 and greater.
if((${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.8) AND (NOT ABSL_PROPAGATE_CXX_STD))
message(WARNING "A future Abseil release will default ABSL_PROPAGATE_CXX_STD to ON for CMake 3.8 and up. We recommend enabling this option to ensure your project still builds correctly.")
endif()
list(APPEND CMAKE_MODULE_PATH
${CMAKE_CURRENT_LIST_DIR}/CMake
${CMAKE_CURRENT_LIST_DIR}/absl/copts
)
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
include(AbseilDll)
include(AbseilHelpers)
##
## 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})
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(ABSL_USING_CLANG ON)
else()
set(ABSL_USING_CLANG OFF)
endif()
# find dependencies
## pthread
find_package(Threads REQUIRED)
include(CMakeDependentOption)
option(ABSL_USE_EXTERNAL_GOOGLETEST
"If ON, Abseil will assume that the targets for GoogleTest are already provided by the including project. This makes sense when Abseil is used with add_subproject." OFF)
cmake_dependent_option(ABSL_FIND_GOOGLETEST
"If ON, Abseil will use find_package(GTest) rather than assuming that GoogleTest is already provided by the including project."
ON
"ABSL_USE_EXTERNAL_GOOGLETEST"
OFF)
option(ABSL_USE_GOOGLETEST_HEAD
"If ON, abseil will download HEAD from GoogleTest at config time." OFF)
set(ABSL_GOOGLETEST_DOWNLOAD_URL "" CACHE STRING "If set, download GoogleTest from this URL")
set(ABSL_LOCAL_GOOGLETEST_DIR "/usr/src/googletest" CACHE PATH
"If ABSL_USE_GOOGLETEST_HEAD is OFF and ABSL_GOOGLETEST_URL is not set, specifies the directory of a local GoogleTest checkout."
)
if(BUILD_TESTING)
## check targets
if (ABSL_USE_EXTERNAL_GOOGLETEST)
if (ABSL_FIND_GOOGLETEST)
find_package(GTest REQUIRED)
else()
if (NOT TARGET gtest AND NOT TARGET GTest::gtest)
message(FATAL_ERROR "ABSL_USE_EXTERNAL_GOOGLETEST is ON and ABSL_FIND_GOOGLETEST is OFF, which means that the top-level project must build the Google Test project. However, the target gtest was not found.")
endif()
endif()
else()
set(absl_gtest_build_dir ${CMAKE_BINARY_DIR}/googletest-build)
if(ABSL_USE_GOOGLETEST_HEAD AND ABSL_GOOGLETEST_DOWNLOAD_URL)
message(FATAL_ERROR "Do not set both ABSL_USE_GOOGLETEST_HEAD and ABSL_GOOGLETEST_DOWNLOAD_URL")
endif()
if(ABSL_USE_GOOGLETEST_HEAD)
set(absl_gtest_download_url "https://github.com/google/googletest/archive/master.zip")
elseif(ABSL_GOOGLETEST_DOWNLOAD_URL)
set(absl_gtest_download_url ${ABSL_GOOGLETEST_DOWNLOAD_URL})
endif()
if(absl_gtest_download_url)
set(absl_gtest_src_dir ${CMAKE_BINARY_DIR}/googletest-src)
else()
set(absl_gtest_src_dir ${ABSL_LOCAL_GOOGLETEST_DIR})
endif()
include(CMake/Googletest/DownloadGTest.cmake)
endif()
if (NOT ABSL_FIND_GOOGLETEST)
# When Google Test is included directly rather than through find_package, the aliases are missing.
add_library(GTest::gtest_main ALIAS gtest_main)
add_library(GTest::gtest ALIAS gtest)
add_library(GTest::gmock ALIAS gmock)
endif()
check_target(GTest::gtest)
check_target(GTest::gtest_main)
check_target(GTest::gmock)
check_target(GTest::gmock_main)
list(APPEND ABSL_TEST_COMMON_LIBRARIES
GTest::gtest_main
GTest::gtest
GTest::gmock
${CMAKE_THREAD_LIBS_INIT}
)
endif()
add_subdirectory(absl)
if(ABSL_ENABLE_INSTALL)
# absl:lts-remove-begin(system installation is supported for LTS releases)
# We don't support system-wide installation
list(APPEND SYSTEM_INSTALL_DIRS "/usr/local" "/usr" "/opt/" "/opt/local" "c:/Program Files/${PROJECT_NAME}")
if(NOT DEFINED CMAKE_INSTALL_PREFIX OR CMAKE_INSTALL_PREFIX IN_LIST SYSTEM_INSTALL_DIRS)
message(WARNING "\
The default and system-level install directories are unsupported except in LTS \
releases of Abseil. Please set CMAKE_INSTALL_PREFIX to install Abseil in your \
source or build tree directly.\
")
endif()
# absl:lts-remove-end
# install as a subdirectory only
install(EXPORT ${PROJECT_NAME}Targets
NAMESPACE absl::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
configure_package_config_file(
CMake/abslConfig.cmake.in
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
# Abseil only has a version in LTS releases. This mechanism is accomplished
# Abseil's internal Copybara (https://github.com/google/copybara) workflows and
# isn't visible in the CMake buildsystem itself.
if(absl_VERSION)
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
COMPATIBILITY ExactVersion
)
install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
endif() # absl_VERSION
install(DIRECTORY absl
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING
PATTERN "*.inc"
PATTERN "*.h"
PATTERN "copts" EXCLUDE
PATTERN "testdata" EXCLUDE
)
endif() # ABSL_ENABLE_INSTALL

141
third_party/abseil-cpp/CONTRIBUTING.md vendored Normal file
View File

@ -0,0 +1,141 @@
# 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.
## Contribution Guidelines
Potential contributors sometimes ask us if the Abseil project is the appropriate
home for their utility library code or for specific functions implementing
missing portions of the standard. Often, the answer to this question is "no".
Wed like to articulate our thinking on this issue so that our choices can be
understood by everyone and so that contributors can have a better intuition
about whether Abseil might be interested in adopting a new library.
### Priorities
Although our mission is to augment the C++ standard library, our goal is not to
provide a full forward-compatible implementation of the latest standard. For us
to consider a library for inclusion in Abseil, it is not enough that a library
is useful. We generally choose to release a library when it meets at least one
of the following criteria:
* **Widespread usage** - Using our internal codebase to help gauge usage, most
of the libraries we've released have tens of thousands of users.
* **Anticipated widespread usage** - Pre-adoption of some standard-compliant
APIs may not have broad adoption initially but can be expected to pick up
usage when it replaces legacy APIs. `absl::from_chars`, for example,
replaces existing code that converts strings to numbers and will therefore
likely see usage growth.
* **High impact** - APIs that provide a key solution to a specific problem,
such as `absl::FixedArray`, have higher impact than usage numbers may signal
and are released because of their importance.
* **Direct support for a library that falls under one of the above** - When we
want access to a smaller library as an implementation detail for a
higher-priority library we plan to release, we may release it, as we did
with portions of `absl/meta/type_traits.h`. One consequence of this is that
the presence of a library in Abseil does not necessarily mean that other
similar libraries would be a high priority.
### API Freeze Consequences
Via the
[Abseil Compatibility Guidelines](https://abseil.io/about/compatibility), we
have promised a large degree of API stability. In particular, we will not make
backward-incompatible changes to released APIs without also shipping a tool or
process that can upgrade our users' code. We are not yet at the point of easily
releasing such tools. Therefore, at this time, shipping a library establishes an
API contract which is borderline unchangeable. (We can add new functionality,
but we cannot easily change existing behavior.) This constraint forces us to
very carefully review all APIs that we ship.
## Coding Style
To keep the source consistent, readable, diffable and easy to merge, we use a
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
If you have [Bazel](https://bazel.build/) installed, use `bazel test
--test_tag_filters="-benchmark" ...` to run the unit tests.
If you are running the Linux operating system and have
[Docker](https://www.docker.com/) installed, you can also run the `linux_*.sh`
scripts under the `ci/`(https://github.com/abseil/abseil-cpp/tree/master/ci)
directory to test Abseil under a variety of conditions.
## 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.

3
third_party/abseil-cpp/DIR_METADATA vendored Normal file
View File

@ -0,0 +1,3 @@
monorail {
component: "Internals>Core"
}

167
third_party/abseil-cpp/FAQ.md vendored Normal file
View File

@ -0,0 +1,167 @@
# Abseil FAQ
## Is Abseil the right home for my utility library?
Most often the answer to the question is "no." As both the [About
Abseil](https://abseil.io/about/) page and our [contributing
guidelines](https://github.com/abseil/abseil-cpp/blob/master/CONTRIBUTING.md#contribution-guidelines)
explain, Abseil contains a variety of core C++ library code that is widely used
at [Google](https://www.google.com/). As such, Abseil's primary purpose is to be
used as a dependency by Google's open source C++ projects. While we do hope that
Abseil is also useful to the C++ community at large, this added constraint also
means that we are unlikely to accept a contribution of utility code that isn't
already widely used by Google.
## How to I set the C++ dialect used to build Abseil?
The short answer is that whatever mechanism you choose, you need to make sure
that you set this option consistently at the global level for your entire
project. If, for example, you want to set the C++ dialect to C++17, with
[Bazel](https://bazel/build/) as the build system and `gcc` or `clang` as the
compiler, there several ways to do this:
* Pass `--cxxopt=-std=c++17` on the command line (for example, `bazel build
--cxxopt=-std=c++17 ...`)
* Set the environment variable `BAZEL_CXXOPTS` (for example,
`BAZEL_CXXOPTS=-std=c++17`)
* Add `build --cxxopt=-std=c++17` to your [`.bazelrc`
file](https://docs.bazel.build/versions/master/guide.html#bazelrc)
If you are using CMake as the build system, you'll need to add a line like
`set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. If you
are developing a library designed to be used by other clients, you should
instead leave `CMAKE_CXX_STANDARD` unset and configure the minimum C++ standard
required by each of your library targets via `target_compile_features`. See the
[CMake build
instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md)
for more information.
For a longer answer to this question and to understand why some other approaches
don't work, see the answer to ["What is ABI and why don't you recommend using a
pre-compiled version of
Abseil?"](#what-is-abi-and-why-dont-you-recommend-using-a-pre-compiled-version-of-abseil)
## What is ABI and why don't you recommend using a pre-compiled version of Abseil?
For the purposes of this discussion, you can think of
[ABI](https://en.wikipedia.org/wiki/Application_binary_interface) as the
compiled representation of the interfaces in code. This is in contrast to
[API](https://en.wikipedia.org/wiki/Application_programming_interface), which
you can think of as the interfaces as defined by the code itself. [Abseil has a
strong promise of API compatibility, but does not make any promise of ABI
compatibility](https://abseil.io/about/compatibility). Let's take a look at what
this means in practice.
You might be tempted to do something like this in a
[Bazel](https://bazel.build/) `BUILD` file:
```
# DON'T DO THIS!!!
cc_library(
name = "my_library",
srcs = ["my_library.cc"],
copts = ["-std=c++17"], # May create a mixed-mode compile!
deps = ["@com_google_absl//absl/strings"],
)
```
Applying `-std=c++17` to an individual target in your `BUILD` file is going to
compile that specific target in C++17 mode, but it isn't going to ensure the
Abseil library is built in C++17 mode, since the Abseil library itself is a
different build target. If your code includes an Abseil header, then your
program may contain conflicting definitions of the same
class/function/variable/enum, etc. As a rule, all compile options that affect
the ABI of a program need to be applied to the entire build on a global basis.
C++ has something called the [One Definition
Rule](https://en.wikipedia.org/wiki/One_Definition_Rule) (ODR). C++ doesn't
allow multiple definitions of the same class/function/variable/enum, etc. ODR
violations sometimes result in linker errors, but linkers do not always catch
violations. Uncaught ODR violations can result in strange runtime behaviors or
crashes that can be hard to debug.
If you build the Abseil library and your code using different compile options
that affect ABI, there is a good chance you will run afoul of the One Definition
Rule. Examples of GCC compile options that affect ABI include (but aren't
limited to) language dialect (e.g. `-std=`), optimization level (e.g. `-O2`),
code generation flags (e.g. `-fexceptions`), and preprocessor defines
(e.g. `-DNDEBUG`).
If you use a pre-compiled version of Abseil, (for example, from your Linux
distribution package manager or from something like
[vcpkg](https://github.com/microsoft/vcpkg)) you have to be very careful to
ensure ABI compatibility across the components of your program. The only way you
can be sure your program is going to be correct regarding ABI is to ensure
you've used the exact same compile options as were used to build the
pre-compiled library. This does not mean that Abseil cannot work as part of a
Linux distribution since a knowledgeable binary packager will have ensured that
all packages have been built with consistent compile options. This is one of the
reasons we warn against - though do not outright reject - using Abseil as a
pre-compiled library.
Another possible way that you might afoul of ABI issues is if you accidentally
include two versions of Abseil in your program. Multiple versions of Abseil can
end up within the same binary if your program uses the Abseil library and
another library also transitively depends on Abseil (resulting in what is
sometimes called the diamond dependency problem). In cases such as this you must
structure your build so that all libraries use the same version of Abseil.
[Abseil's strong promise of API compatibility between
releases](https://abseil.io/about/compatibility) means the latest "HEAD" release
of Abseil is almost certainly the right choice if you are doing as we recommend
and building all of your code from source.
For these reasons we recommend you avoid pre-compiled code and build the Abseil
library yourself in a consistent manner with the rest of your code.
## What is "live at head" and how do I do it?
From Abseil's point-of-view, "live at head" means that every Abseil source
release (which happens on an almost daily basis) is either API compatible with
the previous release, or comes with an automated tool that you can run over code
to make it compatible. In practice, the need to use an automated tool is
extremely rare. This means that upgrading from one source release to another
should be a routine practice that can and should be performed often.
We recommend you update to the [latest commit in the `master` branch of
Abseil](https://github.com/abseil/abseil-cpp/commits/master) as often as
possible. Not only will you pick up bug fixes more quickly, but if you have good
automated testing, you will catch and be able to fix any [Hyrum's
Law](https://www.hyrumslaw.com/) dependency problems on an incremental basis
instead of being overwhelmed by them and having difficulty isolating them if you
wait longer between updates.
If you are using the [Bazel](https://bazel.build/) build system and its
[external dependencies](https://docs.bazel.build/versions/master/external.html)
feature, updating the
[`http_archive`](https://docs.bazel.build/versions/master/repo/http.html#http_archive)
rule in your
[`WORKSPACE`](https://docs.bazel.build/versions/master/be/workspace.html) for
`com_google_abseil` to point to the [latest commit in the `master` branch of
Abseil](https://github.com/abseil/abseil-cpp/commits/master) is all you need to
do. For example, on February 11, 2020, the latest commit to the master branch
was `98eb410c93ad059f9bba1bf43f5bb916fc92a5ea`. To update to this commit, you
would add the following snippet to your `WORKSPACE` file:
```
http_archive(
name = "com_google_absl",
urls = ["https://github.com/abseil/abseil-cpp/archive/98eb410c93ad059f9bba1bf43f5bb916fc92a5ea.zip"], # 2020-02-11T18:50:53Z
strip_prefix = "abseil-cpp-98eb410c93ad059f9bba1bf43f5bb916fc92a5ea",
sha256 = "aabf6c57e3834f8dc3873a927f37eaf69975d4b28117fc7427dfb1c661542a87",
)
```
To get the `sha256` of this URL, run `curl -sL --output -
https://github.com/abseil/abseil-cpp/archive/98eb410c93ad059f9bba1bf43f5bb916fc92a5ea.zip
| sha256sum -`.
You can commit the updated `WORKSPACE` file to your source control every time
you update, and if you have good automated testing, you might even consider
automating this.
One thing we don't recommend is using GitHub's `master.zip` files (for example
[https://github.com/abseil/abseil-cpp/archive/master.zip](https://github.com/abseil/abseil-cpp/archive/master.zip)),
which are always the latest commit in the `master` branch, to implement live at
head. Since these `master.zip` URLs are not versioned, you will lose build
reproducibility. In addition, some build systems, including Bazel, will simply
cache this file, which means you won't actually be updating to the latest
release until your cache is cleared or invalidated.

203
third_party/abseil-cpp/LICENSE vendored Normal file
View File

@ -0,0 +1,203 @@
Apache License
Version 2.0, January 2004
https://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
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

3
third_party/abseil-cpp/OWNERS vendored Normal file
View File

@ -0,0 +1,3 @@
danilchap@chromium.org
kwiberg@chromium.org
mbonadei@chromium.org

36
third_party/abseil-cpp/README.chromium vendored Normal file
View File

@ -0,0 +1,36 @@
Name: Abseil
Short Name: absl
URL: https://github.com/abseil/abseil-cpp
License: Apache 2.0
License File: LICENSE
Version: 0
Revision: 637722af3a60c17915d3325604a0435ee92a41b4
Security Critical: yes
Description:
This directory contains the source code of Abseil for C++. This can be used by
Chromium, subject to the guidance at https://chromium-cpp.appspot.com/; it can
be used without restriction by Chromium's dependencies, except that objects
compiled into Chromium itself cannot use anything relying on
absl::base_internal::FastTypeId (see https://crbug.com/1096380).
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 your source root run third_party/abseil-cpp/generate_def_files.py to
regenerate Windows symbol definition files.
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 have been translated to BUILD.gn files.
* Patches from //third_party/abseil-cpp/patches have been applied.
* Increment this number to silence presubmits about modifying files in
third_party when regenerating absl .def files: 1

139
third_party/abseil-cpp/README.md vendored Normal file
View File

@ -0,0 +1,139 @@
# 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)
- [Support](#support)
- [Codemap](#codemap)
- [Releases](#releases)
- [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](https://bazel.build) and [CMake](https://cmake.org/) are the official
build systems for Abseil.
See the [quickstart](https://abseil.io/docs/cpp/quickstart) for more information
on building Abseil using the Bazel build system.
If you require CMake support, please check the [CMake build
instructions](CMake/README.md) and [CMake
Quickstart](https://abseil.io/docs/cpp/quickstart-cmake).
## Support
Abseil is officially supported on many platforms. See the [Abseil
platform support
guide](https://abseil.io/docs/cpp/platforms/platforms) for details on
supported operating systems, compilers, CPUs, etc.
## 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.
* [`cleanup`](absl/cleanup/)
<br /> The `cleanup` library contains the control-flow-construct-like type
`absl::Cleanup` which is used for executing a callback on scope exit.
* [`container`](absl/container/)
<br /> The `container` library contains additional STL-style containers,
including Abseil's unordered "Swiss table" containers.
* [`debugging`](absl/debugging/)
<br /> The `debugging` library contains code useful for enabling leak
checks, and stacktrace and symbolization utilities.
* [`hash`](absl/hash/)
<br /> The `hash` library contains the hashing framework and default hash
functor implementations for hashable types in Abseil.
* [`memory`](absl/memory/)
<br /> The `memory` library contains C++11-compatible versions of
`std::make_unique()` and related memory management facilities.
* [`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.
* [`status`](absl/status/)
<br /> The `status` contains abstractions for error handling, specifically
`absl::Status` and `absl::StatusOr<T>`.
* [`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.
* [`utility`](absl/utility/)
<br /> The `utility` library contains utility and helper code.
## Releases
Abseil recommends users "live-at-head" (update to the latest commit from the
master branch as often as possible). However, we realize this philosophy doesn't
work for every project, so we also provide [Long Term Support
Releases](https://github.com/abseil/abseil-cpp/releases) to which we backport
fixes for severe bugs. See our [release
management](https://abseil.io/about/releases) document for more details.
## 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](https://abseil.io/about/intro)
* Read [Why Adopt Abseil](https://abseil.io/about/philosophy) to understand our
design philosophy.
* Peruse our
[Abseil Compatibility Guarantees](https://abseil.io/about/compatibility) to
understand both what we promise to you, and what we expect of you in return.

17
third_party/abseil-cpp/UPGRADES.md vendored Normal file
View File

@ -0,0 +1,17 @@
# C++ Upgrade Tools
Abseil may occassionally release API-breaking changes. As noted in our
[Compatibility Guidelines][compatibility-guide], we will aim to provide a tool
to do the work of effecting such API-breaking changes, when absolutely
necessary.
These tools will be listed on the [C++ Upgrade Tools][upgrade-tools] guide on
https://abseil.io.
For more information, the [C++ Automated Upgrade Guide][api-upgrades-guide]
outlines this process.
[compatibility-guide]: https://abseil.io/about/compatibility
[api-upgrades-guide]: https://abseil.io/docs/cpp/tools/api-upgrades
[upgrade-tools]: https://abseil.io/docs/cpp/tools/upgrades/

52
third_party/abseil-cpp/WORKSPACE vendored Normal file
View File

@ -0,0 +1,52 @@
#
# Copyright 2019 The Abseil Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
workspace(name = "com_google_absl")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# GoogleTest/GoogleMock framework. Used by most unit-tests.
http_archive(
name = "com_google_googletest", # 2021-07-09T13:28:13Z
sha256 = "12ef65654dc01ab40f6f33f9d02c04f2097d2cd9fbe48dc6001b29543583b0ad",
strip_prefix = "googletest-8d51ffdfab10b3fba636ae69bc03da4b54f8c235",
# Keep this URL in sync with ABSL_GOOGLETEST_COMMIT in ci/cmake_common.sh.
urls = ["https://github.com/google/googletest/archive/8d51ffdfab10b3fba636ae69bc03da4b54f8c235.zip"],
)
# Google benchmark.
http_archive(
name = "com_github_google_benchmark", # 2021-07-01T09:02:54Z
sha256 = "1cb4b97a90aa1fd9c8e412a6bc29fc13fc140162a4a0db3811af40befd8c9ea5",
strip_prefix = "benchmark-e451e50e9b8af453f076dec10bd6890847f1624e",
urls = ["https://github.com/google/benchmark/archive/e451e50e9b8af453f076dec10bd6890847f1624e.zip"],
)
# C++ rules for Bazel.
http_archive(
name = "rules_cc", # 2021-06-07T16:41:49Z
sha256 = "b295cad8c5899e371dde175079c0a2cdc0151f5127acc92366a8c986beb95c76",
strip_prefix = "rules_cc-daf6ace7cfeacd6a83e9ff2ed659f416537b6c74",
urls = ["https://github.com/bazelbuild/rules_cc/archive/daf6ace7cfeacd6a83e9ff2ed659f416537b6c74.zip"],
)
# Bazel platform rules.
http_archive(
name = "platforms",
sha256 = "b601beaf841244de5c5a50d2b2eddd34839788000fa1be4260ce6603ca0d8eb7",
strip_prefix = "platforms-98939346da932eef0b54cf808622f5bb0928f00b",
urls = ["https://github.com/bazelbuild/platforms/archive/98939346da932eef0b54cf808622f5bb0928f00b.zip"],
)

72
third_party/abseil-cpp/absl/BUILD.bazel vendored Normal file
View File

@ -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
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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"])
config_setting(
name = "clang_compiler",
flag_values = {
"@bazel_tools//tools/cpp:compiler": "clang",
},
visibility = [":__subpackages__"],
)
config_setting(
name = "msvc_compiler",
flag_values = {
"@bazel_tools//tools/cpp:compiler": "msvc-cl",
},
visibility = [":__subpackages__"],
)
config_setting(
name = "clang-cl_compiler",
flag_values = {
"@bazel_tools//tools/cpp:compiler": "clang-cl",
},
visibility = [":__subpackages__"],
)
config_setting(
name = "osx",
constraint_values = [
"@platforms//os:osx",
],
)
config_setting(
name = "ios",
constraint_values = [
"@platforms//os:ios",
],
)
config_setting(
name = "ppc",
values = {
"cpu": "ppc",
},
visibility = [":__subpackages__"],
)
config_setting(
name = "wasm",
values = {
"cpu": "wasm32",
},
visibility = [":__subpackages__"],
)

View File

@ -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
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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(cleanup)
add_subdirectory(container)
add_subdirectory(debugging)
add_subdirectory(flags)
add_subdirectory(functional)
add_subdirectory(hash)
add_subdirectory(memory)
add_subdirectory(meta)
add_subdirectory(numeric)
add_subdirectory(random)
add_subdirectory(status)
add_subdirectory(strings)
add_subdirectory(synchronization)
add_subdirectory(time)
add_subdirectory(types)
add_subdirectory(utility)
if (${ABSL_BUILD_DLL})
absl_make_dll()
endif()

View File

@ -0,0 +1,229 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""This script generates abseil.podspec from all BUILD.bazel files.
This is expected to run on abseil git repository with Bazel 1.0 on Linux.
It recursively analyzes BUILD.bazel files using query command of Bazel to
dump its build rules in XML format. From these rules, it constructs podspec
structure.
"""
import argparse
import collections
import os
import re
import subprocess
import xml.etree.ElementTree
# Template of root podspec.
SPEC_TEMPLATE = """
# This file has been automatically generated from a script.
# Please make modifications to `abseil.podspec.gen.py` instead.
Pod::Spec.new do |s|
s.name = 'abseil'
s.version = '${version}'
s.summary = 'Abseil Common Libraries (C++) from Google'
s.homepage = 'https://abseil.io'
s.license = 'Apache License, Version 2.0'
s.authors = { 'Abseil Team' => 'abseil-io@googlegroups.com' }
s.source = {
:git => 'https://github.com/abseil/abseil-cpp.git',
:tag => '${tag}',
}
s.module_name = 'absl'
s.header_mappings_dir = 'absl'
s.header_dir = 'absl'
s.libraries = 'c++'
s.compiler_flags = '-Wno-everything'
s.pod_target_xcconfig = {
'USER_HEADER_SEARCH_PATHS' => '$(inherited) "$(PODS_TARGET_SRCROOT)"',
'USE_HEADERMAP' => 'NO',
'ALWAYS_SEARCH_USER_PATHS' => 'NO',
}
s.ios.deployment_target = '9.0'
s.osx.deployment_target = '10.10'
s.tvos.deployment_target = '9.0'
s.watchos.deployment_target = '2.0'
"""
# Rule object representing the rule of Bazel BUILD.
Rule = collections.namedtuple(
"Rule", "type name package srcs hdrs textual_hdrs deps visibility testonly")
def get_elem_value(elem, name):
"""Returns the value of XML element with the given name."""
for child in elem:
if child.attrib.get("name") != name:
continue
if child.tag == "string":
return child.attrib.get("value")
if child.tag == "boolean":
return child.attrib.get("value") == "true"
if child.tag == "list":
return [nested_child.attrib.get("value") for nested_child in child]
raise "Cannot recognize tag: " + child.tag
return None
def normalize_paths(paths):
"""Returns the list of normalized path."""
# e.g. ["//absl/strings:dir/header.h"] -> ["absl/strings/dir/header.h"]
return [path.lstrip("/").replace(":", "/") for path in paths]
def parse_rule(elem, package):
"""Returns a rule from bazel XML rule."""
return Rule(
type=elem.attrib["class"],
name=get_elem_value(elem, "name"),
package=package,
srcs=normalize_paths(get_elem_value(elem, "srcs") or []),
hdrs=normalize_paths(get_elem_value(elem, "hdrs") or []),
textual_hdrs=normalize_paths(get_elem_value(elem, "textual_hdrs") or []),
deps=get_elem_value(elem, "deps") or [],
visibility=get_elem_value(elem, "visibility") or [],
testonly=get_elem_value(elem, "testonly") or False)
def read_build(package):
"""Runs bazel query on given package file and returns all cc rules."""
result = subprocess.check_output(
["bazel", "query", package + ":all", "--output", "xml"])
root = xml.etree.ElementTree.fromstring(result)
return [
parse_rule(elem, package)
for elem in root
if elem.tag == "rule" and elem.attrib["class"].startswith("cc_")
]
def collect_rules(root_path):
"""Collects and returns all rules from root path recursively."""
rules = []
for cur, _, _ in os.walk(root_path):
build_path = os.path.join(cur, "BUILD.bazel")
if os.path.exists(build_path):
rules.extend(read_build("//" + cur))
return rules
def relevant_rule(rule):
"""Returns true if a given rule is relevant when generating a podspec."""
return (
# cc_library only (ignore cc_test, cc_binary)
rule.type == "cc_library" and
# ignore empty rule
(rule.hdrs + rule.textual_hdrs + rule.srcs) and
# ignore test-only rule
not rule.testonly)
def get_spec_var(depth):
"""Returns the name of variable for spec with given depth."""
return "s" if depth == 0 else "s{}".format(depth)
def get_spec_name(label):
"""Converts the label of bazel rule to the name of podspec."""
assert label.startswith("//absl/"), "{} doesn't start with //absl/".format(
label)
# e.g. //absl/apple/banana -> abseil/apple/banana
return "abseil/" + label[7:]
def write_podspec(f, rules, args):
"""Writes a podspec from given rules and args."""
rule_dir = build_rule_directory(rules)["abseil"]
# Write root part with given arguments
spec = re.sub(r"\$\{(\w+)\}", lambda x: args[x.group(1)],
SPEC_TEMPLATE).lstrip()
f.write(spec)
# Write all target rules
write_podspec_map(f, rule_dir, 0)
f.write("end\n")
def build_rule_directory(rules):
"""Builds a tree-style rule directory from given rules."""
rule_dir = {}
for rule in rules:
cur = rule_dir
for frag in get_spec_name(rule.package).split("/"):
cur = cur.setdefault(frag, {})
cur[rule.name] = rule
return rule_dir
def write_podspec_map(f, cur_map, depth):
"""Writes podspec from rule map recursively."""
for key, value in sorted(cur_map.items()):
indent = " " * (depth + 1)
f.write("{indent}{var0}.subspec '{key}' do |{var1}|\n".format(
indent=indent,
key=key,
var0=get_spec_var(depth),
var1=get_spec_var(depth + 1)))
if isinstance(value, dict):
write_podspec_map(f, value, depth + 1)
else:
write_podspec_rule(f, value, depth + 1)
f.write("{indent}end\n".format(indent=indent))
def write_podspec_rule(f, rule, depth):
"""Writes podspec from given rule."""
indent = " " * (depth + 1)
spec_var = get_spec_var(depth)
# Puts all files in hdrs, textual_hdrs, and srcs into source_files.
# Since CocoaPods treats header_files a bit differently from bazel,
# this won't generate a header_files field so that all source_files
# are considered as header files.
srcs = sorted(set(rule.hdrs + rule.textual_hdrs + rule.srcs))
write_indented_list(
f, "{indent}{var}.source_files = ".format(indent=indent, var=spec_var),
srcs)
# Writes dependencies of this rule.
for dep in sorted(rule.deps):
name = get_spec_name(dep.replace(":", "/"))
f.write("{indent}{var}.dependency '{dep}'\n".format(
indent=indent, var=spec_var, dep=name))
def write_indented_list(f, leading, values):
"""Writes leading values in an indented style."""
f.write(leading)
f.write((",\n" + " " * len(leading)).join("'{}'".format(v) for v in values))
f.write("\n")
def generate(args):
"""Generates a podspec file from all BUILD files under absl directory."""
rules = filter(relevant_rule, collect_rules("absl"))
with open(args.output, "wt") as f:
write_podspec(f, rules, vars(args))
def main():
parser = argparse.ArgumentParser(
description="Generates abseil.podspec from BUILD.bazel")
parser.add_argument(
"-v", "--version", help="The version of podspec", required=True)
parser.add_argument(
"-t",
"--tag",
default=None,
help="The name of git tag (default: version)")
parser.add_argument(
"-o",
"--output",
default="abseil.podspec",
help="The name of output file (default: abseil.podspec)")
args = parser.parse_args()
if args.tag is None:
args.tag = args.version
generate(args)
if __name__ == "__main__":
main()

View File

@ -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
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load(
"//absl:copts/configure_copts.bzl",
"ABSL_DEFAULT_COPTS",
"ABSL_DEFAULT_LINKOPTS",
"ABSL_TEST_COPTS",
)
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
cc_library(
name = "algorithm",
hdrs = ["algorithm.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
"//absl/base:config",
],
)
cc_test(
name = "algorithm_test",
size = "small",
srcs = ["algorithm_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":algorithm",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "algorithm_benchmark",
srcs = ["equal_benchmark.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
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,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":algorithm",
"//absl/base:core_headers",
"//absl/meta:type_traits",
],
)
cc_test(
name = "container_test",
srcs = ["container_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":container",
"//absl/base",
"//absl/base:core_headers",
"//absl/memory",
"//absl/types:span",
"@com_google_googletest//:gtest_main",
],
)

View File

@ -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
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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_cc_library(
NAME
algorithm
HDRS
"algorithm.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
PUBLIC
)
absl_cc_test(
NAME
algorithm_test
SRCS
"algorithm_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::algorithm
GTest::gmock_main
)
absl_cc_library(
NAME
algorithm_container
HDRS
"container.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::algorithm
absl::core_headers
absl::meta
PUBLIC
)
absl_cc_test(
NAME
container_test
SRCS
"container_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::algorithm_container
absl::base
absl::core_headers
absl::memory
absl::span
GTest::gmock_main
)

View File

@ -0,0 +1,159 @@
// 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
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT 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>
#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
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
// equal()
//
// 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
// https://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{});
}
// Overload of equal() that 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{});
}
// linear_search()
//
// 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;
}
// rotate()
//
// 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>());
}
ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_ALGORITHM_ALGORITHM_H_

View File

@ -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
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT 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

View File

@ -0,0 +1,800 @@
#
# 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
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
load(
"//absl:copts/configure_copts.bzl",
"ABSL_DEFAULT_COPTS",
"ABSL_DEFAULT_LINKOPTS",
"ABSL_TEST_COPTS",
)
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
cc_library(
name = "atomic_hook",
hdrs = ["internal/atomic_hook.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":config",
":core_headers",
],
)
cc_library(
name = "errno_saver",
hdrs = ["internal/errno_saver.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [":config"],
)
cc_library(
name = "log_severity",
srcs = ["log_severity.cc"],
hdrs = ["log_severity.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":config",
":core_headers",
],
)
cc_library(
name = "raw_logging_internal",
srcs = ["internal/raw_logging.cc"],
hdrs = ["internal/raw_logging.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":atomic_hook",
":config",
":core_headers",
":log_severity",
],
)
cc_library(
name = "spinlock_wait",
srcs = [
"internal/spinlock_akaros.inc",
"internal/spinlock_linux.inc",
"internal/spinlock_posix.inc",
"internal/spinlock_wait.cc",
"internal/spinlock_win32.inc",
],
hdrs = ["internal/spinlock_wait.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl/base:__pkg__",
],
deps = [
":base_internal",
":core_headers",
":errno_saver",
],
)
cc_library(
name = "config",
hdrs = [
"config.h",
"options.h",
"policy_checks.h",
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
)
cc_library(
name = "dynamic_annotations",
srcs = [
"internal/dynamic_annotations.h",
],
hdrs = [
"dynamic_annotations.h",
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":config",
":core_headers",
],
)
cc_library(
name = "core_headers",
srcs = [
"internal/thread_annotations.h",
],
hdrs = [
"attributes.h",
"const_init.h",
"macros.h",
"optimization.h",
"port.h",
"thread_annotations.h",
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":config",
],
)
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,
linkopts = select({
"//absl:msvc_compiler": [],
"//absl:clang-cl_compiler": [],
"//absl:wasm": [],
"//conditions:default": ["-pthread"],
}) + ABSL_DEFAULT_LINKOPTS,
visibility = [
"//visibility:public",
],
deps = [
":base",
":base_internal",
":config",
":core_headers",
":dynamic_annotations",
":raw_logging_internal",
],
)
cc_library(
name = "base_internal",
hdrs = [
"internal/hide_ptr.h",
"internal/identity.h",
"internal/inline_variable.h",
"internal/invoke.h",
"internal/scheduling_mode.h",
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":config",
"//absl/meta:type_traits",
],
)
cc_library(
name = "base",
srcs = [
"internal/cycleclock.cc",
"internal/spinlock.cc",
"internal/sysinfo.cc",
"internal/thread_identity.cc",
"internal/unscaledcycleclock.cc",
],
hdrs = [
"call_once.h",
"casts.h",
"internal/cycleclock.h",
"internal/low_level_scheduling.h",
"internal/per_thread_tls.h",
"internal/spinlock.h",
"internal/sysinfo.h",
"internal/thread_identity.h",
"internal/tsan_mutex_interface.h",
"internal/unscaledcycleclock.h",
],
copts = ABSL_DEFAULT_COPTS,
linkopts = select({
"//absl:msvc_compiler": [
"-DEFAULTLIB:advapi32.lib",
],
"//absl:clang-cl_compiler": [
"-DEFAULTLIB:advapi32.lib",
],
"//absl:wasm": [],
"//conditions:default": ["-pthread"],
}) + ABSL_DEFAULT_LINKOPTS,
deps = [
":atomic_hook",
":base_internal",
":config",
":core_headers",
":dynamic_annotations",
":log_severity",
":raw_logging_internal",
":spinlock_wait",
"//absl/meta:type_traits",
],
)
cc_library(
name = "atomic_hook_test_helper",
testonly = 1,
srcs = ["internal/atomic_hook_test_helper.cc"],
hdrs = ["internal/atomic_hook_test_helper.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":atomic_hook",
":core_headers",
],
)
cc_test(
name = "atomic_hook_test",
size = "small",
srcs = ["internal/atomic_hook_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":atomic_hook",
":atomic_hook_test_helper",
":core_headers",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "bit_cast_test",
size = "small",
srcs = [
"bit_cast_test.cc",
],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
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,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":config",
":raw_logging_internal",
],
)
cc_test(
name = "throw_delegate_test",
srcs = ["throw_delegate_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":config",
":throw_delegate",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "errno_saver_test",
size = "small",
srcs = ["internal/errno_saver_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":errno_saver",
":strerror",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "exception_testing",
testonly = 1,
hdrs = ["internal/exception_testing.h"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":config",
"@com_google_googletest//:gtest",
],
)
cc_library(
name = "pretty_function",
hdrs = ["internal/pretty_function.h"],
linkopts = ABSL_DEFAULT_LINKOPTS,
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,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":config",
":pretty_function",
"//absl/memory",
"//absl/meta:type_traits",
"//absl/strings",
"//absl/utility",
"@com_google_googletest//:gtest",
],
)
cc_test(
name = "exception_safety_testing_test",
srcs = ["exception_safety_testing_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
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,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":base_internal",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "invoke_test",
size = "small",
srcs = ["invoke_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
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,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":base",
":base_internal",
":config",
":core_headers",
"//absl/synchronization",
"@com_google_googletest//:gtest",
],
alwayslink = 1,
)
cc_test(
name = "spinlock_test",
size = "medium",
srcs = ["spinlock_test_common.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":base",
":base_internal",
":config",
":core_headers",
"//absl/synchronization",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "spinlock_benchmark_common",
testonly = 1,
srcs = ["internal/spinlock_benchmark.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl/base:__pkg__",
],
deps = [
":base",
":base_internal",
":raw_logging_internal",
"//absl/synchronization",
"@com_github_google_benchmark//:benchmark_main",
],
alwayslink = 1,
)
cc_binary(
name = "spinlock_benchmark",
testonly = 1,
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":spinlock_benchmark_common",
],
)
cc_library(
name = "endian",
hdrs = [
"internal/endian.h",
"internal/unaligned_access.h",
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":base",
":config",
":core_headers",
],
)
cc_test(
name = "endian_test",
srcs = ["internal/endian_test.cc"],
copts = ABSL_TEST_COPTS,
deps = [
":config",
":endian",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "config_test",
srcs = ["config_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
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,
linkopts = ABSL_DEFAULT_LINKOPTS,
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,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":raw_logging_internal",
"//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "sysinfo_test",
size = "small",
srcs = ["internal/sysinfo_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":base",
"//absl/synchronization",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "low_level_alloc_test",
size = "medium",
srcs = ["internal/low_level_alloc_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
tags = [
"no_test_ios_x86_64",
],
deps = [
":malloc_internal",
"//absl/container:node_hash_map",
],
)
cc_test(
name = "thread_identity_test",
size = "small",
srcs = ["internal/thread_identity_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
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,
linkopts = ABSL_DEFAULT_LINKOPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":base",
"//absl/synchronization",
"@com_github_google_benchmark//:benchmark_main",
],
)
cc_library(
name = "exponential_biased",
srcs = ["internal/exponential_biased.cc"],
hdrs = ["internal/exponential_biased.h"],
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":config",
":core_headers",
],
)
cc_test(
name = "exponential_biased_test",
size = "small",
srcs = ["internal/exponential_biased_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:private"],
deps = [
":exponential_biased",
"//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "periodic_sampler",
srcs = ["internal/periodic_sampler.cc"],
hdrs = ["internal/periodic_sampler.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":core_headers",
":exponential_biased",
],
)
cc_test(
name = "periodic_sampler_test",
size = "small",
srcs = ["internal/periodic_sampler_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:private"],
deps = [
":core_headers",
":periodic_sampler",
"@com_google_googletest//:gtest_main",
],
)
cc_binary(
name = "periodic_sampler_benchmark",
testonly = 1,
srcs = ["internal/periodic_sampler_benchmark.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":core_headers",
":periodic_sampler",
"@com_github_google_benchmark//:benchmark_main",
],
)
cc_library(
name = "scoped_set_env",
testonly = 1,
srcs = ["internal/scoped_set_env.cc"],
hdrs = ["internal/scoped_set_env.h"],
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":config",
":raw_logging_internal",
],
)
cc_test(
name = "scoped_set_env_test",
size = "small",
srcs = ["internal/scoped_set_env_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":scoped_set_env",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "log_severity_test",
size = "small",
srcs = ["log_severity_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":log_severity",
"//absl/flags:flag_internal",
"//absl/flags:marshalling",
"//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "strerror",
srcs = ["internal/strerror.cc"],
hdrs = ["internal/strerror.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":config",
":core_headers",
":errno_saver",
],
)
cc_test(
name = "strerror_test",
size = "small",
srcs = ["internal/strerror_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":strerror",
"//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
cc_binary(
name = "strerror_benchmark",
testonly = 1,
srcs = ["internal/strerror_benchmark.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":strerror",
"@com_github_google_benchmark//:benchmark_main",
],
)
cc_library(
name = "fast_type_id",
hdrs = ["internal/fast_type_id.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":config",
],
)
cc_test(
name = "fast_type_id_test",
size = "small",
srcs = ["internal/fast_type_id_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":fast_type_id",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "unique_small_name_test",
size = "small",
srcs = ["internal/unique_small_name_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
linkstatic = 1,
deps = [
":core_headers",
"//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "optimization_test",
size = "small",
srcs = ["optimization_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":core_headers",
"//absl/types:optional",
"@com_google_googletest//:gtest_main",
],
)

View File

@ -0,0 +1,694 @@
#
# 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
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
find_library(LIBRT rt)
absl_cc_library(
NAME
atomic_hook
HDRS
"internal/atomic_hook.h"
DEPS
absl::config
absl::core_headers
COPTS
${ABSL_DEFAULT_COPTS}
)
absl_cc_library(
NAME
errno_saver
HDRS
"internal/errno_saver.h"
DEPS
absl::config
COPTS
${ABSL_DEFAULT_COPTS}
)
absl_cc_library(
NAME
log_severity
HDRS
"log_severity.h"
SRCS
"log_severity.cc"
DEPS
absl::core_headers
COPTS
${ABSL_DEFAULT_COPTS}
)
absl_cc_library(
NAME
raw_logging_internal
HDRS
"internal/raw_logging.h"
SRCS
"internal/raw_logging.cc"
DEPS
absl::atomic_hook
absl::config
absl::core_headers
absl::log_severity
COPTS
${ABSL_DEFAULT_COPTS}
)
absl_cc_library(
NAME
spinlock_wait
HDRS
"internal/spinlock_wait.h"
SRCS
"internal/spinlock_akaros.inc"
"internal/spinlock_linux.inc"
"internal/spinlock_posix.inc"
"internal/spinlock_wait.cc"
"internal/spinlock_win32.inc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::base_internal
absl::core_headers
absl::errno_saver
)
absl_cc_library(
NAME
config
HDRS
"config.h"
"options.h"
"policy_checks.h"
COPTS
${ABSL_DEFAULT_COPTS}
PUBLIC
)
absl_cc_library(
NAME
dynamic_annotations
HDRS
"dynamic_annotations.h"
SRCS
"internal/dynamic_annotations.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
PUBLIC
)
absl_cc_library(
NAME
core_headers
HDRS
"attributes.h"
"const_init.h"
"macros.h"
"optimization.h"
"port.h"
"thread_annotations.h"
"internal/thread_annotations.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
PUBLIC
)
absl_cc_library(
NAME
malloc_internal
HDRS
"internal/direct_mmap.h"
"internal/low_level_alloc.h"
SRCS
"internal/low_level_alloc.cc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::base
absl::base_internal
absl::config
absl::core_headers
absl::dynamic_annotations
absl::raw_logging_internal
Threads::Threads
)
absl_cc_library(
NAME
base_internal
HDRS
"internal/hide_ptr.h"
"internal/identity.h"
"internal/inline_variable.h"
"internal/invoke.h"
"internal/scheduling_mode.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
absl::type_traits
)
absl_cc_library(
NAME
base
HDRS
"call_once.h"
"casts.h"
"internal/cycleclock.h"
"internal/low_level_scheduling.h"
"internal/per_thread_tls.h"
"internal/spinlock.h"
"internal/sysinfo.h"
"internal/thread_identity.h"
"internal/tsan_mutex_interface.h"
"internal/unscaledcycleclock.h"
SRCS
"internal/cycleclock.cc"
"internal/spinlock.cc"
"internal/sysinfo.cc"
"internal/thread_identity.cc"
"internal/unscaledcycleclock.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
$<$<BOOL:${LIBRT}>:-lrt>
$<$<BOOL:${MINGW}>:"advapi32">
DEPS
absl::atomic_hook
absl::base_internal
absl::config
absl::core_headers
absl::dynamic_annotations
absl::log_severity
absl::raw_logging_internal
absl::spinlock_wait
absl::type_traits
Threads::Threads
PUBLIC
)
absl_cc_library(
NAME
throw_delegate
HDRS
"internal/throw_delegate.h"
SRCS
"internal/throw_delegate.cc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
absl::raw_logging_internal
)
absl_cc_library(
NAME
exception_testing
HDRS
"internal/exception_testing.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
GTest::gtest
TESTONLY
)
absl_cc_library(
NAME
pretty_function
HDRS
"internal/pretty_function.h"
COPTS
${ABSL_DEFAULT_COPTS}
)
absl_cc_library(
NAME
exception_safety_testing
HDRS
"internal/exception_safety_testing.h"
SRCS
"internal/exception_safety_testing.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::config
absl::pretty_function
absl::memory
absl::meta
absl::strings
absl::utility
GTest::gtest
TESTONLY
)
absl_cc_test(
NAME
absl_exception_safety_testing_test
SRCS
"exception_safety_testing_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::exception_safety_testing
absl::memory
GTest::gtest_main
)
absl_cc_library(
NAME
atomic_hook_test_helper
SRCS
"internal/atomic_hook_test_helper.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::atomic_hook
absl::core_headers
TESTONLY
)
absl_cc_test(
NAME
atomic_hook_test
SRCS
"internal/atomic_hook_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::atomic_hook_test_helper
absl::atomic_hook
absl::core_headers
GTest::gmock
GTest::gtest_main
)
absl_cc_test(
NAME
bit_cast_test
SRCS
"bit_cast_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::core_headers
GTest::gtest_main
)
absl_cc_test(
NAME
errno_saver_test
SRCS
"internal/errno_saver_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::errno_saver
absl::strerror
GTest::gmock
GTest::gtest_main
)
absl_cc_test(
NAME
throw_delegate_test
SRCS
"throw_delegate_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::config
absl::throw_delegate
GTest::gtest_main
)
absl_cc_test(
NAME
inline_variable_test
SRCS
"internal/inline_variable_testing.h"
"inline_variable_test.cc"
"inline_variable_test_a.cc"
"inline_variable_test_b.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base_internal
GTest::gtest_main
)
absl_cc_test(
NAME
invoke_test
SRCS
"invoke_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base_internal
absl::memory
absl::strings
GTest::gmock
GTest::gtest_main
)
absl_cc_library(
NAME
spinlock_test_common
SRCS
"spinlock_test_common.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::config
absl::base_internal
absl::core_headers
absl::synchronization
GTest::gtest
TESTONLY
)
# On bazel BUILD this target use "alwayslink = 1" which is not implemented here
absl_cc_test(
NAME
spinlock_test
SRCS
"spinlock_test_common.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::base_internal
absl::config
absl::core_headers
absl::synchronization
GTest::gtest_main
)
absl_cc_library(
NAME
endian
HDRS
"internal/endian.h"
"internal/unaligned_access.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::base
absl::config
absl::core_headers
PUBLIC
)
absl_cc_test(
NAME
endian_test
SRCS
"internal/endian_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::config
absl::endian
GTest::gtest_main
)
absl_cc_test(
NAME
config_test
SRCS
"config_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::config
absl::synchronization
GTest::gtest_main
)
absl_cc_test(
NAME
call_once_test
SRCS
"call_once_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::core_headers
absl::synchronization
GTest::gtest_main
)
absl_cc_test(
NAME
raw_logging_test
SRCS
"raw_logging_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::raw_logging_internal
absl::strings
GTest::gtest_main
)
absl_cc_test(
NAME
sysinfo_test
SRCS
"internal/sysinfo_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::synchronization
GTest::gtest_main
)
absl_cc_test(
NAME
low_level_alloc_test
SRCS
"internal/low_level_alloc_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::malloc_internal
absl::node_hash_map
Threads::Threads
)
absl_cc_test(
NAME
thread_identity_test
SRCS
"internal/thread_identity_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::core_headers
absl::synchronization
Threads::Threads
GTest::gtest_main
)
absl_cc_library(
NAME
exponential_biased
SRCS
"internal/exponential_biased.cc"
HDRS
"internal/exponential_biased.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
absl::core_headers
)
absl_cc_test(
NAME
exponential_biased_test
SRCS
"internal/exponential_biased_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::exponential_biased
absl::strings
GTest::gmock_main
)
absl_cc_library(
NAME
periodic_sampler
SRCS
"internal/periodic_sampler.cc"
HDRS
"internal/periodic_sampler.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::core_headers
absl::exponential_biased
)
absl_cc_test(
NAME
periodic_sampler_test
SRCS
"internal/periodic_sampler_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::core_headers
absl::periodic_sampler
GTest::gmock_main
)
absl_cc_library(
NAME
scoped_set_env
SRCS
"internal/scoped_set_env.cc"
HDRS
"internal/scoped_set_env.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
absl::raw_logging_internal
)
absl_cc_test(
NAME
scoped_set_env_test
SRCS
"internal/scoped_set_env_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::scoped_set_env
GTest::gtest_main
)
absl_cc_test(
NAME
cmake_thread_test
SRCS
"internal/cmake_thread_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
)
absl_cc_test(
NAME
log_severity_test
SRCS
"log_severity_test.cc"
DEPS
absl::flags_internal
absl::flags_marshalling
absl::log_severity
absl::strings
GTest::gmock
GTest::gtest_main
)
absl_cc_library(
NAME
strerror
SRCS
"internal/strerror.cc"
HDRS
"internal/strerror.h"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
absl::core_headers
absl::errno_saver
)
absl_cc_test(
NAME
strerror_test
SRCS
"internal/strerror_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::strerror
absl::strings
GTest::gmock
GTest::gtest_main
)
absl_cc_library(
NAME
fast_type_id
HDRS
"internal/fast_type_id.h"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
)
absl_cc_test(
NAME
fast_type_id_test
SRCS
"internal/fast_type_id_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::fast_type_id
GTest::gtest_main
)
absl_cc_test(
NAME
optimization_test
SRCS
"optimization_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::core_headers
absl::optional
GTest::gtest_main
)

View File

@ -0,0 +1,721 @@
// 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
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT 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.
//
// 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).
#ifndef ABSL_BASE_ATTRIBUTES_H_
#define ABSL_BASE_ATTRIBUTES_H_
#include "absl/base/config.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
// (https://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 string checking if the
// compiler supports it; see the 'format' attribute in
// <https://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__) && !defined(__e2k__)
#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.
// Weak attributes did not work properly in LLVM's Windows backend before
// 9.0.0, so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598
// for further information.
// The MinGW compiler doesn't complain about the weak attribute until the link
// step, presumably because Windows doesn't use ELF binaries.
#if (ABSL_HAVE_ATTRIBUTE(weak) || \
(defined(__GNUC__) && !defined(__clang__))) && \
(!defined(_WIN32) || __clang_major__ < 9) && !defined(__MINGW32__)
#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 ABSL_HAVE_ATTRIBUTE(no_sanitize_address)
#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 ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS attribute
// above, but deals with initialized-ness rather than addressability issues.
// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC.
#if ABSL_HAVE_ATTRIBUTE(no_sanitize_memory)
#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 ABSL_HAVE_ATTRIBUTE(no_sanitize_thread)
#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 ABSL_HAVE_ATTRIBUTE(no_sanitize_undefined)
#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \
__attribute__((no_sanitize_undefined))
#elif ABSL_HAVE_ATTRIBUTE(no_sanitize)
#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 ABSL_HAVE_ATTRIBUTE(no_sanitize)
#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi")))
#else
#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI
#endif
// ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK
//
// Tells the SafeStack to not instrument a given function.
// See https://clang.llvm.org/docs/SafeStack.html for details.
#if ABSL_HAVE_ATTRIBUTE(no_sanitize)
#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK \
__attribute__((no_sanitize("safe-stack")))
#else
#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK
#endif
// ABSL_ATTRIBUTE_RETURNS_NONNULL
//
// Tells the compiler that a particular function never returns a null pointer.
#if ABSL_HAVE_ATTRIBUTE(returns_nonnull)
#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. Weak symbol support is
// a prerequisite. Labeled sections are not supported on Darwin/iOS.
#ifdef ABSL_HAVE_ATTRIBUTE_SECTION
#error ABSL_HAVE_ATTRIBUTE_SECTION cannot be directly set
#elif (ABSL_HAVE_ATTRIBUTE(section) || \
(defined(__GNUC__) && !defined(__clang__))) && \
!defined(__APPLE__) && ABSL_HAVE_ATTRIBUTE_WEAK
#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 results.
//
// When annotating a function, it must appear as the first part of the
// declaration or definition. The compiler will warn if the return value from
// such a function is unused:
//
// ABSL_MUST_USE_RESULT Sprocket* AllocateSprocket();
// AllocateSprocket(); // Triggers a warning.
//
// When annotating a class, it is equivalent to annotating every function which
// returns an instance.
//
// class ABSL_MUST_USE_RESULT Sprocket {};
// Sprocket(); // Triggers a warning.
//
// Sprocket MakeSprocket();
// MakeSprocket(); // Triggers a warning.
//
// Note that references and pointers are not instances:
//
// Sprocket* SprocketPointer();
// SprocketPointer(); // Does *not* trigger a warning.
//
// ABSL_MUST_USE_RESULT allows using cast-to-void to suppress the unused result
// warning. For that, warn_unused_result is used only for clang but not for gcc.
// 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.
//
// XRay isn't currently supported on Android:
// https://github.com/android/ndk/issues/368
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_always_instrument) && \
!defined(ABSL_NO_XRAY_ATTRIBUTES) && !defined(__ANDROID__)
#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
// ABSL_ATTRIBUTE_REINITIALIZES
//
// Indicates that a member function reinitializes the entire object to a known
// state, independent of the previous state of the object.
//
// The clang-tidy check bugprone-use-after-move allows member functions marked
// with this attribute to be called on objects that have been moved from;
// without the attribute, this would result in a use-after-move warning.
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::reinitializes)
#define ABSL_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]]
#else
#define ABSL_ATTRIBUTE_REINITIALIZES
#endif
// -----------------------------------------------------------------------------
// Variable Attributes
// -----------------------------------------------------------------------------
// ABSL_ATTRIBUTE_UNUSED
//
// Prevents the compiler from complaining about variables that appear unused.
//
// For code or headers that are assured to only build with C++17 and up, prefer
// just using the standard '[[maybe_unused]]' directly over this macro.
//
// Due to differences in positioning requirements between the old, compiler
// specific __attribute__ syntax and the now standard [[maybe_unused]], this
// macro does not attempt to take advantage of '[[maybe_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
//
// Instructs the compiler not to use natural alignment for a tagged data
// structure, but instead to reduce its alignment to 1. This attribute can
// either be applied to members of a structure or to a structure in its
// entirety. Applying this attribute (judiciously) to a structure in its
// entirety to optimize the memory footprint of very commonly-used structs is
// fine. Do not apply this attribute to a structure in its entirety if the
// purpose is to control the offsets of the members in the structure. Instead,
// apply this attribute only to structure members that need it.
//
// When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the
// natural alignment of structure members not annotated is preserved. Aligned
// member accesses are faster than non-aligned member accesses even if the
// targeted microprocessor supports non-aligned accesses.
#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_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 supported, GCC and Clang can issue a warning on switch labels
// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See
// clang documentation on language extensions for details:
// https://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."
#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough)
#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]]
#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough)
#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]]
#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough)
#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
#else
#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).
//
// Examples:
//
// class ABSL_DEPRECATED("Use Bar instead") Foo {...};
//
// ABSL_DEPRECATED("Use Baz() instead") void Bar() {...}
//
// template <typename T>
// ABSL_DEPRECATED("Use DoThat() instead")
// void DoThis();
//
// 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__) && defined(__cplusplus) && __cplusplus >= 201103L
#define ABSL_DEPRECATED(message) __attribute__((deprecated(message)))
#endif
#ifndef ABSL_DEPRECATED
#define ABSL_DEPRECATED(message)
#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)
#define ABSL_CONST_INIT [[clang::require_constant_initialization]]
#else
#define ABSL_CONST_INIT
#endif // ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization)
// ABSL_ATTRIBUTE_PURE_FUNCTION
//
// ABSL_ATTRIBUTE_PURE_FUNCTION is used to annotate declarations of "pure"
// functions. A function is pure if its return value is only a function of its
// arguments. The pure attribute prohibits a function from modifying the state
// of the program that is observable by means other than inspecting the
// function's return value. Declaring such functions with the pure attribute
// allows the compiler to avoid emitting some calls in repeated invocations of
// the function with the same argument values.
//
// Example:
//
// ABSL_ATTRIBUTE_PURE_FUNCTION int64_t ToInt64Milliseconds(Duration d);
#if ABSL_HAVE_CPP_ATTRIBUTE(gnu::pure)
#define ABSL_ATTRIBUTE_PURE_FUNCTION [[gnu::pure]]
#elif ABSL_HAVE_ATTRIBUTE(pure)
#define ABSL_ATTRIBUTE_PURE_FUNCTION __attribute__((pure))
#else
#define ABSL_ATTRIBUTE_PURE_FUNCTION
#endif
// ABSL_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function
// parameter or implicit object parameter is retained by the return value of the
// annotated function (or, for a parameter of a constructor, in the value of the
// constructed object). This attribute causes warnings to be produced if a
// temporary object does not live long enough.
//
// When applied to a reference parameter, the referenced object is assumed to be
// retained by the return value of the function. When applied to a non-reference
// parameter (for example, a pointer or a class type), all temporaries
// referenced by the parameter are assumed to be retained by the return value of
// the function.
//
// See also the upstream documentation:
// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
#elif ABSL_HAVE_ATTRIBUTE(lifetimebound)
#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
#else
#define ABSL_ATTRIBUTE_LIFETIME_BOUND
#endif
#endif // ABSL_BASE_ATTRIBUTES_H_

View File

@ -0,0 +1,109 @@
// 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
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT 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 {
ABSL_NAMESPACE_BEGIN
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
ABSL_NAMESPACE_END
} // namespace absl

View File

@ -0,0 +1,219 @@
// 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
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT 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 <utility>
#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/optimization.h"
#include "absl/base/port.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
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>
ABSL_ATTRIBUTE_NOINLINE
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_relaxed);
if (old_control != kOnceInit &&
old_control != kOnceRunning &&
old_control != kOnceWaiter &&
old_control != kOnceDone) {
ABSL_RAW_LOG(FATAL, "Unexpected value for control word: 0x%lx",
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.
// The base_internal::SpinLockWait() call returns either kOnceInit or
// kOnceDone. If it returns kOnceDone, it must have loaded the control word
// with std::memory_order_acquire and seen a value of kOnceDone.
uint32_t old_control = kOnceInit;
if (control->compare_exchange_strong(old_control, kOnceRunning,
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->exchange(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)...);
}
}
ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_BASE_CALL_ONCE_H_

View File

@ -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
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT 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/attributes.h"
#include "absl/base/const_init.h"
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace {
absl::once_flag once;
ABSL_CONST_INIT Mutex counters_mu(absl::kConstInit);
int running_thread_count ABSL_GUARDED_BY(counters_mu) = 0;
int call_once_invoke_count ABSL_GUARDED_BY(counters_mu) = 0;
int call_once_finished_count ABSL_GUARDED_BY(counters_mu) = 0;
int call_once_return_count ABSL_GUARDED_BY(counters_mu) = 0;
bool done_blocking ABSL_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*) ABSL_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
ABSL_NAMESPACE_END
} // namespace absl

187
third_party/abseil-cpp/absl/base/casts.h vendored Normal file
View File

@ -0,0 +1,187 @@
//
// 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
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT 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 <utility>
#include "absl/base/internal/identity.h"
#include "absl/base/macros.h"
#include "absl/meta/type_traits.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace internal_casts {
template <class Dest, class Source>
struct is_bitcastable
: std::integral_constant<
bool,
sizeof(Dest) == sizeof(Source) &&
type_traits_internal::is_trivially_copyable<Source>::value &&
type_traits_internal::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>
constexpr 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;
}
ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_BASE_CASTS_H_

View File

@ -0,0 +1,740 @@
//
// 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
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT 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/options.h"
#include "absl/base/policy_checks.h"
// Helper macro to convert a CPP variable to a string literal.
#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x
#define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x)
// -----------------------------------------------------------------------------
// Abseil namespace annotations
// -----------------------------------------------------------------------------
// ABSL_NAMESPACE_BEGIN/ABSL_NAMESPACE_END
//
// An annotation placed at the beginning/end of each `namespace absl` scope.
// This is used to inject an inline namespace.
//
// The proper way to write Abseil code in the `absl` namespace is:
//
// namespace absl {
// ABSL_NAMESPACE_BEGIN
//
// void Foo(); // absl::Foo().
//
// ABSL_NAMESPACE_END
// } // namespace absl
//
// Users of Abseil should not use these macros, because users of Abseil should
// not write `namespace absl {` in their own code for any reason. (Abseil does
// not support forward declarations of its own types, nor does it support
// user-provided specialization of Abseil templates. Code that violates these
// rules may be broken without warning.)
#if !defined(ABSL_OPTION_USE_INLINE_NAMESPACE) || \
!defined(ABSL_OPTION_INLINE_NAMESPACE_NAME)
#error options.h is misconfigured.
#endif
// Check that ABSL_OPTION_INLINE_NAMESPACE_NAME is neither "head" nor ""
#if defined(__cplusplus) && ABSL_OPTION_USE_INLINE_NAMESPACE == 1
#define ABSL_INTERNAL_INLINE_NAMESPACE_STR \
ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME)
static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != '\0',
"options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must "
"not be empty.");
static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
ABSL_INTERNAL_INLINE_NAMESPACE_STR[1] != 'e' ||
ABSL_INTERNAL_INLINE_NAMESPACE_STR[2] != 'a' ||
ABSL_INTERNAL_INLINE_NAMESPACE_STR[3] != 'd' ||
ABSL_INTERNAL_INLINE_NAMESPACE_STR[4] != '\0',
"options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must "
"be changed to a new, unique identifier name.");
#endif
#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0
#define ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_END
#define ABSL_INTERNAL_C_SYMBOL(x) x
#elif ABSL_OPTION_USE_INLINE_NAMESPACE == 1
#define ABSL_NAMESPACE_BEGIN \
inline namespace ABSL_OPTION_INLINE_NAMESPACE_NAME {
#define ABSL_NAMESPACE_END }
#define ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v) x##_##v
#define ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, v) \
ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v)
#define ABSL_INTERNAL_C_SYMBOL(x) \
ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, ABSL_OPTION_INLINE_NAMESPACE_NAME)
#else
#error options.h is misconfigured.
#endif
// -----------------------------------------------------------------------------
// 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
#if defined(__is_identifier)
#define ABSL_INTERNAL_HAS_KEYWORD(x) !(__is_identifier(x))
#else
#define ABSL_INTERNAL_HAS_KEYWORD(x) 0
#endif
#ifdef __has_feature
#define ABSL_HAVE_FEATURE(f) __has_feature(f)
#else
#define ABSL_HAVE_FEATURE(f) 0
#endif
// Portable check for GCC minimum version:
// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) \
(__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y))
#else
#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) 0
#endif
#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) \
(__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y))
#else
#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) 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(_MSC_VER) || \
(!defined(__clang__) && defined(__GLIBCXX__) && \
ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(4, 8))
#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 (but not NVCC).
#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__) && ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(7, 4) && \
(defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \
(defined(_MSC_VER) && !defined(__NVCC__))
#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1
#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1
#endif
// ABSL_HAVE_SOURCE_LOCATION_CURRENT
//
// Indicates whether `absl::SourceLocation::current()` will return useful
// information in some contexts.
#ifndef ABSL_HAVE_SOURCE_LOCATION_CURRENT
#if ABSL_INTERNAL_HAS_KEYWORD(__builtin_LINE) && \
ABSL_INTERNAL_HAS_KEYWORD(__builtin_FILE)
#define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1
#elif ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0)
#define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1
#endif
#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.
// * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator
// targeting iOS 9.x.
// * Xcode 10 moves the deployment target check for iOS < 9.0 to link time
// making ABSL_HAVE_FEATURE unreliable there.
//
#if ABSL_HAVE_FEATURE(cxx_thread_local) && \
!(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
#define ABSL_HAVE_THREAD_LOCAL 1
#endif
#else // !defined(__APPLE__)
#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.
// * 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(__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
// 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 ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(3, 6)
// Clang >= 3.6
#if ABSL_HAVE_FEATURE(cxx_exceptions)
#define ABSL_HAVE_EXCEPTIONS 1
#endif // ABSL_HAVE_FEATURE(cxx_exceptions)
#elif defined(__clang__)
// Clang < 3.6
// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro
#if defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions)
#define ABSL_HAVE_EXCEPTIONS 1
#endif // defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions)
// Handle remaining special cases and default to exceptions being supported.
#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \
!(ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) && \
!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 (macOS 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) || \
defined(__ASYLO__) || defined(__myriad2__)
#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_GETCPU
//
// Checks whether sched_getcpu is available.
#ifdef ABSL_HAVE_SCHED_GETCPU
#error ABSL_HAVE_SCHED_GETCPU cannot be directly set
#elif defined(__linux__)
#define ABSL_HAVE_SCHED_GETCPU 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_init(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(__MINGW32__)
// mingw32 doesn't provide alarm(2):
// https://osdn.net/projects/mingw/scm/git/mingw-org-wsl/blobs/5.2-trunk/mingwrt/include/unistd.h
// mingw-w64 provides a no-op implementation:
// https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/misc/alarm.c
#elif defined(__EMSCRIPTEN__)
// emscripten doesn't support signals
#elif defined(__Fuchsia__)
// Signals don't exist on fuchsia.
#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
// macOS 10.13 and iOS 10.11 don't let you use <any>, <optional>, or <variant>
// even though the headers exist and are publicly noted to work. See
// https://github.com/abseil/abseil-cpp/issues/207 and
// https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes
// libc++ spells out the availability requirements in the file
// llvm-project/libcxx/include/__config via the #define
// _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS.
#if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \
((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400) || \
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000) || \
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000))
#define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 1
#else
#define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 0
#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>) && defined(__cplusplus) && __cplusplus >= 201703L && \
!ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE
#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>) && defined(__cplusplus) && \
__cplusplus >= 201703L && !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE
#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